Add simulation project scaffold
This commit is contained in:
@@ -14,8 +14,9 @@ The user-visible outcome is not merely “new projects were added.” The outcom
|
||||
|
||||
- [x] (2026-04-16 08:24Z) Reviewed `PLANS.md`, the original `groundwork.md`, `SideScrollerGame.sln`, and `godot/SideScrollerGame.Godot.csproj` to anchor this ExecPlan to the current repository state.
|
||||
- [x] (2026-04-16 08:32Z) Rewrote `groundwork.md` as a self-contained ExecPlan with milestones, repository orientation, exact commands, validation guidance, and living-document bookkeeping.
|
||||
- [ ] Create `src/SideScrollerGame.Sim/SideScrollerGame.Sim.csproj` and `tests/SideScrollerGame.Sim.Tests/SideScrollerGame.Sim.Tests.csproj`, add them to `SideScrollerGame.sln`, and wire both projects to the simulation assembly.
|
||||
- [ ] Copy the current root `FixPoint/*.cs` files into `src/SideScrollerGame.Sim/FixPoint/`, update namespaces, and make the simulation project the only assembly that compiles deterministic math code.
|
||||
- [x] (2026-04-16 08:49Z) Created `src/SideScrollerGame.Sim/SideScrollerGame.Sim.csproj` and `tests/SideScrollerGame.Sim.Tests/SideScrollerGame.Sim.Tests.csproj`, added both to `SideScrollerGame.sln`, and wired the Godot and test projects to reference the simulation assembly.
|
||||
- [x] (2026-04-16 08:53Z) Copied the root `FixPoint/*.cs` files into `src/SideScrollerGame.Sim/FixPoint/`, updated the namespace to `SideScrollerGame.Sim.Math`, and added a smoke test proving the simulation project owns the deterministic math layer.
|
||||
- [x] (2026-04-16 09:11Z) Added bootstrap compatibility math types missing from the copied `FixPoint` subset and validated the scaffold with `dotnet build`, `dotnet test`, and `.\godot.cmd --headless --quit --path .\godot --build-solutions`.
|
||||
- [ ] Implement the first runnable simulation spine: `Simulation`, `SimulationState`, `WorldSnapshot`, `TickActionBatch`, deterministic random number generation, and per-tick hashes.
|
||||
- [ ] Implement versioned save/load, replay recording, replay playback, and the optional round-trip verification modes.
|
||||
- [ ] Implement deterministic movement, collision, damage resolution, triggers, and the fixed tick pipeline with exhaustive simulation tests.
|
||||
@@ -32,6 +33,12 @@ The user-visible outcome is not merely “new projects were added.” The outcom
|
||||
Evidence: `rg --files` lists `FixPoint/*.cs`, `godot/SideScrollerGame.Godot.csproj`, `SideScrollerGame.sln`, `PLANS.md`, and `groundwork.md`, but no `src/` or `tests/` projects.
|
||||
- Observation: the repository root contains `godot.cmd`, so all Godot commands in this plan should call that wrapper with `--path .\godot`.
|
||||
Evidence: `rg --files` lists both `godot.cmd` and `godot/project.godot`.
|
||||
- Observation: copied `FixPoint` sources inherit the root files' read-only attribute, so the migration step must clear that attribute before applying namespace edits.
|
||||
Evidence: `Get-Item src/SideScrollerGame.Sim/FixPoint/FixPoint16.cs` reported `Attributes : ReadOnly, Archive` immediately after the copy.
|
||||
- Observation: the root `FixPoint` subset is not self-contained; it references compatibility types such as `IntVector2`, `SInt32Vector2`, `SFixPointQuaternion`, `SFixPointQuaternionTransform`, and `IntMath` that are not present in this repository snapshot.
|
||||
Evidence: the first `dotnet build SideScrollerGame.sln` attempt after the copy failed with CS0246 and CS0103 errors pointing at those missing identifiers inside `FixPointVector2.cs`, `FixPointVector3.cs`, `FixPoint16.cs`, and `FixPoint16Long.cs`.
|
||||
- Observation: `.\godot.cmd --headless --path .\godot --build-solutions` does not terminate on its own in this checkout, but adding `--quit` produces the expected build and exit behavior.
|
||||
Evidence: the plain command timed out after five minutes, while `.\godot.cmd --headless --quit --path .\godot --build-solutions` completed successfully in roughly three seconds.
|
||||
|
||||
## Decision Log
|
||||
|
||||
@@ -47,6 +54,9 @@ The user-visible outcome is not merely “new projects were added.” The outcom
|
||||
- Decision: use `godot.cmd` in all concrete steps instead of the shorthand `.\godot`.
|
||||
Rationale: `godot.cmd` is the wrapper that actually exists in this checkout, so the plan must describe commands that a novice can run without guessing aliases.
|
||||
Date/Author: 2026-04-16 / Codex
|
||||
- Decision: keep the migration moving by introducing local compatibility shims for the missing fixed-point support types instead of blocking Milestone 1 on a broader math-library archaeology pass.
|
||||
Rationale: the copied `FixPoint` subset already compiles and is enough for the upcoming deterministic simulation spine, while the shim types can be replaced later if fuller upstream math primitives become necessary.
|
||||
Date/Author: 2026-04-16 / Codex
|
||||
|
||||
## Outcomes & Retrospective
|
||||
|
||||
@@ -83,7 +93,7 @@ Acceptance for this milestone is that the solution builds, the test project runs
|
||||
This milestone creates the smallest useful simulation loop. At the end of it, a caller can construct a `Simulation`, feed a `TickActionBatch`, advance exactly one tick, and receive a `TickResult` containing events and a deterministic hash. Run the tests and host build from `D:\Code\SideScrollerGame`:
|
||||
|
||||
dotnet test tests/SideScrollerGame.Sim.Tests/SideScrollerGame.Sim.Tests.csproj
|
||||
.\godot.cmd --headless --path .\godot --build-solutions
|
||||
.\godot.cmd --headless --quit --path .\godot --build-solutions
|
||||
|
||||
Acceptance for this milestone is behavioral. Two fresh `Simulation` instances created with the same game definition, configuration, seed, and empty action stream must produce the same tick numbers, the same state hash, and the same serialized state bytes for a sequence of no-op ticks.
|
||||
|
||||
@@ -120,7 +130,7 @@ Acceptance for this milestone is that tests can demonstrate reusable enemy behav
|
||||
|
||||
This milestone connects Godot authoring to simulation-safe content. At the end of it, a designer can author level markers in Godot, run a compile step, and produce deterministic runtime data under `content/compiled/` that both tests and the host can consume. Run the milestone commands from `D:\Code\SideScrollerGame`:
|
||||
|
||||
.\godot.cmd --headless --path .\godot --build-solutions
|
||||
.\godot.cmd --headless --quit --path .\godot --build-solutions
|
||||
dotnet test tests/SideScrollerGame.Sim.Tests/SideScrollerGame.Sim.Tests.csproj --filter Content
|
||||
|
||||
Acceptance for this milestone is that a level scene with spawn markers, checkpoints, trigger zones, encounter data, and music zones compiles into engine-agnostic definitions, and tests can load that compiled data without touching a live Godot scene tree.
|
||||
@@ -130,7 +140,7 @@ Acceptance for this milestone is that a level scene with spawn markers, checkpoi
|
||||
This milestone exposes the simulation to humans. At the end of it, the Godot host translates live input into `TickActionBatch` objects, runs the fixed-step simulation, interpolates between snapshots for rendering, plays overlapping sound effects and cross-faded music, and offers debug transport controls for play, pause, restart, single-step, and fast-forward. Run the proof commands from `D:\Code\SideScrollerGame`:
|
||||
|
||||
.\godot.cmd --editor --path .\godot
|
||||
.\godot.cmd --headless --path .\godot --build-solutions
|
||||
.\godot.cmd --headless --quit --path .\godot --build-solutions
|
||||
dotnet test tests/SideScrollerGame.Sim.Tests/SideScrollerGame.Sim.Tests.csproj
|
||||
|
||||
Acceptance for this milestone is that a developer can start the Godot project, load a test level, pause the simulation, advance one step at a time, jump forward to a later tick using saved checkpoints, and observe the same state hash sequence that the automated replay tests produce.
|
||||
@@ -205,7 +215,7 @@ Run all commands from `D:\Code\SideScrollerGame` unless a step states otherwise.
|
||||
|
||||
Run:
|
||||
|
||||
.\godot.cmd --headless --path .\godot --build-solutions
|
||||
.\godot.cmd --headless --quit --path .\godot --build-solutions
|
||||
|
||||
Expect Godot to regenerate and build C# project artifacts successfully.
|
||||
|
||||
@@ -221,13 +231,13 @@ Run all commands from `D:\Code\SideScrollerGame` unless a step states otherwise.
|
||||
|
||||
The implementation is acceptable only when a human can see deterministic behavior, not merely when the code compiles. Start with automated proof. `dotnet test tests/SideScrollerGame.Sim.Tests/SideScrollerGame.Sim.Tests.csproj` must pass, and replay-oriented tests must demonstrate that the same seed and action stream yield the same per-tick debug hash sequence. The coverage command in `Concrete Steps` must enforce 100 percent line and branch coverage for gameplay logic inside `SideScrollerGame.Sim`, with only narrow exclusions for non-logic infrastructure such as generated serializers or lookup tables.
|
||||
|
||||
Then verify the host integration. `.\godot.cmd --headless --path .\godot --build-solutions` must succeed, proving that the Godot project can consume the simulation assembly. After that, start the editor with `.\godot.cmd --editor --path .\godot`, load a level built from compiled runtime content, and verify the following behaviors manually: play starts the simulation, pause freezes the simulation while leaving the editor responsive, advance-one-step increments the tick exactly once, fast-forward resumes from the nearest saved checkpoint and reaches the requested tick, and replaying the same recorded input reproduces the same state hash display.
|
||||
Then verify the host integration. `.\godot.cmd --headless --quit --path .\godot --build-solutions` must succeed, proving that the Godot project can consume the simulation assembly. After that, start the editor with `.\godot.cmd --editor --path .\godot`, load a level built from compiled runtime content, and verify the following behaviors manually: play starts the simulation, pause freezes the simulation while leaving the editor responsive, advance-one-step increments the tick exactly once, fast-forward resumes from the nearest saved checkpoint and reaches the requested tick, and replaying the same recorded input reproduces the same state hash display.
|
||||
|
||||
The final acceptance scenario is simple and observable. Record a short run in which the player moves, fires, triggers an encounter, collects a pickup, and reaches a checkpoint. Save the replay. Restart the host with the same compiled content and seed, play the replay, and confirm that the tick count, key gameplay events, and final state hash all match the original run. If any of those differ, the implementation is incomplete.
|
||||
|
||||
## Idempotence and Recovery
|
||||
|
||||
Most steps in this plan are additive and safe to repeat. Re-running `dotnet build`, `dotnet test`, or `.\godot.cmd --headless --path .\godot --build-solutions` is safe and should produce the same result when the repository state has not changed. Re-running the host replay validation is also safe because replays and checkpoints are meant to be reproducible.
|
||||
Most steps in this plan are additive and safe to repeat. Re-running `dotnet build`, `dotnet test`, or `.\godot.cmd --headless --quit --path .\godot --build-solutions` is safe and should produce the same result when the repository state has not changed. Re-running the host replay validation is also safe because replays and checkpoints are meant to be reproducible.
|
||||
|
||||
Project creation commands such as `dotnet new classlib` and `dotnet new xunit` are not naturally idempotent once the destination directories already exist. If those directories have already been created, do not delete them to start over. Instead, inspect the generated files, patch them into the required shape, and continue. The same rule applies to content compilation in this Windows environment: prefer overwriting generated runtime content in place instead of deleting directories.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user