diff --git a/docs/BUILD_IN_PUBLIC_PLAN.md b/docs/BUILD_IN_PUBLIC_PLAN.md index d3ba456..ce25514 100644 --- a/docs/BUILD_IN_PUBLIC_PLAN.md +++ b/docs/BUILD_IN_PUBLIC_PLAN.md @@ -640,10 +640,13 @@ Completed: 13. Runtime first-read staging: the capture tool uses an explicit presentation camera preset, the gameplay camera supports the same staging API, and the village has authored dirt path strips for the current task loop. +14. Landmark and work-site silhouettes: the ridge landmark, pantry, guard post, + study desk, and rest bench now have compact presentation props that remain + readable in the runtime cinematic frame. Next: -1. Strengthen landmark and work-site silhouettes without adding new simulation +1. Strengthen water and foreground silhouettes without adding new simulation mechanics. Do not start with GIS data, a full city, a large asset pack, or more NPC diff --git a/docs/LEARNING_ROADMAP.md b/docs/LEARNING_ROADMAP.md index 9baba4d..f2aa6d1 100644 --- a/docs/LEARNING_ROADMAP.md +++ b/docs/LEARNING_ROADMAP.md @@ -687,6 +687,8 @@ Recently completed: leaving the simulation task state authoritative. - Runtime first-read staging now includes a presentation camera preset and authored path strips that reveal the active village task loop. +- Landmark and work-site silhouette props make the ridge landmark, pantry, + guard, study, and rest sites easier to identify without debug labels. This order strengthens the simulation while regularly producing visible progress suitable for public development updates. diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 88865f9..9908a1d 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -333,6 +333,8 @@ distance with resource `safety_risk`, `comfort_distance`, and - deterministic shaped terrain data and six game-owned surface layers; - fortress, houses, mill, bridge, shader river/waterfall, mist, and smoke; - authored dirt path strips that make the current village task loop readable; +- compact silhouette props for the ridge landmark, pantry, guard, study, and + rest sites; - warm sky, fog, shadows, and wind-reactive foliage; - eight ResourceNodes preserving stable food/wood discovery IDs; - typed village pantry storage and typed guard, study, and rest activity sites; diff --git a/docs/baselines/SIMULATION_GARDEN_01.md b/docs/baselines/SIMULATION_GARDEN_01.md index 88718f0..15142a6 100644 --- a/docs/baselines/SIMULATION_GARDEN_01.md +++ b/docs/baselines/SIMULATION_GARDEN_01.md @@ -32,6 +32,9 @@ state. A follow-up pass adds small task glyphs above active NPCs, so the cinematic view now preserves task intent after the debug labels are hidden. A camera-staging pass then gives the runtime capture a wider village view and adds authored dirt path strips that make the task loop readable from the first frame. +The next presentation pass adds compact silhouette props to the ridge landmark, +pantry, guard, study, and rest sites so work locations remain identifiable in +cinematic mode. The frame also makes the next presentation risks plain: @@ -41,9 +44,9 @@ The frame also makes the next presentation risks plain: - terrain texture variation and path strips read better than the old flat map, but landmarks, water, and foreground silhouettes need stronger first-read staging; -- task glyphs help, but the cinematic view still needs clearer work-site props - and route composition so intent is readable before the viewer learns the icon - language. +- task glyphs and work-site props help, but the cinematic view still needs + richer water/foreground shapes and stronger authored silhouettes before it + becomes a strong public-facing shot. Use this baseline as the first runtime comparison image before adding more systems or expanding the terrain. diff --git a/docs/baselines/simulation_garden_01_cinematic.png b/docs/baselines/simulation_garden_01_cinematic.png index c605fda..63a451a 100644 Binary files a/docs/baselines/simulation_garden_01_cinematic.png and b/docs/baselines/simulation_garden_01_cinematic.png differ diff --git a/docs/baselines/simulation_garden_01_debug.png b/docs/baselines/simulation_garden_01_debug.png index 2ff02f8..c2e7c44 100644 Binary files a/docs/baselines/simulation_garden_01_debug.png and b/docs/baselines/simulation_garden_01_debug.png differ diff --git a/tests/jajce_runtime_integration_test.gd b/tests/jajce_runtime_integration_test.gd index 5202b0c..a4c17dd 100644 --- a/tests/jajce_runtime_integration_test.gd +++ b/tests/jajce_runtime_integration_test.gd @@ -64,6 +64,26 @@ func _run() -> void: if child.name.begins_with("Path_"): path_strips += 1 _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" + ) + _check( + main_scene.has_node("JajceWorld/WorldObjects/StorageSites/VillagePantry/PantrySign"), + "Pantry storage should have a readable work-site silhouette" + ) + _check( + main_scene.has_node("JajceWorld/WorldObjects/ActivitySites/GuardPost/GuardPennant"), + "Guard site should have a readable work-site silhouette" + ) + _check( + main_scene.has_node("JajceWorld/WorldObjects/ActivitySites/StudyDesk/OpenBook_A"), + "Study site should have readable study props" + ) + _check( + main_scene.has_node("JajceWorld/WorldObjects/ActivitySites/RestBench/RestCanopy"), + "Rest site should have a readable rest silhouette" + ) var navigation_map: RID = main_scene.get_world_3d().navigation_map var navigation_region := main_scene.get_node("JajceWorld/NavigationRegion3D") as NavigationRegion3D diff --git a/world/jajce/JajceWorld.tscn b/world/jajce/JajceWorld.tscn index 6c760ca..5e84d2f 100644 --- a/world/jajce/JajceWorld.tscn +++ b/world/jajce/JajceWorld.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=29 format=3] +[gd_scene load_steps=39 format=3] [ext_resource type="Terrain3DAssets" path="res://terrain/jajce/assets.tres" id="1_assets"] [ext_resource type="PackedScene" path="res://world/resource_nodes/ResourceNode.tscn" id="2_resource"] @@ -53,6 +53,48 @@ roughness = 0.95 material = SubResource("Material_path_readability") size = Vector3(1, 0.06, 1) +[sub_resource type="StandardMaterial3D" id="Material_landmark_banner"] +albedo_color = Color(0.68, 0.12, 0.1, 1) +roughness = 0.72 + +[sub_resource type="StandardMaterial3D" id="Material_site_canvas"] +albedo_color = Color(0.82, 0.68, 0.38, 1) +roughness = 0.88 + +[sub_resource type="StandardMaterial3D" id="Material_site_dark_wood"] +albedo_color = Color(0.24, 0.13, 0.07, 1) +roughness = 0.82 + +[sub_resource type="StandardMaterial3D" id="Material_site_book"] +albedo_color = Color(0.37, 0.18, 0.62, 1) +roughness = 0.74 + +[sub_resource type="BoxMesh" id="Mesh_landmark_banner"] +material = SubResource("Material_landmark_banner") +size = Vector3(0.12, 1.7, 1.0) + +[sub_resource type="CylinderMesh" id="Mesh_site_pole"] +material = SubResource("Material_site_dark_wood") +top_radius = 0.06 +bottom_radius = 0.07 +height = 2.2 + +[sub_resource type="BoxMesh" id="Mesh_site_sign"] +material = SubResource("Material_site_canvas") +size = Vector3(1.0, 0.08, 0.5) + +[sub_resource type="BoxMesh" id="Mesh_site_sack"] +material = SubResource("Material_site_canvas") +size = Vector3(0.5, 0.62, 0.42) + +[sub_resource type="BoxMesh" id="Mesh_study_book"] +material = SubResource("Material_site_book") +size = Vector3(0.42, 0.08, 0.3) + +[sub_resource type="BoxMesh" id="Mesh_rest_canopy"] +material = SubResource("Material_site_canvas") +size = Vector3(2.9, 0.08, 1.4) + [sub_resource type="ProceduralSkyMaterial" id="SkyMaterial_jajce"] sky_top_color = Color(0.23, 0.43, 0.62, 1) sky_horizon_color = Color(0.82, 0.68, 0.5, 1) @@ -144,6 +186,14 @@ position = Vector3(-25, 7, 9) [node name="Keep" parent="FortressBlockout" instance=ExtResource("5_fortress")] +[node name="RidgeBannerPole" type="MeshInstance3D" parent="FortressBlockout/Keep"] +position = Vector3(2.2, 8.6, 2.8) +mesh = SubResource("Mesh_site_pole") + +[node name="RidgeBanner" type="MeshInstance3D" parent="FortressBlockout/Keep"] +position = Vector3(2.2, 8.95, 3.35) +mesh = SubResource("Mesh_landmark_banner") + [node name="WaterRoot" type="Node3D" parent="."] [node name="RiverSurface" parent="WaterRoot" instance=ExtResource("9_water")] @@ -369,6 +419,25 @@ discovery_priority = 0.75 [node name="VillagePantry" parent="WorldObjects/StorageSites" instance=ExtResource("14_storage")] position = Vector3(0, 0, -8) +[node name="PantrySignPole" type="MeshInstance3D" parent="WorldObjects/StorageSites/VillagePantry"] +position = Vector3(-1.05, 1.1, 1.25) +mesh = SubResource("Mesh_site_pole") + +[node name="PantrySign" type="MeshInstance3D" parent="WorldObjects/StorageSites/VillagePantry"] +position = Vector3(-1.05, 1.85, 1.25) +rotation_degrees = Vector3(0, 90, 0) +mesh = SubResource("Mesh_site_sign") + +[node name="PantrySack_A" type="MeshInstance3D" parent="WorldObjects/StorageSites/VillagePantry"] +position = Vector3(-0.95, 0.3, -0.65) +scale = Vector3(0.65, 1.0, 0.65) +mesh = SubResource("Mesh_site_sack") + +[node name="PantrySack_B" type="MeshInstance3D" parent="WorldObjects/StorageSites/VillagePantry"] +position = Vector3(-1.35, 0.22, -0.25) +scale = Vector3(0.5, 0.75, 0.5) +mesh = SubResource("Mesh_site_sack") + [node name="ActivitySites" type="Node3D" parent="WorldObjects"] [node name="GuardPost" type="Node3D" parent="WorldObjects/ActivitySites"] @@ -383,6 +452,15 @@ capacity = 2 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.25, 0) mesh = SubResource("Mesh_guard_post") +[node name="GuardPennantPole" type="MeshInstance3D" parent="WorldObjects/ActivitySites/GuardPost"] +position = Vector3(0.45, 2.35, 0) +mesh = SubResource("Mesh_site_pole") + +[node name="GuardPennant" type="MeshInstance3D" parent="WorldObjects/ActivitySites/GuardPost"] +position = Vector3(0.45, 2.85, 0.48) +scale = Vector3(0.8, 0.55, 0.65) +mesh = SubResource("Mesh_landmark_banner") + [node name="InteractionPoint" type="Marker3D" parent="WorldObjects/ActivitySites/GuardPost"] [node name="DebugLabel" type="Label3D" parent="WorldObjects/ActivitySites/GuardPost"] @@ -405,6 +483,16 @@ display_name = "Study Desk" transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.125, 0) mesh = SubResource("Mesh_study_desk") +[node name="OpenBook_A" type="MeshInstance3D" parent="WorldObjects/ActivitySites/StudyDesk"] +position = Vector3(-0.25, 0.32, 0) +rotation_degrees = Vector3(0, 14, 0) +mesh = SubResource("Mesh_study_book") + +[node name="OpenBook_B" type="MeshInstance3D" parent="WorldObjects/ActivitySites/StudyDesk"] +position = Vector3(0.22, 0.32, 0.04) +rotation_degrees = Vector3(0, -14, 0) +mesh = SubResource("Mesh_study_book") + [node name="InteractionPoint" type="Marker3D" parent="WorldObjects/ActivitySites/StudyDesk"] [node name="DebugLabel" type="Label3D" parent="WorldObjects/ActivitySites/StudyDesk"] @@ -428,6 +516,21 @@ capacity = 2 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.15, 0) mesh = SubResource("Mesh_rest_bench") +[node name="RestCanopy" type="MeshInstance3D" parent="WorldObjects/ActivitySites/RestBench"] +position = Vector3(0, 1.35, 0) +rotation_degrees = Vector3(0, 0, -6) +mesh = SubResource("Mesh_rest_canopy") + +[node name="RestCanopyPost_A" type="MeshInstance3D" parent="WorldObjects/ActivitySites/RestBench"] +position = Vector3(-1.25, 0.72, -0.52) +scale = Vector3(0.8, 0.8, 0.8) +mesh = SubResource("Mesh_site_pole") + +[node name="RestCanopyPost_B" type="MeshInstance3D" parent="WorldObjects/ActivitySites/RestBench"] +position = Vector3(1.25, 0.72, 0.52) +scale = Vector3(0.8, 0.8, 0.8) +mesh = SubResource("Mesh_site_pole") + [node name="InteractionPoint" type="Marker3D" parent="WorldObjects/ActivitySites/RestBench"] [node name="DebugLabel" type="Label3D" parent="WorldObjects/ActivitySites/RestBench"]