21 Commits

Author SHA1 Message Date
Vaillant Jeremy d7956ecdb4 chore(assets): re-import prop textures for ETC2/ASTC
Build Puzzle Quest / Validate GDScript (push) Successful in 27s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 37s
Build Puzzle Quest / Export Linux (push) Failing after 0s
Build Puzzle Quest / Export Windows (push) Failing after 0s
Build Puzzle Quest / Export Android (push) Failing after 0s
Build Puzzle Quest / Lint GDScript (push) Successful in 50s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 48s
Build Puzzle Quest / Export Linux (pull_request) Successful in 6m3s
Build Puzzle Quest / Export Windows (pull_request) Successful in 6m24s
Build Puzzle Quest / Export Android (pull_request) Successful in 7m8s
Adds the etc2 dest path + "etc2_astc" import format to every prop
texture sidecar. Generated by `godot --headless --import` after
flipping rendering/textures/vram_compression/import_etc2_astc to
true in project.godot (commit 46ab28f). Without these sidecars,
re-running --import on a clean checkout would regenerate them
anyway, but committing keeps imported_formats deterministic and
avoids spurious diffs on every CI / dev machine.

39 .import files touched, all under assets/props/. No texture
binaries changed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 21:19:05 +02:00
Vaillant Jeremy 4f9fa60fa0 ci(android): explicit apksigner step after Godot export
Build Puzzle Quest / Lint GDScript (push) Successful in 29s
Build Puzzle Quest / Validate GDScript (push) Successful in 35s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 39s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 23s
Build Puzzle Quest / Export Linux (push) Successful in 6m32s
Build Puzzle Quest / Export Windows (push) Successful in 6m44s
Build Puzzle Quest / Export Android (push) Successful in 7m41s
Build Puzzle Quest / Export Windows (pull_request) Successful in 5m30s
Build Puzzle Quest / Export Linux (pull_request) Successful in 6m10s
Build Puzzle Quest / Export Android (pull_request) Successful in 6m48s
Godot 4.6 produces an unsigned APK in headless mode on this
runner — verified by apksigner: "DOES NOT VERIFY, Missing
META-INF/MANIFEST.MF". The internal sign step seems to bail
silently (likely because the apksigner subprocess can't locate
java without inheriting JAVA_HOME). The export step still
reports success.

Sign the APK ourselves after the export with the same debug
keystore the workflow provisions. Idempotent if Godot ever
starts signing again; mandatory until then.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 20:59:33 +02:00
Vaillant Jeremy 46ab28f76f fix(android): enable ETC2/ASTC import + use versioned editor settings
Build Puzzle Quest / Validate GDScript (push) Successful in 25s
Build Puzzle Quest / Lint GDScript (push) Successful in 26s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 40s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 48s
Build Puzzle Quest / Export Linux (push) Successful in 6m18s
Build Puzzle Quest / Export Windows (push) Successful in 5m43s
Build Puzzle Quest / Export Android (push) Successful in 8m44s
Build Puzzle Quest / Export Linux (pull_request) Successful in 7m0s
Build Puzzle Quest / Export Windows (pull_request) Successful in 6m58s
Build Puzzle Quest / Export Android (pull_request) Successful in 5m34s
Two fixes that finally land the Android export. Verified locally
with godot 4.6.2-arch + downloaded 4.6 templates + Android SDK.

- project.godot: add
  rendering/textures/vram_compression/import_etc2_astc=true.
  Without it Godot refuses the Android export with "La plateforme
  cible nécessite une compression de texture « ETC2/ASTC »". In
  headless mode this surfaces as an *empty* configuration-errors
  block, which is what kept us stuck in CI.

- workflow: write Godot editor settings to
  editor_settings-${GODOT_VERSION}.tres (i.e. -4.6.tres on 4.6),
  not -4.tres. Godot 4.5+ uses a minor-version-suffixed settings
  file; the major-only name is ignored by 4.6, so our injected
  android_sdk_path / java_sdk_path / debug_keystore never reached
  the export plugin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 20:35:58 +02:00
Vaillant Jeremy 918328c42a fix(android): set explicit package/unique_name for export
Build Puzzle Quest / Lint GDScript (push) Successful in 30s
Build Puzzle Quest / Validate GDScript (push) Successful in 32s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 37s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 19s
Build Puzzle Quest / Export Windows (push) Successful in 5m4s
Build Puzzle Quest / Export Android (push) Failing after 7m32s
Build Puzzle Quest / Export Linux (push) Successful in 8m21s
Build Puzzle Quest / Export Linux (pull_request) Successful in 4m35s
Build Puzzle Quest / Export Windows (pull_request) Successful in 4m34s
Build Puzzle Quest / Export Android (pull_request) Failing after 5m16s
The Android export preset relied on Godot's $genname placeholder
("org.godotengine.$genname"). With the project name "Puzzle
Quest" containing a space, Godot 4 refuses the headless export
with:

  The project name does not meet the requirement for the package
  name format and will be updated to "puzzlequest". Please
  explicitly specify the package name if needed.

Pin both Android presets (AndroidTesting, AndroidDebug) to
com.devcrea.puzzlequest — clean, follows reverse-DNS, matches
the DevCrea organization.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 20:06:40 +02:00
Vaillant Jeremy fbc2b9247a ci: comment macOS, empty Windows icon path, fix Android keystore preset
Build Puzzle Quest / Validate GDScript (push) Successful in 43s
Build Puzzle Quest / Lint GDScript (push) Successful in 32s
Build Puzzle Quest / Export Windows (pull_request) Has been skipped
Build Puzzle Quest / Export Linux (push) Failing after 0s
Build Puzzle Quest / Export Windows (push) Failing after 1s
Build Puzzle Quest / Export Android (push) Failing after 0s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 25s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 26s
Build Puzzle Quest / Export Linux (pull_request) Successful in 4m9s
Build Puzzle Quest / Export Android (pull_request) Failing after 5m2s
Three follow-ups from run #12:

- export-desktop: comment out the macOS matrix entry. The preset
  is still missing in export_presets.cfg; the entry can be
  uncommented once the macOS preset is added in the Godot editor.

- export Windows: `application/icon` referenced
  res://releases/windows/project.ico, which has never been in the
  repo (releases/windows/ holds only .keep). Godot rejected the
  export with "Invalid icon path". Cleared the field in both
  WindowsDebug and WindowsTesting presets — Godot falls back to
  its built-in icon.

- export-android: Godot validation requires all three of
  keystore/debug{,_user,_password} to be set together (or all
  empty). The keystore step only patched keystore/debug and left
  the other two empty, triggering
  "Either Debug Keystore, Debug User AND Debug Password must be
  configured OR none of them". Patch all three now.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 19:39:42 +02:00
Vaillant Jeremy 4e159b1065 ci: fix lint venv, drop artifact cache, fix Android sdkmanager pipe
Build Puzzle Quest / Lint GDScript (push) Successful in 33s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 33s
Build Puzzle Quest / Validate GDScript (push) Successful in 42s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 25s
Build Puzzle Quest / Export macOS (pull_request) Failing after 4m55s
Build Puzzle Quest / Export Linux (pull_request) Successful in 7m3s
Build Puzzle Quest / Export Windows (pull_request) Failing after 6m53s
Build Puzzle Quest / Export Android (pull_request) Failing after 6m16s
Build Puzzle Quest / Export macOS (push) Failing after 6m27s
Build Puzzle Quest / Export Linux (push) Successful in 6m44s
Build Puzzle Quest / Export Windows (push) Failing after 4m48s
Build Puzzle Quest / Export Android (push) Failing after 4m23s
Three follow-up fixes from the first non-container run (#10):

- lint: Ubuntu 24.04 / Python 3.12 enforces PEP 668, so
  `pip install --user` exits with externally-managed-environment.
  Install gdtoolkit into a throwaway venv at /tmp/gdlint-venv
  instead.

- exports: drop the .godot/ artifact cache shared between
  `validate` and the export jobs. Gitea's artifact service returns
  404 on actions/download-artifact@v3 (v3 protocol incomplete on
  this server). Each export job now runs its own
  `godot --headless --import` before exporting — costs ~30s but
  avoids the failing cross-job artifact dependency.

- export-android: `yes | sdkmanager --licenses` returned 141
  (SIGPIPE) under `set -o pipefail` because sdkmanager closes
  stdin after accepting all licenses while `yes` keeps writing.
  Feed a finite `printf 'y\n%.0s' {1..50}` instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 19:26:06 +02:00
Vaillant Jeremy db2460b9ee ci: drop container: for Godot jobs, install via composite action
Build Puzzle Quest / Lint GDScript (push) Failing after 15s
Build Puzzle Quest / Lint GDScript (pull_request) Failing after 16s
Build Puzzle Quest / Validate GDScript (push) Successful in 47s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 50s
Build Puzzle Quest / Export Linux (push) Failing after 6m5s
Build Puzzle Quest / Export macOS (push) Failing after 7m5s
Build Puzzle Quest / Export Windows (push) Failing after 7m14s
Build Puzzle Quest / Export Android (push) Failing after 5m45s
Build Puzzle Quest / Export Linux (pull_request) Failing after 7m10s
Build Puzzle Quest / Export macOS (pull_request) Failing after 7m24s
Build Puzzle Quest / Export Windows (pull_request) Failing after 4m7s
Build Puzzle Quest / Export Android (pull_request) Failing after 3m3s
The first Gitea Actions runs failed at actions/checkout@v4 because
barichello/godot-ci:4.6 ships without Node.js, which the JS-based
checkout action requires. Rather than chase a Godot CI image that
bundles Node, drop the container: blocks entirely: the default
catthehacker/ubuntu:act-latest runner image already has Node /
Python / git / JDK, and Godot is installed per-job from the
official GitHub release.

Pulled the install logic into a local composite action at
.gitea/actions/setup-godot/ to avoid duplicating 15 lines of wget +
unzip across the three Godot-using jobs. Inputs:
  - version  (default 4.6)
  - templates (default false — export jobs flip to true)

Other tweaks:
- export-android now puts $ANDROID_HOME under $GITHUB_WORKSPACE so
  no sudo is needed; editor_settings-4.tres interpolates that path.
- export-android writes the keystore under /tmp instead of /root
  (catthehacker runners don't run as root).

README updated: jobs table reflects the new "Tooling installed by the
job" column, prerequisites no longer mention the Docker image, and
known-issue #1 is closed out with the dated fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 18:30:57 +02:00
Vaillant Jeremy 734b5931e9 docs(ci): record first-run failures + URL prefix fix
Adds a "Known issues from first runs" section to the workflow
README capturing what broke on 2026-05-17:

- Container jobs (validate, export-*) fail at actions/checkout@v4
  with `node: not found` because barichello/godot-ci:4.6 has no Node.
  Workflow fix pending.
- The earlier `actions/checkout` URL-prefix problem (Gitea behind
  YunoHost at /gitea/) is now resolved server-side by moving Gitea
  to the root; the note records this for future reference.
- Default-branch mismatch (Gitea = main, CLAUDE.md says dev).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 18:22:16 +02:00
Vaillant Jeremy 2d8ca9dfbb ci: trigger workflow on feature/godot-migration too
Build Puzzle Quest / Lint GDScript (push) Failing after 28s
Build Puzzle Quest / Export Linux (push) Has been cancelled
Build Puzzle Quest / Export macOS (push) Has been cancelled
Build Puzzle Quest / Export Windows (push) Has been cancelled
Build Puzzle Quest / Export Android (push) Has been cancelled
Build Puzzle Quest / Validate GDScript (push) Has been cancelled
Build Puzzle Quest / Lint GDScript (pull_request) Failing after 21s
Build Puzzle Quest / Export macOS (pull_request) Has been skipped
Build Puzzle Quest / Export Windows (pull_request) Has been skipped
Build Puzzle Quest / Validate GDScript (pull_request) Failing after 4m14s
Build Puzzle Quest / Export Linux (pull_request) Has been skipped
Build Puzzle Quest / Export Android (pull_request) Has been skipped
Temporary addition so the workflow can run before the branch is
merged into dev. Remove this branch from the push: list once dev
has the workflow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:38:19 +02:00
Vaillant Jeremy 238fccef95 Fix gdlint findings in Global / Database / Levels
- Global.gd: move @onready var animation below the regular vars
  (gdlint class-definitions-order expects onready vars after
  public/private vars).
- Database.gd::DB: move the three _*_PROPS constants above the vars
  (constants come before vars in a class body).
- Levels.gd:_search_button_to_use: drop the elif after a branch
  that returns (no-elif-return).
- Levels.gd:_gyroscope_changed_{down,up}: continuation lines of the
  multi-line return mixed two tabs + three spaces; normalised to
  pure tabs.

No semantic change: @onready is property-level so source ordering
doesn't affect init; elif after a return is equivalent to if; the
continuation indent is cosmetic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 14:48:20 +02:00
Vaillant Jeremy e883d662f2 Add gdlint job + gdlintrc to Gitea CI
Lints scripts/, db/, scenes/ via gdtoolkit==4.* on ubuntu-latest
(Python, no Godot needed), in parallel with the validate job.
addons/ (third-party LOD plugin) and developers/ (sandbox) are
left out. Non-blocking for now: the export jobs still only need
validate, so a lint regression won't break builds while the
Godot-3 leftover code is being cleaned up.

gdlintrc bumps max-line-length from 100 to 140 because Godot
$-style node paths and typed signatures routinely push past 100
without that being a real readability problem.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 14:48:13 +02:00
Vaillant Jeremy 410c135870 Replace Drone CI with Gitea Actions workflow
Drone server is gone; CI now lives in .gitea/workflows/build.yml.
Three jobs: GDScript validation (godot --headless --import + error
grep), desktop matrix (Windows / Linux / macOS), and Android (JDK 17
+ SDK installed at runtime, keystore from ANDROID_KEYSTORE_BASE64
secret or generated). Build only — Butler / itch.io deploy not wired.

Notes in .gitea/workflows/README.md cover the Godot-4 pre-reqs
(macOS preset to add, Linux/X11Debug likely renamed on first 4.x
save, Docker image tag) and how to plug Butler back in later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 12:36:34 +02:00
Vaillant Jeremy d61a0ffcb0 Add developers/.gdignore; let Godot 4 canonicalise saved scenes
The developers/aurelien sandbox scenes still reference legacy non-LOD
mesh paths (sm_book.mesh, sm_candlestick.mesh, ...) that don't exist
anymore — the production scenes were migrated to *_lod0/1/2.mesh.
Godot's full-project file scanner reads every .tscn at editor open
and emits 'Cannot open file' errors for each broken ext_resource,
even for scenes that the game never loads.

Mark developers/ as out-of-scope for Godot's filesystem walker with
a .gdignore at its root. The .import / .uid sidecars Godot had
generated for files inside (CheckLightmap.exr.import,
CheckLightmap.gd.uid) are auto-removed by the editor since they are
now orphaned metadata — only the source files (.tscn, .gd, .exr,
.lmbake) remain. Re-enabling the sandbox later just means deleting
the .gdignore; Godot will regenerate the sidecars.

The other diffs in this commit are Godot 4 canonicalising whatever
.tscn / .tres files were touched in the editor session that ran the
LightmapGI bake attempt: ext_resource uid= attributes added, format
bumped 2 -> 3, property order normalised. No behavioural change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:24:19 +02:00
Vaillant Jeremy 6146d84b87 Fix Levels.gd type inference + Database integer-division warning + brighten scenes
- scenes/levels/Levels.gd: replace 'var level := Global.database
  .level_by_index(...)' with explicit 'var level: LevelEntry = ...'.
  Global.database is typed RefCounted so the parser can't see DB's
  return types through the walrus operator. Two callsites.
- scripts/Database.gd: annotate the two 'range(data.size() / W)'
  loops with @warning_ignore('integer_division'). The division is
  intentional (row count = bytes / row width); Godot 4 warns by
  default in case the slash was a typo.
- env: ambient_light_energy 0.4 -> 1.0 in WarCraft.tscn, Home.tscn
  and env_warcraft.tres. 0.4 left the floor pitch-black; 1.0 is a
  compromise between the original 1.55 (oversaturated) and this.
  Re-baking the lightmap in the editor is still the right fix —
  this commit just keeps the scene playable in the meantime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:02:59 +02:00
Vaillant Jeremy c17769246f Replace M* table-wrapper classes with typed Resources; add type hints
Two related cleanups from the best-practice audit:

Task 3 — typed Resources instead of MBase / MScene / MLevel / MSetting

The old model classes wrapped the godot_db_manager Table API: each row
read went through table.get_data_at_row_idx(int), Cell.get_data(),
and 'as int' / 'as String' casts that don't actually parse anything
in Godot 4. m_value, m_lock, m_label, ... members shadowed the cell
indirection. Setters round-tripped through table.edit_data() +
Global.database.save_db(). That's a lot of plumbing for what is, in
the end, three flat tables of static strings.

Introduce three @export-typed Resources:
  db/scene_entry.gd     class_name SceneEntry
  db/level_entry.gd     class_name LevelEntry
  db/settings_data.gd   class_name SettingsData

Rewrite scripts/Database.gd so Database.DB holds:
  settings: SettingsData
  levels:   Array[LevelEntry]
  scenes:   Array[SceneEntry]

Build them once at startup from ahog.json, and serialise back to the
same JSON shape on save() so existing progress files keep working.
LevelEntry carries its own object_to_find / object_finding / reset
methods (talking to Global.database for cross-table lookups), and
SceneEntry carries its own mesh_path / audio_sound. Per-scene
dissolve state (value, tick_reference, dissolved) lives on
SceneEntry as non-exported runtime fields.

Delete db/MBase.gd / db/MScene.gd / db/MLevel.gd / db/MSetting.gd.

Update consumers:
- scripts/Setting.gd: read/write Global.database.settings directly,
  call Global.database.save() after each setter.
- scenes/levels/Levels.gd: iterate Global.database.scenes_for_level(
  current_scene_int) instead of mscene.new(i) for every row; scene
  state reads (scene.lock, scene.mesh, scene.counter, ...) replace
  scene.lock() / scene.mesh() / scene.counter() method calls; runtime
  dissolve state lives on the SceneEntry instance instead of mutable
  m_value / m_tick_reference members on MScene; 'dissolved' flag
  replaces set_mesh(null) signalling.
- scenes/UI/choose_scenes/ChooseScene.gd: iterate Global.database
  .levels; level.name / level.thumb property access in place of
  level.name() / level.thumbnail(). configure_reset() loses its
  redundant index argument (LevelEntry knows its own index).
- scripts/event.gd: _on_reset_level signature now takes LevelEntry,
  reset path drops index forwarding.

Task 2 — type hints across the remaining scripts

scripts/Global.gd, scenes/Main.gd, scenes/UI/ending/Ending.gd,
scenes/UI/loading/Loading.gd, scenes/UI/settings/Settings.gd: add
typed parameters and -> return annotations. current_scene_int is now
'int = -1' (sentinel) so callers don't fall into Variant comparisons;
event.gd:_on_reset_level resets it to -1 instead of null.
Settings.gd no longer wraps button_pressed in int() before passing to
the now-typed bool setters.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:58:11 +02:00
Vaillant Jeremy 60d9f614ee Replace Event + GlobalAnimation autoloads with class_name + static funcs
Two of the five autoloads were stateless helper bundles, not the
persistent application-wide systems that the Godot 4 best-practice
guide reserves autoload slots for. Convert them to plain classes with
all-static methods so they no longer need a Node living under /root.

- scripts/Animation.gd -> scripts/game_animation.gd (renamed:
  conflict with the built-in Animation class; the autoload sidestepped
  it by being called GlobalAnimation). class_name GameAnimation,
  every helper static. The dissolve tween now captures its target
  material in a lambda closure, eliminating the current_material
  member that the autoload kept as shared mutable state.
- scripts/Event.gd -> scripts/event.gd, class_name Event, every
  handler static. Added Event.level_pressed(name) -> Callable for the
  one place ChooseScene needed dynamic lookup of a per-level handler
  (replaces the old _build_method('_on_' + name + '_pressed') +
  Callable(autoload, string) reflection trick with an explicit match).

Updated call sites:
- scripts/Global.gd: animation.connect('animation_started',
  Callable(Event, '...')) -> animation.animation_started.connect(
  Event._loading_is_started). Same for animation_finished.
- scenes/levels/Levels.gd: GlobalAnimation.* -> GameAnimation.*;
  Quit/TextureButton.connect('pressed', Callable(Event, '...')) ->
  pressed.connect(Event._on_main_scene_pressed).
- scenes/UI/choose_scenes/ChooseScene.gd: per-level button connects
  go through Event.level_pressed(); reset button's bound callable now
  reads Event._on_reset_level.bind(...); cleanup no longer relies on
  is_connected with an unbound Callable (which would never match a
  bound one anyway) -- iterates reset.pressed.get_connections()
  instead. Drop the now-dead _build_method helper.

Also: organise scripts/ by promoting the one-shot migration helpers
(migrate_shaders, migrate_misc, resave_scenes, devisualize_shaders,
find_visualshaders) into scripts/migration/. They are not part of
the runtime and should not be browsable next to the autoloads.

Autoload count goes 5 -> 3 (Loading, Global, Setting remain --
Setting will move to a Resource in a later refactor).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:50:00 +02:00
Vaillant Jeremy ca67fc6ec3 Convert all VisualShaders to plain Shaders; clean editor noise
Godot 4 emits two unavoidable warnings every time it reconstructs a
Godot-3-authored VisualShader graph: 'graph_offset property is
deprecated' (the editor's pan position, removed in 4.x) and
'connect_nodes_forced: Index p_from_port = 1 is out of bounds'
(node-graph ports that no longer line up). The compiled GLSL inside
each ShaderMaterial is correct; only the graph reconstruction is
broken.

scripts/devisualize_shaders.gd walks every .material, .tres, and
.mesh under res:// and replaces ShaderMaterial.shader from
VisualShader to a plain Shader carrying the same .code. 15 materials
converted (font outline, dissolve, color tints, book/candle/godet/
growler/parchment/rock-floor/stool/table). Godot now loads the
compiled shader directly with no graph reconstruction → both
warnings gone, rendering identical.

Also:
- scripts/resave_scenes.gd: load + re-save every .tscn so inline
  ArrayMesh sub-resources (notably WarCraft.tscn::17, the baked
  floor) move from Godot-3 PoolByteArray to Godot-4 PackedByteArray
  surface format. Silences 'Mesh uses old surface format'.
- scripts/find_visualshaders.gd: companion audit tool that lists
  every Resource still backed by a VisualShader. Useful if new
  legacy materials get added.
- Drop the now-orphan inline VisualShader / ShaderMaterial sub-
  resources (id 1..17) from Summary.tscn. The PanelWood lost its
  screen-blend tint material; a plain Panel renders fine and the
  effect can be re-authored as a hand-written shader if wanted.
- Add releases/.gdignore and tighten .gitignore so Godot stops
  warning 'Detected another project.godot at res://releases'. The
  releases/ directory has its own placeholder project.godot which
  Godot would otherwise flag at every editor open.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:42:28 +02:00
Vaillant Jeremy 81e6ceb003 Silence Godot 4 editor warnings (debugger)
Address every warning that surfaced in the running game's debugger:

- Drop deprecated 'graph_offset = Vector2(...)' lines from the three
  in-tree VisualShader resources (red.tres, green.tres,
  Summary.tscn). The property is editor-only graph pan, ignored at
  runtime but warns at load.
- Add android/.gdignore so Godot stops scanning the build template
  copies of red.tres/green.tres (which still had graph_offset). Tighten
  .gitignore to keep tracking the .gdignore marker only.
- Drop the broken 'nodes/fragment/connections = ...' line from the
  inline VisualShader in Summary.tscn — connections referenced
  out-of-bounds ports (e.g. port 1 on a 1-output node). The
  pre-compiled 'code = ...' string is kept so rendering is unaffected.
- Drop the orphaned 'ext_resource WarCraft.lmbake' from WarCraft.tscn:
  the LightmapGI node no longer references it but Godot still loaded
  the (Godot-3-format) blob from the ext_resource declaration alone,
  triggering '(p_data.size() % 4) != 0'.
- Animation tracks: SlideReset (Template.tscn), BorderAnim
  (Loading.tscn), and ObjectFindAll (ListObjects.tscn) each had a
  bezier track with empty PackedFloat32Array keys, which
  AnimationMixer rejects in Godot 4. Drop the empty x track in each
  (the y track held the actual motion).
- Re-save 57 .mesh files via scripts/migrate_misc.gd so the surface
  format is the current Godot 4 variant. sm_stackgold.mesh in
  particular triggered the deprecation warning every load.

GDScript: rename function parameters and locals that shadowed
Node.name / Node.value in:
- db/MScene.gd (set_lock, set_mesh, set_tick_reference, set_value)
- scripts/Setting.gd untouched (no shadow, false positive earlier)
- scenes/UI/choose_scenes/ChooseScene.gd (_load_scene, _build_path,
  _build_method)
- scenes/levels/Levels.gd (_create_animation_slide,
  _create_animation_warning, _add_animation_to_player,
  _create_button_info, _node_object_list)

lod plugin: Godot 4 added 'lod_bias' as a native property on
VisualInstance3D, which collided with the plugin's 'lod_bias' member
across all five lod_*.gd files. Rename to 'lod_distance_bias' so the
scripts parse again. Also drop Light3D.shadow_color writes in
lod_omni_light.gd and lod_spot_light.gd — that property was removed
in Godot 4, so the related shadow_value computation became dead code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:28:22 +02:00
Vaillant Jeremy 601bc649dd Center menu button labels: clear stale Main.tscn overrides
Summary.tscn was correctly set up (Label anchored to full button rect,
horizontal/vertical_alignment = 1). But Main.tscn — which instances
Summary.tscn as UI_summary — had per-Label overrides that reset the
anchors back to 0 and shrunk the Label rect to 1x23 px (legacy from
Godot 3 where margin-based positioning was the default), making the
text render in the top-left 1 px corner.

Drop the layout_mode=0 / anchor_right=0 / anchor_bottom=0 / offset_*
overrides on each ButtonPuzzle/Setting/Credits/Quit Label so they
inherit Summary.tscn's full-rect anchors and the centered alignment
becomes visible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:08:54 +02:00
Vaillant Jeremy 5148599e33 Fix Summary.tscn vertical separator: stretch_mode 2 -> 1
In Godot 3 the TextureRect stretch_mode enum included a deprecated
"Scale on Expand" at value 0, so Tile=2. Godot 4 dropped that value
and shifted everything down: Tile is now 1. The convert-3to4 tool
does not remap enum values, so the separator at the right edge of
the menu kept Godot 3's Tile=2, which Godot 4 reads as Keep — the
texture rendered once at natural size at the top instead of tiling
down the full menu height.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 20:57:38 +02:00
Vaillant Jeremy 6f3f8b8f64 Wire up UI in Godot 4: fonts, translations, layout, fog, shadow
Discovered while playtesting the migrated build. Each fix has a
specific Godot-3-to-4 cause that the --convert-3to4 tool did not catch.

Fonts:
- Replace 4 .tres font wrappers (MKX_Base, kirsty_base/medium/title)
  with FontVariation pointing at the .otf/.ttf source. Godot 3
  DynamicFont with size= and font_data= is invalid in Godot 4 (those
  properties don't exist on FontFile).
- Apply size 46 via theme_override_font_sizes/font_size on the 5
  Labels that used kirsty_title.tres (LabelLoading + 4 in Summary).
- Drop the broken VisualShader text_outline.material from the 4
  Labels in Summary — Index p_from_port errors in Godot 4 meant
  COLOR was never written, so text rendered invisible.
- Migrate VisualShader nodes inside text_outline.material (compressed
  asset; updated by the inspect/migrate scripts).

Translations:
- Move project.godot section from [locale] (Godot 3) to
  [internationalization] with locale/translations=... (Godot 4). The
  old section was silently ignored so tr() returned the raw msgid.
- Adjust Setting.translate_int_to_locale to return "en"/"fr" to
  match what the .po files declare (was "en_GB"/"fr_FR", which Godot
  3 fell back from automatically but Godot 4 does not).

Label alignment (Godot 3 names not auto-renamed):
- align -> horizontal_alignment, valign -> vertical_alignment across
  9 .tscn files.

Background / Loading / ChooseScene layout:
- Rewrite Background.tscn from a VisualShader-textured Panel to a
  plain TextureRect (the visual shader connection ports went out of
  bounds in Godot 4, leaving the panel grey on scene reload).
- Set layout_mode=1 + anchors_preset=15 on BackgroundPicture
  instances in Main.tscn and Loading.tscn — Godot 4 inheritance no
  longer applies the .tscn-root's anchors to an instanced child
  unless layout_mode is set to Anchors mode explicitly.
- Replace scroll_horizontal_enabled (Godot 3) with
  horizontal_scroll_mode/vertical_scroll_mode (Godot 4) on
  ChooseScene's ScrollContainer.
- Add theme_override_styles/panel = StyleBoxEmpty on the
  ScrollContainer (Godot 4 ScrollContainer ships a default dark
  panel style that Godot 3 did not).
- Hide BackgroundTile in Template.tscn — it points at
  UI-level-btn-shadow.png (228x228, 83% opaque black) which used to
  render at natural size in Godot 3 but is stretched to fill the
  456px rect in Godot 4, leaving a big black square below each
  thumbnail. The proper drop-shadow needs a shader or 9-patch.
- TextureRect.expand=true (Godot 3) -> expand_mode=1 (Godot 4) on
  ThumbnailLevel and TopPart's content rects.

Lighting:
- background_mode 3 (which used to mean Sky in Godot 3) -> 2 (Sky in
  Godot 4; 3 is now Canvas, producing a black background).
- background_sky -> sky, background_energy -> background_energy_multiplier,
  fog_color -> fog_light_color, fog_height_min -> fog_height; drop
  fog_height_enabled / fog_height_max / fog_height_curve /
  dof_blur_far_distance (no longer exist).
- Add fog_mode = 1 so Godot 4 uses fog_depth_* instead of the new
  default fog_density-based exponential fog (which rendered as a
  thick white cloud).
- ambient_light_energy 1.55 -> 0.4 — the new pipeline interprets
  the value much more strongly so 1.55 produced a saturated pink scene.
- Remove the light_data = ExtResource(41) reference to
  WarCraft.lmbake — Godot 3 baked lightmap binary format is
  incompatible with Godot 4. Re-bake in editor when ready.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 20:55:47 +02:00
211 changed files with 2716 additions and 3009 deletions
+43
View File
@@ -0,0 +1,43 @@
name: Setup Godot
description: Download a Godot headless Linux binary and (optionally) export templates.
inputs:
version:
description: Godot version (e.g. 4.6). Templates land under <version>.stable.
required: false
default: "4.6"
templates:
description: Install export templates too. "true" / "false".
required: false
default: "false"
runs:
using: composite
steps:
- name: Install Godot ${{ inputs.version }}
shell: bash
run: |
set -euo pipefail
VER="${{ inputs.version }}"
URL="https://github.com/godotengine/godot/releases/download/${VER}-stable/Godot_v${VER}-stable_linux.x86_64.zip"
wget -q "$URL" -O /tmp/godot.zip
mkdir -p "$HOME/bin"
unzip -q /tmp/godot.zip -d /tmp
mv "/tmp/Godot_v${VER}-stable_linux.x86_64" "$HOME/bin/godot"
chmod +x "$HOME/bin/godot"
echo "$HOME/bin" >> "$GITHUB_PATH"
"$HOME/bin/godot" --version
- name: Install export templates
if: inputs.templates == 'true'
shell: bash
run: |
set -euo pipefail
VER="${{ inputs.version }}"
URL="https://github.com/godotengine/godot/releases/download/${VER}-stable/Godot_v${VER}-stable_export_templates.tpz"
wget -q "$URL" -O /tmp/templates.tpz
DEST="$HOME/.local/share/godot/export_templates/${VER}.stable"
mkdir -p "$DEST"
unzip -q /tmp/templates.tpz -d /tmp/templates_extracted
mv /tmp/templates_extracted/templates/* "$DEST/"
ls "$DEST" | head
+118
View File
@@ -0,0 +1,118 @@
# Gitea Actions CI
Workflow defined in [`build.yml`](./build.yml). Triggered on push / PR to
`dev` and `main`, or manually via `workflow_dispatch`.
## Jobs
All jobs run on the default `ubuntu-latest` runner image (which already
ships Node, Python, git, wget, unzip, etc.). Godot is installed per-job
via the local composite action [`.gitea/actions/setup-godot`](../actions/setup-godot/action.yml),
which downloads the official Linux binary from the godotengine GitHub
release and (optionally) export templates into `$HOME`.
| Job | Tooling installed by the job | Role |
|------------------|---------------------------------------------------------------------------|------------------------------------------------------------------------------------------|
| `validate` | Godot binary (no templates) | `godot --headless --import` then grep for `SCRIPT ERROR` / `Parse Error`. Uploads `.godot/` cache. |
| `lint` | `gdtoolkit==4.*` via `pip` | `gdlint scripts db scenes`. Parallel to `validate`; does not gate exports yet. |
| `export-desktop` | Godot binary + export templates | Matrix: Windows / Linux / macOS. Reuses the import cache, uploads each binary as artifact. |
| `export-android` | Godot binary + export templates + JDK 17 + Android SDK (under `$GITHUB_WORKSPACE/.android-sdk`) | Provisions keystore, writes `editor_settings-4.tres` with SDK / JDK paths, exports APK. |
Artifacts are kept 14 days, accessible from the Gitea run page.
## Prerequisites before the first successful run
1. **Godot version**`GODOT_VERSION` is set at the top of the workflow
(currently `4.6`). The setup action expects a stable release on the
godotengine GitHub releases page; bump in lockstep with the project.
2. **macOS preset missing** — add it in Godot Editor → Project → Export →
Add → macOS, name it exactly `macOS` (or change the matrix entry). The
`.zip` will be unsigned; on Mac it needs
`xattr -dr com.apple.quarantine` to launch.
3. **`Linux/X11Debug` preset** — Godot-3-era name. Reopen the project in
Godot 4 once and re-save the preset (the editor may rename it). Update
the matrix `preset:` field accordingly if it does.
4. **Gitea runner**`act_runner` with the default
`catthehacker/ubuntu:act-latest` image is enough; no Docker-in-Docker
needed now that no job uses `container:`. The runner must reach
`github.com` (for actions + Godot release downloads) and
`dl.google.com` (for the Android SDK).
5. **Optional secret** `ANDROID_KEYSTORE_BASE64``base64 -w0 debug.keystore`,
stored as a Gitea repo secret. Without it, a throwaway keystore is
generated per run, so the APK signature changes every build.
## Linting
`gdlint` (from Scony's `gdtoolkit`) runs in the `lint` job over `scripts/`,
`db/`, and `scenes/`. `addons/` (third-party LOD plugin) and `developers/`
(sandbox) are intentionally excluded.
The job is **non-blocking** today — the export jobs only depend on
`validate`, so a lint failure prints warnings but still produces binaries.
Once the codebase is clean, switch the export jobs' `needs: validate` to
`needs: [validate, lint]` to make lint a hard gate.
Suppress specific rules per-line with `# gdlint: disable=<rule>` or
project-wide with a `gdlintrc` file at the repo root (see
[gdtoolkit docs](https://github.com/Scony/godot-gdscript-toolkit/wiki)).
## Known issues from first runs
Captured from the first triggered runs on `feature/godot-migration`
(2026-05-17). Both must be resolved before the workflow can pass.
### 1. Container jobs failed with `node: not found` (resolved 2026-05-17)
The first runs used `container: barichello/godot-ci:4.6` for the Godot
jobs. That image does not ship Node.js, so `actions/checkout@v4` (a JS
action) crashed at startup with
`OCI runtime exec failed: exec: "node": executable file not found`.
Resolved by removing every `container:` block. The runner's default
`catthehacker/ubuntu:act-latest` image already has Node / Python / git /
JDK, and Godot is now installed at the start of each job via the local
composite action `.gitea/actions/setup-godot/`.
### 2. `actions/checkout` clones the wrong URL (resolved 2026-05-17)
The first runs failed at clone time because the runner asked for
`https://dev.stilobique.com/darknight/puzzle-quest/info/refs` while
Gitea was mounted under `/gitea/` behind YunoHost — the request was
intercepted by the YunoHost SSO at the root and redirected before
reaching Gitea.
Resolved by relocating Gitea to the root: it now serves at
`https://dev.stilobique.com/` directly (API at `/api/v1/...`,
`clone_url` at `/<owner>/<repo>.git`). The runner-injected
`GITHUB_SERVER_URL` and the actual Gitea base URL now agree.
If Gitea is ever moved back under a sub-path, the fix is `ROOT_URL` in
`app.ini` (`[server] ROOT_URL = https://<host>/<prefix>/`) or
re-registering `act_runner` with the full instance URL.
### 3. Default-branch mismatch
The Gitea API reports `default_branch: main` for the repo, but
`CLAUDE.md` describes `dev` as the default. The workflow listens to both,
so jobs trigger correctly either way, but the "Workflows" sidebar in the
Gitea UI reads from whatever the actual default branch is. If you intend
`dev` to be the default, update it under repo Settings → Branches.
## Differences from the old `.drone.yml`
- No more Drone, no more Butler — build only, artifacts downloadable from
the Gitea UI.
- GDScript validation step before export (didn't exist).
- `.godot/` import cache shared between jobs (faster reruns).
- Keystore via Gitea secret instead of a public pCloud link.
- macOS target added (preset still to be created in Godot).
- `master` / empty `ReleaseVersion` pipeline → replaced by triggers on
`main` (release branch per `CLAUDE.md`).
## Future: itch.io deploy via Butler
Not wired. When you want it back, add a `deploy-itch` job gated on tag
push (`v*`) that downloads the artifacts and runs
`butler push <dir> dev-crea/ahog:<channel>` with `BUTLER_API_KEY` from
secrets. Channels used historically:
`windows`, `linux`, `android`, `mac`.
+217
View File
@@ -0,0 +1,217 @@
name: Build Puzzle Quest
on:
push:
branches: [dev, main, feature/godot-migration]
pull_request:
branches: [dev, main]
workflow_dispatch:
env:
GODOT_VERSION: "4.6"
jobs:
# ---------------------------------------------------------------------------
# 1. GDScript validation — parse every script and fail on errors / warnings.
# ---------------------------------------------------------------------------
validate:
name: Validate GDScript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.gitea/actions/setup-godot
with:
version: ${{ env.GODOT_VERSION }}
- name: Import project (parses every .gd / .tscn)
run: |
godot --headless --import 2>&1 | tee /tmp/godot-import.log || true
- name: Fail on parse / script errors
run: |
if grep -qE "SCRIPT ERROR|Parse Error|ERROR: .*\.gd" /tmp/godot-import.log; then
echo "::error::GDScript errors detected during import"
grep -E "SCRIPT ERROR|Parse Error|ERROR: .*\.gd" /tmp/godot-import.log
exit 1
fi
# ---------------------------------------------------------------------------
# 2. Static analysis — gdlint from Scony's gdtoolkit (Python, no Godot).
# Runs in parallel with `validate`. Exports do NOT depend on this job,
# so a lint failure does not block builds while the Godot-3 leftovers
# are still being cleaned up. Once the tree is clean, add this job to
# the `needs:` of the export jobs to make it a hard gate.
# ---------------------------------------------------------------------------
lint:
name: Lint GDScript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install gdtoolkit
run: |
python3 -m venv /tmp/gdlint-venv
/tmp/gdlint-venv/bin/pip install --quiet "gdtoolkit==4.*"
echo "/tmp/gdlint-venv/bin" >> "$GITHUB_PATH"
- name: Run gdlint
run: gdlint scripts db scenes
# ---------------------------------------------------------------------------
# 3. Desktop exports — runs in parallel.
# macOS is commented out until a preset is added in the Godot editor
# (export_presets.cfg has none today). Restore the entry once the preset
# exists; the matrix is otherwise ready to take it.
# ---------------------------------------------------------------------------
export-desktop:
name: Export ${{ matrix.platform }}
needs: validate
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- platform: Windows
preset: WindowsDebug
output: releases/windows/Puzzle-Quest.exe
artifact_path: releases/windows
- platform: Linux
preset: Linux/X11Debug
output: releases/linux/Puzzle-Quest.x86_64
artifact_path: releases/linux
# - platform: macOS
# preset: macOS
# output: releases/macos/Puzzle-Quest.zip
# artifact_path: releases/macos
steps:
- uses: actions/checkout@v4
- uses: ./.gitea/actions/setup-godot
with:
version: ${{ env.GODOT_VERSION }}
templates: "true"
- name: Import project
run: godot --headless --import || true
- name: Prepare output dir
run: mkdir -p "${{ matrix.artifact_path }}"
- name: Export ${{ matrix.platform }}
run: godot --headless --export-debug "${{ matrix.preset }}" "${{ matrix.output }}"
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: PuzzleQuest-${{ matrix.platform }}
path: ${{ matrix.artifact_path }}
if-no-files-found: error
retention-days: 14
# ---------------------------------------------------------------------------
# 4. Android export — Godot + JDK 17 + Android SDK installed in $HOME.
# Provide ANDROID_KEYSTORE_BASE64 as a Gitea secret for a stable signature;
# otherwise a fresh debug keystore is generated on each run.
# ---------------------------------------------------------------------------
export-android:
name: Export Android
needs: validate
runs-on: ubuntu-latest
env:
ANDROID_HOME: ${{ github.workspace }}/.android-sdk
steps:
- uses: actions/checkout@v4
- uses: ./.gitea/actions/setup-godot
with:
version: ${{ env.GODOT_VERSION }}
templates: "true"
- name: Install JDK 17
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends openjdk-17-jdk
echo "JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> "$GITHUB_ENV"
- name: Install Android command-line tools + SDK
run: |
set -euo pipefail
mkdir -p "$ANDROID_HOME/cmdline-tools"
wget -q https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O /tmp/cmdline.zip
unzip -q /tmp/cmdline.zip -d "$ANDROID_HOME/cmdline-tools"
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
# `yes |` returns 141 (SIGPIPE) under `set -o pipefail` once sdkmanager
# closes its stdin — feed a finite stream of "y" answers instead.
printf 'y\n%.0s' {1..50} | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses >/dev/null
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" \
"platform-tools" "platforms;android-34" "build-tools;34.0.0" >/dev/null
- name: Provision debug keystore
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
if [ -n "${ANDROID_KEYSTORE_BASE64:-}" ]; then
echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > /tmp/debug.keystore
else
keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android \
-keystore /tmp/debug.keystore -storepass android \
-dname "CN=Android Debug,O=Android,C=US" -validity 9999
fi
# Godot rejects exports unless all three keystore/debug{,_user,_password}
# are set together (or all three empty) — patch every one.
sed -i 's@keystore/debug=".*"@keystore/debug="/tmp/debug.keystore"@g' export_presets.cfg
sed -i 's@keystore/debug_user=".*"@keystore/debug_user="androiddebugkey"@g' export_presets.cfg
sed -i 's@keystore/debug_password=".*"@keystore/debug_password="android"@g' export_presets.cfg
- name: Write Godot editor settings (Android SDK / JDK paths)
run: |
mkdir -p ~/.config/godot
# Godot 4.5+ uses a minor-version-suffixed settings file
# (editor_settings-4.6.tres for 4.6), not the major-only -4.tres.
cat > ~/.config/godot/editor_settings-${GODOT_VERSION}.tres <<EOF
[gd_resource type="EditorSettings" format=3]
[resource]
export/android/android_sdk_path = "${ANDROID_HOME}"
export/android/java_sdk_path = "/usr/lib/jvm/java-17-openjdk-amd64"
export/android/debug_keystore = "/tmp/debug.keystore"
export/android/debug_keystore_user = "androiddebugkey"
export/android/debug_keystore_pass = "android"
EOF
- name: Import project
run: godot --headless --import || true
- name: Prepare output dir
run: mkdir -p releases/android
- name: Export Android APK
run: godot --headless --export-debug "AndroidDebug" "releases/android/Puzzle-Quest.apk"
- name: Sign + verify APK
run: |
set -euo pipefail
APK="releases/android/Puzzle-Quest.apk"
APKSIGNER="$ANDROID_HOME/build-tools/34.0.0/apksigner"
# Godot 4.6 sometimes ships an unsigned APK from the headless
# export (sign step skips silently when its internal apksigner
# call can't locate java). Re-sign unconditionally — idempotent
# if Godot did sign, and guarantees a valid APK if it didn't.
"$APKSIGNER" sign \
--ks /tmp/debug.keystore \
--ks-pass pass:android \
--ks-key-alias androiddebugkey \
--key-pass pass:android \
--v1-signing-enabled true \
--v2-signing-enabled true \
--v3-signing-enabled true \
"$APK"
"$APKSIGNER" verify --verbose "$APK"
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: PuzzleQuest-Android
path: releases/android
if-no-files-found: error
retention-days: 14
+6 -2
View File
@@ -10,7 +10,9 @@
.godot/
# Android build template directory generated by the editor
android/
# (the .gdignore file is kept; everything else under android/ is build output)
android/*
!android/.gdignore
export.cfg
@@ -65,7 +67,9 @@ $RECYCLE.BIN/
# End of https://www.toptal.com/developers/gitignore/api/godot,linux,windows
# Ignore folders releases and build Android
releases
# (the .gdignore marker is tracked so Godot skips scanning this directory)
releases/*
!releases/.gdignore
# Ignore override godot
override.cfg
+173
View File
@@ -0,0 +1,173 @@
# Puzzle Quest
Hidden-object game built with **Godot 4.6** (single renderer: Forward+).
Branched from a Godot 3.3 codebase — migration is recent, expect leftover
Godot-3-isms to occasionally surface.
## Run
```
godot --editor # open project in the editor
godot # run the main scene (scenes/Main.tscn)
```
The system package `godot` (Arch `extra/godot`) is the project's Godot. There
is no in-repo Godot binary.
## Architecture
**Autoloads** (declared in `project.godot [autoload]`, loaded in this order):
| Name | Source | Role |
|------------------|---------------------------------------|-------------------------------------------------------------------|
| `Loading` | `scenes/UI/loading/Loading.tscn` | Full-screen transition overlay (BG + animated border + progress) |
| `Global` | `scripts/Global.gd` | Async scene loader (`goto_scene(path)`) + `database` reference |
| `Setting` | `scripts/Setting.gd` | Reads/writes the settings table; applies locale/resolution/fullscreen |
| `Event` | `scripts/Event.gd` | Static handlers connected to scene buttons (Warcraft / Home / reset / back) |
| `GlobalAnimation`| `scripts/Animation.gd` | Tween-based dissolve + HUD slide/warning animations |
**Database (`scripts/Database.gd`)**
- Plain JSON at `db/ahog.json`. Three tables: `settings`, `levels`, `scenes`.
- On Android the file is copied once to `user://database.json` and written
there (game saves modify lock state per item).
- `Global.database` is a `Database.DB` instance exposing
`get_table_by_name(name)` and `save_db()`. Each `Table` exposes
`get_data_at_row_idx(row_id)`, `edit_data(prop_id, row_id, value)`,
`m_rows_count`, `get_data_by_prop_name_and_data(prop_name, value)`,
`get_dictionary_by_prop_name_and_data(prop_name, value)`.
- `db/M*.gd` are typed accessors (MBase / MScene / MLevel / MSetting) that
read rows via the API above — extend these, not the JSON shape directly.
**Scene transitions** (`Global.goto_scene(path)`)
Uses `ResourceLoader.load_threaded_request` + `load_threaded_get_status` +
`load_threaded_get` (Godot 4 API; the original `load_interactive`/`poll()`
was removed). The Loading overlay (autoload) plays `BorderAnim` while the
new scene loads in a background thread; `Event._loading_is_started/finished`
flip `Global.loaded` so the poll only runs once the entry animation has set
the boolean. Don't call `current_scene.queue_free()` outside this function
— it will leak the resource and break the loader state.
**Levels.tscn / level scenes**
`scenes/levels/Levels.tscn` is the shared shell; concrete levels
(`warcraft/WarCraft.tscn`, `home/Home.tscn`) inherit from it. Each scene
has a `HiddenObjectsItems/<Item>` `MeshInstance3D` with an `Area3D`
collision shape; clicking it triggers `Levels._check_collider`
`_start_dissolve(name)``GlobalAnimation.start_dissolve(mesh, material)`
which runs the dissolve shader on `material.dissolve_amount`.
The runtime hidden-object list lives under
`scenes/levels/parts/ListObjects.tscn` and is populated dynamically from
the `scenes` table for the current `Global.current_scene_int`.
## Migration notes (Godot 3 → 4)
The conversion is mostly done but a few classes of mistake keep surfacing
because `godot --convert-3to4` does not handle them:
- **Label**: `align/valign``horizontal_alignment/vertical_alignment`.
- **Button**: `pressed` (property) → `button_pressed`; `set_pressed()`
assignment to `button_pressed`. The `pressed` *signal* still exists.
- **ScrollContainer**: `scroll_horizontal_enabled = false`
`horizontal_scroll_mode = 0` (and same for vertical). ScrollContainer
also ships a non-empty default panel style in Godot 4 — set
`theme_override_styles/panel = StyleBoxEmpty` if you need transparency.
- **TextureRect / TextureButton**: `expand = true``expand_mode = 1`.
`stretch_mode` enum values **shifted down by 1** between 3 and 4 (the
deprecated "Scale on Expand" at index 0 was removed): G3's Tile (2) is
G4's Tile (1), G3's Keep (3) is G4's Keep (2), etc.
- **Environment**: `background_mode` enum changed (G3 3=Sky → G4 2=Sky;
G4 3 is Canvas which renders black). `background_sky``sky`;
`background_energy``background_energy_multiplier`;
`fog_color``fog_light_color`; `fog_height_min``fog_height`;
`fog_mode = 1` (Depth) needed to keep `fog_depth_*` semantics, otherwise
Godot 4 falls back to dense `fog_density` exponential fog.
- **AnimationPlayer**: `add_animation(name, anim)` removed — go through
`get_animation_library("")` (create one with `add_animation_library("")`
if it returns null) and call `lib.add_animation(name, anim)`.
- **Tween**: no longer a Node — call `create_tween()` from any Node and use
`tween.tween_method(...)`. Delete any `[node type="Tween"]` from older
`.tscn` files (the loader will crash otherwise).
- **PhysicsRayQuery**: `space_state.intersect_ray(from, to, ...)`
`PhysicsRayQueryParameters3D.create(from, to)`, set fields, then
`space_state.intersect_ray(query)`.
- **PackedScene.instance()** → `instantiate()`.
- **String / cast operators**: `String(x)` constructor doesn't exist — use
`str(x)`. `x as int/String/bool` does **not** parse strings — use
`int(s)`, `str(x)`, `bool(int(s))`.
- **Internationalization**: project setting is `[internationalization]
locale/translations=...`, not `[locale] translations=...`. Locale codes
must match `.po` filenames exactly (`fr.po` → `"fr"`; G3-style `fr_FR`
no longer auto-falls-back).
- **Inherited scenes**: nodes from an instanced child scene need
`layout_mode = 1` + `anchors_preset = 15` explicitly set in the parent
scene file, otherwise Godot 4 treats them as Position-mode and zeroes
the anchors. Watch for stale per-Label `layout_mode = 0` /
`anchor_right = 0` overrides in Main.tscn-style parent scenes.
## Plugins
- `addons/lod/` — Calinou's Level-of-Detail plugin (Spatial / OmniLight /
SpotLight / Particles → 3D variants). Class declarations use the Godot 4
form (`@icon("...") class_name X` + `extends Node3D` separately).
- `addons/godot_db_manager/` — **removed during migration**. Don't restore
it; it relies on `WindowDialog`/`Tabs`/`PopupPanel` which were dropped in
Godot 4. The replacement is `scripts/Database.gd` (see above).
## Custom shaders / materials
Drop-in shaders live in `.material` resources (binary `RSCC` format) next
to each prop. `scripts/migrate_shaders.gd` is a one-shot tool that walks
`assets/` and rewrites the embedded shader code (Godot 3 → 4 keyword
renames: `depth_draw_alpha_prepass`, `hint_color`, `NORMALMAP`). Re-run it
with `godot --headless --script scripts/migrate_shaders.gd` after adding
new materials authored in Godot 3.
`assets/fonts/text_outline.material` is a VisualShader graph from Godot 3
that doesn't connect cleanly in 4 (out-of-bounds `p_from_port` errors,
COLOR never written). It has been detached from the Summary menu labels;
re-author it with Godot 4's built-in `theme_override_constants/outline_size`
+ `theme_override_colors/font_outline_color` instead.
## Known visual issues to revisit
- **Baked lightmap is gone.** `scenes/levels/warcraft/WarCraft.lmbake` is
in Godot 3's binary format (incompatible). The `LightmapGI` node still
exists in `WarCraft.tscn` but its `light_data` reference is cleared.
Open the scene in the editor and re-bake (Scene → Bake Lightmaps).
- **`assets/ui/themes/tab_select/UI-level-btn-shadow.png`** is 83% opaque
black with feathered edges (a drop-shadow texture). In Godot 4 it
renders stretched and opaque, which looked like a black square below
each level tile, so its `BackgroundTile` TextureRect is currently
`visible = false`. Replace with a proper 9-patch / shader if the shadow
effect is wanted.
- `developers/aurelien/` is a sandbox — files there (`ui_scrolls.tscn`,
`ui_tile.tscn`, `CheckLightmap.tscn`) still use Godot-3 property names
in places. Not on the main flow, low priority.
## CI
Gitea Actions workflow at `.gitea/workflows/build.yml`, documented in
`.gitea/workflows/README.md`. Three jobs: GDScript validation
(`godot --headless --import` + error grep), desktop matrix
(Windows / Linux / macOS), and Android. Build only — no Butler / itch.io
deploy currently wired (channels used historically were
`dev-crea/ahog:windows|android|linux|mac`). Drone pipeline removed.
Branches: default `dev`, releases from `main`. Long-running migration work
on `feature/godot-migration`.
## Conventions
- Don't commit `db/ahog.json` runtime mutations (lock progress saved
during play). The README documents using `git update-index --skip-worktree`
but the cleaner alternative is just to `git checkout db/ahog.json`
before staging.
- `android/`, `.godot/`, and `releases/` are in `.gitignore`. The
`.import` sidecars next to assets **are** committed (they carry the
stable UIDs Godot 4 generates).
- Commit messages: imperative, English, explain the *why* (especially for
migration commits — the next person reading the diff won't have the
Godot 3 context).
-2
View File
@@ -1,5 +1,3 @@
[![Build Status](https://drone.dev-crea.com/api/badges/Athena/game-source/status.svg)](https://drone.dev-crea.com/Athena/game-source)
- Hidden Object
- Tips
- Log on Android
+3 -3
View File
@@ -23,7 +23,7 @@ var refresh_rate := 0.25
# Positive values will decrease the detail level and improve performance.
# Negative values will improve visual appearance at the cost of performance.
# This can overridden by setting the project setting `lod/bias`.
var lod_bias := 0.0
var lod_distance_bias := 0.0
# The internal refresh timer.
var timer := 0.0
@@ -31,7 +31,7 @@ var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/particle_bias"):
lod_bias = ProjectSettings.get_setting("lod/particle_bias")
lod_distance_bias = ProjectSettings.get_setting("lod/particle_bias")
if ProjectSettings.has_setting("lod/refresh_rate"):
refresh_rate = ProjectSettings.get_setting("lod/refresh_rate")
@@ -56,5 +56,5 @@ func _physics_process(delta: float) -> void:
timer = 0.0
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_bias
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
emitting = distance < max_emit_distance
+3 -11
View File
@@ -36,7 +36,7 @@ var refresh_rate := 0.05
# Positive values will decrease the detail level and improve performance.
# Negative values will improve visual appearance at the cost of performance.
# This can overridden by setting the project setting `lod/bias`.
var lod_bias := 0.0
var lod_distance_bias := 0.0
# The internal refresh timer.
var timer := 0.0
@@ -47,7 +47,7 @@ var base_light_energy := light_energy
func _ready() -> void:
if ProjectSettings.has_setting("lod/light_bias"):
lod_bias = ProjectSettings.get_setting("lod/light_bias")
lod_distance_bias = ProjectSettings.get_setting("lod/light_bias")
if ProjectSettings.has_setting("lod/light_refresh_rate"):
refresh_rate = ProjectSettings.get_setting("lod/light_refresh_rate")
@@ -72,7 +72,7 @@ func _physics_process(delta: float) -> void:
timer = 0.0
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_bias
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
visible = distance < light_max_distance
var light_fade_start_distance := light_max_distance * light_fade_start
@@ -83,11 +83,3 @@ func _physics_process(delta: float) -> void:
light_energy = base_light_energy
shadow_enabled = distance < shadow_max_distance
var shadow_fade_start_distance := shadow_max_distance * shadow_fade_start
var shadow_value: float
if distance > shadow_fade_start_distance:
shadow_value = min(1, (distance - shadow_fade_start_distance) / (shadow_max_distance - shadow_fade_start_distance))
else:
# We're close enough to the light to show its shadow at full darkness.
shadow_value = 0.0
shadow_color = Color(shadow_value, shadow_value, shadow_value)
+3 -3
View File
@@ -23,7 +23,7 @@ var refresh_rate := 0.25
# Positive values will decrease the detail level and improve performance.
# Negative values will improve visual appearance at the cost of performance.
# This can overridden by setting the project setting `lod/bias`.
var lod_bias := 0.0
var lod_distance_bias := 0.0
# The internal refresh timer.
var timer := 0.0
@@ -31,7 +31,7 @@ var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/particle_bias"):
lod_bias = ProjectSettings.get_setting("lod/particle_bias")
lod_distance_bias = ProjectSettings.get_setting("lod/particle_bias")
if ProjectSettings.has_setting("lod/refresh_rate"):
refresh_rate = ProjectSettings.get_setting("lod/refresh_rate")
@@ -56,5 +56,5 @@ func _physics_process(delta: float) -> void:
timer = 0.0
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_bias
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
emitting = distance < max_emit_distance
+3 -3
View File
@@ -30,7 +30,7 @@ var refresh_rate := 0.25
# Positive values will decrease the detail level and improve performance.
# Negative values will improve visual appearance at the cost of performance.
# This can overridden by setting the project setting `lod/bias`.
var lod_bias := 0.0
var lod_distance_bias := 0.0
# The internal refresh timer.
var timer := 0.0
@@ -38,7 +38,7 @@ var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/spatial_bias"):
lod_bias = ProjectSettings.get_setting("lod/spatial_bias")
lod_distance_bias = ProjectSettings.get_setting("lod/spatial_bias")
if ProjectSettings.has_setting("lod/refresh_rate"):
refresh_rate = ProjectSettings.get_setting("lod/refresh_rate")
@@ -64,7 +64,7 @@ func _physics_process(delta: float) -> void:
timer = 0.0
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_bias
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
# The LOD level to choose (lower is more detailed).
var lod: int
if distance < lod_0_max_distance:
+3 -11
View File
@@ -36,7 +36,7 @@ var refresh_rate := 0.05
# Positive values will decrease the detail level and improve performance.
# Negative values will improve visual appearance at the cost of performance.
# This can overridden by setting the project setting `lod/bias`.
var lod_bias := 0.0
var lod_distance_bias := 0.0
# The internal refresh timer.
var timer := 0.0
@@ -47,7 +47,7 @@ var base_light_energy := light_energy
func _ready() -> void:
if ProjectSettings.has_setting("lod/light_bias"):
lod_bias = ProjectSettings.get_setting("lod/light_bias")
lod_distance_bias = ProjectSettings.get_setting("lod/light_bias")
if ProjectSettings.has_setting("lod/light_refresh_rate"):
refresh_rate = ProjectSettings.get_setting("lod/light_refresh_rate")
@@ -72,7 +72,7 @@ func _physics_process(delta: float) -> void:
timer = 0.0
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_bias
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
visible = distance < light_max_distance
var light_fade_start_distance := light_max_distance * light_fade_start
@@ -83,11 +83,3 @@ func _physics_process(delta: float) -> void:
light_energy = base_light_energy
shadow_enabled = distance < shadow_max_distance
var shadow_fade_start_distance := shadow_max_distance * shadow_fade_start
var shadow_value: float
if distance > shadow_fade_start_distance:
shadow_value = min(1, (distance - shadow_fade_start_distance) / (shadow_max_distance - shadow_fade_start_distance))
else:
# We're close enough to the light to show its shadow at full darkness.
shadow_value = 0.0
shadow_color = Color(shadow_value, shadow_value, shadow_value)
View File
+9 -20
View File
@@ -1,28 +1,17 @@
[gd_resource type="Environment" load_steps=3 format=2]
[gd_resource type="Environment" format=3 uid="uid://cosbxx1qhfx35"]
[ext_resource path="res://assets/hdri/tx_night_place.hdr" type="Texture2D" id=1]
[sub_resource type="Sky" id=2]
panorama = ExtResource( 1 )
[sub_resource type="Sky" id="2"]
[resource]
background_mode = 3
background_sky = SubResource( 2 )
background_color = Color( 0.188235, 0.133333, 0.133333, 1 )
background_energy = 0.6
ambient_light_color = Color( 0.694118, 0.168627, 0.67451, 1 )
ambient_light_energy = 1.55
background_color = Color(0.188235, 0.133333, 0.133333, 1)
sky = SubResource("2")
ambient_light_color = Color(0.694118, 0.168627, 0.67451, 1)
ambient_light_sky_contribution = 0.5
ambient_light_energy = 1.55
tonemap_mode = 2
glow_enabled = true
fog_enabled = true
fog_color = Color( 0.562167, 0.29, 1, 0.941176 )
fog_depth_curve = 1.10957
fog_depth_begin = 0.0
fog_depth_end = 60.0
fog_depth_curve = 1.10957
fog_height_enabled = true
fog_height_min = 2.0
fog_height_max = -20.0
fog_height_curve = 0.965936
tonemap_mode = 2
ss_reflections_enabled = true
dof_blur_far_distance = 2.0
glow_enabled = true
+3 -4
View File
@@ -1,7 +1,6 @@
[gd_resource type="FontFile" load_steps=2 format=2]
[gd_resource type="FontVariation" format=3 uid="uid://ehvxks08bpr"]
[ext_resource path="res://assets/fonts/MKX Title.ttf" type="FontFile" id=1]
[ext_resource type="FontFile" uid="uid://c7ps8q01ej5du" path="res://assets/fonts/MKX Title.ttf" id="1"]
[resource]
size = 30
font_data = ExtResource( 1 )
base_font = ExtResource("1")
+3 -5
View File
@@ -1,8 +1,6 @@
[gd_resource type="FontFile" load_steps=2 format=2]
[gd_resource type="FontVariation" format=3 uid="uid://inv1rofq17xy"]
[ext_resource path="res://assets/fonts/kirsty/kirsty rg.otf" type="FontFile" id=1]
[ext_resource type="FontFile" uid="uid://c0gq63h6u1c0f" path="res://assets/fonts/kirsty/kirsty rg.otf" id="1"]
[resource]
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )
base_font = ExtResource("1")
+3 -6
View File
@@ -1,9 +1,6 @@
[gd_resource type="FontFile" load_steps=2 format=2]
[gd_resource type="FontVariation" format=3 uid="uid://dxs8032ya4bwr"]
[ext_resource path="res://assets/fonts/kirsty/kirsty rg.otf" type="FontFile" id=1]
[ext_resource type="FontFile" uid="uid://c0gq63h6u1c0f" path="res://assets/fonts/kirsty/kirsty rg.otf" id="1"]
[resource]
size = 24
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )
base_font = ExtResource("1")
+3 -6
View File
@@ -1,9 +1,6 @@
[gd_resource type="FontFile" load_steps=2 format=2]
[gd_resource type="FontVariation" format=3 uid="uid://bqx3uv23bwjul"]
[ext_resource path="res://assets/fonts/kirsty/kirsty bd.otf" type="FontFile" id=1]
[ext_resource type="FontFile" uid="uid://bgrwp4g3d0ywx" path="res://assets/fonts/kirsty/kirsty bd.otf" id="1"]
[resource]
size = 46
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )
base_font = ExtResource("1")
Binary file not shown.
+3 -6
View File
@@ -1,10 +1,7 @@
[gd_resource type="Environment" load_steps=3 format=2]
[gd_resource type="Environment" format=3 uid="uid://b4goeb432cjl4"]
[ext_resource path="res://assets/hdri/tx_night_place.hdr" type="Texture2D" id=1]
[sub_resource type="Sky" id=1]
panorama = ExtResource( 1 )
[sub_resource type="Sky" id="1"]
[resource]
background_mode = 3
background_sky = SubResource( 1 )
sky = SubResource("1")
Binary file not shown.
+9 -23
View File
@@ -1,38 +1,24 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=2]
[gd_resource type="ShaderMaterial" format=3 uid="uid://vj5s8nwv5ac7"]
[sub_resource type="VisualShaderNodeColorConstant" id=1]
constant = Color( 0.117188, 0.0709553, 0.0709553, 1 )
[sub_resource type="VisualShader" id=2]
[sub_resource type="Shader" id="Shader_6qnue"]
code = "shader_type spatial;
render_mode specular_schlick_ggx;
render_mode blend_mix, depth_draw_opaque, depth_test_default, cull_back, diffuse_lambert, specular_schlick_ggx;
void vertex() {
// Output:0
}
void fragment() {
// Color:3
vec3 n_out3p0 = vec3(0.117188, 0.070955, 0.070955);
float n_out3p1 = 1.000000;
// ColorConstant:3
vec4 n_out3p0 = vec4(0.117188, 0.070955, 0.070955, 1.000000);
// Output:0
ALBEDO = n_out3p0;
ALBEDO = vec3(n_out3p0.xyz);
}
void light() {
// Output:0
}
"
nodes/fragment/3/node = SubResource( 1 )
nodes/fragment/3/position = Vector2( 0, 140 )
nodes/fragment/connections = PackedInt32Array( 3, 0, 0, 0 )
[resource]
shader = SubResource( 2 )
render_priority = 0
shader = SubResource("Shader_6qnue")
+10 -25
View File
@@ -1,41 +1,26 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=2]
[gd_resource type="ShaderMaterial" format=3 uid="uid://8cbl1rknioqx"]
[sub_resource type="VisualShaderNodeColorParameter" id=1]
uniform_name = "BaseColor"
[sub_resource type="VisualShader" id=2]
[sub_resource type="Shader" id="Shader_iwepy"]
code = "shader_type spatial;
render_mode specular_schlick_ggx;
render_mode blend_mix, depth_draw_opaque, depth_test_default, cull_back, diffuse_lambert, specular_schlick_ggx;
uniform vec4 BaseColor : source_color;
void vertex() {
// Output:0
}
void fragment() {
// ColorUniform:5
vec3 n_out5p0 = BaseColor.rgb;
float n_out5p1 = BaseColor.a;
// ColorParameter:5
vec4 n_out5p0 = BaseColor;
// Output:0
ALBEDO = n_out5p0;
ALBEDO = vec3(n_out5p0.xyz);
}
void light() {
// Output:0
}
"
graph_offset = Vector2( -278, -353.75 )
nodes/fragment/5/node = SubResource( 1 )
nodes/fragment/5/position = Vector2( 180, 140 )
nodes/fragment/connections = PackedInt32Array( 5, 0, 0, 0 )
[resource]
shader = SubResource( 2 )
shader_param/BaseColor = Color( 0.313726, 1, 0, 1 )
render_priority = 0
shader = SubResource("Shader_iwepy")
shader_parameter/BaseColor = Color(0.313726, 1, 0, 1)
+10 -25
View File
@@ -1,41 +1,26 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=2]
[gd_resource type="ShaderMaterial" format=3 uid="uid://dj27bh8fh6g7f"]
[sub_resource type="VisualShaderNodeColorParameter" id=1]
uniform_name = "BaseColor"
[sub_resource type="VisualShader" id=2]
[sub_resource type="Shader" id="Shader_b630w"]
code = "shader_type spatial;
render_mode specular_schlick_ggx;
render_mode blend_mix, depth_draw_opaque, depth_test_default, cull_back, diffuse_lambert, specular_schlick_ggx;
uniform vec4 BaseColor : source_color;
void vertex() {
// Output:0
}
void fragment() {
// ColorUniform:5
vec3 n_out5p0 = BaseColor.rgb;
float n_out5p1 = BaseColor.a;
// ColorParameter:5
vec4 n_out5p0 = BaseColor;
// Output:0
ALBEDO = n_out5p0;
ALBEDO = vec3(n_out5p0.xyz);
}
void light() {
// Output:0
}
"
graph_offset = Vector2( -278, -353.75 )
nodes/fragment/5/node = SubResource( 1 )
nodes/fragment/5/position = Vector2( 180, 140 )
nodes/fragment/connections = PackedInt32Array( 5, 0, 0, 0 )
[resource]
shader = SubResource( 2 )
shader_param/BaseColor = Color( 1, 0, 0, 1 )
render_priority = 0
shader = SubResource("Shader_b630w")
shader_parameter/BaseColor = Color(1, 0, 0, 1)
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5 -7
View File
@@ -1,10 +1,8 @@
[gd_scene load_steps=2 format=2]
[gd_scene format=3 uid="uid://lt8fwag3uivj"]
[ext_resource path="res://assets/props/book/sm_book_lod1.mesh" type="ArrayMesh" id=2]
[ext_resource type="ArrayMesh" path="res://assets/props/book/sm_book_lod1.mesh" id="2"]
[node name="sm_book" type="Node3D"]
[node name="sm_book" type="Node3D" unique_id=1509736704]
[node name="sm_book-lod1" type="MeshInstance3D" parent="."]
use_in_baked_light = true
mesh = ExtResource( 2 )
surface_material_override/0 = null
[node name="sm_book-lod1" type="MeshInstance3D" parent="." unique_id=56438111]
mesh = ExtResource("2")
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://dfbfbwe12r27y"
path.s3tc="res://.godot/imported/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.s3tc.ctex"
path.etc2="res://.godot/imported/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_Paper_BC.tga"
dest_files=["res://.godot/imported/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.s3tc.ctex", "res://.godot/imported/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://bhi4c5xbbstve"
path.s3tc="res://.godot/imported/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.s3tc.ctex"
path.etc2="res://.godot/imported/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_Paper_NM.tga"
dest_files=["res://.godot/imported/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.s3tc.ctex", "res://.godot/imported/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://dpnkeyvi4nm1y"
path.s3tc="res://.godot/imported/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.s3tc.ctex"
path.etc2="res://.godot/imported/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_Paper_ORM.tga"
dest_files=["res://.godot/imported/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.s3tc.ctex", "res://.godot/imported/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://bwh77ikekvh78"
path.s3tc="res://.godot/imported/tx_book_BC.tga-043df0783ead34530de9f256a143cacb.s3tc.ctex"
path.etc2="res://.godot/imported/tx_book_BC.tga-043df0783ead34530de9f256a143cacb.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_book_BC.tga"
dest_files=["res://.godot/imported/tx_book_BC.tga-043df0783ead34530de9f256a143cacb.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_book_BC.tga-043df0783ead34530de9f256a143cacb.s3tc.ctex", "res://.godot/imported/tx_book_BC.tga-043df0783ead34530de9f256a143cacb.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://d1vrxpmwvdpnk"
path.s3tc="res://.godot/imported/tx_book_MK.tga-8a7c0fa94467fd29a69c4f5b665eec9c.s3tc.ctex"
path.etc2="res://.godot/imported/tx_book_MK.tga-8a7c0fa94467fd29a69c4f5b665eec9c.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_book_MK.tga"
dest_files=["res://.godot/imported/tx_book_MK.tga-8a7c0fa94467fd29a69c4f5b665eec9c.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_book_MK.tga-8a7c0fa94467fd29a69c4f5b665eec9c.s3tc.ctex", "res://.godot/imported/tx_book_MK.tga-8a7c0fa94467fd29a69c4f5b665eec9c.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://dhsjp8ba7b5hp"
path.s3tc="res://.godot/imported/tx_book_NM.tga-76afe8f7bcf6cb8cc6055b785f89befe.s3tc.ctex"
path.etc2="res://.godot/imported/tx_book_NM.tga-76afe8f7bcf6cb8cc6055b785f89befe.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_book_NM.tga"
dest_files=["res://.godot/imported/tx_book_NM.tga-76afe8f7bcf6cb8cc6055b785f89befe.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_book_NM.tga-76afe8f7bcf6cb8cc6055b785f89befe.s3tc.ctex", "res://.godot/imported/tx_book_NM.tga-76afe8f7bcf6cb8cc6055b785f89befe.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://dq6s5nt1pko83"
path.s3tc="res://.godot/imported/tx_book_ORM.tga-314f28a993b713578d4773124db322ff.s3tc.ctex"
path.etc2="res://.godot/imported/tx_book_ORM.tga-314f28a993b713578d4773124db322ff.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_book_ORM.tga"
dest_files=["res://.godot/imported/tx_book_ORM.tga-314f28a993b713578d4773124db322ff.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_book_ORM.tga-314f28a993b713578d4773124db322ff.s3tc.ctex", "res://.godot/imported/tx_book_ORM.tga-314f28a993b713578d4773124db322ff.etc2.ctex"]
[params]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14 -18
View File
@@ -1,29 +1,25 @@
[gd_scene load_steps=4 format=2]
[gd_scene format=3 uid="uid://tlua1pg4ro8u"]
[ext_resource path="res://assets/props/candle/sm_candlestick_lod1.mesh" type="ArrayMesh" id=1]
[ext_resource path="res://assets/props/candle/candle.gd" type="Script" id=2]
[ext_resource path="res://assets/props/candle/sm_candle_top_lod1.mesh" type="ArrayMesh" id=3]
[ext_resource type="ArrayMesh" path="res://assets/props/candle/sm_candlestick_lod1.mesh" id="1"]
[ext_resource type="Script" uid="uid://0v7yafm2dil" path="res://assets/props/candle/candle.gd" id="2"]
[ext_resource type="ArrayMesh" path="res://assets/props/candle/sm_candle_top_lod1.mesh" id="3"]
[node name="sm_candlestick" type="Node3D"]
script = ExtResource( 2 )
[node name="sm_candlestick" type="Node3D" unique_id=158803858]
script = ExtResource("2")
[node name="sm_candlestick_lod1" type="MeshInstance3D" parent="."]
mesh = ExtResource( 1 )
surface_material_override/0 = null
[node name="sm_candlestick_lod1" type="MeshInstance3D" parent="." unique_id=93495968]
mesh = ExtResource("1")
[node name="candles" type="MeshInstance3D" parent="sm_candlestick_lod1"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.000981584, 0.150082, 0 )
use_in_baked_light = true
mesh = ExtResource( 3 )
surface_material_override/0 = null
[node name="candles" type="MeshInstance3D" parent="sm_candlestick_lod1" unique_id=1542964088]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.000981584, 0.150082, 0)
mesh = ExtResource("3")
[node name="OmniLight3D" type="OmniLight3D" parent="sm_candlestick_lod1/candles"]
transform = Transform3D( 1, 5.5022e-09, 1.96774e-13, -5.5022e-09, 1, 1.08271e-21, -1.96774e-13, -2.1654e-21, 1, 1.3737e-08, 0.0619183, -2.98023e-08 )
[node name="OmniLight3D" type="OmniLight3D" parent="sm_candlestick_lod1/candles" unique_id=1368663821]
transform = Transform3D(1, 5.5022e-09, 1.96774e-13, -5.5022e-09, 1, 1.08271e-21, -1.96774e-13, -2.1654e-21, 1, 1.3737e-08, 0.0619183, -2.98023e-08)
visible = false
light_color = Color( 0.960784, 0.611765, 0.00784314, 1 )
light_color = Color(0.960784, 0.611765, 0.00784314, 1)
light_energy = 12.0
light_indirect_energy = 1.4
light_bake_mode = 2
editor_only = true
omni_range = 1.6
omni_attenuation = 2.73208
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://bmfepyv5gimbe"
path.s3tc="res://.godot/imported/tx_candle_BCS.tga-8a28bd77a964ef96f453c0c2c4de7ed9.s3tc.ctex"
path.etc2="res://.godot/imported/tx_candle_BCS.tga-8a28bd77a964ef96f453c0c2c4de7ed9.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/candle/textures/tx_candle_BCS.tga"
dest_files=["res://.godot/imported/tx_candle_BCS.tga-8a28bd77a964ef96f453c0c2c4de7ed9.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_candle_BCS.tga-8a28bd77a964ef96f453c0c2c4de7ed9.s3tc.ctex", "res://.godot/imported/tx_candle_BCS.tga-8a28bd77a964ef96f453c0c2c4de7ed9.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://dco3vmw0jdw7t"
path.s3tc="res://.godot/imported/tx_candle_NM.tga-0d1354b171e73543cc7b627d3a46536f.s3tc.ctex"
path.etc2="res://.godot/imported/tx_candle_NM.tga-0d1354b171e73543cc7b627d3a46536f.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/candle/textures/tx_candle_NM.tga"
dest_files=["res://.godot/imported/tx_candle_NM.tga-0d1354b171e73543cc7b627d3a46536f.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_candle_NM.tga-0d1354b171e73543cc7b627d3a46536f.s3tc.ctex", "res://.godot/imported/tx_candle_NM.tga-0d1354b171e73543cc7b627d3a46536f.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://baqeh5ceph0e"
path.s3tc="res://.godot/imported/tx_candle_ORM.tga-3575951580ec8d12904f46fd8f10069c.s3tc.ctex"
path.etc2="res://.godot/imported/tx_candle_ORM.tga-3575951580ec8d12904f46fd8f10069c.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/candle/textures/tx_candle_ORM.tga"
dest_files=["res://.godot/imported/tx_candle_ORM.tga-3575951580ec8d12904f46fd8f10069c.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_candle_ORM.tga-3575951580ec8d12904f46fd8f10069c.s3tc.ctex", "res://.godot/imported/tx_candle_ORM.tga-3575951580ec8d12904f46fd8f10069c.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://bfuna15etfwhg"
path.s3tc="res://.godot/imported/tx_candle_scatter.tga-bc0a35b3e6c5b6443faff3a90e4ee73d.s3tc.ctex"
path.etc2="res://.godot/imported/tx_candle_scatter.tga-bc0a35b3e6c5b6443faff3a90e4ee73d.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/candle/textures/tx_candle_scatter.tga"
dest_files=["res://.godot/imported/tx_candle_scatter.tga-bc0a35b3e6c5b6443faff3a90e4ee73d.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_candle_scatter.tga-bc0a35b3e6c5b6443faff3a90e4ee73d.s3tc.ctex", "res://.godot/imported/tx_candle_scatter.tga-bc0a35b3e6c5b6443faff3a90e4ee73d.etc2.ctex"]
[params]
Binary file not shown.
Binary file not shown.
@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dvoars6va7511"
path="res://.godot/imported/dagger_Dagger_BC.png-6deff32a41940f92bbdb14bc9b47beb3.ctex"
path.s3tc="res://.godot/imported/dagger_Dagger_BC.png-6deff32a41940f92bbdb14bc9b47beb3.s3tc.ctex"
path.etc2="res://.godot/imported/dagger_Dagger_BC.png-6deff32a41940f92bbdb14bc9b47beb3.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/dagger/dagger_Dagger_BC.png"
dest_files=["res://.godot/imported/dagger_Dagger_BC.png-6deff32a41940f92bbdb14bc9b47beb3.ctex"]
dest_files=["res://.godot/imported/dagger_Dagger_BC.png-6deff32a41940f92bbdb14bc9b47beb3.s3tc.ctex", "res://.godot/imported/dagger_Dagger_BC.png-6deff32a41940f92bbdb14bc9b47beb3.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,4 +39,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
detect_3d/compress_to=0
@@ -3,30 +3,32 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cfhmpp3pitqbi"
path="res://.godot/imported/dagger_Dagger_NM.png-16adfa9ec4fd4455ed9dd788fbba2519.ctex"
path.s3tc="res://.godot/imported/dagger_Dagger_NM.png-16adfa9ec4fd4455ed9dd788fbba2519.s3tc.ctex"
path.etc2="res://.godot/imported/dagger_Dagger_NM.png-16adfa9ec4fd4455ed9dd788fbba2519.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/dagger/dagger_Dagger_NM.png"
dest_files=["res://.godot/imported/dagger_Dagger_NM.png-16adfa9ec4fd4455ed9dd788fbba2519.ctex"]
dest_files=["res://.godot/imported/dagger_Dagger_NM.png-16adfa9ec4fd4455ed9dd788fbba2519.s3tc.ctex", "res://.godot/imported/dagger_Dagger_NM.png-16adfa9ec4fd4455ed9dd788fbba2519.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/normal_map=1
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
roughness/mode=1
roughness/src_normal="res://assets/props/dagger/dagger_Dagger_NM.png"
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
@@ -37,4 +39,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
detect_3d/compress_to=0
@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b5jfvsejxruax"
path="res://.godot/imported/dagger_dagger_E.png-f59a7c6d2e36ce0df3488a3ad845f982.ctex"
path.s3tc="res://.godot/imported/dagger_dagger_E.png-f59a7c6d2e36ce0df3488a3ad845f982.s3tc.ctex"
path.etc2="res://.godot/imported/dagger_dagger_E.png-f59a7c6d2e36ce0df3488a3ad845f982.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/dagger/dagger_dagger_E.png"
dest_files=["res://.godot/imported/dagger_dagger_E.png-f59a7c6d2e36ce0df3488a3ad845f982.ctex"]
dest_files=["res://.godot/imported/dagger_dagger_E.png-f59a7c6d2e36ce0df3488a3ad845f982.s3tc.ctex", "res://.godot/imported/dagger_dagger_E.png-f59a7c6d2e36ce0df3488a3ad845f982.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,4 +39,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
detect_3d/compress_to=0
@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b2yaxbeog0iiq"
path="res://.godot/imported/dagger_dagger_ORM.png-d6cee18aee3cb84d78327e37eda49e85.ctex"
path.s3tc="res://.godot/imported/dagger_dagger_ORM.png-d6cee18aee3cb84d78327e37eda49e85.s3tc.ctex"
path.etc2="res://.godot/imported/dagger_dagger_ORM.png-d6cee18aee3cb84d78327e37eda49e85.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/dagger/dagger_dagger_ORM.png"
dest_files=["res://.godot/imported/dagger_dagger_ORM.png-d6cee18aee3cb84d78327e37eda49e85.ctex"]
dest_files=["res://.godot/imported/dagger_dagger_ORM.png-d6cee18aee3cb84d78327e37eda49e85.s3tc.ctex", "res://.godot/imported/dagger_dagger_ORM.png-d6cee18aee3cb84d78327e37eda49e85.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,4 +39,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
detect_3d/compress_to=0
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://cos4nywdtkchr"
path.s3tc="res://.godot/imported/dagger_BC.tga-8c56f407df61bdb7c529101388df0d01.s3tc.ctex"
path.etc2="res://.godot/imported/dagger_BC.tga-8c56f407df61bdb7c529101388df0d01.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/dagger/textures/dagger_BC.tga"
dest_files=["res://.godot/imported/dagger_BC.tga-8c56f407df61bdb7c529101388df0d01.s3tc.ctex"]
dest_files=["res://.godot/imported/dagger_BC.tga-8c56f407df61bdb7c529101388df0d01.s3tc.ctex", "res://.godot/imported/dagger_BC.tga-8c56f407df61bdb7c529101388df0d01.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://bn2pvfwupk616"
path.s3tc="res://.godot/imported/dagger_NM.tga-02457e4299815720542e6c6827c3099f.s3tc.ctex"
path.etc2="res://.godot/imported/dagger_NM.tga-02457e4299815720542e6c6827c3099f.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/dagger/textures/dagger_NM.tga"
dest_files=["res://.godot/imported/dagger_NM.tga-02457e4299815720542e6c6827c3099f.s3tc.ctex"]
dest_files=["res://.godot/imported/dagger_NM.tga-02457e4299815720542e6c6827c3099f.s3tc.ctex", "res://.godot/imported/dagger_NM.tga-02457e4299815720542e6c6827c3099f.etc2.ctex"]
[params]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5 -7
View File
@@ -1,10 +1,8 @@
[gd_scene load_steps=2 format=2]
[gd_scene format=3 uid="uid://cgi8sru6qky81"]
[ext_resource path="res://assets/props/godet/sm_godet_lod1.mesh" type="ArrayMesh" id=1]
[ext_resource type="ArrayMesh" path="res://assets/props/godet/sm_godet_lod1.mesh" id="1"]
[node name="sm_godet" type="Node3D"]
[node name="sm_godet" type="Node3D" unique_id=2120062082]
[node name="sm_godet_lod1" type="MeshInstance3D" parent="."]
use_in_baked_light = true
mesh = ExtResource( 1 )
surface_material_override/0 = null
[node name="sm_godet_lod1" type="MeshInstance3D" parent="." unique_id=2083222404]
mesh = ExtResource("1")
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://cxid6xyfqv6bv"
path.s3tc="res://.godot/imported/tx_godet_BC.tga-0e7c29ed5a0f4c80e30557e304a14e49.s3tc.ctex"
path.etc2="res://.godot/imported/tx_godet_BC.tga-0e7c29ed5a0f4c80e30557e304a14e49.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/godet/textures/tx_godet_BC.tga"
dest_files=["res://.godot/imported/tx_godet_BC.tga-0e7c29ed5a0f4c80e30557e304a14e49.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_godet_BC.tga-0e7c29ed5a0f4c80e30557e304a14e49.s3tc.ctex", "res://.godot/imported/tx_godet_BC.tga-0e7c29ed5a0f4c80e30557e304a14e49.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://byv10yo0gvfju"
path.s3tc="res://.godot/imported/tx_godet_NM.tga-9410c62c3e8f99e54c6df8c71e04ecff.s3tc.ctex"
path.etc2="res://.godot/imported/tx_godet_NM.tga-9410c62c3e8f99e54c6df8c71e04ecff.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/godet/textures/tx_godet_NM.tga"
dest_files=["res://.godot/imported/tx_godet_NM.tga-9410c62c3e8f99e54c6df8c71e04ecff.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_godet_NM.tga-9410c62c3e8f99e54c6df8c71e04ecff.s3tc.ctex", "res://.godot/imported/tx_godet_NM.tga-9410c62c3e8f99e54c6df8c71e04ecff.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://cpi12be1h168j"
path.s3tc="res://.godot/imported/tx_godet_ORM.tga-d01c51d4f8d8c261e86184c55282ab2b.s3tc.ctex"
path.etc2="res://.godot/imported/tx_godet_ORM.tga-d01c51d4f8d8c261e86184c55282ab2b.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/godet/textures/tx_godet_ORM.tga"
dest_files=["res://.godot/imported/tx_godet_ORM.tga-d01c51d4f8d8c261e86184c55282ab2b.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_godet_ORM.tga-d01c51d4f8d8c261e86184c55282ab2b.s3tc.ctex", "res://.godot/imported/tx_godet_ORM.tga-d01c51d4f8d8c261e86184c55282ab2b.etc2.ctex"]
[params]
Binary file not shown.
+5 -7
View File
@@ -1,10 +1,8 @@
[gd_scene load_steps=2 format=2]
[gd_scene format=3 uid="uid://ceyvbjwaca6gl"]
[ext_resource path="res://assets/props/growler/sm_growler_lod1.mesh" type="ArrayMesh" id=1]
[ext_resource type="ArrayMesh" path="res://assets/props/growler/sm_growler_lod1.mesh" id="1"]
[node name="sm_growler" type="Node3D"]
[node name="sm_growler" type="Node3D" unique_id=1516724524]
[node name="sm_growler_lod1" type="MeshInstance3D" parent="."]
use_in_baked_light = true
mesh = ExtResource( 1 )
surface_material_override/0 = null
[node name="sm_growler_lod1" type="MeshInstance3D" parent="." unique_id=358704487]
mesh = ExtResource("1")
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://crk5i2qr13hme"
path.s3tc="res://.godot/imported/tx_growler_BC.tga-aa118cf1c458a342a6a74017661c1ae7.s3tc.ctex"
path.etc2="res://.godot/imported/tx_growler_BC.tga-aa118cf1c458a342a6a74017661c1ae7.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/growler/textures/tx_growler_BC.tga"
dest_files=["res://.godot/imported/tx_growler_BC.tga-aa118cf1c458a342a6a74017661c1ae7.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_growler_BC.tga-aa118cf1c458a342a6a74017661c1ae7.s3tc.ctex", "res://.godot/imported/tx_growler_BC.tga-aa118cf1c458a342a6a74017661c1ae7.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://rc3kqnqss1u"
path.s3tc="res://.godot/imported/tx_growler_NM.tga-2a1c81bcbfbece34756c1cdbc715b7f4.s3tc.ctex"
path.etc2="res://.godot/imported/tx_growler_NM.tga-2a1c81bcbfbece34756c1cdbc715b7f4.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/growler/textures/tx_growler_NM.tga"
dest_files=["res://.godot/imported/tx_growler_NM.tga-2a1c81bcbfbece34756c1cdbc715b7f4.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_growler_NM.tga-2a1c81bcbfbece34756c1cdbc715b7f4.s3tc.ctex", "res://.godot/imported/tx_growler_NM.tga-2a1c81bcbfbece34756c1cdbc715b7f4.etc2.ctex"]
[params]
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://ctls0ywsxpmr7"
path.s3tc="res://.godot/imported/tx_growler_ORM.tga-de03bcfefddaf9accd2e00b4472eb37d.s3tc.ctex"
path.etc2="res://.godot/imported/tx_growler_ORM.tga-de03bcfefddaf9accd2e00b4472eb37d.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/props/growler/textures/tx_growler_ORM.tga"
dest_files=["res://.godot/imported/tx_growler_ORM.tga-de03bcfefddaf9accd2e00b4472eb37d.s3tc.ctex"]
dest_files=["res://.godot/imported/tx_growler_ORM.tga-de03bcfefddaf9accd2e00b4472eb37d.s3tc.ctex", "res://.godot/imported/tx_growler_ORM.tga-de03bcfefddaf9accd2e00b4472eb37d.etc2.ctex"]
[params]
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -14
View File
@@ -1,19 +1,15 @@
[gd_scene load_steps=4 format=2]
[gd_scene format=3 uid="uid://ck15k8nlgsgyw"]
[ext_resource path="res://assets/props/parchment/sm_wood_parchment_lod1.mesh" type="ArrayMesh" id=1]
[ext_resource path="res://assets/props/parchment/parchment.gd" type="Script" id=2]
[ext_resource path="res://assets/props/parchment/sm_paperparchment_lod0.mesh" type="ArrayMesh" id=3]
[ext_resource type="ArrayMesh" path="res://assets/props/parchment/sm_wood_parchment_lod1.mesh" id="1"]
[ext_resource type="Script" uid="uid://ckf1nh8pcemh1" path="res://assets/props/parchment/parchment.gd" id="2"]
[ext_resource type="ArrayMesh" path="res://assets/props/parchment/sm_paperparchment_lod0.mesh" id="3"]
[node name="sm_parchment" type="Node3D"]
script = ExtResource( 2 )
[node name="sm_parchment" type="Node3D" unique_id=1182674480]
script = ExtResource("2")
[node name="sm_wood_parchment_lod1" type="MeshInstance3D" parent="."]
use_in_baked_light = true
mesh = ExtResource( 1 )
surface_material_override/0 = null
[node name="sm_wood_parchment_lod1" type="MeshInstance3D" parent="." unique_id=875384535]
mesh = ExtResource("1")
[node name="paper" type="MeshInstance3D" parent="."]
[node name="paper" type="MeshInstance3D" parent="." unique_id=1202959838]
visible = false
use_in_baked_light = true
mesh = ExtResource( 3 )
surface_material_override/0 = null
mesh = ExtResource("3")
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More