Codebase Summary - Night Ninja: Twilight Voyage
Overview
NNTV is a turn-based stealth puzzle game built with Svelte 5 and Vite 6.x. The codebase separates pure JS game engine (classes in lib/game/) from Svelte rendering (scenes + components). State flows one-way: game classes mutate internally, then renderVersion++ triggers Svelte re-derivation.
Module Inventory
Entry Point
- src/main.js — Mounts
App.svelte into #app
Scene Router
- src/App.svelte —
{#key currentScene} with transition:fade, passes navigate function as prop to all scenes
Scenes (src/scenes/)
| File |
Purpose |
| MainMenu.svelte |
Start game, level select, settings, guide |
| StoryIntro.svelte |
Scrolling narrative with skip button |
| LevelIntro.svelte |
Level name + story text + continue |
| LevelSelect.svelte |
4x3 grid of level buttons (locked/unlocked/completed) |
| Game.svelte |
Main gameplay: state owner, input, turn loop, rendering |
| GameOver.svelte |
Loss/twist screen, retry/menu |
| Settings.svelte |
Language toggle (EN/VI) |
| Guide.svelte |
Rules, controls, enemy types |
Components (src/components/)
| File |
Purpose |
| Button.svelte |
Reusable styled button |
| GameBoard.svelte |
CSS grid of cells, each rendering a pixel-art tile |
| GameHud.svelte |
Level, lives (pixel hearts), turns, pixel-icon action buttons |
| PlayerSprite.svelte |
Pixel-art ninja rabbit sprite |
| GuardSprite.svelte |
Pixel-art veggie sprite dispatched by guard.type + direction indicator |
| DetectionPopup.svelte |
"Detected!" overlay with retry |
| LevelCompletePopup.svelte |
Star rating, best moves, next-level action |
| PauseMenu.svelte |
Resume / restart / main menu |
| ControlsOverlay.svelte |
Keyboard / tap / swipe reference overlay |
Game Engine (src/lib/game/) — Pure JS, no Svelte
| File |
Purpose |
| grid-system.js |
GridSystem class: cell state, walls, goals, lighting |
| player.js |
Player class: position, movement validation |
| guards.js |
Guard base + 6 subclasses (Static, Rotating, Blinking, Mirror, Patrolling, Chaser) |
| turn-manager.js |
TurnManager: turn cycle, guard updates, detection |
| level-manager.js |
loadLevel(): GUARD_REGISTRY factory pattern for guard instantiation |
| level-solver.js |
BFS solvability checker (test-only); reuses runtime AI via capture()/apply() |
| game-history.js |
GameHistory class: undo/redo snapshots (Z/Y keys) |
| princess-mechanic.js |
Princess detection logic: escalating light rings on level 12 |
| touch-controls.js |
TouchControls class: pointer gesture detection (legacy; no mobile support claim) |
Level Data (src/lib/levels/)
| File |
Purpose |
| levels.js |
LEVELS array: 12 level definitions (grid, guards, walls, goals); L1-L11 solvable, L12 intentionally unsolvable |
| levels.solvability.test.js |
CI-enforced invariants: each L1-L11 solvable, L12 unsolvable, no wall/light overlaps, exactly 12 levels |
Pixel-Art Pipeline (src/lib/pixel/)
| File |
Purpose |
| Pixel.svelte |
SVG renderer: string-art + palette → run-length-merged <rect>s |
| palette.js |
NNTV color constants (mirrors theme.css guard colors; extended atmosphere palette) |
| art-characters.js |
32×32 sprites: rabbit, princess, 6 guard veggies + GUARD_SPRITES map |
| art-tiles.js |
16×16 board tiles: empty, wall, goal, lit, mirror, preview |
| art-ui.js |
Heart (full/empty), moon, logo, pixel icons (undo/redo/eye/pause/settings/lang/arrow) |
| art-scenes.js |
80×N act backdrops + SCENE_BY_LEVEL mapping (garden/walls/fortress/underground/palace/chamber) |
Audio System (src/lib/)
| File |
Purpose |
| audio.js |
Web Audio API procedural sound: playTone, playMoveSound, playDetectionSound, playCompleteSound, toggleMute |
Utilities (src/lib/)
| File |
Purpose |
| localization.js |
getText/setLanguage/getLanguage/initLanguage |
| progress.js |
getProgress/completeLevel via localStorage |
Localization (src/lib/locales/)
| File |
Keys |
Purpose |
| en.json |
~55 |
English translations |
| vi.json |
~55 |
Vietnamese translations |
Styles (src/styles/)
| File |
Purpose |
| theme.css |
CSS variables: colors, fonts, guard colors, grid colors |
Class Hierarchy
Guard Inheritance
Key Data Structures
Level Definition
Cell State
Progress (localStorage)
Public API Summary
GridSystem
Player
Guards
PrincessMechanic
GameHistory
TurnManager
Dependencies
| Package |
Version |
Purpose |
| svelte |
5.x |
UI framework (runes mode) |
| vite |
6.3.6 |
Build tool, dev server |
| @sveltejs/vite-plugin-svelte |
6.x |
Svelte compiler for Vite |
File Dependency Map
Statistics
| Metric |
Value |
| Total Source Files |
~36 (8 scenes + 9 components + 8 engine + 6 pixel + audio + utils) |
| Number of Classes |
10 (GridSystem, Player, Guard + 6 subclasses, TurnManager, GameHistory, TouchControls) |
| Number of Levels |
12 (across 6 acts) |
| Guard Types |
6 (Static, Rotating, Blinking, Mirror, Patrolling, Chaser) |
| Localization Keys |
~67 per language |
| Max Grid Size |
10x10 |
| Max Guards/Level |
8 |