typescript-game-state

Applies TypeScript conventions for modelling game state with discriminated unions, branded ids, and pure engine functions.

1|Updated Aug 31, 2026
One-click install
npx skills add https://github.com/gagandeepgill/puzzle-game --skill typescript-game-state-gagandeepgill
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: typescript-game-state
Source: https://github.com/gagandeepgill/puzzle-game/tree/main/.claude/skills/typescript-game-state
Command: npx skills add https://github.com/gagandeepgill/puzzle-game --skill typescript-game-state-gagandeepgill

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Game codebases drift into invalid states when phases are modelled as parallel booleans, ids are passed as interchangeable numbers, and the rules engine leaks renderer dependencies. This Skill encodes the TypeScript conventions that make illegal states unrepresentable and keep the pure rules engine in src/game free of any DOM or React knowledge. ## Core Features & Use Cases - Discriminated union phases: Model game phases as a union on a kind field with an assertNever default, so adding a phase produces compiler errors instead of runtime bugs. - Exhaustive part handling: Define parts via a const tuple, a Record<PartKey, PartDef> table, and switch-based resolution so a new part cannot silently no-op. - Branded ids and readonly outputs: Distinguish CellIndex from Column at compile time and return readonly structures from the engine for honest replay and reliable React change detection. - Use Case: When adding a new part type or blueprint to the Payload engine, follow these conventions so the compiler lists every site that needs updating rather than letting one resolver quietly skip the new key. ## Quick Start Ask the AI to add a new part type to src/game following the typescript-game-state conventions, including the PART_KEYS entry, PARTS record entry, and exhaustive switch case.

Frequently Asked Questions about typescript-game-state

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I model game phases in TypeScript without invalid states?▼

Model phases as a discriminated union on a `kind` field instead of parallel boolean flags like `busy` and `submitted`. Read it with a switch whose default calls an `assertNever(x: never)` helper, so adding a phase produces compile errors at every unhandled site.

How to make TypeScript compiler find every place a new enum member needs handling?▼

Define the keys as a const tuple, derive the union type from it, and store definitions in a `Record<Key, Def>` rather than a Partial. Resolve effects through a switch with an assertNever default so any missing case fails to compile.

What are branded types in TypeScript and when should I use them?▼

Branded types intersect a primitive with a unique tag, such as `number & { __brand: 'CellIndex' }`, giving zero-runtime-cost nominal typing. Use them where two same-typed values are easily swapped, like cell indices and column numbers, but keep them out of view components.

Should a game rules engine import React or access the DOM?▼

No. The rules engine should be pure TypeScript with no `document`, `window`, or React imports, which makes it testable, replayable, and portable across web and native. This can be enforced mechanically by grepping the engine directory for renderer imports in CI.

What does noUncheckedIndexedAccess catch in game board code?▼

It forces an undefined check whenever an array is indexed by a computed position, which is exactly how board cells are accessed. Without it, off-grid arithmetic silently yields undefined instead of failing at the access site.

When should I avoid heavy typing in React components?▼

Keep branded ids and exhaustive unions in the engine layer and let React components take plain props. Typing CSS class strings or building a type-level design system adds ceremony without safety, since utility CSS correctness comes from editor tooling rather than the type system.