Modularization slice 1: module/element framework + deadair module #28

Merged
merith-tk merged 2 commits from muse-lantern/da-game:modular-slice-1 into main 2026-11-05 20:31:08 +00:00
Member

Opened for testing and review — not a merge request yet. Slice 1 of the everything-is-a-module framework, built on merged main (PR #23 bundle included).

What it adds:

  • Module = .pck pack + addon.json manifest (id, version, elements; no order field — an order field is a hard manifest error). Discovery scans res://modules/ after packs mount.
  • Typed registry under namespaced ids modid.type.name (rig_hands, rig_arms, rig_body, item); shipped names are addition-only. Ties are startup errors naming both sides (two packs claiming one module id, one element id twice, two modules replacing one target), all tested with negative controls.
  • Element bases RigHands/RigArms/RigBody with a small stable handler surface (build, apply_curl, calibrate); the rest is overridable-but-discouraged. PlayerRig gained apply methods that rebuild hand/arms views from elements; default boot is unchanged.
  • The deadair module proving internal use: glove hands element, PSX arms (dormant/hidden), capsule body, 6 starter-kit items. Grip resolution tested end to end: explicit pose → auto-detect → wrist-pivot fallback.
  • Sandbox spawn path via ModuleSpawner.spawn_item(). Docs updated in docs/addons.md (Modules section). New suite tests/module_check.gd (61 checks).

Verification: all 12 pre-existing headless suites pass with no regressions (baseline on clean main also all-pass), plus MODULE CHECK PASS. Godot --import clean after double import.

Deliberately NOT in slice 1 (follow-ups tracked in issue #27): boot-time module loading is not wired (Game boot untouched); replaces is conflict-checked only, no lookup redirect yet; sandbox spawn is the path, not a menu button; pck-only is convention + docs, not loader-enforced.

One open design call for review: items are ONE collapsed GenericItem class (kind tags + grip_poses[] + markers dict) on Zach's "might even collapse them" lean. If reviewers prefer three classes, kind tags become subclasses — a one-file refactor, not a rewrite. That call is still open and blocks merge, not testing.

Opened for testing and review — not a merge request yet. Slice 1 of the everything-is-a-module framework, built on merged main (PR #23 bundle included). What it adds: - Module = .pck pack + addon.json manifest (id, version, elements; no order field — an order field is a hard manifest error). Discovery scans res://modules/ after packs mount. - Typed registry under namespaced ids modid.type.name (rig_hands, rig_arms, rig_body, item); shipped names are addition-only. Ties are startup errors naming both sides (two packs claiming one module id, one element id twice, two modules replacing one target), all tested with negative controls. - Element bases RigHands/RigArms/RigBody with a small stable handler surface (build, apply_curl, calibrate); the rest is overridable-but-discouraged. PlayerRig gained apply methods that rebuild hand/arms views from elements; default boot is unchanged. - The deadair module proving internal use: glove hands element, PSX arms (dormant/hidden), capsule body, 6 starter-kit items. Grip resolution tested end to end: explicit pose → auto-detect → wrist-pivot fallback. - Sandbox spawn path via ModuleSpawner.spawn_item(). Docs updated in docs/addons.md (Modules section). New suite tests/module_check.gd (61 checks). Verification: all 12 pre-existing headless suites pass with no regressions (baseline on clean main also all-pass), plus MODULE CHECK PASS. Godot --import clean after double import. Deliberately NOT in slice 1 (follow-ups tracked in issue #27): boot-time module loading is not wired (Game boot untouched); replaces is conflict-checked only, no lookup redirect yet; sandbox spawn is the path, not a menu button; pck-only is convention + docs, not loader-enforced. One open design call for review: items are ONE collapsed GenericItem class (kind tags + grip_poses[] + markers dict) on Zach's "might even collapse them" lean. If reviewers prefer three classes, kind tags become subclasses — a one-file refactor, not a rewrite. That call is still open and blocks merge, not testing.
HandView.rebuild_with() and ArmsView.rebuild_with() (+
model_path_override) rebuild a view from new model settings; the
_ready paths are refactored into shared _build_and_calibrate()
helpers with identical behaviour, so default boot is unchanged.
PlayerRig gains apply_rig_hands/arms/body_element() + active
elements storage. No behaviour change for existing scenes or
suites: the hooks only run when an element is applied.
modules: slice-1 module/element framework + deadair module
All checks were successful
tests / test (pull_request) Successful in 52s
634466a092
Module = .pck pack + addon.json manifest (id, version, element
list, no order field). Typed registry with namespaced ids
(modid.type.name), addition-only names, and tie-as-startup-error
(duplicate module id, duplicate element id, or two modules
replacing one target all fail the load naming both sides).
Element bases RigHands/RigArms/RigBody (build/apply_curl/
calibrate) + one collapsed GenericItem (kind tags, grip_poses[],
markers dict, properties). Grip resolution: explicit pose ->
Grip*/marker auto-detect -> wrist-pivot fallback; one hand
pivots at the wrist, two at the palm midpoint. Base game ships
as module deadair (Valve glove hands element, dormant PSX arms
element, capsule body element, 6 starter-kit items). Discovery
scans res://modules/ after packs mount (DirAccess enumerates
mounted .pck dirs, probe-verified). ModuleSpawner is the
sandbox spawn path. AddonLoader untouched; load order, hot
reload, addon manager, WorldEdits, grab physics out of scope.
tests/module_check.gd: 61 checks incl. tie negative controls.
Author
Member

Note: upstream branch craftanything (tip c64b8bd) includes this PR's files as-is and builds on top of them — the loader layer (manifests, entrypoints, dependency resolution, replaces redirects), gameplay foundations (health/stamina/survival, items, firearms, grab systems), desktop play, and bridge tools.

If craftanything merges, this PR closes as superseded. Until then it stays open for testing — the branch is not a PR yet and nothing in it is in main.

Verified on the branch (lantern-vm, Godot 4.6.3): clean double import, module_check + modloader_check + the full headless suite list PASS.

Note: upstream branch `craftanything` (tip `c64b8bd`) includes this PR's files as-is and builds on top of them — the loader layer (manifests, entrypoints, dependency resolution, `replaces` redirects), gameplay foundations (health/stamina/survival, items, firearms, grab systems), desktop play, and bridge tools. If `craftanything` merges, this PR closes as superseded. Until then it stays open for testing — the branch is not a PR yet and nothing in it is in main. Verified on the branch (lantern-vm, Godot 4.6.3): clean double import, `module_check` + `modloader_check` + the full headless suite list PASS.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
dead-air/engine!28
No description provided.