docs: capture jajce lookdev baseline

This commit is contained in:
2026-07-08 16:01:08 +02:00
parent 324084f233
commit 0fa8d80119
8 changed files with 140 additions and 3 deletions
+4 -2
View File
@@ -629,11 +629,13 @@ Completed:
9. Terrain3D-derived playable-loop navigation: `JajceWorld` now uses an 9. Terrain3D-derived playable-loop navigation: `JajceWorld` now uses an
external baked navigation resource generated from Terrain3D source geometry, external baked navigation resource generated from Terrain3D source geometry,
and runtime tests reject partial paths that do not reach their targets. and runtime tests reject partial paths that do not reach their targets.
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.
Next: Next:
1. Capture and visually review “Jajce Lookdev 01.” 1. Capture “Simulation Garden 01.”
2. Capture “Simulation Garden 01.”
Do not start with GIS data, a full city, a large asset pack, or more NPC 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 mechanics. The next proof is a beautiful stage for the systems that already
+2
View File
@@ -678,6 +678,8 @@ Recently completed:
Terrain3D-derived navigation mesh resource generated by Terrain3D-derived navigation mesh resource generated by
`tools/bake_jajce_navigation.gd`; route tests now also reject partial paths `tools/bake_jajce_navigation.gd`; route tests now also reject partial paths
that do not reach their requested targets. 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/`.
This order strengthens the simulation while regularly producing visible This order strengthens the simulation while regularly producing visible
progress suitable for public development updates. progress suitable for public development updates.
+7 -1
View File
@@ -195,6 +195,9 @@ study, and patrol target typed activity sites. The migration is documented in
- **Jajce runtime:** reusable 512 m Terrain3D seed, greybox landmarks, stable - **Jajce runtime:** reusable 512 m Terrain3D seed, greybox landmarks, stable
ResourceNode placement, lookdev camera, and Terrain3D-derived runtime ResourceNode placement, lookdev camera, and Terrain3D-derived runtime
navigation with collision guardrails navigation with collision guardrails
- **Lookdev baseline:** `Jajce Lookdev 01` is captured at
`docs/baselines/jajce_lookdev_01.png` with
`tools/capture_jajce_lookdev.gd`
- **Terrain compatibility floor:** Godot 4.4 according to the bundled extension - **Terrain compatibility floor:** Godot 4.4 according to the bundled extension
- **Version control:** Git - **Version control:** Git
- **Primary branch:** `main` - **Primary branch:** `main`
@@ -334,6 +337,8 @@ distance with resource `safety_risk`, `comfort_distance`, and
their targets, and compare required navigation paths against the Terrain3D their targets, and compare required navigation paths against the Terrain3D
height field; height field;
- a look-development scene and camera. - a look-development scene and camera.
- a reproducible daytime lookdev capture and review note under
`docs/baselines/`.
This is a runtime integration proof, not the final terrain composition. This is a runtime integration proof, not the final terrain composition.
Terrain3D startup requires several physics frames before reliable Terrain3D startup requires several physics frames before reliable
@@ -544,7 +549,8 @@ These are expected prototype constraints, not necessarily isolated bugs:
playable-loop pass, so future terrain sculpting should rerun the bake tool and playable-loop pass, so future terrain sculpting should rerun the bake tool and
recheck reachability rather than hand-editing navigation polygons. recheck reachability rather than hand-editing navigation polygons.
- Terrain3D and the bounded Jajce beauty baseline now run in the main game - Terrain3D and the bounded Jajce beauty baseline now run in the main game
scene; final visual review and character/profession readability remain. scene; `Jajce Lookdev 01` is captured, while the runtime `Simulation Garden
01` capture remains the next presentation checkpoint.
- Combat, companions, factions, politics, trade, rumours, quests, persistence, - Combat, companions, factions, politics, trade, rumours, quests, persistence,
and regional travel do not yet exist. and regional travel do not yet exist.
- Placeholder geometry is sufficient for debugging but not for build-in-public - Placeholder geometry is sufficient for debugging but not for build-in-public
+46
View File
@@ -0,0 +1,46 @@
# Jajce Lookdev 01
- **Captured:** 2026-07-08
- **Scene:** `res://world/jajce/JajceLookdev.tscn`
- **Image:** [`jajce_lookdev_01.png`](jajce_lookdev_01.png)
- **Capture tool:** `res://tools/capture_jajce_lookdev.gd`
## Contract
This checkpoint captures the first readable Jajce visual stage after the
Terrain3D-derived navigation pass. It is a visual composition baseline, not a
gameplay regression test.
The image should show:
- the broad shaped valley terrain;
- the village and fortress blockouts;
- water, waterfall/foam, and bridge silhouettes;
- visible foliage clusters;
- warm daylight/fog treatment;
- stable enough framing to compare future terrain, lighting, and asset passes.
## Review
The scene now reads as a coherent daytime valley rather than the previous dark
startup view. The terrain, homes, bridge, water, waterfall, smoke/mist, and
first foliage clusters are all visible in one frame.
Known follow-up work:
- reduce the heavy haze if it hides terrain color and landmark silhouettes;
- improve fortress/waterfall readability from the beauty-camera angle;
- replace blockout architecture and placeholder resource markers gradually;
- capture a runtime `Simulation Garden 01` view with active NPC behavior.
## Command
Run with a real display driver, not `--headless`; headless Godot uses the dummy
renderer on this machine and cannot read back a viewport image.
```powershell
$env:APPDATA = "$PWD\logs\quality\godot_profile"
$env:LOCALAPPDATA = "$PWD\logs\quality\godot_profile"
& "C:\Users\Rijad\Downloads\tools\Godot_v4.7-stable_win64.exe\Godot_v4.7-stable_win64_console.exe" `
--path "$PWD" --script res://tools/capture_jajce_lookdev.gd
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 732 KiB

+71
View File
@@ -0,0 +1,71 @@
extends SceneTree
const OUTPUT_PATH := "res://docs/baselines/jajce_lookdev_01.png"
const SCENE_PATH := "res://world/jajce/JajceLookdev.tscn"
const CAPTURE_SIZE := Vector2i(1280, 720)
const WARMUP_FRAMES := 90
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 lookdev := scene.instantiate() as Node3D
root.add_child(lookdev)
await process_frame
for _frame in WARMUP_FRAMES:
await process_frame
var image := root.get_texture().get_image()
if image == null or image.is_empty():
push_error("Lookdev capture produced no image")
quit(1)
return
var analysis := _analyze_image(image)
if analysis.get("range", 0.0) < 0.05:
push_error("Lookdev capture is too uniform: %s" % analysis)
quit(1)
return
var error := image.save_png(OUTPUT_PATH)
if error != OK:
push_error("Could not save %s: %s" % [OUTPUT_PATH, error_string(error)])
quit(1)
return
print("[TOOL] Saved %s | %s" % [OUTPUT_PATH, analysis])
quit(0)
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,
}
+3
View File
@@ -7,6 +7,9 @@
[node name="JajceWorld" parent="." instance=ExtResource("1_world")] [node name="JajceWorld" parent="." instance=ExtResource("1_world")]
[node name="DayNightCycle" parent="JajceWorld" index="9"]
initial_cycle = 0.38
[node name="BeautyCamera" type="Camera3D" parent="."] [node name="BeautyCamera" type="Camera3D" parent="."]
position = Vector3(44, 34, 44) position = Vector3(44, 34, 44)
current = true current = true
+7
View File
@@ -1,6 +1,7 @@
extends Node extends Node
@export var cycle_duration_seconds := 240.0 @export var cycle_duration_seconds := 240.0
@export_range(0.0, 1.0, 0.01) var initial_cycle := 0.35
@export var directional_light: DirectionalLight3D @export var directional_light: DirectionalLight3D
@export var world_environment: WorldEnvironment @export var world_environment: WorldEnvironment
@@ -37,6 +38,12 @@ const SUNRISE_SUNSET_ENERGY := 0.8
var elapsed := 0.0 var elapsed := 0.0
func _ready() -> void:
elapsed = cycle_duration_seconds * initial_cycle
_apply_light_rotation(initial_cycle)
_apply_environment(initial_cycle)
func _process(delta: float) -> void: func _process(delta: float) -> void:
elapsed += delta elapsed += delta
if elapsed >= cycle_duration_seconds: if elapsed >= cycle_duration_seconds: