docs: capture simulation garden baseline
This commit is contained in:
@@ -632,10 +632,15 @@ Completed:
|
||||
10. `Jajce Lookdev 01` capture and review: a reproducible capture tool writes
|
||||
the daytime lookdev baseline to `docs/baselines/jajce_lookdev_01.png`, and
|
||||
the review notes the current strengths and visual follow-ups.
|
||||
11. `Simulation Garden 01` capture and review: a reproducible runtime capture
|
||||
tool writes debug and cinematic `main.tscn` baselines to `docs/baselines/`
|
||||
and verifies live NPC visuals in the terrain-backed village.
|
||||
|
||||
Next:
|
||||
|
||||
1. Capture “Simulation Garden 01.”
|
||||
1. Improve the runtime first-read: camera staging, readable path/landmark
|
||||
composition, and diegetic task communication without adding new simulation
|
||||
mechanics.
|
||||
|
||||
Do not start with GIS data, a full city, a large asset pack, or more NPC
|
||||
mechanics. The next proof is a beautiful stage for the systems that already
|
||||
|
||||
@@ -680,6 +680,9 @@ Recently completed:
|
||||
that do not reach their requested targets.
|
||||
- `Jajce Lookdev 01` is captured and reviewed with a project-owned capture
|
||||
script and a daytime baseline image under `docs/baselines/`.
|
||||
- `Simulation Garden 01` is captured and reviewed from `main.tscn` with paired
|
||||
debug/cinematic baselines that verify live NPC visuals in the Terrain3D-backed
|
||||
village.
|
||||
|
||||
This order strengthens the simulation while regularly producing visible
|
||||
progress suitable for public development updates.
|
||||
|
||||
@@ -198,6 +198,9 @@ study, and patrol target typed activity sites. The migration is documented in
|
||||
- **Lookdev baseline:** `Jajce Lookdev 01` is captured at
|
||||
`docs/baselines/jajce_lookdev_01.png` with
|
||||
`tools/capture_jajce_lookdev.gd`
|
||||
- **Runtime baseline:** `Simulation Garden 01` is captured as paired debug and
|
||||
cinematic `main.tscn` images under `docs/baselines/` with
|
||||
`tools/capture_simulation_garden.gd`
|
||||
- **Terrain compatibility floor:** Godot 4.4 according to the bundled extension
|
||||
- **Version control:** Git
|
||||
- **Primary branch:** `main`
|
||||
@@ -336,8 +339,8 @@ distance with resource `safety_risk`, `comfort_distance`, and
|
||||
keep the old greybox ground out of runtime physics, require paths to reach
|
||||
their targets, and compare required navigation paths against the Terrain3D
|
||||
height field;
|
||||
- a look-development scene and camera.
|
||||
- a reproducible daytime lookdev capture and review note under
|
||||
- a look-development scene and camera;
|
||||
- reproducible lookdev and runtime capture scripts plus review notes under
|
||||
`docs/baselines/`.
|
||||
|
||||
This is a runtime integration proof, not the final terrain composition.
|
||||
@@ -549,8 +552,8 @@ These are expected prototype constraints, not necessarily isolated bugs:
|
||||
playable-loop pass, so future terrain sculpting should rerun the bake tool and
|
||||
recheck reachability rather than hand-editing navigation polygons.
|
||||
- Terrain3D and the bounded Jajce beauty baseline now run in the main game
|
||||
scene; `Jajce Lookdev 01` is captured, while the runtime `Simulation Garden
|
||||
01` capture remains the next presentation checkpoint.
|
||||
scene; `Jajce Lookdev 01` and the runtime `Simulation Garden 01` are captured
|
||||
as reproducible presentation baselines.
|
||||
- Combat, companions, factions, politics, trade, rumours, quests, persistence,
|
||||
and regional travel do not yet exist.
|
||||
- Placeholder geometry is sufficient for debugging but not for build-in-public
|
||||
@@ -768,7 +771,8 @@ eating consumes it. Each successful transfer creates a persisted structured
|
||||
event, and active NPCs visibly carry food through presentation derived from
|
||||
their inventory. The bounded save-slot slice is also complete, including
|
||||
validation, atomic replacement recovery, and active-visual rebuilding.
|
||||
Terrain3D runtime integration and the simulation-garden beauty pass are next.
|
||||
Terrain3D runtime integration, the bounded Jajce beauty pass, and the first
|
||||
simulation-garden runtime capture are complete.
|
||||
|
||||
The coherent visual slice can then aim for:
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Simulation Garden 01
|
||||
|
||||
Captured: 2026-07-08
|
||||
|
||||
## Files
|
||||
|
||||
- `docs/baselines/simulation_garden_01_debug.png`
|
||||
- `docs/baselines/simulation_garden_01_cinematic.png`
|
||||
- `tools/capture_simulation_garden.gd`
|
||||
|
||||
## Capture Command
|
||||
|
||||
Run from the project root with the normal renderer:
|
||||
|
||||
```powershell
|
||||
$env:APPDATA = 'C:\Users\Rijad\Documents\Simulation Game\logs\quality\godot_profile'
|
||||
$env:LOCALAPPDATA = 'C:\Users\Rijad\Documents\Simulation Game\logs\quality\godot_profile'
|
||||
& 'C:\Users\Rijad\Downloads\tools\Godot_v4.7-stable_win64.exe\Godot_v4.7-stable_win64_console.exe' --path 'C:\Users\Rijad\Documents\Simulation Game' --script res://tools/capture_simulation_garden.gd
|
||||
```
|
||||
|
||||
The script warms up `main.tscn`, verifies that the simulation and active NPC
|
||||
visuals exist, captures the F10 debug presentation, then captures the cinematic
|
||||
presentation with development labels and UI hidden.
|
||||
|
||||
## Review
|
||||
|
||||
The milestone is valid as a runtime integration checkpoint: the same Jajce
|
||||
Terrain3D world is running in `main.tscn`, NPCs are alive in the terrain-backed
|
||||
village, the selected-NPC reason inspector is fed by real task scoring, and the
|
||||
cinematic/debug toggle produces a shareable view without changing simulation
|
||||
state.
|
||||
|
||||
The frame also makes the next presentation risks plain:
|
||||
|
||||
- the camera still favors verification over composition;
|
||||
- placeholder characters, houses, and work props remain useful but visibly
|
||||
prototype-grade;
|
||||
- terrain texture variation reads better than the old flat map, but paths,
|
||||
landmarks, water, and foreground silhouettes need stronger first-read staging;
|
||||
- labels explain the system well, while the cinematic view still needs more
|
||||
diegetic task communication.
|
||||
|
||||
Use this baseline as the first runtime comparison image before adding more
|
||||
systems or expanding the terrain.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 505 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 530 KiB |
@@ -0,0 +1,106 @@
|
||||
extends SceneTree
|
||||
|
||||
const SCENE_PATH := "res://main.tscn"
|
||||
const DEBUG_OUTPUT_PATH := "res://docs/baselines/simulation_garden_01_debug.png"
|
||||
const CINEMATIC_OUTPUT_PATH := "res://docs/baselines/simulation_garden_01_cinematic.png"
|
||||
const CAPTURE_SIZE := Vector2i(1280, 720)
|
||||
const WARMUP_FRAMES := 540
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
root.size = CAPTURE_SIZE
|
||||
var scene := load(SCENE_PATH) as PackedScene
|
||||
if scene == null:
|
||||
push_error("Could not load %s" % SCENE_PATH)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var main_scene := scene.instantiate()
|
||||
var simulation_manager := main_scene.get_node("SimulationManager")
|
||||
simulation_manager.debug_logs = false
|
||||
|
||||
root.add_child(main_scene)
|
||||
await process_frame
|
||||
for _frame in WARMUP_FRAMES:
|
||||
await process_frame
|
||||
|
||||
var active_npcs := main_scene.get_node("ActiveNPCs")
|
||||
var demo_controller := main_scene.get_node("DemoController")
|
||||
if simulation_manager.npcs.is_empty() or active_npcs.get_child_count() == 0:
|
||||
push_error("Simulation Garden capture needs active NPCs")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
if demo_controller.has_method("toggle_debug_overlay"):
|
||||
if not demo_controller.debug_overlay_visible:
|
||||
demo_controller.toggle_debug_overlay()
|
||||
|
||||
var debug_analysis := _capture(DEBUG_OUTPUT_PATH)
|
||||
if debug_analysis.is_empty():
|
||||
quit(1)
|
||||
return
|
||||
|
||||
if demo_controller.has_method("toggle_debug_overlay") and demo_controller.debug_overlay_visible:
|
||||
demo_controller.toggle_debug_overlay()
|
||||
await process_frame
|
||||
for _frame in 30:
|
||||
await process_frame
|
||||
|
||||
var cinematic_analysis := _capture(CINEMATIC_OUTPUT_PATH)
|
||||
if cinematic_analysis.is_empty():
|
||||
quit(1)
|
||||
return
|
||||
|
||||
print(
|
||||
"[TOOL] Saved Simulation Garden captures | debug %s | cinematic %s"
|
||||
% [debug_analysis, cinematic_analysis]
|
||||
)
|
||||
quit(0)
|
||||
|
||||
|
||||
func _capture(output_path: String) -> Dictionary:
|
||||
var image := root.get_texture().get_image()
|
||||
if image == null or image.is_empty():
|
||||
push_error("Simulation Garden capture produced no image")
|
||||
return {}
|
||||
|
||||
var analysis := _analyze_image(image)
|
||||
if analysis.get("range", 0.0) < 0.05:
|
||||
push_error("Simulation Garden capture is too uniform: %s" % analysis)
|
||||
return {}
|
||||
|
||||
var error := image.save_png(output_path)
|
||||
if error != OK:
|
||||
push_error("Could not save %s: %s" % [output_path, error_string(error)])
|
||||
return {}
|
||||
|
||||
return analysis
|
||||
|
||||
|
||||
func _analyze_image(image: Image) -> Dictionary:
|
||||
var min_luma := INF
|
||||
var max_luma := -INF
|
||||
var total_luma := 0.0
|
||||
var samples := 0
|
||||
var step_x = maxi(1, image.get_width() / 64)
|
||||
var step_y = maxi(1, image.get_height() / 36)
|
||||
|
||||
for y in range(0, image.get_height(), step_y):
|
||||
for x in range(0, image.get_width(), step_x):
|
||||
var color := image.get_pixel(x, y)
|
||||
var luma := color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722
|
||||
min_luma = minf(min_luma, luma)
|
||||
max_luma = maxf(max_luma, luma)
|
||||
total_luma += luma
|
||||
samples += 1
|
||||
|
||||
return {
|
||||
"size": "%sx%s" % [image.get_width(), image.get_height()],
|
||||
"samples": samples,
|
||||
"average_luma": total_luma / samples,
|
||||
"range": max_luma - min_luma,
|
||||
}
|
||||
Reference in New Issue
Block a user