Skip to content

refactor(innovation): separate GameState data from engine logic#14

Merged
AnotherSava merged 4 commits intomainfrom
gamestate-restructuring
Mar 17, 2026
Merged

refactor(innovation): separate GameState data from engine logic#14
AnotherSava merged 4 commits intomainfrom
gamestate-restructuring

Conversation

@AnotherSava
Copy link
Owner

@AnotherSava AnotherSava commented Mar 16, 2026

Summary

  • Split monolithic GameState class into a plain GameState interface (zone data) and GameEngine class (CardDatabase + mutation logic)
  • Stripped Card to data fields and computed getters only — mutation methods moved to engine
  • Extracted toJSON/fromJSON as standalone functions storing full candidate names (no CardDatabase dependency for deserialization)
  • Typed PipelineResults as a discriminated union on gameName with runPipeline overloads for automatic narrowing

Plan: docs/plans/completed/2026-03-15-gamestate-restructuring.md

Update: split game_state.ts into three modules

  • Extract GameEngine class + helpers to game_engine.ts (~594 lines)
  • Extract toJSON/fromJSON + serialization types to serialization.ts (~149 lines)
  • Trim game_state.ts to data-only module: GameState interface, createGameState(), cardsAt()
  • Update all consumer imports across 7 files
  • Reject old exclusion-based serialization format with a clear error instead of silently producing empty candidate sets
  • Remove unused restrictCandidates method (dead code)

Plan: docs/plans/completed/2026-03-15-split-game-state.md

Update: complete subset detection in merge

  • Replace dead-code naked subset elimination in propagate() with complete subset detection in mergeCandidates/mergeSuspects
  • When N cards have exactly N candidates between them, resolve 1:1 instead of widening to the union
  • Same logic for suspect merging — preserve exact opponent knowledge when subset is complete
  • Remove combinations() helper (no longer needed)
  • Add no-test-only-production-code guideline to CLAUDE.md

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.
@AnotherSava AnotherSava merged commit b9ed603 into main Mar 17, 2026
@AnotherSava AnotherSava deleted the gamestate-restructuring branch March 17, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant