feat: add scattered discoverable resources

This commit is contained in:
2026-07-07 15:38:31 +02:00
parent 036c9d5141
commit 72d1cfc15d
7 changed files with 66 additions and 17 deletions
+4 -4
View File
@@ -41,8 +41,8 @@ Do not redo these tasks:
- hunger, energy, starvation, death, task scoring, and task duration;
- task-change and village-change signals;
- visual NPC navigation and arrival reporting;
- finite berry/tree ResourceNodes plus typed food, guard, study, and rest
world sites;
- finite berry/tree/animal-camp ResourceNodes plus typed food, guard, study,
and rest world sites;
- aggregate village UI;
- initial tree assets;
- a baked navigation region for the current flat test area.
@@ -436,7 +436,7 @@ Do not move simulation ownership into `JajceWorld` to make wiring convenient.
**Status: runtime integration complete.** `main.tscn` now instances the reusable
world and points player/simulation adapters at its stable-ID resources, storage
site, and activity sites. The duplicate flat world objects were removed.
The runtime regression checks Terrain3D presence, 24 navigation routes, core
The runtime regression checks Terrain3D presence, 36 navigation routes, core
task execution, starvation/death, player extraction parity, reservations, and
NPC visual lifecycle. Terrain sculpting and presentation polish remain
separate work, not blockers for this wiring milestone.
@@ -599,7 +599,7 @@ The adjusted first milestone is complete when:
The follow-up milestone is complete when:
- `JajceWorld` is instanced in `main.tscn`;
- food and wood ResourceNodes work in the terrain;
- scattered food and wood ResourceNodes work in the terrain;
- remaining legacy task markers are reconnected;
- player movement and all existing interactions work;
- all three current NPCs navigate, work, eat, rest, starve, and die correctly;
+3 -3
View File
@@ -655,9 +655,9 @@ The practical next sequence is:
1. Add a cinematic/debug toggle and repeatable simulation-garden demo reset.
2. Expand resource discovery with many finite `ResourceNode` instances placed
in meaningful foliage, animal-camp, berry, and village-stockpile contexts.
The first distance/safety/comfort scoring pass exists; next, add more
authored resources and validate their navigation/reachability rather than
reintroducing abstract resource zones.
The first distance/safety/comfort scoring pass and small authored resource
spread exist; next, validate placement rules and grow the authored set
carefully rather than reintroducing abstract resource zones.
3. Expand persistence only when schedules, player state, or a real save menu
creates a concrete requirement.
+1 -1
View File
@@ -325,7 +325,7 @@ 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;
- warm sky, fog, shadows, and wind-reactive foliage;
- four ResourceNodes preserving the flat-map stable IDs;
- eight ResourceNodes preserving stable food/wood discovery IDs;
- typed village pantry storage and typed guard, study, and rest activity sites;
- a temporary baked navigation loop with 24 tested routes;
- a look-development scene and camera.
+2 -2
View File
@@ -13,9 +13,9 @@ same contract now runs against the integrated `JajceWorld` runtime.
The automated baseline verifies:
- the scene creates six simulated NPCs;
- four stable-ID ResourceNodes register;
- eight stable-ID ResourceNodes register;
- three fixed origins can reach the typed pantry, three typed activity sites,
and four ResourceNode interaction points (24 route checks);
and eight ResourceNode interaction points (36 route checks);
- a two-tick working task completes;
- starvation still reaches death at its configured threshold.
+4 -4
View File
@@ -36,10 +36,10 @@ 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() == 4, "Runtime should contain four Jajce ResourceNodes")
_check(resource_root.get_child_count() == 8, "Runtime should contain eight Jajce ResourceNodes")
_check(
simulation_manager.resource_states.size() == 4,
"Simulation authority should bind all four Jajce resources"
simulation_manager.resource_states.size() == 8,
"Simulation authority should bind all eight Jajce resources"
)
var navigation_map: RID = main_scene.get_world_3d().navigation_map
@@ -102,7 +102,7 @@ func _run() -> void:
)
if failures.is_empty():
print("[TEST] Jajce runtime passed: 6 NPCs, typed storage and activity sites")
print("[TEST] Jajce runtime passed: 6 NPCs, 8 resources, typed sites")
quit(0)
return
+13 -3
View File
@@ -113,8 +113,18 @@ func _run() -> void:
ids.append(String((resource as ResourceNode).node_id))
ids.sort()
_check(
ids == ["berry_bush_01", "berry_bush_02", "tree_01", "tree_02"],
"Jajce resources should preserve all stable IDs"
ids
== [
"animal_camp_01",
"berry_bush_01",
"berry_bush_02",
"berry_patch_river_01",
"tree_01",
"tree_02",
"tree_north_outskirts_01",
"tree_south_edge_01"
],
"Jajce resources should preserve all stable and discoverable IDs"
)
var metadata_valid := true
for resource in resources:
@@ -218,7 +228,7 @@ func _run() -> void:
if failures.is_empty():
print(
"[TEST] Jajce scaffold passed: Terrain3D, storage/activity sites, shader water"
"[TEST] Jajce scaffold passed: Terrain3D, scattered resources, typed sites"
)
quit(0)
return
+39
View File
@@ -237,6 +237,24 @@ safety_risk = 0.08
comfort_distance = 20.0
discovery_priority = 0.5
[node name="BerryPatch_River_01" parent="WorldObjects/ResourceNodes" instance=ExtResource("2_resource")]
position = Vector3(12, 0, 10)
node_id = &"berry_patch_river_01"
initial_amount = 6.0
yield_per_action = 1.5
safety_risk = 0.18
comfort_distance = 22.0
discovery_priority = 0.25
[node name="AnimalCamp_01" parent="WorldObjects/ResourceNodes" instance=ExtResource("2_resource")]
position = Vector3(-12, 0, 8)
node_id = &"animal_camp_01"
initial_amount = 5.0
yield_per_action = 1.0
safety_risk = 0.35
comfort_distance = 24.0
discovery_priority = -0.5
[node name="Tree_01" parent="WorldObjects/ResourceNodes" instance=ExtResource("2_resource")]
position = Vector3(6, 0, -8)
node_id = &"tree_01"
@@ -257,6 +275,27 @@ yield_per_action = 3.0
safety_risk = 0.16
comfort_distance = 26.0
[node name="Tree_North_Outskirts_01" parent="WorldObjects/ResourceNodes" instance=ExtResource("2_resource")]
position = Vector3(6, 0, 12)
node_id = &"tree_north_outskirts_01"
action_id = &"gather_wood"
resource_id = &"wood"
initial_amount = 10.0
yield_per_action = 2.0
safety_risk = 0.2
comfort_distance = 28.0
discovery_priority = 0.25
[node name="Tree_South_Edge_01" parent="WorldObjects/ResourceNodes" instance=ExtResource("2_resource")]
position = Vector3(-12, 0, -12)
node_id = &"tree_south_edge_01"
action_id = &"gather_wood"
resource_id = &"wood"
initial_amount = 9.0
yield_per_action = 2.0
safety_risk = 0.24
comfort_distance = 26.0
[node name="StorageSites" type="Node3D" parent="WorldObjects"]
[node name="VillagePantry" parent="WorldObjects/StorageSites" instance=ExtResource("14_storage")]