303 lines
17 KiB
Markdown
303 lines
17 KiB
Markdown
# 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=<value>` and `--seed=<integer>`, 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.
|