Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions STATE OF WORLD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# STATE OF WORLD

## Baseline Snapshot
- Date/time: 2026-03-02T20:19:29.5824836-06:00
- Branch: `feat/xbox-controller-support`
- Attempt: Fork `kalepail/kalien` into `tacticalnoot/kalien` and implement upstreamable Xbox controller support PR.

## Git Remotes
- `origin`: `https://github.com/tacticalnoot/kalien.git`
- `upstream`: `https://github.com/kalepail/kalien.git`

## Tool Versions
- `bun`: `1.3.9`
- `node`: `v22.21.1`
- `cargo`: `cargo 1.91.1 (ea2d97820 2025-10-10)`
- `gh auth`: logged in as `tacticalnoot` with active account

## Baseline Audit Results
- `bun install`: pass
- Baseline `bun run check`: fail (pre-existing gate)
- `worker-configuration.d.ts` out of date (`wrangler types --check` fails)

## Final Snapshot
- Date/time: 2026-03-02T20:50:34.0314779-06:00
- Branch: `feat/xbox-controller-support`
- Controller support implementation complete in `src/game` input path.
- Deterministic tape/replay contract unchanged.
- Deferred pass complete: replay-mode controller shortcuts + optional controller rumble + expanded controller HUD hints.

## Validation Runbook (Final)
- `bun test tests/src/gamepad-input.test.ts`: pass (8 tests)
- `bun run lint`: pass
- `bun run typecheck`: fail at pre-existing `typegen:check` gate when `worker-configuration.d.ts` is not regenerated
- `bun run check`: not fully passable in this environment without unrelated repo churn:
- If `worker-configuration.d.ts` is regenerated, typecheck/lint pass, then `format:check` reports existing formatting drift across ~120 files in `src/` and `worker/`.

## Caveats
- Manual browser/controller smoke test was not run in this shell session (no attached Xbox controller hardware/browser interaction in terminal workflow).
- Full root `bun run check` remains blocked by pre-existing repository state unrelated to controller logic.
47 changes: 47 additions & 0 deletions docs/CONTROLLER-SUPPORT-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Controller Support Plan

Date: 2026-03-02
Branch: `feat/xbox-controller-support`

## Current Input Architecture
- Keyboard events are handled by `InputController` in `src/game/input.ts`.
- Held state (`down`) and edge state (`pressed`) are tracked per key code.
- `LiveInputSource` in `src/game/input-source.ts` turns keyboard (or autopilot) into per-frame booleans: `left`, `right`, `thrust`, `fire`.
- `AsteroidsGame` reads one frame input in `updateSimulation()`, records it to tape, and updates simulation.
- Menu/pause/restart/replay controls are edge-triggered in `AsteroidsGame.handleGlobalInput()` via `consumePress(...)`.
- Frame loop is `requestAnimationFrame -> updateFrame()`, which is suitable for per-frame gamepad polling.

## Files To Touch
- `src/game/input.ts`
- `src/game/input-source.ts`
- `src/game/AsteroidsGame.ts`
- New small adapter: `src/game/gamepad.ts`
- Focused tests under `src/game/*.test.ts`
- Canonical docs under `docs/games/asteroids/`

## Determinism Risks
- Risk: introducing a parallel simulation path for controller input.
- Mitigation: controller state is normalized into existing action booleans only.
- Risk: edge-triggered menu actions repeatedly firing while a button is held.
- Mitigation: track controller pressed-vs-held edges and consume once per frame.
- Risk: stick drift causing unintended turn input.
- Mitigation: deadzone threshold (~0.25).
- Risk: replay mode drift.
- Mitigation: tape/replay input source remains unchanged; only live input path is extended.

## Implementation Plan
1. Add controller action/edge state support to `InputController` with keyboard behavior unchanged.
2. Add gamepad polling adapter using `navigator.getGamepads()` and Xbox-style mapping.
3. Poll controller once per frame in `AsteroidsGame.updateFrame()`.
4. Route gameplay booleans through unified action state (`keyboard OR controller`) in `LiveInputSource`.
5. Route one-shot global actions through keyboard-or-controller consume methods.
6. Add targeted tests for mapping/deadzone/edge behavior.
7. Update docs and state notes.

## Acceptance Tests
- Left stick and D-pad map to left/right with deadzone respected.
- A/RT maps to fire; thrust mapping is consistent and documented.
- Start/Menu maps to start/resume/pause behavior.
- Back/View maps to return-to-menu behavior.
- Keyboard controls continue to behave exactly as before.
- Per-frame deterministic booleans remain the only simulation input path.
58 changes: 58 additions & 0 deletions docs/CONTROLLER-SUPPORT-ROLLUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Controller Support Rollup

Date: 2026-03-02
Branch: `feat/xbox-controller-support`

## Summary
Added Xbox-style gamepad support to live Asteroids play by polling the browser Gamepad API each frame and normalizing state into the existing deterministic action model (`left`, `right`, `thrust`, `fire`).
This pass also adds replay-mode controller shortcuts and optional controller rumble feedback.

Keyboard controls remain unchanged and continue to work in parallel (`keyboard OR controller`).

## Files Touched
- `src/game/input.ts`
- `src/game/input-source.ts`
- `src/game/AsteroidsGame.ts`
- `src/game/gamepad.ts` (new)
- `tests/src/gamepad-input.test.ts` (new)
- `docs/games/asteroids/README.md`
- `docs/games/asteroids/01-GAME-SPEC.md`
- `docs/games/asteroids/15-DOCS-PARITY-CHECKLIST.md`
- `docs/CONTROLLER-SUPPORT-PLAN.md`

## Controller Mapping
- Left stick X < `-0.25` or d-pad left -> `left`
- Left stick X > `0.25` or d-pad right -> `right`
- `LT` or `LB` -> `thrust`
- `A` or `RT` -> `fire`
- `Start/Menu` -> start game / pause / resume (mode-dependent global action)
- `Back/View` -> return to menu
- Replay controls: `X=1x`, `Y=2x`, `B=4x`, `A/Start=pause`

## Gamepad API Constraints
- Uses polling (`navigator.getGamepads()`) once per animation frame.
- Uses edge detection for one-shot controller actions (`start`, `menu`) to avoid repeated triggers while held.
- Replay/tape format is unchanged. Controller input is only a live-input source mapped to existing booleans.
- Optional gamepad rumble uses browser Gamepad vibration APIs when available; unsupported implementations are ignored safely.

## Test Evidence
- `bun test tests/src/gamepad-input.test.ts`
- 8 passing tests:
- deadzone behavior
- left/right mapping (stick + d-pad)
- fire/thrust/start/menu mapping
- replay shortcut button mapping
- keyboard press semantics unchanged
- keyboard+controller held-state merge
- gamepad press edge semantics
- replay shortcut edge semantics
- `bun run typecheck` fails at pre-existing `typegen:check` (`worker-configuration.d.ts` out of date)
- with regenerated worker types, app/node/worker/script typechecks pass
- `bun run lint` passed
- `bun run format:check` currently fails repository-wide due pre-existing formatting drift across many files unrelated to this change.

## Manual Smoke Test
Not executed in this shell session (no browser/controller hardware attached).

## Follow-up Ideas (Deferred)
- In-game rebinding UI for controller mappings.
9 changes: 9 additions & 0 deletions docs/games/asteroids/01-GAME-SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ Game state transitions must be deterministic given:
## Input Model
- 4 action bits per frame: `left`, `right`, `thrust`, `fire`.
- High nibble reserved and must be zero.
- Live controls (keyboard/gamepad) must normalize into these same 4 bits before simulation.
- Xbox-style controller mapping for live play:
- left stick X or d-pad left/right -> `left` / `right`
- `LT` or `LB` -> `thrust`
- `A` or `RT` -> `fire`
- `Start` -> menu start/resume/pause action (UI/global only, not tape bit)
- `Back/View` -> return-to-menu action (UI/global only, not tape bit)
- replay-only shortcuts: `X=1x`, `Y=2x`, `B=4x`, `A/Start=pause`
- Optional controller haptics may be emitted in interactive mode; they are cosmetic and not part of deterministic replay state.

## Core Mechanics
### Ship
Expand Down
16 changes: 15 additions & 1 deletion docs/games/asteroids/15-DOCS-PARITY-CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Asteroids Docs Parity Checklist (AST4)

Date: 2026-02-28
Date: 2026-03-02

## Purpose
Code-backed checklist confirming that Asteroids docs match the current TS/Rust/Worker/Contract implementation.
Expand All @@ -14,6 +14,9 @@ This is a point-in-time snapshot. Keep canonical docs updated directly; refresh
- `kalien-verifier/asteroids-core/src/constants.rs`
- Gameplay rules/math:
- `src/game/AsteroidsGame.ts`
- `src/game/input.ts`
- `src/game/input-source.ts`
- `src/game/gamepad.ts`
- `src/game/constants.ts`
- `kalien-verifier/asteroids-core/src/sim/mod.rs`
- `kalien-verifier/asteroids-core/src/sim/game.rs`
Expand Down Expand Up @@ -57,12 +60,23 @@ This is a point-in-time snapshot. Keep canonical docs updated directly; refresh
- Prover `proof_mode` is forced from `RISC0_DEV_MODE` (not request-driven).
- Score contract call is `submit_score(seal, journal_raw)`.

7. Live input normalization
- Live gameplay input still enters simulation only as `left/right/thrust/fire` booleans.
- Keyboard and gamepad input are merged before simulation, and tape encoding semantics are unchanged.
- Controller-only global actions (`Start`, `Back/View`) affect menu/pause flow only and are not serialized into tape bits.
- Replay shortcut buttons (`X/Y/B/A/Start`) map to replay controls only and do not alter tape semantics.

8. Controller haptics (cosmetic)
- Browser gamepad rumble calls are optional runtime effects in interactive mode only.
- Haptic effects are outside simulation state and do not influence deterministic replay, tape bytes, verifier behavior, or score outcomes.

## Docs Updated In This Pass
- `docs/games/asteroids/README.md`
- `docs/games/asteroids/01-GAME-SPEC.md`
- `docs/games/asteroids/02-VERIFICATION-SPEC.md`
- `docs/games/asteroids/04-INTEGER-MATH-SPEC.md`
- `docs/games/asteroids/06-IMPLEMENTATION-STATUS.md`
- `docs/games/asteroids/15-DOCS-PARITY-CHECKLIST.md`
- `docs/archive/games/asteroids/13-ORIGINAL-RULESET-VARIANCE-AUDIT.md`
- `docs/archive/games/asteroids/14-VARIANCE-RESOLUTION-PLAN.md`

Expand Down
138 changes: 138 additions & 0 deletions docs/games/asteroids/16-GAME-CONTENT-INVENTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# 16 - Game Content Inventory (AST4)

## Current Build Snapshot
- Generated from current code/docs baseline on 2026-03-02.
- Ruleset: `AST4` (`rules_tag=4`).
- Core deterministic input contract remains `left/right/thrust/fire` only.
- Status: `Implemented`
- Evidence:
- `src/game/tape.ts:15` (four-bit nibble mapping)
- `src/game/constants.ts:68` (`RULES_TAG = 4`)
- `docs/games/asteroids/01-GAME-SPEC.md:7`

## Core Player Verbs
| ID | Verb | Status | Evidence |
|---|---|---|---|
| `action_left` | Turn Left | Implemented | `src/game/tape.ts:19`, `src/game/AsteroidsGame.ts:970` |
| `action_right` | Turn Right | Implemented | `src/game/tape.ts:20`, `src/game/AsteroidsGame.ts:971` |
| `action_thrust` | Thrust | Implemented | `src/game/tape.ts:21`, `src/game/AsteroidsGame.ts:972` |
| `action_fire` | Fire | Implemented | `src/game/tape.ts:22`, `src/game/AsteroidsGame.ts:1002` |
| `action_keyboard_controls` | Keyboard Controls | Implemented | `src/game/input.ts:1`, `docs/games/asteroids/README.md:38` |
| `action_xbox_controller` | Xbox Controller Mapping | Implemented | `src/game/gamepad.ts:3`, `src/game/input.ts:132`, `docs/games/asteroids/README.md:39` |

## Game Modes
| ID | Mode | Status | Evidence |
|---|---|---|---|
| `mode_menu` | Menu Mode | Implemented | `src/game/types.ts:9`, `src/game/AsteroidsGame.ts:303` |
| `mode_playing` | Playing Mode | Implemented | `src/game/types.ts:9`, `src/game/AsteroidsGame.ts:489` |
| `mode_paused` | Paused Mode | Implemented | `src/game/types.ts:9`, `src/game/AsteroidsGame.ts:515` |
| `mode_game_over` | Game Over Mode | Implemented | `src/game/types.ts:9`, `src/game/AsteroidsGame.ts:700` |
| `mode_replay` | Replay Mode | Implemented | `src/game/types.ts:9`, `src/game/AsteroidsGame.ts:1673` |

## Entities
| ID | Entity | Status | Notes |
|---|---|---|---|
| `entity_ship` | Player Ship | Implemented | Respawn + invulnerability timers |
| `entity_asteroid_sizes` | Asteroid Size Chain | Implemented | Large -> Medium -> Small |
| `weapon_ship_bullets` | Ship Bullets | Implemented | Cap + cooldown + lifetime |
| `weapon_saucer_bullets` | Saucer Bullets | Implemented | Cap + lifetime |

Evidence:
- `src/game/types.ts:11`
- `src/game/AsteroidsGame.ts:876`
- `src/game/AsteroidsGame.ts:1254`
- `src/game/constants.ts:24`

## Enemies
| ID | Enemy Group | Status | Evidence |
|---|---|---|---|
| `entity_asteroid_sizes` | Asteroids (large/medium/small) | Implemented | `src/game/types.ts:11`, `src/game/AsteroidsGame.ts:1479` |
| `enemy_saucers` | Saucers (large/small) | Implemented | `src/game/types.ts:51`, `src/game/AsteroidsGame.ts:1217` |

## Weapons / Attacks
| ID | Weapon | Status | Evidence |
|---|---|---|---|
| `weapon_ship_bullets` | Ship Bullets | Implemented | `src/game/AsteroidsGame.ts:1003`, `src/game/constants.ts:18` |
| `weapon_saucer_bullets` | Saucer Bullets | Implemented | `src/game/AsteroidsGame.ts:1255`, `src/game/constants.ts:21` |

## Scoring Rules
- Status: `Implemented`
- Asteroid score bands: `20 / 50 / 100`
- Saucer score bands: `200 / 990`
- Extra life step: `10,000`
- Evidence:
- `src/game/constants.ts:37`
- `src/game/constants.ts:41`
- `src/game/constants.ts:9`
- `src/game/AsteroidsGame.ts:1523`

## Progression / Waves / Pressure
- Status: `Implemented`
- `progress_wave_system`: wave spawns scale up to 16 large asteroids.
- `progress_anti_lurk`: `timeSinceLastKill` pressure kicks in after `360` frames.
- Saucer concurrency by wave tier: `1`, then `2`, then `3`.
- Evidence:
- `src/game/AsteroidsGame.ts:94` (`waveLargeAsteroidCount`)
- `src/game/AsteroidsGame.ts:102` (`maxSaucersForWave`)
- `src/game/AsteroidsGame.ts:1133` (`saucerLurkPressurePct`)
- `src/game/constants.ts:61`

## Session End Conditions
- Status: `Implemented`
- `session_hard_cap`: game-over if frame count exceeds `MAX_GAME_FRAMES`.
- Life exhaustion (`lives <= 0`) also causes game-over.
- Evidence:
- `src/game/AsteroidsGame.ts:699`
- `src/game/AsteroidsGame.ts:1510`
- `src/game/constants.ts:65`

## Determinism-Critical Rules
- Status: `Implemented`
- `deterministic_tape_recording`: AST4 tape format, nibble-packed body, CRC32.
- `system_score_claim_flow`: proof/claim path bound by `(seed_id, claimant)` and `submit_score`.
- `action_*` and progression rules feed deterministic per-frame simulation.
- Evidence:
- `src/game/tape.ts:1`
- `worker/api/routes-proofs.ts:301`
- `kalien-contract/contracts/asteroids_score/src/lib.rs:125`
- `docs/games/asteroids/15-DOCS-PARITY-CHECKLIST.md:33`

## Non-Consensus Presentation Layer
- `cosmetic_gamepad_rumble`: Implemented
- Scope: browser rumble only; no replay/proof/score effect.
- Evidence:
- `src/game/gamepad.ts:78`
- `src/game/AsteroidsGame.ts:1118`
- `docs/games/asteroids/15-DOCS-PARITY-CHECKLIST.md:69`

## Explicit Omissions / Not Present
| ID | Feature | Status | Evidence |
|---|---|---|---|
| `omission_hyperspace` | Hyperspace | Absent | `docs/games/asteroids/01-GAME-SPEC.md:74` |
| `omission_bosses` | Bosses | Absent | no gameplay symbols in `src/game` audit |
| `omission_powerups` | Powerups and Pickups | Absent | no gameplay symbols in `src/game` audit |
| `omission_shields` | Shield mechanics | Absent | no shield action/state; only spawn invulnerability timer |

## Known Ambiguities
| ID | Topic | Status | Follow-up |
|---|---|---|---|
| `unknown_hidden_menus` | Hidden menus | Unknown | Keep scanning non-gameplay UI routes for hidden dev toggles |
| `unknown_secret_lore` | Secret lore/easter eggs | Unknown | If added, register in manifest + manual as non-consensus flavor |

## Evidence Index
- `src/game/tape.ts`
- `src/game/constants.ts`
- `src/game/input.ts`
- `src/game/gamepad.ts`
- `src/game/input-source.ts`
- `src/game/AsteroidsGame.ts`
- `src/game/types.ts`
- `worker/api/routes-proofs.ts`
- `worker/queue/consumer.ts`
- `kalien-contract/contracts/asteroids_score/src/lib.rs`
- `docs/games/asteroids/01-GAME-SPEC.md`
- `docs/games/asteroids/15-DOCS-PARITY-CHECKLIST.md`
- `docs/archive/games/asteroids/13-ORIGINAL-RULESET-VARIANCE-AUDIT.md`

## Inventory IDs (Machine Cross-Check)
`mode_menu`, `mode_playing`, `mode_paused`, `mode_game_over`, `mode_replay`, `action_left`, `action_right`, `action_thrust`, `action_fire`, `action_keyboard_controls`, `action_xbox_controller`, `entity_ship`, `entity_asteroid_sizes`, `enemy_saucers`, `weapon_ship_bullets`, `weapon_saucer_bullets`, `progress_wave_system`, `progress_anti_lurk`, `progress_extra_lives`, `session_hard_cap`, `system_replay_load_download`, `system_autopilot`, `system_leaderboard_hooks`, `system_score_claim_flow`, `cosmetic_gamepad_rumble`, `omission_hyperspace`, `omission_bosses`, `omission_powerups`, `omission_shields`, `unknown_hidden_menus`, `unknown_secret_lore`, `planned_classic_hyperspace_profile`
Loading