feat(@projects/@magic-civilization): ✨ add full-game visual demo proof scene
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
70490781f3
commit
63ec984c36
1 changed files with 156 additions and 0 deletions
156
src/game/engine/scenes/tests/full_game_demo_proof.gd
Normal file
156
src/game/engine/scenes/tests/full_game_demo_proof.gd
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
extends Node2D
|
||||
## p2-66 Full-game visual demo proof.
|
||||
##
|
||||
## Bypasses world_map.tscn's SubViewport tiering (which renders black under
|
||||
## headless llvmpipe when mounted as a child node) and instead drives the
|
||||
## hex / unit / city renderers directly with a Camera2D pointed at the map
|
||||
## centre. All tiles are forced fully visible (fog disabled). Captures a
|
||||
## non-black 1920×1080 screenshot proving the gameplay surface renders.
|
||||
|
||||
const MapGeneratorScript: GDScript = preload("res://engine/src/generation/map_generator.gd")
|
||||
const PlayerScript: GDScript = preload("res://engine/src/entities/player.gd")
|
||||
const UnitScript: GDScript = preload("res://engine/src/entities/unit.gd")
|
||||
const CityScript: GDScript = preload("res://engine/src/entities/city.gd")
|
||||
const HexUtilsScript: GDScript = preload("res://engine/src/map/hex_utils.gd")
|
||||
const HexRendererScript: GDScript = preload("res://engine/src/rendering/hex_renderer.gd")
|
||||
const UnitRendererScript: GDScript = preload("res://engine/src/rendering/unit_renderer.gd")
|
||||
const CityRendererScript: GDScript = preload("res://engine/src/rendering/city_renderer.gd")
|
||||
|
||||
const OUTPUT_DIR: String = "user://screenshots"
|
||||
const VIEWPORT_SIZE: Vector2i = Vector2i(1920, 1080)
|
||||
|
||||
var _captured: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
OS.set_environment("MC_USE_PROCEDURAL_SPRITES", "1")
|
||||
OS.set_environment("FORCE_DISABLE_FOGOFWAR", "true")
|
||||
DisplayServer.window_set_size(VIEWPORT_SIZE)
|
||||
get_viewport().size = VIEWPORT_SIZE
|
||||
RenderingServer.set_default_clear_color(Color(0.05, 0.07, 0.10))
|
||||
|
||||
DataLoader.load_theme("age-of-dwarves")
|
||||
DataLoader.load_world("earth")
|
||||
ThemeAssets.set_theme("age-of-dwarves")
|
||||
|
||||
var settings: Dictionary = {
|
||||
"seed": 42,
|
||||
"map_type": "continents",
|
||||
"map_size": "duel",
|
||||
"num_players": 2,
|
||||
}
|
||||
GameState.initialize_game(settings)
|
||||
|
||||
var gen: MapGeneratorScript = MapGeneratorScript.new()
|
||||
var game_map: RefCounted = gen.generate(settings)
|
||||
if game_map == null:
|
||||
push_error("full_game_demo: MapGenerator returned null")
|
||||
get_tree().quit(1)
|
||||
return
|
||||
print("full_game_demo: Map %dx%d (%d tiles)" % [
|
||||
game_map.width, game_map.height, game_map.tiles.size()
|
||||
])
|
||||
|
||||
var primary: Dictionary = GameState.get_primary_layer()
|
||||
primary["map"] = game_map
|
||||
|
||||
# Spawn 2 players + a founder unit + a capital city per player at
|
||||
# their map start positions so the unit + city renderers have data.
|
||||
for i: int in range(2):
|
||||
var player: PlayerScript = PlayerScript.new()
|
||||
player.index = i
|
||||
player.is_human = (i == 0)
|
||||
player.player_name = "Player %d" % (i + 1)
|
||||
player.race_id = "dwarf"
|
||||
player.color = Color(0.85, 0.65, 0.2) if i == 0 else Color(0.2, 0.55, 0.85)
|
||||
GameState.players.append(player)
|
||||
|
||||
var start: Vector2i = Vector2i.ZERO
|
||||
if i < game_map.start_positions.size():
|
||||
start = game_map.start_positions[i]
|
||||
|
||||
var unit: UnitScript = UnitScript.new("dwarf_warrior", i, start)
|
||||
unit.id = "unit_%d_warrior" % i
|
||||
player.units.append(unit)
|
||||
|
||||
var city: CityScript = CityScript.new()
|
||||
city.player_index = i
|
||||
city.position = start
|
||||
city.id = "city_%d_capital" % i
|
||||
city.city_name = "%s Capital" % player.player_name
|
||||
city.population = 3 + i
|
||||
player.cities.append(city)
|
||||
|
||||
# Build the renderers as direct children — no SubViewport hierarchy.
|
||||
var hex: Node2D = HexRendererScript.new()
|
||||
hex.name = "HexRenderer"
|
||||
add_child(hex)
|
||||
# Force-mark every tile as fully visible by feeding update_fog all positions.
|
||||
hex.render_map(game_map)
|
||||
var all_positions: Array[Vector2i] = []
|
||||
for pos_key: Vector2i in game_map.tiles:
|
||||
all_positions.append(pos_key)
|
||||
hex.update_fog(all_positions, [])
|
||||
|
||||
var units: Node2D = UnitRendererScript.new()
|
||||
units.name = "UnitRenderer"
|
||||
add_child(units)
|
||||
if units.has_method("setup_visibility"):
|
||||
units.call("setup_visibility", 0, game_map)
|
||||
if units.has_method("render_units"):
|
||||
units.call("render_units", game_map)
|
||||
elif units.has_method("refresh"):
|
||||
units.call("refresh")
|
||||
|
||||
var cities: Node2D = CityRendererScript.new()
|
||||
cities.name = "CityRenderer"
|
||||
add_child(cities)
|
||||
if cities.has_method("refresh"):
|
||||
cities.call("refresh")
|
||||
elif cities.has_method("render_cities"):
|
||||
cities.call("render_cities")
|
||||
|
||||
# Camera centred on the map middle, zoomed out enough to see the
|
||||
# whole continent.
|
||||
var cam: Camera2D = Camera2D.new()
|
||||
cam.name = "DemoCamera"
|
||||
var mid_axial: Vector2i = Vector2i(game_map.width / 2, game_map.height / 2)
|
||||
var mid_pixel: Vector2 = HexUtilsScript.axial_to_pixel(mid_axial)
|
||||
cam.position = mid_pixel
|
||||
# axial_to_pixel scales each tile to ~150px; duel map (40×24) = ~6000×3600 px.
|
||||
# Zoom 0.18 fits the whole map into 1920×1080.
|
||||
cam.zoom = Vector2(0.18, 0.18)
|
||||
cam.make_current()
|
||||
add_child(cam)
|
||||
|
||||
# Wait for the renderers to flush their _draw passes.
|
||||
for _i: int in range(20):
|
||||
await get_tree().process_frame
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
_capture_and_quit()
|
||||
|
||||
|
||||
func _capture_and_quit() -> void:
|
||||
if _captured:
|
||||
return
|
||||
_captured = true
|
||||
DirAccess.make_dir_recursive_absolute(
|
||||
ProjectSettings.globalize_path(OUTPUT_DIR)
|
||||
)
|
||||
var image: Image = get_viewport().get_texture().get_image()
|
||||
if image == null:
|
||||
push_error("full_game_demo: viewport image null")
|
||||
get_tree().quit(1)
|
||||
return
|
||||
var timestamp: String = Time.get_datetime_string_from_system().replace(
|
||||
":", "-"
|
||||
).replace("T", "_")
|
||||
var rel: String = "%s/full_game_demo_%s.png" % [OUTPUT_DIR, timestamp]
|
||||
var abs_path: String = ProjectSettings.globalize_path(rel)
|
||||
var err: Error = image.save_png(abs_path)
|
||||
if err == OK:
|
||||
print("SCREENSHOT_PATH:%s" % abs_path)
|
||||
print("full_game_demo: %dx%d saved" % [image.get_width(), image.get_height()])
|
||||
else:
|
||||
push_error("full_game_demo: save failed: %s" % error_string(err))
|
||||
get_tree().quit()
|
||||
Loading…
Add table
Reference in a new issue