# HyperTwist — Comprehensive Reconstruction Roadmap
## Status: Draft — Post-Audit Reality Alignment
## Date: 2026-06-10

## Remaining Repo Inventory (Authoritative Reconstruction)

Source: `HYPERTWIST_REPO_STATE_BOARD_2026-05-11.md` and `HYPERTWIST_REPO_EVALUATION_RESET_AND_IMPLEMENTATION_SCHEDULE_2026-05-11.md`

**Within the original 71-row shallow-eval set:**

| Category | Count |
|----------|-------|
| Implemented/live (all licenses) | 29 |
| **Selected, not live (permissive candidates)** | **29** |
| Reference / benchmark / discard | 13 |
| **Total non-live** | **42** |

**Outside the 71-row set:**

| Category | Count | Repos |
|----------|-------|-------|
| Speech rows (landed as attribution only) | 4 | `ggml-org/whisper.cpp`, `rhasspy/piper`, `SYSTRAN/faster-whisper`, `coqui-ai/TTS` |

**The 29 selected-not-live permissive candidates include:**
- `cahidenes/rubiks-cube-solver`
- `tentone/rubix-solver`
- `NuiLab/code-vr`
- `pissang/claygl`
- `pissang/clay-viewer`
- `pmndrs/postprocessing`, `pmndrs/react-postprocessing`, `pmndrs/drei`, `pmndrs/react-spring`, `@react-spring/*`, `pmndrs/three-stdlib`, `pmndrs/maath`, `pmndrs/uikit`, `pmndrs/zustand`, `pmndrs/leva`, `pmndrs/use-gesture`
- `ecomfe/zrender`, `ecomfe/echarts-gl`
- `KhronosGroup/glTF-Sample-Viewer`, `KhronosGroup/glTF-Sample-Renderer`
- `google/model-viewer/packages/*` (sub-packages)
- And others in the 0R-B backlog

**None of these 29 are currently wired into the Unreal build.** They exist only as attribution bundles and JSONL reference pages.

---

---

## Executive Summary

This roadmap replaces the self-referential validation-ladder sequence with a
functional, repo-first reconstruction plan. The audit confirms that HyperTwist
is ~80% documentation scaffolding, ~15% data-structure code, and ~5% actual
game logic. No 3D puzzle renderer exists. No playable level exists. No donor
repos are wired into the build.

**The new rule:** Repos are wired before features are claimed. Features are
playable before they are documented. Validation tests verify behavior, not
structural metadata.

---

## Phase 0: Foundation — Build Infrastructure for Repo Wiring

**Goal:** Enable actual donor code to be compiled, linked, and shipped.

**Deliverables:**
- [x] Create `.external/` directory with 23 git submodules
- [x] Create `ThirdParty/` directory for direct-source C++ integration
- [x] Add `.gitmodules` for the first wave of C++ donor repos
- [x] Add `Build.cs` rules in `UnrealHyperTwist.Build.cs` for `PublicIncludePaths`
- [x] Windows build validation after each sub-step (prove the linker sees donor symbols)

**Estimated actions:** ~15 build actions per sub-step
**Estimated time:** 2–3 hours per sub-step (infrastructure compiles fast)

---

## Phase 1: Wire All Donor Repos (Repo-First Constraint)

**Principle:** Repos are wired into the build BEFORE any feature claims them.
See `HYPERTWIST_UNWIRED_REPO_INVENTORY_AND_WIRING_SCHEDULE_2026-06-10.md`
for the full 29-repo queue and per-repo wiring posture.

### 1A — Solver Backend: `efrantar/rob-twophase` ✅ COMPLETE
- [x] Add submodule `mirrors/rob-twophase`
- [x] Copy source to `Private/ThirdParty/rob-twophase/`
- [x] Fix UE macro conflicts (`check`→`ValidateCube`, `UF`→`UF_EDGE`)
- [x] Add `msvc_compat.h` for POSIX `ffs`/`ffsll` on Windows
- [x] Fix `unistd.h` → `direct.h`/`io.h`, `qt_skip1` C4700
- [x] Windows build validated: 5 actions, 38.87s, exit code 0
- [ ] Runtime test: feed a known scrambled state, assert solution length < 25 (deferred to Phase 4C)

### 1B — Speech-to-Text: `freestyle-voice/freestyle` (MIT)
- [ ] Decision gate: `freestyle` is a hotkey-driven dictation client, not an embeddable C++ library. It calls cloud APIs (OpenAI, Groq, Anthropic, Google, Deepgram, ElevenLabs) via HTTP.
- [ ] Integration path A (recommended): Run `freestyle` as external sidecar process. UE communicates via local HTTP loopback or IPC.
- [ ] Integration path B (fallback): Embed `freestyle` source (Tauri/Rust or Electron) as a UE plugin — evaluate complexity vs. value.
- [ ] Expose `UHyperTwistSpeechLibrary::StartDictationSession()` / `EndDictationSession()`
- [ ] On hotkey hold: capture microphone via UE `VoiceModule`, stream PCM to `freestyle` loopback endpoint
- [ ] On release: receive transcript JSON, parse cleaned text, execute move notation or coach command
- [ ] **Audio Ducking**: when `bDictationActive = true`, duck all non-speech `UAudioComponent` volumes to 15% via `FAudioDevice` mixer gain or per-component `VolumeMultiplier`
- [ ] Restore full volume 200ms after `EndDictationSession()`
- [ ] Automation test: simulate hotkey hold, assert `VolumeMultiplier < 0.2f` on background music component; assert restoration after release

### 1C — Text-to-Speech: `rhasspy/piper`
- [ ] Add submodule `mirrors/piper`
- [ ] Compile `piper` as static library (espeak-ng dependency)
- [ ] Download one small voice model (~50MB) into `Content/Voices/`
- [ ] Expose `UHyperTwistSpeechLibrary::Synthesize(FString Text, FString VoiceId)` → `TArray<uint8> PCM16`
- [ ] Automation test: synthesize "hello", assert PCM output is non-empty and has correct sample rate

### 1D — Compact Solver Oracle: `brownan/Rubiks-Cube-Solver` (GPL-2.0)
- [ ] Host as external IPC process (never link GPL into Unreal binary)
- [ ] Expose `UHyperTwistSolverLibrary::VerifySolution(FString State, TArray<FString> Moves)` → `bool`

### 1E — glTF Reference Renderer: `KhronosGroup/glTF-Sample-Renderer` (Apache-2.0)
- [ ] Add submodule `mirrors/glTF-Sample-Renderer`
- [ ] Evaluate: header-only portions vs. full renderer
- [ ] If linkable: add to `Build.cs`, expose asset import validation helpers
- [ ] If too heavy: retain as reference-only for QA pipeline

### 1F — Solver Adjunct: `cahidenes/rubiks-cube-solver` (MIT)
- [ ] Host as external IPC process (Python)
- [ ] Expose comparison endpoint: same state to both solvers, assert identical solution length

### 1G — Browser Solver: `tentone/rubix-solver` (MIT)
- [ ] Bundle into browser runtime (`Content/Browser/`)
- [ ] Load in embedded WebBrowser widget as demo/fallback solver UI

### 1H — Browser Spatial Stack (13 JS repos)
- [ ] Add all as npm dependencies or prebuilt bundles in `Content/Browser/`
- [ ] Repos: `NuiLab/code-vr`, `pissang/claygl`, `pissang/clay-viewer`, `pmndrs/postprocessing`, `pmndrs/react-postprocessing`, `pmndrs/drei`, `pmndrs/uikit`, `pmndrs/three-stdlib`, `pmndrs/maath`, `pmndrs/zustand`, `pmndrs/leva`, `pmndrs/use-gesture`, `pmndrs/react-spring` + sub-packages
- [ ] Build once via npm → bundle `browser-spatial-runtime.js`
- [ ] Load bundle in `UHyperTwistBrowserWidget`
- [ ] State bridge: UE `FJsonObject` ↔ JS `postMessage`

### 1I — Analytics Stack (2 JS repos)
- [ ] `ecomfe/zrender`, `ecomfe/echarts-gl`
- [ ] Bundle into browser runtime; subordinate to already-landed `apache/echarts`
- [ ] Expose chart data endpoint from UE analytics subsystem

### 1J — Model-Viewer Sub-Packages (3 JS repos, runtime)
- [ ] `google/model-viewer/packages/model-viewer-effects`, `space-opera`, `render-fidelity-tools`
- [ ] Bundle into browser runtime alongside already-landed `google/model-viewer`
- [ ] `render-fidelity-tools` → QA comparison pipeline only

**Estimated actions:** 40–60 per repo (UHT regen on first include)
**Estimated time:** 1–2 days per repo (build-debug cycles)

---

## Phase 2: Core Puzzle Renderer — The Missing Centerpiece

**Goal:** HyperTwist becomes a visible, interactive product.

**Principle:** This is the highest-priority functional gap. It blocks every user-facing feature.

### 2A — Procedural Classic Cube Geometry ✅ COMPLETE
- [x] Create `AHyperTwistClassicCubeActor` : `AActor`
- [x] Generate 26 pieces (6 centers, 12 edges, 8 corners) as `UProceduralMeshComponent` instances
- [x] 6 sections per piece, one per face direction; materials assigned per section
- [x] Place pieces in solved-state positions in a 3×3×3 grid
- [x] Windows build validated: 4 actions, 38.38s, exit code 0, zero warnings
- [ ] Editor-assigned colored materials (deferred to content creation pass)

### 2B — Face Rotation Logic ✅ COMPLETE
- [x] `RotateFace(ECubeFace Face, ERotationDirection Dir)` with move queueing
- [x] Piece identity tracking (26 pieces with fixed colored-face identities)
- [x] Tick-based pivot animation with smooth-step interpolation
- [x] 0.15s quarter-turn duration
- [x] Verified permutation cycles for all 6 faces against standard cube notation
- [x] Windows build validated: 6 actions, 66.53s, exit code 0, zero warnings

### 2C — Mouse/Touch Input ✅ COMPLETE
- [x] `ProcessClick(RayOrigin, RayDirection, bCounterClockwise)` with line trace
- [x] Hit normal → cube face mapping (Up/Down/Front/Back/Left/Right)
- [x] Wired to `RotateFace()` for interactive manipulation
- [x] Left click = clockwise, right click / bool flag = counter-clockwise
- [x] Windows build validated: 6 actions, 68.48s, exit code 0, zero warnings

### 2D — Scramble Generation ✅ COMPLETE
- [x] `GenerateScramble(int32 Length)` → `TArray<FString>` WCA-style notation
- [x] `ApplyScramble(MoveStrings)` parsing with ', 2 suffixes
- [x] Queued through existing RotateFace() pipeline with sequential animation
- [x] Windows build validated: 6 actions, 95.39s, exit code 0, zero warnings

### 2E — Timer + HUD
- [ ] Create `WBP_HyperTwistGameHUD` (UMG Widget)
- [ ] Timer display (minutes:seconds.milliseconds)
- [ ] Inspection countdown (15s standard)
- [ ] Scramble notation panel
- [ ] Bind timer start to first face turn, stop to solved-state detection

**Estimated actions:** 80–120 (geometry + input + HUD)
**Estimated time:** 3–5 days

---

## Phase 3: First Playable Level

**Goal:** A level you can launch, scramble, solve, and time.

### 3A — Level Creation
- [ ] Create `L_HyperTwist_ClassicTraining` (`.umap`)
- [ ] Place `AHyperTwistClassicCubeActor` at world origin
- [ ] Add directional light + ambient environment (basic, not immersive yet)
- [ ] Add `WBP_HyperTwistGameHUD` to viewport
- [ ] Add camera pawn with orbit controls (mouse drag orbits, scroll zooms)

### 3B — Game Mode
- [ ] Create `AHyperTwistClassicGameMode` : `AGameModeBase`
- [ ] Handle game state: `Idle`, `Inspecting`, `Solving`, `Solved`
- [ ] On `Solved`: stop timer, show solve time, offer "New Scramble"

### 3C — Build & Package Validation
- [ ] Package `UnrealHyperTwist` for Windows (not just Editor build)
- [ ] Launch packaged build on Windows host
- [ ] Verify: cube visible, clickable, scramble applies, timer works, solve detected

**Estimated actions:** 20–30
**Estimated time:** 1–2 days

---

## Phase 4: Wire Solver into Training Pipeline

**Prerequisite:** Phase 1A (rob-twophase) + Phase 2 (renderer)

### 4A — Solver HUD Integration
- [ ] Add "Hint" button to HUD
- [ ] On click: query solver for next optimal move from current state
- [ ] Animate hint (glow the suggested face)
- [ ] Option: show full solution sequence as notation list

### 4B — Training Mode: Follow-Along
- [ ] Create `L_HyperTwist_FollowAlongTraining` (`.umap`)
- [ ] Load a known scramble, show user the moves one at a time
- [ ] User must match each move before advancing
- [ ] Track accuracy and time

### 4C — Solver Verification
- [ ] After user solve, verify state is actually solved (not just timer stopped)
- [ ] If not solved, show "DNF" (Did Not Finish)

**Estimated actions:** 30–50
**Estimated time:** 2–3 days

---

## Phase 5: Speech Pipeline (STT + TTS)

**Prerequisite:** Phase 1B (freestyle) + Phase 1C (piper)

### 5A — Voice Command Input
- [ ] Add "Voice" button to HUD (or use freestyle global hotkey)
- [ ] On hotkey hold: capture microphone audio → stream to freestyle loopback
- [ ] On release: receive cleaned transcript from freestyle
- [ ] Parse transcript for move notation: "R", "R prime", "R2", "slice M", etc.
- [ ] Execute parsed move on cube
- [ ] **Audio ducking active during entire hold duration**

### 5B — Coach Narration Output
- [ ] Add narration events: "Scramble ready", "Inspection time", "Go!", "Solved!"
- [ ] Feed event text to piper → PCM16
- [ ] Play PCM16 through UE `USoundWaveProcedural` or `FSoundSource`
- [ ] Support multiple voice models (coach personality selection)
- [ ] **Narration audio is NOT ducking candidate** — only background music/ambient

### 5C — Voice Session Tests
- [ ] Automation test: simulate hotkey hold, assert background `VolumeMultiplier < 0.2f`
- [ ] Automation test: assert transcript "R prime" → parsed move `ECubeFace::R, ERotationDirection::CounterClockwise`
- [ ] Automation test: "Solved!" → piper → assert PCM length > 0

**Estimated actions:** 40–60
**Estimated time:** 2–3 days

---

## Phase 6: Hypercube Renderer (4D/5D)

**Prerequisite:** Phase 2 (classic renderer)

### 6A — 2×2×2×2 Projection
- [ ] Port Melinda 2×2×2×2 state math (already exists) to visible geometry
- [ ] Implement cell-first projection (8 cells, each a 3D cube)
- [ ] Color 16 stickers per cell using permutation/orientation state
- [ ] Mouse interaction: click cell + axis → twist

### 6B — 3×3×3×3 Projection
- [ ] Extend to 3×3×3×3 (27 tesseracts, 81 cells visible in projection)
- [ ] Use wireframe or transparent cells to avoid occlusion chaos
- [ ] Keyboard shortcuts for axis rotation and slice twists

### 6C — Magic120Cell & MagicCube5D
- [ ] Decision gate: port roice3 code (Java/C#) or implement clean-room in UE
- [ ] If port: host as external process, stream state via IPC
- [ ] If clean-room: implement 120-cell dodecahedral projection from spec

**Estimated actions:** 100–200
**Estimated time:** 1–2 weeks

---

## Phase 7: Non-Euclidean Puzzles (MagicTile)

**Prerequisite:** Phase 6 (hypercube renderer)

### 7A — MagicTile Host Decision
- [ ] Evaluate: port MagicTile Java/OpenTK to Unreal vs. host in embedded browser
- [ ] If browser: wire `react-three-fiber` + `three.js` into embedded CEF
- [ ] If port: implement spherical/hyperbolic tiling math from spec

### 7B — Puzzle State Bridge
- [ ] Unreal ↔ MagicTile state serialization
- [ ] Shared scramble notation parser
- [ ] Unified timer across puzzle types

**Estimated actions:** 80–150
**Estimated time:** 1–2 weeks

---

## Phase 8: Browser-Based Renderer

**Prerequisite:** Phase 2 (classic renderer)

### 8A — Embedded Browser Runtime
- [ ] Add `WebBrowser` plugin to `.uproject`
- [ ] Create `UHyperTwistBrowserWidget` wrapping `SWebBrowser`
- [ ] Load local `three.js` + `react-three-fiber` build

### 8B — State Synchronization
- [ ] Bridge UE cube state to browser via `FJsonObject` → JavaScript `postMessage`
- [ ] Browser renders cube using Three.js; UE handles input and logic
- [ ] Alternative: full browser client with HTTP API to UE backend

**Estimated actions:** 50–80
**Estimated time:** 3–5 days

---

## Phase 9: Social & Export

**Prerequisite:** Phase 3 (playable level)

### 9A — Replay Recording
- [ ] Record move sequence + timestamps during solve
- [ ] Export to `.json` replay file
- [ ] Load replay, reconstruct animation

### 9B — Media Export
- [ ] Integrate `remotion-dev/remotion` or UE `MovieRenderQueue` for video export
- [ ] Export solve animation as MP4
- [ ] Export scramble + time as shareable image

### 9C — Leaderboard Stub
- [ ] Local SQLite or JSON leaderboard (no backend yet)
- [ ] Store best times per puzzle type + scramble length
- [ ] Display in HUD

**Estimated actions:** 40–60
**Estimated time:** 2–3 days

---

## Phase 10: Validation Reconstruction

**Principle:** Validation only verifies what actually exists.

### 10A — Deprecate Structural-Only Tests
- [ ] Mark all Phase J tests that only verify contract ID stability as `Deprecated`
- [ ] Do not delete (preserves build history), but stop adding new ones

### 10B — Behavior-Based Validation Tests
- [ ] `FHyperTwistClassicCubeRotationTest`: Rotate R face, assert piece positions updated
- [ ] `FHyperTwistClassicCubeSolveTest`: Apply known solution, assert solved-state
- [ ] `FHyperTwistSolverAccuracyTest`: Feed 100 random states to solver, assert all solvable
- [ ] `FHyperTwistTimerAccuracyTest`: Start timer, wait 5s, assert 4.9s < elapsed < 5.1s
- [ ] `FHyperTwistSpeechTranscriptionTest`: Synthetic PCM "R prime" → assert move parsed

### 10C — Integration Tests
- [ ] Launch `L_HyperTwist_ClassicTraining`, simulate 10 moves, verify no crash
- [ ] Package build test: verify `UnrealHyperTwist.exe` launches and cube is visible

**Estimated actions:** 20–30
**Estimated time:** 1–2 days

---

## Cross-Cutting Concerns

### Licensing & Attribution
- Each wired repo gets a `LICENSE.thirdparty` entry
- GPL repos (brownan) remain IPC-only; never linked
- MIT/Apache repos compile and link directly
- Attribution bundles updated from metadata-only to runtime-provenance

### Build Validation Doctrine
- Every phase requires Windows Unreal build validation
- Phase 0–1: expect 50–100 actions (infrastructure)
- Phase 2–3: expect 150–250 actions (geometry + input)
- Phase 4+: expect 80–150 actions (feature wiring)
- Package validation (Phase 3C) is the real gate, not Editor build

### Documentation Rule
- Docs describe what IS implemented, not what MIGHT be
- No new "packet" files for scaffolding
- Architecture docs updated only after functional code is merged

---

## Summary: What Changes vs. Old Roadmap

| Old Approach | New Approach |
|--------------|--------------|
| Add struct pairs (J-HG → J-HM) | Wire repos (freestyle, piper, rob-twophase) |
| Tests verify contract IDs | Tests verify cube rotation, solve accuracy, speech |
| Docs claim features are "landed" | Features are playable before documented |
| 318 test files, 0 gameplay | 30 test files, 1 playable level |
| 1,142 docs, 20 content assets | Docs trimmed to functional truth |
| No donor repos linked | C++ repos compiled and linked |
| No .uasset, .umap | Procedural geometry + playable level |

---

## Immediate Next Step

**Phase 2E + 3:** Timer/HUD and First Playable Level. These require Unreal Editor
content creation (UMG widgets, materials, levels, game mode blueprints) that cannot
be created from text/C++ alone. The C++ backend is ready:

- `AHyperTwistClassicCubeActor` with geometry, rotation, click input, scramble
- `UHyperTwistSolverLibrary` with rob-twophase two-phase solver

Editor-side work needed:
- Create 6 simple colored materials (White, Yellow, Green, Blue, Orange, Red)
- Create `WBP_HyperTwistGameHUD` UMG widget with timer and scramble display
- Create `L_HyperTwist_ClassicTraining` level with cube actor, lights, camera
- Create Blueprint GameMode binding click input to `ProcessClick()`
