refactor(engine): input as data + live-shadow walk events#209
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The ECS review of the runtime chain (player → trigger → teleport) found the chain largely clean — event-driven decoupling, per-tick state on the session singleton, stateless reactive systems — with two real violations, both fixed here:
InputSourceComponentfrom day one):PlayerSystem.handleInputread the keyboard directly. Now the newInputSystemis the single device-facing system — it polls the local keyboard each tick and publishes a pure-data intent vector (InputSourceComponent—moveX/moveYnormalised,actionHeld) on the session singleton;PlayerSystemconsumes the component and never sees a device. Remote peers / replays / AI drivers can drive the player by writing the same component — split-screen and network multiplayer stay a plug-in, not a refactor. Registered beforePlayerSystemso the intent is same-frame. Outside runtime mode the intent resets to neutral (mode exit stops the player).WalkOnTileSystemraced live edits: it resolved tile properties frommapData.layers[].sprites— the snapshot that only updates on the persistence fold — while collision reads the live tilemap shadow. A tile painted mid-play didn't change walk events until a save. It now resolves through the shadow (findTileMapForLayer+getSpritesAt), falling back to mapData for layers without a live tilemap (headless contexts).Specs (both registered in test.mts; engine suite 717 → 761 assertions, green on gjs + node): InputSystem keyboard→component contract incl. runtime gating, diagonal normalisation and neutral-reset; WalkOnTileSystem live-shadow-wins-over-stale-mapData, mid-play edit visibility, empty-tile default.
Docs in the same commit:
collaboration-and-multiplayer.md§ 5 now records the shipped v1 (singleton intent vector) and keeps the per-player source-descriptor design as the split-screen phase; the stale TODO entry ("nothing emits player-tile-changed today" — false since movement landed) is rewritten to the actually-remaining work.