# Loaded Resource Discovery 01 ## Question Can villagers resolve finite resource anchors spread across a larger Terrain3D world without scanning every loaded `ResourceNode`, while selecting exactly the same target as the existing distance/risk/comfort/priority score? ## Reviewed workload - Godot: `4.7-stable (official)`; - host: Apple M1 Max, 64 GB; - benchmark seed: `17331`; - loaded resources: 18, 180, and 1,800; - 400 deterministic target resolutions per sample; - seven fresh timing samples per case; - 20 m horizontal source spacing with varied terrain-like height, safety risk, comfort distance, discovery priority, and deterministic disabled sources; - each query performs the real availability check, score, reservation, and release through `ActionTargetResolver` and `ResourceStateRecord`. The linear reference reproduces the previous `ResourceNode.get_all()` scan. The spatial path uses the production `ActiveWorldAdapter` and its 24 m resource-specific horizontal grid. Fixture construction, rendering, navigation pathfinding, simulation ticks, and serialization are excluded. ## Results | Loaded anchors | Linear µs/query | Spatial µs/query | Speedup | Average inspected | Reduction | | ---: | ---: | ---: | ---: | ---: | ---: | | 18 | 65.04 | 33.26 | 1.96x | 18 → 3.705 | 79.42% | | 180 | 589.03 | 38.83 | 15.17x | 180 → 4.375 | 97.57% | | 1,800 | 6,448.00 | 46.94 | 137.37x | 1,800 → 4.445 | 99.75% | Every spatial sample produced the same selected-target checksum as its linear reference. The raw samples are in [`loaded_resource_discovery_01.json`](loaded_resource_discovery_01.json). These are local workload measurements, not portable performance promises. The important shape is that ordinary local queries remain near four inspected anchors while the loaded set grows by 100x. ## Exactness contract `ActionTargetResolver` queries successively larger grid radii. It may stop only when the best possible score of every farther anchor is strictly worse than the current winner. The lower bound uses the loaded action's authoritative maximum comfort distance, minimum safety risk, and maximum discovery priority. Stable registration order preserves the former first-loaded tie behavior. Unavailable, depleted, and reserved state remains authoritative in `ResourceStateRecord`; the grid indexes only loaded IDs, interaction positions, and disposable score bounds. Unloading removes an anchor without deleting its state. Rebinding the same ID or moving a loaded anchor refreshes the index. One focused regression also gives the farthest test source an extreme priority. The query expands beyond its local cells and selects that source exactly as the linear scan does, proving that the common local fast path is not a hard range cutoff. ## Decision Keep the resource-specific grid inside `ActiveWorldAdapter`. It has one real consumer, preserves current gameplay, and directly supports larger authored source fields. Do not generalize it into a people/building/event index or a simulation-LOD framework yet. Terrain3D foliage instances remain decorative unless an intentional stable-ID `ResourceNode` anchor binds simulation-owned state. A later placement workflow can author those anchors alongside visual instancing without making every tree an authoritative resource. ## Capture command ```bash /Applications/Godot.app/Contents/MacOS/Godot \ --headless --path "$PWD" \ --script res://tools/benchmark_loaded_resource_discovery.gd -- \ --queries=400 --samples=7 \ --host-label=Apple_M1_Max_64_GB \ --output=res://docs/benchmarks/loaded_resource_discovery_01.json ```