feat(engine): structure rotation, occupancy categories, demolish#1
Merged
Gizmotronn merged 1 commit intoJul 20, 2026
Conversation
Adds the three placement mechanics the engine was missing for consumers that need base-building beyond single-purpose outposts: - StructureDef gains a `category` (functional | decorative, defaults to functional). Occupancy is now checked per-category rather than per-tile, so a decorative structure (nav beacon) can share a tile with one functional structure; two functional structures still can't share a tile. - Structure gains an optional cosmetic `facing`, set from the rover's facing at build time. `Simulation.rotateStructure(id)` cycles it 90° at a time; requires the rover to be adjacent, same range as deposit/launch interactions. - `Simulation.demolish(id)` removes a placed structure the rover is adjacent to. No resource refund in this pass — demolition is a deliberate, lossy action. Both new interactions are exposed on the `RoverGame` facade (`rotateStructure`, `demolish`) and wired into the existing audio/error event mapping. Save/resume needs no changes since `serialize()` already spreads the full Structure object. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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
StructureDef.category(functional|decorative, defaults tofunctional) — occupancy is now checked per-category per-tile instead of strictly one-structure-per-tile. A decorative structure (nav beacon) can now share a tile with one functional structure; two functional structures still can't share a tile.Structure.facing(optional, cosmetic) — set from the rover's facing at build time.Simulation.rotateStructure(id)cycles it 90° at a time, requiring the rover be adjacent (same range as deposit/launch).Simulation.demolish(id)— removes a placed structure the rover is adjacent to. No resource refund in this pass.RoverGame(rotateStructure,demolish) and wired into the existing audio/error event mapping (rotated/rotateFailed/demolished/demolishFailed).serialize()already spreads the fullStructureobject, sofacinground-trips through existing saves asundefined(defaults to 0).Why
This closes the gap a downstream consumer (Star Sailors' Landnam) hit: base-building needs occupancy rules that distinguish decoration from function, rotation, and a way to undo a placement — none of which existed in the engine yet. Building these here rather than downstream so any game on
@takeon/enginebenefits.Test plan
npm run test -w @takeon/engine— 63/63 passing, including 6 new tests covering decorative overlap, functional-on-functional blocking, rotation cycling, adjacency guards on rotate/demolish, and unknown-id handlingnpm run build— engine, pixi, and the Next.js web app all typecheck and build clean against the widened types