Skip to content
Merged
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
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ These are the working rules for agents in this repo. Puzzle Boy is a faithful, c

## Code layout

- `external/puzzle-boy-engine`: the shared engine, a pinned git submodule. `PuzzleBoy.Rules` has stage parsing (`Stage`, `Cell`) and the rules (`Board`), with no MonoGame and no file I/O. `PuzzleBoy.Nocturne` finds the install (`GameInstall`) and decodes its bundles. `PuzzleBoy.Rendering` draws the board and Jack (`BoardView`, `CharacterView`, `CharacterModel`), runs the camera and move timing (`ViewCamera`, `MoveAnimation`) and plays `Sounds`. Don't edit them here: a change and its test go into the engine repo first, then this repo bumps the pin with `build: bump engine to <short-sha>`. Community Edition draws its Classic theme with the same code, so a change there changes both games.
- `src/PuzzleBoy`: the MonoGame (DesktopGL) game: the tick loop (`PuzzleBoyGame`), `GameAssets`, the HUD, dialogue, menu and `TextRenderer`. `OriginalStageOrder` lists the original's 20 stage files in order. `Program` finds the player's install through the engine's `GameInstall`, or takes the game folder as the first argument. It has no content pipeline; every asset is read at runtime.
- `tests/PuzzleBoy.Tests`: xunit.v3 on Microsoft Testing Platform, covering the game. The rules, asset-reading and rendering tests live in the engine. Tests that need a board draw it as text with `Ascii.cs`; its summary has the legend. Test names read as sentences.
- `external/puzzle-boy-engine`: the shared engine, a pinned git submodule. `PuzzleBoy.Rules` has stage parsing (`Stage`, `Cell`) and the rules (`Board`), with no MonoGame and no file I/O. `PuzzleBoy.Nocturne` finds the install (`GameInstall`) and decodes its bundles. `PuzzleBoy.Rendering` draws the board and Jack (`BoardView`, `CharacterView`, `CharacterModel`), runs the camera and move timing (`ViewCamera`, `MoveAnimation`), plays `Sounds`, and draws the original's interface (`Hud`, `TextRenderer`, `Menu`, `Dialogue`). Don't edit them here: a change and its test go into the engine repo first, then this repo bumps the pin with `build: bump engine to <short-sha>`. Community Edition draws its Classic theme with the same code, so a change there changes both games.
- `src/PuzzleBoy`: the MonoGame (DesktopGL) game: the tick loop (`PuzzleBoyGame`), which decides when the HUD, dialogue, menu and help show, and `GameAssets`. `OriginalStageOrder` lists the original's 20 stage files in order. `Program` finds the player's install through the engine's `GameInstall`, or takes the game folder as the first argument. It has no content pipeline; every asset is read at runtime.
- `tests/PuzzleBoy.Tests`: xunit.v3 on Microsoft Testing Platform, covering the game. The rules, asset-reading, rendering and UI tests live in the engine. Tests that need a board draw it as text with `Ascii.cs`; its summary has the legend. Test names read as sentences.

## Working style

Expand Down
17 changes: 15 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,28 @@ Community Edition's Classic theme draws the original with this port's code, so t

[v0.3.0](https://github.com/hazeliscoding/puzzle-boy/releases/tag/v0.3.0) published the split (PR #3): the original's 20 stages on the shared engine, after the start checks passed on all three systems ([run 38775719377](https://github.com/hazeliscoding/puzzle-boy/actions/runs/38775719377)).

## M7: Shared original UI (2026.10.15)

Community Edition's Classic theme shows the original's HUD, controls and menus, so the code that draws them moves to the engine too, as in M6. Nothing about what this port shows, or when, may change.

- [x] Move `Hud` (with `UiLayout`, `UiSheets`, `HudState` and `BarSet`), `TextRenderer` and `BakedText`, `Menu`, `MenuItem` and `KeyRepeat`, and `Dialogue` to the engine's `PuzzleBoy.Rendering`. `Dialogue` goes too because `Hud.DrawDialogue` takes one; when the Manikin Kid talks stays in `PuzzleBoyGame`.
- [x] Use them here, pinned at engine `49a07d8`, and delete the copies.
- Evidence (observed): each moved file diffed against `83c9565`, the last commit before the move. 8 files, 1,081 lines; 19 lines changed and 1 line removed. Every change is the namespace (8), `internal` to `public` on a type (11), or the `using PuzzleBoy.Rendering;` that `Hud.cs` no longer needs inside that namespace. No citation, statement, constant or expression changed.
- 28 of the 51 tests moved with the code: Hud 10, TextRenderer 10, Menu 4, Dialogue 4. The engine went from 238 to 266, and 23 stay here (Controls 17, PreservationScope 6). `ControlsTests` stays whole: every case reads `PuzzleBoyGame`'s key tables.
- `PuzzleBoy no-game-here` prints the same missing-game message from a debug build.
- Not checked: a screen drawn from the owner's install. The code is the same, but the screen wasn't compared.

**Done when** the moved code differs from this port's last copy only in namespace and visibility, no test is lost, and every gate passes.

## Cross-repo ledger (2026.10.15)

| Repo | Role | Engine pin |
|---|---|---|
| [puzzle-boy-engine](https://github.com/hazeliscoding/puzzle-boy-engine) | Headless rules (`PuzzleBoy.Rules`), plus reading (`PuzzleBoy.Nocturne`) and drawing (`PuzzleBoy.Rendering`) the player's own Nocturne files. Not a game. | — |
| [puzzle-boy](https://github.com/hazeliscoding/puzzle-boy) (this repo, `split/three-repos`, draft PR #3) | The preservation port: the original 20 stages from the player's own copy. | `2a38379` |
| [puzzle-boy](https://github.com/hazeliscoding/puzzle-boy) (this repo) | The preservation port: the original 20 stages from the player's own copy. | `49a07d8` on `shared-ui` (M7), `2a38379` on `main` |
| [puzzle-boy-community](https://github.com/hazeliscoding/puzzle-boy-community) | The minigame expanded: new stages, editor, packs, bonus stages; Default theme bundled, Classic theme from the player's copy. | `2a38379` |

Both games must pin the same engine commit. An engine change lands there first, then both bump with `build: bump engine to <short-sha>`.
Both games must pin the same engine commit. An engine change lands there first, then both bump with `build: bump engine to <short-sha>`. Community bumps to `49a07d8` with its C7; until then the pins differ.

**Definition of done, where it stands:** the engine (E1 to E3) and this port's split (M5, M6) are done, with CI green on GitHub. This port plays only the original 20 (`The_original_order_is_exactly_the_twenty_documented_files`, `The_original_order_holds_no_bonus_file`, `The_preservation_game_never_calls_Board_Switch`, `The_preservation_game_has_no_switch_or_stage_skip_key`). Community's C1 to C4 and C6 are done and C5 (its first release) is open; its own ROADMAP has the per-platform table. Still open: merging PR #3 (the owner's call), replaying the 20 stages from the owner's install since the split, signing, and hand-play on macOS and Linux.

Expand Down
7 changes: 4 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Architecture

> [!TIP]
> **TL;DR:** There are two projects, plus the engine. The engine, [puzzle-boy-engine](https://github.com/hazeliscoding/puzzle-boy-engine), is a git submodule in `external/puzzle-boy-engine` that Community Edition shares. Its `PuzzleBoy.Rules` holds the game's logic, with no graphics and no file access, so tests drive it with plain bytes. Its `PuzzleBoy.Nocturne` reads your install's bundles, and its `PuzzleBoy.Rendering` draws the board and Jack and plays the sounds. `PuzzleBoy` is the MonoGame app: it reads everything from your install once at startup, then runs the original's 30-tick loop and draws the HUD, dialogue and menu.
> **TL;DR:** There are two projects, plus the engine. The engine, [puzzle-boy-engine](https://github.com/hazeliscoding/puzzle-boy-engine), is a git submodule in `external/puzzle-boy-engine` that Community Edition shares. Its `PuzzleBoy.Rules` holds the game's logic, with no graphics and no file access, so tests drive it with plain bytes. Its `PuzzleBoy.Nocturne` reads your install's bundles, and its `PuzzleBoy.Rendering` draws the board, Jack, the HUD, dialogue and menu and plays the sounds. `PuzzleBoy` is the MonoGame app: it reads everything from your install once at startup, then runs the original's 30-tick loop and decides what shows when.

**Read time:** 4 minutes

Expand All @@ -15,19 +15,20 @@ flowchart LR
subgraph app["PuzzleBoy (MonoGame)"]
order["OriginalStageOrder<br>which files, in what order"] --> ga
ga["GameAssets<br>everything, decoded once"] --> loop["PuzzleBoyGame<br>the tick loop"]
loop --> hud["Hud, TextRenderer,<br>dialogue and menu"]
end
subgraph nocturne["PuzzleBoy.Nocturne, from the engine"]
gi["GameInstall<br>finds and reads the bundles"]
end
subgraph rendering["PuzzleBoy.Rendering, from the engine"]
views["BoardView, CharacterView,<br>ViewCamera, MoveAnimation, Sounds"]
hud["Hud, TextRenderer,<br>Dialogue and Menu"]
end
subgraph rules["PuzzleBoy.Rules, from the engine"]
stage["Stage<br>parses 828-byte files"] --> board["Board<br>steps, pushes, swivels, undo"]
end
gi --> ga
loop --> views
loop --> hud
bundles --> gi
ga -- "stage bytes" --> stage
loop -- "Step, Undo, Retry" --> board
Expand Down Expand Up @@ -77,7 +78,7 @@ sequenceDiagram
| `GameInstall` | Finds the Steam install and reads bundles with AssetsTools.NET (engine, `PuzzleBoy.Nocturne`) |
| `GameAssets` | Reads and decodes every asset once at startup, in about 2 seconds |
| `PuzzleBoyGame` | The tick loop: input, menus, dialogue, stage flow |
| `ViewCamera` | The follow camera, view turns, the overhead view and the quake (engine, `PuzzleBoy.Rendering`, like the next three and `Sounds`) |
| `ViewCamera` | The follow camera, view turns, the overhead view and the quake (engine, `PuzzleBoy.Rendering`, like the next five and `Sounds`) |
| `MoveAnimation` | Replays one move over its ticks |
| `BoardView` | Board geometry, glass walls, outlines, the goal and the backdrop |
| `CharacterModel`, `CharacterView` | Pose and skin Jack each tick, then draw him with his shadow and glow |
Expand Down
2 changes: 1 addition & 1 deletion docs/rendering-and-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> [!TIP]
> **TL;DR:** The board is unlit, textured from the game's own atlas, with see-through glass walls and a glowing goal. Jack is skinned on the CPU and toon-shaded. The HUD keeps the original's 1920×1080 layout at any window size, and all text goes through a TextMeshPro distance-field renderer written for the CPU. The finer numbers were checked against gameplay footage.

**Read time:** 5 minutes · **Code:** `Hud.cs`, `TextRenderer.cs`, and `BoardView.cs`, `CharacterModel.cs` and `CharacterView.cs` in the engine's `PuzzleBoy.Rendering`
**Read time:** 5 minutes · **Code:** `Hud.cs`, `TextRenderer.cs`, `BoardView.cs`, `CharacterModel.cs` and `CharacterView.cs` in the engine's `PuzzleBoy.Rendering`

## Coordinates

Expand Down
155 changes: 0 additions & 155 deletions src/PuzzleBoy/Dialogue.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/PuzzleBoy/GameAssets.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using PuzzleBoy.Nocturne;
using PuzzleBoy.Rendering;
using PuzzleBoy.Rules;

namespace PuzzleBoy;
Expand Down
Loading
Loading