feat: add witnessed knowledge and wind ambience

This commit is contained in:
Rijad Zuzo
2026-07-11 11:27:40 +02:00
parent 2ed93de6d1
commit 81409650df
72 changed files with 3001 additions and 606 deletions
+93 -12
View File
@@ -16,8 +16,56 @@ func _run() -> void:
var simulation_manager: Node = main_scene.get_node("SimulationManager")
simulation_manager.set_process(false)
var saved_clock_ticks: int = simulation_manager.clock.elapsed_ticks
simulation_manager.clock.elapsed_ticks = 0
await process_frame
await process_frame
var environment: Environment = (
(main_scene.get_node("JajceWorld/WorldEnvironment") as WorldEnvironment).environment
)
_check(
is_equal_approx(environment.ambient_light_energy, 0.25),
"Day/night presentation should follow the authoritative simulation clock"
)
simulation_manager.clock.elapsed_ticks = saved_clock_ticks
await process_frame
_check(simulation_manager.npcs.size() == 6, "Baseline should create six NPCs")
var inspector_label := (
main_scene.get_node("UI/NpcInspectorPanel/MarginContainer/NpcInspectorLabel") as Label
)
_check(
(
"Relationship:" in inspector_label.text
and "familiar 50%" in inspector_label.text
and "trust 50%" in inspector_label.text
),
"Runtime inspector should render authoritative directed relationship state"
)
var contributor: SimNPC = simulation_manager.npcs[0]
var witness: SimNPC = simulation_manager.npcs[1]
contributor.position = Vector3.ZERO
witness.position = Vector3(4.0, 0.0, 0.0)
witness.hunger = 85.0
contributor.add_inventory(SimulationIds.RESOURCE_FOOD, 1.0)
_check(
is_equal_approx(
simulation_manager.economy.deposit_inventory(contributor, SimulationIds.RESOURCE_FOOD),
1.0
),
"Runtime knowledge UI check should use a completed simulation transaction"
)
var village_ui := main_scene.get_node("UI")
village_ui.selected_npc_index = witness.id
village_ui.call("_refresh_npc_inspector")
_check(
(
"Known fact: %s deposited" % contributor.npc_name in inspector_label.text
and "Relationship: %s" % contributor.npc_name in inspector_label.text
and "Because:" in inspector_label.text
),
"NPC inspector should show the witnessed fact and its relationship consequence"
)
_check(
main_scene.has_node("JajceWorld/TerrainRoot/Terrain3D"),
"Playable runtime should instance the Jajce Terrain3D world"
@@ -39,6 +87,21 @@ func _run() -> void:
"Presentation preset should pull the camera back from the village focus"
)
_check(terrain.collision_mode != 0, "Runtime Terrain3D collision should be enabled")
_check(
(
main_scene.has_node("Player/Visual/Body")
and main_scene.has_node("Player/Visual/Head")
and main_scene.has_node("Player/Visual/Scarf")
),
"Player should use the same readable multi-part visual language as villagers"
)
_check(
(
not main_scene.has_node("Player/MeshInstance3D")
and not main_scene.has_node("Player/FaceMarker")
),
"Runtime should not retain the placeholder player capsule presentation"
)
_check(
not main_scene.has_node("JajceWorld/NavigationRegion3D/GreyboxGround"),
"Runtime should not keep the temporary greybox navigation ground"
@@ -53,7 +116,9 @@ func _run() -> void:
"Runtime should not retain duplicate flat-world objects"
)
var resource_root := main_scene.get_node("JajceWorld/WorldObjects/ResourceNodes")
_check(resource_root.get_child_count() == 18, "Runtime should contain eighteen Jajce ResourceNodes")
_check(
resource_root.get_child_count() == 18, "Runtime should contain eighteen Jajce ResourceNodes"
)
_check(
simulation_manager.resource_states.size() == 18,
"Simulation authority should bind all eighteen Jajce resources"
@@ -63,7 +128,9 @@ func _run() -> void:
for child in village_root.get_children():
if child.name.begins_with("Path_"):
path_strips += 1
_check(path_strips >= 4, "Runtime should include authored path strips for first-read composition")
_check(
path_strips >= 4, "Runtime should include authored path strips for first-read composition"
)
_check(
main_scene.has_node("JajceWorld/FortressBlockout/Keep/RidgeBanner"),
"Runtime should include a readable ridge landmark banner"
@@ -86,9 +153,14 @@ func _run() -> void:
)
var navigation_map: RID = main_scene.get_world_3d().navigation_map
var navigation_region := main_scene.get_node("JajceWorld/NavigationRegion3D") as NavigationRegion3D
var navigation_region := (
main_scene.get_node("JajceWorld/NavigationRegion3D") as NavigationRegion3D
)
_check(
navigation_region.navigation_mesh.resource_path == "res://world/jajce/JajceNavigationMesh.tres",
(
navigation_region.navigation_mesh.resource_path
== "res://world/jajce/JajceNavigationMesh.tres"
),
"Runtime navigation should use the Terrain3D-derived baked mesh resource"
)
await _wait_for_navigation_map(navigation_map)
@@ -104,13 +176,17 @@ func _run() -> void:
not main_scene.has_node("JajceWorld/LegacyActivityMarkers/PantryMarker"),
"Runtime should not keep the pantry as a legacy activity marker"
)
var pantry := main_scene.get_node("JajceWorld/WorldObjects/StorageSites/VillagePantry") as StorageNode
var pantry := (
main_scene.get_node("JajceWorld/WorldObjects/StorageSites/VillagePantry") as StorageNode
)
destinations.append(pantry.get_interaction_position())
_check(
main_scene.has_node("JajceWorld/WorldObjects/StorageSites/VillageWoodpile"),
"Runtime should expose a typed VillageWoodpile StorageNode"
)
var woodpile := main_scene.get_node("JajceWorld/WorldObjects/StorageSites/VillageWoodpile") as StorageNode
var woodpile := (
main_scene.get_node("JajceWorld/WorldObjects/StorageSites/VillageWoodpile") as StorageNode
)
destinations.append(woodpile.get_interaction_position())
var activity_root := main_scene.get_node("JajceWorld/WorldObjects/ActivitySites")
_check(activity_root.get_child_count() == 3, "Runtime should expose three typed activity sites")
@@ -193,7 +269,9 @@ func _check(condition: bool, message: String) -> void:
failures.append(message)
func _check_path_tracks_terrain(terrain: Terrain3D, path: PackedVector3Array, message: String) -> void:
func _check_path_tracks_terrain(
terrain: Terrain3D, path: PackedVector3Array, message: String
) -> void:
if path.is_empty():
return
@@ -204,13 +282,17 @@ func _check_path_tracks_terrain(terrain: Terrain3D, path: PackedVector3Array, me
return
if absf(point.y - terrain_height) > 0.85:
failures.append(
"%s: path point %s is too far from terrain height %.2f"
% [message, point, terrain_height]
(
"%s: path point %s is too far from terrain height %.2f"
% [message, point, terrain_height]
)
)
return
func _check_path_reaches_destination(path: PackedVector3Array, destination: Vector3, message: String) -> void:
func _check_path_reaches_destination(
path: PackedVector3Array, destination: Vector3, message: String
) -> void:
if path.is_empty():
return
@@ -219,6 +301,5 @@ func _check_path_reaches_destination(path: PackedVector3Array, destination: Vect
var destination_xz := Vector2(destination.x, destination.z)
if final_xz.distance_to(destination_xz) > 1.5:
failures.append(
"%s: final path point %s is too far from %s"
% [message, final_point, destination]
"%s: final path point %s is too far from %s" % [message, final_point, destination]
)