Turn dev mode into sandbox menu

This commit is contained in:
Loïc Wisniewski 2026-09-03 20:05:33 +02:00
commit c325501999
19 changed files with 651 additions and 54 deletions

View file

@ -185,9 +185,12 @@ var research_points: int = 0
# generation is static and dependency-free by design. This stays the single
# place to set it - assigning dev_mode anywhere, tests included, reaches
# world generation.
var dev_unlimited_resources: bool = false
var dev_mode: bool = false:
set(value):
dev_mode = value
if not value:
dev_unlimited_resources = false
WORLD_GEN.dev_planets_enabled = value
# Explored-chunk history for the world map's fog-of-war reveal. Lives
@ -763,6 +766,7 @@ func reset_new_game() -> void:
_distorder_drain_progress = 0.0
boost_depleted_notice = false
research_points = 0
dev_unlimited_resources = false
dev_mode = false
explored_chunks.clear()
bank_inventory = INVENTORY.new()
@ -786,12 +790,15 @@ func reset_new_game() -> void:
# the game immediately, without being so large that costs stop registering.
const DEV_RESOURCE_AMOUNT: int = 2000
const DEV_RESEARCH_POINTS: int = 500
const DEV_UNLIMITED_AMOUNT: int = 999999
# A new game stocked for play-testing: every resource banked, research points
# to spend, and one of each planet type next to the spawn (WorldGen reads
# dev_mode for that). Offered by the main menu only when running from Godot -
# see MainMenu.gd - so it cannot be reached in a shipped build.
# A post-prologue game stocked for play-testing: every resource banked,
# research points to spend, and one of each planet type next to the spawn
# (WorldGen reads dev_mode for that). Offered by the main menu only when
# running from Godot - see MainMenu.gd - so it cannot be reached in a shipped
# build. Dev mode is for iterating on the game itself, not replaying the long
# scripted introduction before every check.
#
# Deliberately built ON TOP of reset_new_game() rather than beside it, so a
# dev game is a normal game plus a stock rather than a second, separately
@ -799,12 +806,51 @@ const DEV_RESEARCH_POINTS: int = 500
func start_dev_game() -> void:
reset_new_game()
dev_mode = true
intro_active = false
for resource_type in resource_types():
bank_inventory.set_amount(resource_type, DEV_RESOURCE_AMOUNT)
research_points = DEV_RESEARCH_POINTS
research_points_changed.emit(research_points)
# Development toggles deliberately live beside the state they affect. The
# menu is only a front-end; scene swaps cannot turn an infinite bank off or
# forget which doctrines were exposed.
func set_dev_unlimited_resources(enabled: bool) -> bool:
if enabled and not dev_mode:
return false
dev_unlimited_resources = enabled
if enabled:
_refill_dev_resources()
return true
func _refill_dev_resources() -> void:
for resource_type in resource_types():
if bank_inventory.amount(resource_type) < DEV_UNLIMITED_AMOUNT:
bank_inventory.set_amount(resource_type, DEV_UNLIMITED_AMOUNT)
if research_points < DEV_UNLIMITED_AMOUNT:
research_points = DEV_UNLIMITED_AMOUNT
research_points_changed.emit(research_points)
func dev_unlock_all_skills() -> int:
if not dev_mode:
return 0
var added: int = 0
for node in SKILL_TREE:
var id: String = String(node.id)
if id in unlocked:
continue
unlocked.append(id)
added += 1
# These permanent doctrines affect structures which may already exist.
# Sync once after the batch instead of once per node.
_sync_hub_transporters()
_sync_workshop_drones()
return added
# --- building stock and production queue (#16) -----------------------------
# Since #12, a building cannot just deduct from the bank at the moment of
@ -2755,6 +2801,8 @@ func wave_cleared() -> void:
func _process(delta: float) -> void:
# Runs in the autoload, so mining and transport continue while the player
# is on a planet's surface or nowhere near either.
if dev_mode and dev_unlimited_resources:
_refill_dev_resources()
advance_waves(delta)
_advance_production(delta)
_advance_lab_research(delta)