Add Godot project shell
This commit is contained in:
37
SLICE1.MD
37
SLICE1.MD
@@ -15,10 +15,10 @@ The observable result is small but concrete: from `D:\Code\zfxaction26_1`, `dotn
|
|||||||
- [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) 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 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.
|
- [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.
|
- [x] (2026-04-21 16:52Z) Implemented root scene, placeholder scene, smoke scene, input actions, and debug boot code.
|
||||||
- [ ] Run formatting for touched C# files with `jb cleanupcode --build=False`.
|
- [x] (2026-04-21 16:52Z) Ran formatting for touched C# files with `jb cleanupcode --build=False`.
|
||||||
- [ ] Validate with .NET build, Godot solution build, and headless smoke boot.
|
- [x] (2026-04-21 16:52Z) Validated with .NET build, Godot solution build, and headless smoke boot.
|
||||||
- [ ] Commit the completed slice.
|
- [x] (2026-04-21 16:52Z) Commit the completed slice.
|
||||||
|
|
||||||
## Surprises & Discoveries
|
## Surprises & Discoveries
|
||||||
|
|
||||||
@@ -31,6 +31,12 @@ The observable result is small but concrete: from `D:\Code\zfxaction26_1`, `dotn
|
|||||||
- 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.
|
- 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.
|
Evidence: the parallel build attempt failed with `CS2012: Cannot open ... SideScrollerGame.Godot.dll for writing`. A serial `dotnet build SideScrollerGame.sln` immediately afterward succeeded.
|
||||||
|
|
||||||
|
- Observation: `godot/project.godot` had `project/assembly_name="SideScrollerGame"`, while the fixed C# project builds `SideScrollerGame.Godot.dll`.
|
||||||
|
Evidence: the first smoke boot did not instantiate C# scripts, and `.\godot --headless --path godot --quit` reported that `GameRoot.cs` and `DebugOverlay.cs` classes could not be found. Updating the Godot assembly name to `SideScrollerGame.Godot` fixed script loading.
|
||||||
|
|
||||||
|
- Observation: Quoting the semicolon-separated `jb cleanupcode` file list made JetBrains treat the full list as one path.
|
||||||
|
Evidence: `jb cleanupcode --build=False "file1;file2;..."` exited with "No items were found to cleanup." Running `jb cleanupcode --build=False file1 file2 ...` formatted all touched C# files.
|
||||||
|
|
||||||
## Decision Log
|
## Decision Log
|
||||||
|
|
||||||
- Decision: Keep `godot/project.godot` as the canonical Godot project entrypoint for this slice.
|
- Decision: Keep `godot/project.godot` as the canonical Godot project entrypoint for this slice.
|
||||||
@@ -49,9 +55,30 @@ The observable result is small but concrete: from `D:\Code\zfxaction26_1`, `dotn
|
|||||||
Rationale: Command-line boot modes make sandbox and smoke testing fast without editor interaction. Project setting fallback keeps editor boot predictable.
|
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.
|
Date/Author: 2026-04-21 / Codex.
|
||||||
|
|
||||||
|
- Decision: Match `godot/project.godot`'s .NET assembly name to the existing C# project output, `SideScrollerGame.Godot`.
|
||||||
|
Rationale: Godot resolves attached C# scripts through the configured assembly name. The project already builds `SideScrollerGame.Godot.dll`, and changing the Godot setting avoids touching the user's fixed `.csproj`.
|
||||||
|
Date/Author: 2026-04-21 / Codex.
|
||||||
|
|
||||||
## Outcomes & Retrospective
|
## 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.
|
Implemented a bootable Godot project shell under `godot/`. Created the root scene, menu placeholder scene, smoke scene, debug boot settings reader, debug overlay, and smoke controller. Added project input actions and configured `res://scenes/bootstrap/GameRoot.tscn` as the main scene.
|
||||||
|
|
||||||
|
Validation completed:
|
||||||
|
|
||||||
|
dotnet build SideScrollerGame.sln
|
||||||
|
Build succeeded.
|
||||||
|
0 Warning(s)
|
||||||
|
0 Error(s)
|
||||||
|
|
||||||
|
.\godot --headless --path godot --build-solutions --quit
|
||||||
|
Exited successfully.
|
||||||
|
|
||||||
|
.\godot --headless --path godot -- --debug-boot=smoke --seed=12345
|
||||||
|
Debug boot: Smoke
|
||||||
|
Seed: 12345
|
||||||
|
Smoke scene loaded
|
||||||
|
|
||||||
|
Remaining risk: editor visual layout was not manually inspected in a window during this slice. The headless boot path and script loading are validated.
|
||||||
|
|
||||||
## Context and Orientation
|
## Context and Orientation
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,69 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="SideScrollerGame"
|
config/name="SideScrollerGame"
|
||||||
|
run/main_scene="res://scenes/bootstrap/GameRoot.tscn"
|
||||||
|
run/debug_boot_mode="menu"
|
||||||
|
run/debug_seed=1
|
||||||
config/features=PackedStringArray("4.5", "C#", "Forward Plus")
|
config/features=PackedStringArray("4.5", "C#", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
[dotnet]
|
[dotnet]
|
||||||
|
|
||||||
project/assembly_name="SideScrollerGame"
|
project/assembly_name="SideScrollerGame.Godot"
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
move_up={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_down={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_left={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
move_right={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
fire_primary={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
fire_secondary={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":70,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
fire_special={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":69,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
pause_game={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
debug_overlay={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194336,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
quick_restart={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":true,"meta_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
14
godot/scenes/bootstrap/GameRoot.tscn
Normal file
14
godot/scenes/bootstrap/GameRoot.tscn
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[gd_scene load_steps=5 format=3 uid="uid://b1fxc23gkbqre"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scripts/bootstrap/GameRoot.cs" id="1_game_root"]
|
||||||
|
[ext_resource type="Script" path="res://scripts/debug/DebugOverlay.cs" id="2_debug_overlay"]
|
||||||
|
[ext_resource type="PackedScene" path="res://scenes/menu/MenuPlaceholder.tscn" id="3_menu"]
|
||||||
|
[ext_resource type="PackedScene" path="res://scenes/debug/SmokeScene.tscn" id="4_smoke"]
|
||||||
|
|
||||||
|
[node name="GameRoot" type="Node"]
|
||||||
|
script = ExtResource("1_game_root")
|
||||||
|
MenuScene = ExtResource("3_menu")
|
||||||
|
SmokeScene = ExtResource("4_smoke")
|
||||||
|
|
||||||
|
[node name="DebugOverlay" type="CanvasLayer" parent="."]
|
||||||
|
script = ExtResource("2_debug_overlay")
|
||||||
18
godot/scenes/debug/SmokeScene.tscn
Normal file
18
godot/scenes/debug/SmokeScene.tscn
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://dpsx0hxc4vd5s"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scripts/debug/SmokeSceneController.cs" id="1_smoke_scene_controller"]
|
||||||
|
|
||||||
|
[node name="SmokeScene" type="Node2D"]
|
||||||
|
script = ExtResource("1_smoke_scene_controller")
|
||||||
|
|
||||||
|
[node name="HeroPlaceholder" type="Polygon2D" parent="."]
|
||||||
|
position = Vector2(160, 180)
|
||||||
|
color = Color(0.25, 0.85, 1, 1)
|
||||||
|
polygon = PackedVector2Array(48, 0, -32, -24, -12, 0, -32, 24)
|
||||||
|
|
||||||
|
[node name="SmokeLabel" type="Label" parent="."]
|
||||||
|
offset_left = 96.0
|
||||||
|
offset_top = 224.0
|
||||||
|
offset_right = 384.0
|
||||||
|
offset_bottom = 256.0
|
||||||
|
text = "Smoke Scene"
|
||||||
46
godot/scenes/menu/MenuPlaceholder.tscn
Normal file
46
godot/scenes/menu/MenuPlaceholder.tscn
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://cg86dxl2ys1vh"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scripts/menu/MenuPlaceholder.cs" id="1_menu_placeholder"]
|
||||||
|
|
||||||
|
[node name="MenuPlaceholder" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_menu_placeholder")
|
||||||
|
|
||||||
|
[node name="Title" type="Label" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -210.0
|
||||||
|
offset_top = -32.0
|
||||||
|
offset_right = 210.0
|
||||||
|
offset_bottom = 0.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
text = "SideScrollerGame - Menu Placeholder"
|
||||||
|
|
||||||
|
[node name="Hint" type="Label" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -240.0
|
||||||
|
offset_top = 8.0
|
||||||
|
offset_right = 240.0
|
||||||
|
offset_bottom = 40.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
text = "Run with -- --debug-boot=smoke for smoke scene"
|
||||||
59
godot/scripts/bootstrap/GameRoot.cs
Normal file
59
godot/scripts/bootstrap/GameRoot.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using SideScrollerGame.Debug;
|
||||||
|
|
||||||
|
namespace SideScrollerGame.Bootstrap;
|
||||||
|
|
||||||
|
public partial class GameRoot : Node
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
m_Settings = DebugSettings.Load();
|
||||||
|
GD.Seed((ulong)m_Settings.Seed);
|
||||||
|
|
||||||
|
GD.Print($"Debug boot: {m_Settings.BootMode}");
|
||||||
|
GD.Print($"Seed: {m_Settings.Seed}");
|
||||||
|
|
||||||
|
LoadBootScene(m_Settings.BootMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadBootScene(DebugBootMode bootMode)
|
||||||
|
{
|
||||||
|
PackedScene? scene = bootMode switch
|
||||||
|
{
|
||||||
|
DebugBootMode.Smoke => SmokeScene,
|
||||||
|
_ => MenuScene
|
||||||
|
};
|
||||||
|
|
||||||
|
string loadedSceneId = bootMode.ToString();
|
||||||
|
if (scene is null)
|
||||||
|
{
|
||||||
|
GD.PushError($"No scene configured for debug boot mode '{bootMode}'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_LoadedScene is not null)
|
||||||
|
{
|
||||||
|
m_LoadedScene.QueueFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LoadedScene = scene.Instantiate();
|
||||||
|
AddChild(m_LoadedScene);
|
||||||
|
|
||||||
|
DebugOverlay? overlay = GetNodeOrNull<DebugOverlay>("DebugOverlay");
|
||||||
|
if (overlay is not null && m_Settings is not null)
|
||||||
|
{
|
||||||
|
overlay.SetStatus(m_Settings, loadedSceneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public PackedScene? MenuScene { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public PackedScene? SmokeScene { get; set; }
|
||||||
|
|
||||||
|
private Node? m_LoadedScene;
|
||||||
|
private DebugSettings? m_Settings;
|
||||||
|
}
|
||||||
1
godot/scripts/bootstrap/GameRoot.cs.uid
Normal file
1
godot/scripts/bootstrap/GameRoot.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://b28od0hdkj1kx
|
||||||
7
godot/scripts/debug/DebugBootMode.cs
Normal file
7
godot/scripts/debug/DebugBootMode.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace SideScrollerGame.Debug;
|
||||||
|
|
||||||
|
public enum DebugBootMode
|
||||||
|
{
|
||||||
|
Menu,
|
||||||
|
Smoke
|
||||||
|
}
|
||||||
1
godot/scripts/debug/DebugBootMode.cs.uid
Normal file
1
godot/scripts/debug/DebugBootMode.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cebwe1o0qw160
|
||||||
43
godot/scripts/debug/DebugOverlay.cs
Normal file
43
godot/scripts/debug/DebugOverlay.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SideScrollerGame.Debug;
|
||||||
|
|
||||||
|
public partial class DebugOverlay : CanvasLayer
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
Layer = 100;
|
||||||
|
ProcessMode = ProcessModeEnum.Always;
|
||||||
|
EnsureLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStatus(DebugSettings settings, string loadedSceneId)
|
||||||
|
{
|
||||||
|
Label label = EnsureLabel();
|
||||||
|
label.Text = $"Debug boot: {settings.BootMode}\nSeed: {settings.Seed}\nScene: {loadedSceneId}\nDebug: {OS.IsDebugBuild()}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label EnsureLabel()
|
||||||
|
{
|
||||||
|
if (m_StatusLabel is not null)
|
||||||
|
{
|
||||||
|
return m_StatusLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_StatusLabel = GetNodeOrNull<Label>("StatusLabel");
|
||||||
|
if (m_StatusLabel is null)
|
||||||
|
{
|
||||||
|
m_StatusLabel = new Label { Name = "StatusLabel" };
|
||||||
|
AddChild(m_StatusLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_StatusLabel.MouseFilter = Control.MouseFilterEnum.Ignore;
|
||||||
|
m_StatusLabel.Position = new Vector2(8.0f, 8.0f);
|
||||||
|
m_StatusLabel.AutowrapMode = TextServer.AutowrapMode.Off;
|
||||||
|
return m_StatusLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label? m_StatusLabel;
|
||||||
|
}
|
||||||
1
godot/scripts/debug/DebugOverlay.cs.uid
Normal file
1
godot/scripts/debug/DebugOverlay.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://b41hmmnemingf
|
||||||
91
godot/scripts/debug/DebugSettings.cs
Normal file
91
godot/scripts/debug/DebugSettings.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SideScrollerGame.Debug;
|
||||||
|
|
||||||
|
public sealed class DebugSettings
|
||||||
|
{
|
||||||
|
public DebugSettings(DebugBootMode bootMode, int seed)
|
||||||
|
{
|
||||||
|
BootMode = bootMode;
|
||||||
|
Seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DebugSettings Load()
|
||||||
|
{
|
||||||
|
DebugBootMode bootMode = LoadBootModeFromProjectSettings();
|
||||||
|
int seed = LoadSeedFromProjectSettings();
|
||||||
|
|
||||||
|
foreach (string argument in OS.GetCmdlineUserArgs())
|
||||||
|
{
|
||||||
|
if (argument.StartsWith(DebugBootModePrefix, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
string value = argument[DebugBootModePrefix.Length..];
|
||||||
|
if (TryParseBootMode(value, out DebugBootMode parsedBootMode))
|
||||||
|
{
|
||||||
|
bootMode = parsedBootMode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GD.PushWarning($"Unknown debug boot mode '{value}'. Falling back to Menu.");
|
||||||
|
bootMode = DebugBootMode.Menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argument.StartsWith(SeedPrefix, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
string value = argument[SeedPrefix.Length..];
|
||||||
|
if (int.TryParse(value, out int parsedSeed))
|
||||||
|
{
|
||||||
|
seed = parsedSeed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GD.PushWarning($"Unknown debug seed '{value}'. Keeping seed {seed}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DebugSettings(bootMode, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DebugBootMode BootMode { get; }
|
||||||
|
|
||||||
|
public int Seed { get; }
|
||||||
|
|
||||||
|
private static DebugBootMode LoadBootModeFromProjectSettings()
|
||||||
|
{
|
||||||
|
if (!ProjectSettings.HasSetting(DebugBootModeSetting))
|
||||||
|
{
|
||||||
|
return DebugBootMode.Menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
string configuredBootMode = ProjectSettings.GetSetting(DebugBootModeSetting).AsString();
|
||||||
|
if (TryParseBootMode(configuredBootMode, out DebugBootMode bootMode))
|
||||||
|
{
|
||||||
|
return bootMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
GD.PushWarning($"Unknown configured debug boot mode '{configuredBootMode}'. Falling back to Menu.");
|
||||||
|
return DebugBootMode.Menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int LoadSeedFromProjectSettings()
|
||||||
|
{
|
||||||
|
if (!ProjectSettings.HasSetting(DebugSeedSetting))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProjectSettings.GetSetting(DebugSeedSetting).AsInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseBootMode(string value, out DebugBootMode bootMode)
|
||||||
|
{
|
||||||
|
return Enum.TryParse(value, true, out bootMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string DebugBootModePrefix = "--debug-boot=";
|
||||||
|
private const string DebugBootModeSetting = "application/run/debug_boot_mode";
|
||||||
|
private const string DebugSeedSetting = "application/run/debug_seed";
|
||||||
|
private const string SeedPrefix = "--seed=";
|
||||||
|
}
|
||||||
1
godot/scripts/debug/DebugSettings.cs.uid
Normal file
1
godot/scripts/debug/DebugSettings.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://m3c08h4ms4qu
|
||||||
24
godot/scripts/debug/SmokeSceneController.cs
Normal file
24
godot/scripts/debug/SmokeSceneController.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SideScrollerGame.Debug;
|
||||||
|
|
||||||
|
public partial class SmokeSceneController : Node2D
|
||||||
|
{
|
||||||
|
public override async void _Ready()
|
||||||
|
{
|
||||||
|
GD.Print("Smoke scene loaded");
|
||||||
|
|
||||||
|
if (!IsHeadless())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame);
|
||||||
|
GetTree().Quit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsHeadless()
|
||||||
|
{
|
||||||
|
return DisplayServer.GetName().Equals("headless", System.StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
1
godot/scripts/debug/SmokeSceneController.cs.uid
Normal file
1
godot/scripts/debug/SmokeSceneController.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dwc6njr4c222l
|
||||||
23
godot/scripts/menu/MenuPlaceholder.cs
Normal file
23
godot/scripts/menu/MenuPlaceholder.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SideScrollerGame.Menu;
|
||||||
|
|
||||||
|
public partial class MenuPlaceholder : Control
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
Label? title = GetNodeOrNull<Label>("Title");
|
||||||
|
if (title is not null)
|
||||||
|
{
|
||||||
|
title.Text = "SideScrollerGame - Menu Placeholder";
|
||||||
|
}
|
||||||
|
|
||||||
|
Label? hint = GetNodeOrNull<Label>("Hint");
|
||||||
|
if (hint is not null)
|
||||||
|
{
|
||||||
|
hint.Text = "Run with -- --debug-boot=smoke for smoke scene";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
godot/scripts/menu/MenuPlaceholder.cs.uid
Normal file
1
godot/scripts/menu/MenuPlaceholder.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bhmyn841byhuk
|
||||||
Reference in New Issue
Block a user