Main menu scene #47

Closed
opened 2026-08-15 11:16:21 +00:00 by metaheavens · 1 comment
Owner

Part of #40, which needs a main menu to host the map editor. There is none today - project.godot boots straight into res://Main.tscn.

Scope

  1. MainMenu.tscn + MainMenu.gd - 720x1280 portrait, styled like the existing menus: ui_theme.tres, IconButton, NeonDraw. Reusing the starfield.gdshader background from Main.tscn gives it the right look for free.
  2. Entries:
    • Play -> get_tree().change_scene_to_file("res://Main.tscn")
    • Map editor -> res://PlanetSetupEditor.tscn; until that ticket lands, keep the button present but disabled with a short "coming soon" state rather than a dead link.
    • Quit -> get_tree().quit(), hidden when OS.has_feature("web").
  3. project.godot: run/main_scene="res://MainMenu.tscn".
  4. Do not make Main.tscn depend on having come through the menu. Every existing headless test loads res://Main.tscn directly and must keep working untouched.
  5. Play must start a clean run: add GameState.reset_new_game() (resetting bank/fleet/buildings/extractors/transporters/research/conquest to their initial values) and call it from the Play handler, so returning to the menu and pressing Play again does not inherit the previous run. Keep it in one place - the autoload persists across change_scene_to_file.

Acceptance criteria

  • Launching the project shows the menu; Play reaches Main.tscn with a default fleet and empty buildings.
  • Returning to the menu and playing again starts from defaults, not from the previous run's state.
  • Quit is absent in a web build.
  • The full existing suite passes unchanged.

Tests

tests/test_main_menu.gd (bash tests/run_tests.sh menu) covering scene load, the reset call, and the web-conditional Quit button; plus a 720x1280 screenshot of the menu.

Repo notes (read before starting)

  • Godot 4.7.1, portrait 720x1280, touch UI. Project dir: /storage/emulated/0/GodotProjects/SpaceshipTest.
  • After editing any project file, run touch on it. Android FUSE does not bump mtime under ~/storage/shared, and Godot's import cache will silently keep serving the old version, making a correct fix look like it did nothing.
  • Headless tests: bash tests/run_tests.sh <substring>; full suite with no argument. Tests are SceneTree scripts printing TEST_NAME: PASS / TEST_NAME: FAIL (reason) and calling quit(0|1) - copy the shape of tests/test_gas_bomber_cooldowns.gd.
  • Real screenshots: bash tests/screenshot.sh <res://Scene.tscn> <out.png> <frames> 720x1280. Use few frames (~10-20); the software rasterizer is slow. --headless renders nothing at all, so it cannot validate visuals.
  • Drawing goes through NeonDraw / NeonPiece; do not introduce a different visual idiom.
  • The repo deliberately has no type switches left (tickets #31-#35): behaviour comes from *Definition resources plus capability component scenes. Do not add if type == "..." branches.
  • There is no persistence layer (no FileAccess, no user:// anywhere outside this ticket's explicit scope). GameState is an in-memory autoload. Do not invent a save system.
  • Commit each ticket separately and run the full suite before pushing.
Part of #40, which needs a main menu to host the map editor. There is none today - `project.godot` boots straight into `res://Main.tscn`. ### Scope 1. `MainMenu.tscn` + `MainMenu.gd` - 720x1280 portrait, styled like the existing menus: `ui_theme.tres`, `IconButton`, `NeonDraw`. Reusing the `starfield.gdshader` background from `Main.tscn` gives it the right look for free. 2. Entries: - **Play** -> `get_tree().change_scene_to_file("res://Main.tscn")` - **Map editor** -> `res://PlanetSetupEditor.tscn`; until that ticket lands, keep the button present but disabled with a short "coming soon" state rather than a dead link. - **Quit** -> `get_tree().quit()`, hidden when `OS.has_feature("web")`. 3. `project.godot`: `run/main_scene="res://MainMenu.tscn"`. 4. **Do not** make `Main.tscn` depend on having come through the menu. Every existing headless test loads `res://Main.tscn` directly and must keep working untouched. 5. Play must start a clean run: add `GameState.reset_new_game()` (resetting bank/fleet/buildings/extractors/transporters/research/conquest to their initial values) and call it from the Play handler, so returning to the menu and pressing Play again does not inherit the previous run. Keep it in one place - the autoload persists across `change_scene_to_file`. ### Acceptance criteria - Launching the project shows the menu; Play reaches `Main.tscn` with a default fleet and empty buildings. - Returning to the menu and playing again starts from defaults, not from the previous run's state. - Quit is absent in a web build. - The full existing suite passes unchanged. ### Tests `tests/test_main_menu.gd` (`bash tests/run_tests.sh menu`) covering scene load, the reset call, and the web-conditional Quit button; plus a 720x1280 screenshot of the menu. ### Repo notes (read before starting) - Godot 4.7.1, portrait 720x1280, touch UI. Project dir: `/storage/emulated/0/GodotProjects/SpaceshipTest`. - **After editing any project file, run `touch` on it.** Android FUSE does not bump mtime under `~/storage/shared`, and Godot's import cache will silently keep serving the old version, making a correct fix look like it did nothing. - Headless tests: `bash tests/run_tests.sh <substring>`; full suite with no argument. Tests are `SceneTree` scripts printing `TEST_NAME: PASS` / `TEST_NAME: FAIL (reason)` and calling `quit(0|1)` - copy the shape of `tests/test_gas_bomber_cooldowns.gd`. - Real screenshots: `bash tests/screenshot.sh <res://Scene.tscn> <out.png> <frames> 720x1280`. Use few frames (~10-20); the software rasterizer is slow. `--headless` renders nothing at all, so it cannot validate visuals. - Drawing goes through `NeonDraw` / `NeonPiece`; do not introduce a different visual idiom. - The repo deliberately has **no type switches** left (tickets #31-#35): behaviour comes from `*Definition` resources plus capability component scenes. Do not add `if type == "..."` branches. - There is **no persistence layer** (no `FileAccess`, no `user://` anywhere outside this ticket's explicit scope). `GameState` is an in-memory autoload. Do not invent a save system. - Commit each ticket separately and run the full suite before pushing.
Author
Owner

Implemented and pushed as a1fb239.

  • MainMenu.tscn is now project.godot's entry point: Play / Map Editor (disabled, explains itself with a status message until #48 wires it up) / Quit (hidden in web builds), styled like the rest of the game's menus and reusing the starfield shader for its background.
  • GameState.reset_new_game() resets bank/fleet/buildings/extractors/transporters/research/formation/conquest to defaults; Play calls it before swapping to Main.tscn, so a second playthrough in the same process starts fresh instead of inheriting the previous run's state.

New test tests/test_main_menu.gd covers the disabled editor button explaining itself, Quit's visibility following OS.has_feature("web"), and Play genuinely resetting a dirtied GameState before reaching Main.tscn. All existing tests still load Main.tscn directly and are unaffected by the entry-point change. Verified visually at 720x1280.

#48 needs this as its entry point.

Implemented and pushed as `a1fb239`. - `MainMenu.tscn` is now `project.godot`'s entry point: Play / Map Editor (disabled, explains itself with a status message until #48 wires it up) / Quit (hidden in web builds), styled like the rest of the game's menus and reusing the starfield shader for its background. - `GameState.reset_new_game()` resets bank/fleet/buildings/extractors/transporters/research/formation/conquest to defaults; Play calls it before swapping to `Main.tscn`, so a second playthrough in the same process starts fresh instead of inheriting the previous run's state. New test `tests/test_main_menu.gd` covers the disabled editor button explaining itself, Quit's visibility following `OS.has_feature("web")`, and Play genuinely resetting a dirtied GameState before reaching `Main.tscn`. All existing tests still load `Main.tscn` directly and are unaffected by the entry-point change. Verified visually at 720x1280. #48 needs this as its entry point.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
metaheavens/spaceship#47
No description provided.