diff --git a/SLICE1.MD b/SLICE1.MD new file mode 100644 index 0000000..0d6b275 --- /dev/null +++ b/SLICE1.MD @@ -0,0 +1,302 @@ +# Build the Godot Project Shell + +This ExecPlan is a living document. The sections `Progress`, `Surprises & Discoveries`, `Decision Log`, and `Outcomes & Retrospective` must be kept up to date as work proceeds. + +This plan follows `PLANS.md` in the repository root. It is intentionally self-contained so a developer with only this repository and this file can implement Slice 1 without reading prior chat history. + +## Purpose / Big Picture + +After this slice, the repository will contain a bootable Godot 4 .NET project shell for the side-scrolling shooter. A developer will be able to build the C# project, start the Godot project, see a root scene load a normal placeholder scene, and boot directly into a smoke test scene through a debug boot mode. This gives later slices a stable place to add content, input, debug tools, and test harnesses without first repairing project setup. + +The observable result is small but concrete: from `D:\Code\zfxaction26_1`, `dotnet build SideScrollerGame.sln` succeeds, `.\godot --headless --path godot --build-solutions --quit` succeeds, and `.\godot --headless --path godot -- --debug-boot=smoke` starts the root scene, loads the smoke scene, prints a short confirmation line, and exits with code 0. + +## Progress + +- [x] (2026-04-21 16:36Z) Read repository rules, Windows rules, `PLANS.md`, `CODE.md`, and current Godot project files. +- [x] (2026-04-21 16:36Z) Verified that the Godot project currently lives in `godot/project.godot`, not at the repository root. +- [x] (2026-04-21 16:36Z) Verified that `SideScrollerGame.sln` and `godot/SideScrollerGame.Godot.csproj` currently build with `dotnet build SideScrollerGame.sln` after the user's fixes. +- [ ] Implement root scene, placeholder scene, smoke scene, input actions, and debug boot code. +- [ ] Run formatting for touched C# files with `jb cleanupcode --build=False`. +- [ ] Validate with .NET build, Godot solution build, and headless smoke boot. +- [ ] Commit the completed slice. + +## Surprises & Discoveries + +- Observation: The current Godot project is under the `godot/` subdirectory. The repository-root wrapper is still used from `D:\Code\zfxaction26_1`, but commands must pass `--path godot`. + Evidence: `rg --files godot` lists `godot/project.godot` and `godot/SideScrollerGame.Godot.csproj`. + +- Observation: A prior `.\godot --headless --path godot --build-solutions` command was observed to keep running without `--quit`. + Evidence: the process command line was `--headless --path godot --build-solutions`, and it had to be stopped. This plan uses `--build-solutions --quit` for validation. + +- Observation: Running `dotnet build SideScrollerGame.sln` and `dotnet build godot\SideScrollerGame.Godot.csproj` at the same time can race on the same Godot temp assembly. + Evidence: the parallel build attempt failed with `CS2012: Cannot open ... SideScrollerGame.Godot.dll for writing`. A serial `dotnet build SideScrollerGame.sln` immediately afterward succeeded. + +## Decision Log + +- Decision: Keep `godot/project.godot` as the canonical Godot project entrypoint for this slice. + Rationale: The current repository already has the Godot project under `godot/`, the user explicitly corrected that it is not missing, and moving it would create unnecessary churn before gameplay exists. + Date/Author: 2026-04-21 / Codex. + +- Decision: Implement Slice 1 as a minimal boot shell with placeholder scenes, not gameplay systems. + Rationale: `CODE.md` defines Slice 1 as the project shell. Later slices depend on stable project loading, input actions, debug boot mode, and a reliable smoke test. + Date/Author: 2026-04-21 / Codex. + +- Decision: Use C# scripts for root boot, debug settings, overlay, and smoke exit behavior. + Rationale: This is a Godot .NET project, and later slices need reusable C# debug services and typed state. Keeping this in C# avoids replacing GDScript glue later. + Date/Author: 2026-04-21 / Codex. + +- Decision: Parse debug boot settings from Godot user arguments such as `--debug-boot=smoke` and `--seed=12345`, with project settings as fallback. + Rationale: Command-line boot modes make sandbox and smoke testing fast without editor interaction. Project setting fallback keeps editor boot predictable. + Date/Author: 2026-04-21 / Codex. + +## Outcomes & Retrospective + +Not started. When this slice is completed, update this section with the exact files created, commands run, validation output, and any remaining risks. + +## Context and Orientation + +The repository root is `D:\Code\zfxaction26_1`. The Godot project root is `D:\Code\zfxaction26_1\godot`. The wrapper `D:\Code\zfxaction26_1\godot.cmd` launches the local Godot 4.5.1 .NET executable, so commands are run from the repository root as `.\godot --path godot ...`. + +Current important files are: + +- `godot/project.godot`: the Godot project configuration. It currently has project name, C# feature flags, icon, and .NET assembly name, but no main scene and no input actions. +- `godot/SideScrollerGame.Godot.csproj`: the C# project for Godot scripts. It currently targets `net8.0` and uses `Godot.NET.Sdk/4.5.1`. +- `SideScrollerGame.sln`: the Visual Studio solution. It currently contains the Godot C# project and builds successfully after the user's fixes. +- `CODE.md`: the broader implementation plan. Its Slice 1 section asks for a project shell, root scene, input actions, smoke scene, debug boot mode, deterministic seed setting, and visible build/version label. +- `DESIGN.md`: the design document. It has user modifications and must not be touched by this slice. + +There are currently no tracked scenes or gameplay scripts under `godot/scenes/` or `godot/scripts/`. This slice creates those directories and the minimal files needed to boot. + +Definitions used in this plan: + +- A root scene is the first Godot scene loaded by the project. It owns scene switching and debug boot selection. +- A placeholder scene is a simple visible scene used before real menu or gameplay exists. +- A smoke scene is a tiny scene used to prove the project can start. In headless mode it exits automatically with code 0 so it can be used by scripts and CI. +- Headless mode means Godot runs without opening a window. It is used for build and smoke validation. +- Debug boot mode means a developer can start the project directly in a specific scene by passing a command-line argument instead of clicking through menus. + +## Plan of Work + +First, create the scene and script folders under `godot/` so the project follows the planned layout without touching unrelated files. Add `godot/scripts/debug/DebugBootMode.cs`, an enum with at least `Menu` and `Smoke`. Add `godot/scripts/debug/DebugSettings.cs`, a small settings reader that parses `OS.GetCmdlineUserArgs()` for `--debug-boot=` and `--seed=`, then falls back to Godot project settings `application/run/debug_boot_mode` and `application/run/debug_seed`. + +Next, add `godot/scripts/bootstrap/GameRoot.cs`. This script should extend `Godot.Node`, read `DebugSettings` in `_Ready`, instantiate either the menu placeholder scene or smoke scene, and add it as a child. It should also create or update a debug overlay label so the screen shows the active boot mode, seed, current scene id, and whether debug mode is active. The root script should expose scene paths or `PackedScene` exports so a designer can change them in the Godot editor later. + +Then add `godot/scripts/debug/DebugOverlay.cs`. It should extend `CanvasLayer` or `Control`, contain a `Label`, and expose a method like `SetStatus(DebugSettings settings, string loadedSceneId)`. Keep it simple: it only needs to show text in the top-left corner. Later slices will extend the overlay with mission time, enemies, projectiles, and hero state. + +Then add `godot/scripts/menu/MenuPlaceholder.cs` and `godot/scripts/debug/SmokeSceneController.cs`. The menu placeholder should show a label such as `SideScrollerGame - Menu Placeholder` and a short debug instruction such as `Run with -- --debug-boot=smoke for smoke scene`. The smoke controller should show a simple placeholder hero shape or label. If the display server is headless, it should print `Smoke scene loaded` and quit successfully after one idle frame. In a normal window, it should stay visible. + +Next, create the scene files: + +- `godot/scenes/bootstrap/GameRoot.tscn` +- `godot/scenes/menu/MenuPlaceholder.tscn` +- `godot/scenes/debug/SmokeScene.tscn` + +The root scene should be a `Node` with the `GameRoot.cs` script attached and a child `DebugOverlay`. The menu placeholder should be a `Control` or `Node2D` with a label and the `MenuPlaceholder.cs` script attached. The smoke scene should be a `Node2D` with a label or simple `Polygon2D` hero placeholder and the `SmokeSceneController.cs` script attached. + +Finally, update `godot/project.godot`. Add `config/main_scene="res://scenes/bootstrap/GameRoot.tscn"` under `[application]`. Add input map entries for `move_up`, `move_down`, `move_left`, `move_right`, `fire_primary`, `fire_secondary`, `fire_special`, `pause_game`, `debug_overlay`, and `quick_restart`. Add project settings for default debug boot mode and seed. Keep the existing project name, features, icon, and .NET assembly name. + +Do not edit `DESIGN.md`. Do not revert the user's current `SideScrollerGame.sln` or `godot/SideScrollerGame.Godot.csproj` changes. If those files must be touched during implementation, read the current content first and make only the minimal required edits. + +## Concrete Steps + +Run all commands from `D:\Code\zfxaction26_1`. + +1. Confirm the current state before editing: + + git status --short + rg --files godot + dotnet build SideScrollerGame.sln + + Expected result: `git status --short` may show user changes to `DESIGN.md`, `SideScrollerGame.sln`, and `godot/SideScrollerGame.Godot.csproj`. `rg --files godot` should show the current Godot project files. `dotnet build SideScrollerGame.sln` should end with `Build succeeded`. + +2. Create directories: + + godot/scenes/bootstrap + godot/scenes/menu + godot/scenes/debug + godot/scripts/bootstrap + godot/scripts/menu + godot/scripts/debug + +3. Add the C# scripts listed in the Plan of Work. Use 4 spaces for indentation. Use nullable reference types where practical. Keep one primary public type per file. Follow the repository type member order from `AGENTS.md`: nested types, constructors, disposable implementation, methods, properties, static members, events, fields. + +4. Add the three scene files and attach the scripts. Prefer simple Godot built-in nodes and the existing `godot/icon.svg` for any placeholder image. No imported art is required for this slice. + +5. Update `godot/project.godot` to set the main scene, input actions, and default debug settings. Use Godot's existing text format and preserve existing settings. + +6. Format touched C# files: + + jb cleanupcode --build=False godot\scripts\bootstrap\GameRoot.cs;godot\scripts\debug\DebugBootMode.cs;godot\scripts\debug\DebugSettings.cs;godot\scripts\debug\DebugOverlay.cs;godot\scripts\debug\SmokeSceneController.cs;godot\scripts\menu\MenuPlaceholder.cs + + If `jb cleanupcode` is unavailable, record the exact error in `Surprises & Discoveries`, keep formatting manually consistent, and continue validation. + +7. Validate the project: + + dotnet build SideScrollerGame.sln + .\godot --headless --path godot --build-solutions --quit + .\godot --headless --path godot -- --debug-boot=smoke --seed=12345 + + Expected result: the .NET build succeeds, the Godot build exits, and the smoke boot prints a line containing `Smoke scene loaded` and exits with code 0. + +8. Check the diff: + + git status --short + git diff -- godot/project.godot godot/scenes godot/scripts SLICE1.MD + + Expected result: the slice diff only includes the intended project shell files. User changes in `DESIGN.md`, `SideScrollerGame.sln`, or `godot/SideScrollerGame.Godot.csproj` must not be reverted. + +9. Commit this slice after validation: + + git add godot/project.godot godot/scenes godot/scripts SLICE1.MD + git commit -m "Add Godot project shell" + +## Validation and Acceptance + +This slice is accepted when the following observable behaviors are true. + +Building from the repository root succeeds: + + dotnet build SideScrollerGame.sln + +The expected final lines include: + + Build succeeded. + 0 Warning(s) + 0 Error(s) + +Godot can build the C# solution and exit: + + .\godot --headless --path godot --build-solutions --quit + +The command should exit without a stuck Godot process. If it prints Godot warnings that do not fail the process, record them in this plan. + +The project can boot through its main scene into the smoke scene: + + .\godot --headless --path godot -- --debug-boot=smoke --seed=12345 + +The expected output includes: + + Smoke scene loaded + Debug boot: Smoke + Seed: 12345 + +Opening the editor should show the project and root scene: + + .\godot --editor --path godot + +In the editor, `res://scenes/bootstrap/GameRoot.tscn` should be the configured main scene. Running it without arguments should show the menu placeholder and debug/version label. Running it with `-- --debug-boot=smoke` should show the smoke placeholder in a window or exit automatically in headless mode. + +There is no automated unit test required for this slice because no pure gameplay rules exist yet. The smoke scene is the automated project-start test. + +## Idempotence and Recovery + +The implementation is additive and safe to repeat. Creating directories that already exist should do nothing. Re-running the validation commands should produce the same result. + +If scene files are malformed, open the project with `.\godot --editor --path godot`, let Godot report the scene load error, and repair the smallest affected scene file. Do not delete unrelated files. If Godot generates `.uid` files for new scenes or scripts, keep them if Godot requires them; otherwise do not hand-edit generated IDs. + +If `.\godot --headless --path godot --build-solutions --quit` hangs, stop only the stuck Godot process, record the command and process details in `Surprises & Discoveries`, and validate with `dotnet build SideScrollerGame.sln` plus the smoke boot command. Do not use broad process-kill commands that could stop an editor session the user is actively using. + +If user changes appear in files outside this slice, leave them untouched. If a user change conflicts with `godot/project.godot`, read the file and merge only the needed main scene, input map, and debug setting entries. + +## Artifacts and Notes + +Current verification before implementation: + + dotnet build SideScrollerGame.sln + Determining projects to restore... + All projects are up-to-date for restore. + SideScrollerGame.Godot -> D:\Code\zfxaction26_1\godot\.godot\mono\temp\bin\Debug\SideScrollerGame.Godot.dll + Build succeeded. + 0 Warning(s) + 0 Error(s) + +Current Godot project files before implementation: + + godot\SideScrollerGame.Godot.csproj + godot\project.godot + godot\icon.svg.import + godot\icon.svg + +Current dirty files before implementation: + + M DESIGN.md + M SideScrollerGame.sln + M godot/SideScrollerGame.Godot.csproj + +Those modified files are user work. This slice must not revert them. + +## Interfaces and Dependencies + +The project uses Godot 4.5.1 .NET through `Godot.NET.Sdk/4.5.1` and targets `net8.0` for desktop builds. Scripts should use the `Godot` C# namespace and partial Godot classes where required by the engine. + +At the end of this slice, these C# types should exist: + +In `godot/scripts/debug/DebugBootMode.cs`: + + namespace SideScrollerGame.Debug; + + public enum DebugBootMode + { + Menu, + Smoke + } + +In `godot/scripts/debug/DebugSettings.cs`: + + namespace SideScrollerGame.Debug; + + public sealed class DebugSettings + { + public DebugBootMode BootMode { get; } + public int Seed { get; } + public static DebugSettings Load(); + } + +`DebugSettings.Load()` must read user command-line arguments first, then fall back to project settings. Unknown boot modes should fall back to `Menu` and print a Godot warning. + +In `godot/scripts/bootstrap/GameRoot.cs`: + + namespace SideScrollerGame.Bootstrap; + + public partial class GameRoot : Node + { + public override void _Ready(); + public void LoadBootScene(DebugBootMode bootMode); + } + +`GameRoot` must instantiate `res://scenes/menu/MenuPlaceholder.tscn` for `Menu` and `res://scenes/debug/SmokeScene.tscn` for `Smoke`. + +In `godot/scripts/debug/DebugOverlay.cs`: + + namespace SideScrollerGame.Debug; + + public partial class DebugOverlay : CanvasLayer + { + public void SetStatus(DebugSettings settings, string loadedSceneId); + } + +The overlay should be visible by default in non-release builds. It should be small, top-left, and not block input. + +In `godot/scripts/debug/SmokeSceneController.cs`: + + namespace SideScrollerGame.Debug; + + public partial class SmokeSceneController : Node2D + { + public override void _Ready(); + } + +In headless mode, the smoke controller should print confirmation and call `GetTree().Quit(0)` after at least one idle frame. + +In `godot/scripts/menu/MenuPlaceholder.cs`: + + namespace SideScrollerGame.Menu; + + public partial class MenuPlaceholder : Control + { + public override void _Ready(); + } + +The menu placeholder may only set label text in this slice. Real menu behavior belongs to a later slice. + +Revision note 2026-04-21: Created this ExecPlan from current repository state. The plan keeps `godot/project.godot` as the project entrypoint, incorporates the user's fixed solution and C# project state, and scopes Slice 1 to a bootable Godot shell with debug boot and smoke validation.