Migrate to Godot 4 #1
Merged
darknight
merged 27 commits from 2026-05-17 21:32:26 +02:00
feature/godot-migration into main
27 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
21176546eb |
Add dagger PBR textures, font import sidecars, migrate_shaders uid
- assets/props/dagger/dagger_Dagger_{BC,NM}.png + dagger_dagger_{E,ORM}.png:
complete PBR texture set for the dagger prop.
- assets/fonts/MKX Title.ttf.import + kirsty/*.otf.import: Godot 4 import
metadata sidecars for fonts whose source files were already tracked.
- scripts/migrate_shaders.gd.uid: UID sidecar missed in the previous
migration commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
4d5db7bb61 |
Make Main, Settings, ChooseScene, and gameplay run in Godot 4.6
Catch-all commit for everything the --convert-3to4 tool missed during a
manual playtest of the game. All errors raised by clicking through Main
-> Puzzles -> level were fixed.
GDScript:
- PackedScene.instance() -> instantiate() (ChooseScene.gd)
- String(x) constructor doesn't exist -> str(x) (MBase, MScene,
MLevel, Animation, Levels)
- 'x as int/String/bool' doesn't parse strings -> explicit
int()/str()/bool(int()) (MScene, MLevel, MSetting)
- BaseButton.pressed (property) -> button_pressed; set_pressed() ->
direct assignment (Settings.gd)
- AnimationPlayer.add_animation() removed -> go through
AnimationLibrary (Levels.gd)
- PhysicsDirectSpaceState3D.intersect_ray(from, to, ...) ->
PhysicsRayQueryParameters3D.create() (Levels.gd)
- @export with type-hint-in-comment ('# (String, ...)') -> explicit
@export_enum (candle.gd)
- Get effective material with get_active_material() instead of
get_surface_override_material(), with null guard (Levels.gd)
- get_node() -> get_node_or_null() so missing items from ahog.json
(e.g. sm_super_dager in Home) don't crash (Levels.gd)
Scenes/resources:
- Remove 14 Tween nodes from WarCraft.tscn — Tween is no longer a
Node in Godot 4. Rewrite Animation.start_dissolve to use
create_tween().tween_method().
- Rename property material/N -> surface_material_override/N in every
.tscn (10 files) — Godot 3 -> 4 rename that --convert-3to4 missed.
Without this, MeshInstance3D.get_active_material(0) returned the
glTF-imported StandardMaterial3D instead of the project's custom
dissolve ShaderMaterial.
Shaders:
- One-shot scripts/migrate_shaders.gd walks every .material under
assets/ and fixes Godot 3 -> 4 shader code in-place. Fixed 17
materials: depth_draw_alpha_prepass -> depth_prepass_alpha,
hint_color -> source_color, NORMALMAP -> NORMAL_MAP.
Result: Main, Settings, ChooseScene, and the WarCraft level all run
without script or shader errors. Remaining noise is non-blocking
(visual_shader graph in text_outline.material, baked lightmap binary
format from Godot 3, and empty animation tracks).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
770434482d |
Fix Setting.gd Vector2/Window API, re-import all assets for Godot 4
- apply_resolution: Vector2 strings -> Vector2i(int, int); use Window.content_scale_size instead of removed Viewport.set_size_2d_override variants. - Re-import 162 assets to Godot 4 format (.godot/imported/ now, .stex -> .ctex, FontFile, CompressedTexture2D, etc.). - Add .uid sidecars Godot 4 generates next to every script. - Ignore .godot/ cache and android/ template directories. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
ec906117bb |
Replace godot_db_manager plugin with native DB, port lod plugin
godot_db_manager was incompatible with Godot 4 (used WindowDialog, Tabs, PopupPanel which were all removed). Replace with a minimal Database.gd that parses the same ahog.json format and exposes the same surface API (get_table_by_name, get_data_at_row_idx, edit_data, save_db, etc.) used by the M* model classes — no changes needed in MBase/MScene/MLevel/MSetting. Also port the lod plugin: fix class_name syntax (Godot 4 uses @icon separately from class_name extends) and Particles -> GPUParticles3D. Rewrite Global.gd async scene loading: the convert-3to4 tool mapped load_interactive -> load_threaded_request but those have different APIs (stage count, poll vs. status enum). Reimplement using the new load_threaded_get_status / load_threaded_get pair. Clean project.godot: drop the old _global_script_classes table (Godot 4 uses inline class_name declarations), remove gddb_* autoloads, and remove the godot_db_manager entry from editor_plugins. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
01ea3af253 |
Run godot --convert-3to4 (automated conversion)
Apply Godot 4.6 automated conversion: renames Spatial.translate->position, margin_*->offset_*, tool->@tool, .empty()->.is_empty(), DynamicFont->FontFile, onready->@onready, export()->@export, and many more. 127 files changed by the tool. Manual fixes still required for: - godot_db_manager plugin (incompatible APIs: WindowDialog, Tabs, etc.) - lod plugin (Spatial -> Node3D renames) - ResourceLoader.load_interactive removed -> load_threaded_request - OS.set_window_fullscreen removed -> DisplayServer - Viewport.set_size_override removed Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
efa35a444a |
Migrate to Godot 3.5 LTS
Open project with Godot 3.5.3 to update project.godot to the new config format (adds physical_scancode field to InputEventKey). Intermediate step before --convert-3to4 to Godot 4.x. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |