refactor(innovation): separate GameState data from engine logic#14
Merged
AnotherSava merged 4 commits intomainfrom Mar 17, 2026
Merged
refactor(innovation): separate GameState data from engine logic#14AnotherSava merged 4 commits intomainfrom
AnotherSava merged 4 commits intomainfrom
Conversation
The old gamestate restructuring draft is superseded by a finalized plan; the new draft explores a CLI runner for debugging pipeline stages locally.
GameState was a monolithic class mixing zone data, constraint propagation, serialization, and CardDatabase references. Split into a plain GameState interface (zone maps + players + perspective) and a GameEngine class that owns CardDatabase and mutation logic. Card class stripped to data fields and computed getters only. Serialization extracted as standalone toJSON/fromJSON functions storing full candidate names instead of exclusion lists, removing the CardDatabase dependency from deserialization. PipelineResults typed as a discriminated union on gameName for type-safe access. Plan: 2026-03-15-gamestate-restructuring
GameState data layer, GameEngine class, and serialization were independent concerns sharing one 803-line file. Extract engine logic to game_engine.ts and toJSON/fromJSON to serialization.ts, leaving game_state.ts as a slim data-only module. Reject old exclusion-based serialization format instead of silently producing empty candidate sets. Remove unused restrictCandidates method.
…n in merge Naked subset elimination in propagate() was dead code — all unresolved cards in a group always have identical candidate sets after propagation. Instead, detect complete subsets (N cards with exactly N candidates) directly in mergeCandidates and mergeSuspects, resolving cards 1:1 instead of widening.
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.
Summary
GameStateclass into a plainGameStateinterface (zone data) andGameEngineclass (CardDatabase + mutation logic)Cardto data fields and computed getters only — mutation methods moved to enginetoJSON/fromJSONas standalone functions storing full candidate names (no CardDatabase dependency for deserialization)PipelineResultsas a discriminated union ongameNamewithrunPipelineoverloads for automatic narrowingPlan:
docs/plans/completed/2026-03-15-gamestate-restructuring.mdUpdate: split game_state.ts into three modules
GameEngineclass + helpers togame_engine.ts(~594 lines)toJSON/fromJSON+ serialization types toserialization.ts(~149 lines)game_state.tsto data-only module:GameStateinterface,createGameState(),cardsAt()restrictCandidatesmethod (dead code)Plan:
docs/plans/completed/2026-03-15-split-game-state.mdUpdate: complete subset detection in merge
combinations()helper (no longer needed)