feat(art): add storybook meadow and woodland villagers

This commit is contained in:
Rijad Zuzo
2026-09-05 18:56:44 +02:00
parent 6aae41d36f
commit da3bed67a0
60 changed files with 1222 additions and 373 deletions
+1 -1
View File
@@ -535,7 +535,7 @@ func _run() -> void:
(
main_scene.has_node("Player/Visual/Body")
and main_scene.has_node("Player/Visual/Head")
and main_scene.has_node("Player/Visual/Scarf")
and main_scene.get_node("Player/Visual").get_meta("animal_species") == &"fox"
),
"Player should use the same readable multi-part visual language as villagers"
)
+9
View File
@@ -89,6 +89,11 @@ func _run() -> void:
"Village center should include a few oversized ambient butterflies"
)
var grass_field := world.get_node("TerrainRoot/Terrain3D/CozyGrassField")
var grass_mesh := grass_field.get("mesh") as ArrayMesh
_check(
grass_mesh != null and grass_mesh.get_faces().size() == 105,
"Meadow grass must reuse the 35-triangle Blender tuft"
)
var grass_material := grass_field.get("mesh_material_override") as ShaderMaterial
var grass_process := grass_field.get("process_material") as ShaderMaterial
_check(
@@ -112,6 +117,10 @@ func _run() -> void:
"Grass placement should stay short enough to preserve villagers and paths"
)
var grass_controller := world.get_node("TerrainRoot/GrassInteractionController")
_check(
grass_material.get_shader_parameter("clearing_count") == 4,
"Grass must leave the four authored walking paths clear"
)
_check(
grass_controller.get("grass_material") == grass_material,
"Grass interaction should update the same material rendered by Terrain3D particles"
+20 -5
View File
@@ -26,17 +26,28 @@ func _run() -> void:
var trust_reaction_root: Node3D = visual.get_node("TrustReactionRoot")
_check(not trust_reaction_root.visible, "A newly spawned visual should not replay reactions")
_check(
body.material_override.albedo_color == profession_definition.visual_color,
"NPC body color should come from its profession definition"
(
body.material_override is ShaderMaterial
and (
body.material_override.get_shader_parameter("coat_color")
== profession_definition.visual_color
)
),
"NPC cel material should retain its authoritative profession color"
)
_check(
(
body.mesh is CylinderMesh
body.mesh is ArrayMesh
and visual.has_node("Head")
and visual.has_node("ArmLeft")
and visual.has_node("LegRight/Foot")
and visual.get_node("Tail").mesh is ArrayMesh
),
"NPC presentation should use a readable multi-part villager silhouette"
"NPC presentation should use the Blender animal body and tail"
)
var original_species: StringName = visual.get_meta("animal_species")
_check(
visual.get_node("TaskGlyphRoot").position.y >= 2.9,
"Task cues must sit above the animal cast's tall ears"
)
_check(
(
@@ -184,6 +195,10 @@ func _run() -> void:
_check(view.reload_npc_visual(npc.id), "Visual should reload")
var reloaded: Node3D = view.active_npc_visuals[npc.id]
reloaded.set_physics_process(false)
_check(
reloaded.get_meta("animal_species") == original_species,
"Reload must derive the same animal identity without saved appearance or RNG"
)
_check(
reloaded.global_position.is_equal_approx(authoritative_position),
"Reloaded visual should use authoritative position"