Adopt the realism pass and refresh screenshots/docs
Full build / Import + headless tests (push) Successful in 34s
Full build / Full desktop build + optional release (push) Skipped

- add the v2 runtime picks: per-phase skyline panoramas, brick, sidewalk
  pavers, dry/wet asphalt, awning canvas, and their normal maps
- add the realism tooling and evidence: tools/scene_concepts.py, capture_realism.gd,
  concept frames, reports/sheets, and tests
- retune phase lighting/fog/exposure, add sun yaw, brighten the night glow,
  add the flashlight beam mesh, and rebuild the planter/tree assets
- regenerate all eleven staged screenshots from the current build; compare is
  11 good / 0 bad
- finish the visual-alignment closeout in DONE/TODO, update architecture,
  blender-assets, PLAN, and ignore rules (editable Blender sources untracked)
- keep the judge retry and document the verified default judge model

Verification: headless 227/227; Python tooling 86/86; check_screenshots 11/11.
This commit is contained in:
zwitschi committed 2026-11-01 17:03:05 +01:00
1 parent 26ecb93fd4
commit d7e523f63c
70 files changed
+4042 -101

No files matched your search

+35 -11
View File
@@ -46,19 +46,19 @@ var _last_phase: int = -1
## structure — phase-based lighting). Night phases switch street lamps on.
const PHASE_LIGHTING := {
Rules.Phase.EARLY: {
"sun_energy": 0.62, "sun_angle": -50.0, "sun_color": Color(1.0, 0.96, 0.88),
"sun_energy": 0.62, "sun_angle": -34.0, "sun_yaw": -30.0, "sun_color": Color(1.0, 0.96, 0.88),
"sky_top": Color(0.32, 0.55, 0.95), "sky_horizon": Color(0.82, 0.88, 0.95),
"sky_ground": Color(0.45, 0.5, 0.55), "ambient": Color(0.75, 0.78, 0.85), "night": false,
"exposure": 0.6, "glow": 0.35, "fog_color": Color(0.80, 0.85, 0.92),
"fog_density": 0.0026, "fog_energy": 0.75, "contrast": 1.05, "saturation": 1.06,
"exposure": 0.6, "glow": 0.45, "fog_color": Color(0.87, 0.83, 0.76),
"fog_density": 0.0034, "fog_energy": 0.5, "contrast": 1.05, "saturation": 1.04,
"ambient_energy": 0.1,
},
Rules.Phase.MIDDAY: {
"sun_energy": 1.0, "sun_angle": -62.0, "sun_color": Color(1.0, 0.99, 0.96),
"sun_energy": 1.0, "sun_angle": -62.0, "sun_yaw": -30.0, "sun_color": Color(1.0, 0.99, 0.96),
"sky_top": Color(0.3, 0.52, 0.95), "sky_horizon": Color(0.85, 0.9, 0.96),
"sky_ground": Color(0.5, 0.54, 0.58), "ambient": Color(0.85, 0.88, 0.95), "night": false,
"exposure": 0.6, "glow": 0.3, "fog_color": Color(0.84, 0.88, 0.94),
"fog_density": 0.0021, "fog_energy": 0.8, "contrast": 1.06, "saturation": 1.05,
"exposure": 0.6, "glow": 0.4, "fog_color": Color(0.88, 0.87, 0.83),
"fog_density": 0.0028, "fog_energy": 0.5, "contrast": 1.06, "saturation": 1.04,
"ambient_energy": 0.28,
},
# Evening is dusk, not a bright sunset: the sun is almost down and the street
@@ -75,7 +75,7 @@ const PHASE_LIGHTING := {
"sun_energy": 0.02, "sun_angle": -8.0, "sun_color": Color(0.3, 0.35, 0.5),
"sky_top": Color(0.015, 0.02, 0.05), "sky_horizon": Color(0.06, 0.07, 0.13),
"sky_ground": Color(0.03, 0.03, 0.05), "ambient": Color(0.06, 0.07, 0.12), "night": true,
"exposure": 0.95, "glow": 1.0, "fog_color": Color(0.08, 0.1, 0.2),
"exposure": 0.95, "glow": 1.15, "fog_color": Color(0.08, 0.1, 0.2),
"fog_density": 0.0028, "fog_energy": 0.45, "contrast": 1.12, "saturation": 1.0,
"ambient_energy": 0.22,
},
@@ -190,10 +190,31 @@ func _build_guard() -> GuardController:
# Aim straight ahead: tilting it down made the cone hit the ground right in
# front of the guard instead of the person or door being checked.
flashlight.rotation_degrees = Vector3.ZERO
flashlight.spot_range = 22.0
flashlight.spot_angle = 30.0
flashlight.spot_range = 16.0
flashlight.spot_angle = 20.0
flashlight.light_energy = 4.0
flashlight.spot_attenuation = 0.6
flashlight.spot_attenuation = 0.8
flashlight.spot_angle_attenuation = 0.9
# Visible beam: a fading additive cone parented to the lamp, because the
# Compatibility renderer has no volumetric light. It is offset forward so the
# near cap never fills the first-person view.
var beam := MeshInstance3D.new()
beam.name = "Beam"
var cone := CylinderMesh.new()
cone.top_radius = 1.0
cone.bottom_radius = 0.05
cone.height = 5.5
cone.radial_segments = 16
cone.rings = 1
cone.cap_top = false
cone.cap_bottom = false
beam.mesh = cone
# Cylinder axis is +Y; -90° about X aims the wide end along -Z (forward).
beam.rotation_degrees = Vector3(-90, 0, 0)
beam.position = Vector3(0, 0, -3.65)
beam.material_override = Materials.light_beam()
beam.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
flashlight.add_child(beam)
head.add_child(flashlight)
var collider := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
@@ -484,7 +505,10 @@ func _apply_phase_lighting() -> void:
if _sun:
_sun.light_energy = float(cfg.get("sun_energy", 1.0))
_sun.light_color = cfg.get("sun_color", Color.WHITE)
_sun.rotation_degrees = Vector3(float(cfg.get("sun_angle", -50.0)), -30, 0)
# `sun_yaw` sets which side of the street the light comes from; the
# entrance view reads as shade when the sun is off the facade.
_sun.rotation_degrees = Vector3(float(cfg.get("sun_angle", -50.0)),
float(cfg.get("sun_yaw", -30.0)), 0)
if _sky:
_sky.sky_top_color = cfg.get("sky_top", Color.BLUE)
_sky.sky_horizon_color = cfg.get("sky_horizon", Color.WHITE)