feat: score resource discovery by comfort and safety
This commit is contained in:
@@ -10,7 +10,7 @@ class FakeActiveWorld:
|
||||
func get_resource_candidates(_action_id: StringName) -> Array[Dictionary]:
|
||||
return resource_candidates
|
||||
|
||||
func get_activity_target(_action_id: StringName) -> Dictionary:
|
||||
func get_activity_target(_action_id: StringName, _origin: Vector3 = Vector3.ZERO) -> Dictionary:
|
||||
return {"target_id": "", "position": activity_position}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ func _test_selection_and_execution_are_separate() -> void:
|
||||
func _test_target_resolution_and_travel_are_separate() -> void:
|
||||
var adapter := FakeActiveWorld.new()
|
||||
adapter.resource_candidates = [
|
||||
{"target_id": "boundary_risky_bush", "position": Vector3(1.0, 0.0, 0.0)},
|
||||
{"target_id": "boundary_bush", "position": Vector3(3.0, 0.0, 2.0)}
|
||||
]
|
||||
root.add_child(adapter)
|
||||
@@ -91,20 +92,42 @@ func _test_target_resolution_and_travel_are_separate() -> void:
|
||||
"reserved_by": -1,
|
||||
"enabled": true,
|
||||
"can_npcs_use": true,
|
||||
"can_player_use": true
|
||||
"can_player_use": true,
|
||||
"safety_risk": 0.0,
|
||||
"comfort_distance": 18.0,
|
||||
"discovery_priority": 0.0
|
||||
}
|
||||
)
|
||||
manager.resource_states[resource_state.get_node_id()] = resource_state
|
||||
var risky_resource_state := ResourceStateRecord.from_dictionary(
|
||||
{
|
||||
"schema_version": ResourceStateRecord.SCHEMA_VERSION,
|
||||
"node_id": "boundary_risky_bush",
|
||||
"action_id": String(SimulationIds.ACTION_GATHER_FOOD),
|
||||
"resource_id": String(SimulationIds.RESOURCE_FOOD),
|
||||
"amount_remaining": 5.0,
|
||||
"yield_per_action": 1.0,
|
||||
"reserved_by": -1,
|
||||
"enabled": true,
|
||||
"can_npcs_use": true,
|
||||
"can_player_use": true,
|
||||
"safety_risk": 1.0,
|
||||
"comfort_distance": 18.0,
|
||||
"discovery_priority": 0.0
|
||||
}
|
||||
)
|
||||
manager.resource_states[risky_resource_state.get_node_id()] = risky_resource_state
|
||||
|
||||
var npc: SimNPC = manager.npcs[0]
|
||||
npc.energy = 40.0
|
||||
npc.set_task(SimulationIds.ACTION_GATHER_FOOD)
|
||||
_check(
|
||||
manager.resolve_npc_target(npc.id, Vector3.ZERO),
|
||||
"Target resolver should resolve a resource from adapter facts"
|
||||
"Target resolver should resolve a scored resource from adapter facts"
|
||||
)
|
||||
_check(
|
||||
npc.target_id == &"boundary_bush" and resource_state.get_reserved_by() == npc.id,
|
||||
"Target resolver should authoritatively assign and reserve the target"
|
||||
"Target resolver should prefer the safer comfortable resource over risky proximity"
|
||||
)
|
||||
_check(
|
||||
travel_requests == [Vector3(3.0, 0.0, 2.0)],
|
||||
|
||||
@@ -27,7 +27,10 @@ func _run() -> void:
|
||||
"reserved_by": -1,
|
||||
"enabled": true,
|
||||
"can_npcs_use": true,
|
||||
"can_player_use": true
|
||||
"can_player_use": true,
|
||||
"safety_risk": 0.0,
|
||||
"comfort_distance": 18.0,
|
||||
"discovery_priority": 0.0
|
||||
}
|
||||
)
|
||||
manager.resource_states[resource.get_node_id()] = resource
|
||||
|
||||
@@ -116,6 +116,16 @@ func _run() -> void:
|
||||
ids == ["berry_bush_01", "berry_bush_02", "tree_01", "tree_02"],
|
||||
"Jajce resources should preserve all stable IDs"
|
||||
)
|
||||
var metadata_valid := true
|
||||
for resource in resources:
|
||||
var node := resource as ResourceNode
|
||||
metadata_valid = (
|
||||
metadata_valid
|
||||
and node.comfort_distance > 0.0
|
||||
and node.safety_risk >= 0.0
|
||||
and node.safety_risk <= 1.0
|
||||
)
|
||||
_check(metadata_valid, "Jajce resources should define discovery metadata")
|
||||
_check(world.has_node("WorldObjects/StorageSites"), "JajceWorld should expose StorageSites")
|
||||
var pantry := world.get_node("WorldObjects/StorageSites/VillagePantry") as StorageNode
|
||||
_check(pantry != null, "JajceWorld should include a typed VillagePantry StorageNode")
|
||||
|
||||
@@ -156,6 +156,11 @@ func _test_legacy_resource_migration() -> void:
|
||||
is_equal_approx(migrated.get_amount_remaining(), 6.0) and migrated.get_reserved_by() == 12,
|
||||
"Resource migration should preserve mutable authority"
|
||||
)
|
||||
_check(
|
||||
is_equal_approx(migrated.get_safety_risk(), 0.0)
|
||||
and is_equal_approx(migrated.get_comfort_distance(), 18.0),
|
||||
"Resource migration should default discovery metadata"
|
||||
)
|
||||
|
||||
|
||||
func _test_legacy_npc_migration() -> void:
|
||||
|
||||
Reference in New Issue
Block a user