feat: scale village queries and enrich Jajce center
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Simulation scaling baseline 02
|
||||
|
||||
This is the reviewed comparison after introducing one reusable per-tick
|
||||
`SimulationPopulationView`. The view indexes all, living, and starving NPCs by
|
||||
stable ID, is refreshed as each NPC advances, and is shared by relationship and
|
||||
action-selection queries. It is transient derived state and is not serialized.
|
||||
|
||||
The machine-readable samples are in
|
||||
[`simulation_scaling_baseline_02.json`](simulation_scaling_baseline_02.json).
|
||||
The workload, seed, host, exclusions, warmup, and three-sample median contract
|
||||
match [baseline 01](SIMULATION_SCALING_BASELINE_01.md).
|
||||
|
||||
## Results
|
||||
|
||||
| Case | NPCs | Seeded history | Median us/tick | Ticks/s | Simulated realtime | Arrival share | End JSON |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
||||
| Population 6 | 6 | 0 | 63.85 | 15,662.93 | 18,795.5x | 4.5% | 0.06 MiB |
|
||||
| Population 60 | 60 | 0 | 662.62 | 1,509.17 | 1,811.0x | 5.7% | 0.56 MiB |
|
||||
| Population 600 | 600 | 0 | 11,654.10 | 85.81 | 103.0x | 18.0% | 5.67 MiB |
|
||||
| History 600 | 60 | 600 | 722.60 | 1,383.90 | 1,660.7x | 5.2% | 0.71 MiB |
|
||||
| History 6,000 | 60 | 6,000 | 1,430.65 | 698.98 | 838.8x | 2.6% | 2.04 MiB |
|
||||
|
||||
All samples within each case were deterministic. More importantly, every final
|
||||
checksum exactly matches the corresponding baseline-01 checksum, so the
|
||||
optimization preserves selection, interleaved NPC updates, event growth, and
|
||||
serialized continuation state.
|
||||
|
||||
## Comparison
|
||||
|
||||
| Case | Baseline 01 us/tick | Baseline 02 us/tick | Change |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| Population 6 | 55.74 | 63.85 | 14.6% slower |
|
||||
| Population 60 | 621.87 | 662.62 | 6.6% slower |
|
||||
| Population 600 | 15,187.74 | 11,654.10 | **23.3% faster** |
|
||||
| History 600 | 677.12 | 722.60 | 6.7% slower |
|
||||
| History 6,000 | 1,421.19 | 1,430.65 | 0.7% slower |
|
||||
|
||||
The shared dictionaries add a small fixed per-tick cost, visible in tiny
|
||||
fixtures and normal local timing noise. At the measured population knee they
|
||||
remove repeated all-NPC lookup construction and improve the 600-NPC case from
|
||||
65.84 to 85.81 ticks per second. The local 50-ticks-per-second reference target
|
||||
remains comfortably met without introducing simulation LOD.
|
||||
|
||||
## Decision and next measurement
|
||||
|
||||
Keep the population view. It has a real relationship/action consumer, improves
|
||||
the measured pressure point, and preserves exact state. Do not add batching or
|
||||
active/abstract NPC modes merely to improve this data-only number.
|
||||
|
||||
The next bounded scale slice should support the world vision directly: a
|
||||
loaded-resource spatial query owned by `ActiveWorldAdapter`. It should let
|
||||
villagers discover finite, stable-ID `ResourceNode` anchors placed much farther
|
||||
apart across Terrain3D while preserving the current score, reachability,
|
||||
reservation, and save/rebind contracts. A benchmark should compare 18, 180,
|
||||
and 1,800 loaded candidates before choosing a grid, tree, or other index.
|
||||
|
||||
Terrain3D-instanced visual trees and grass are not automatically authoritative
|
||||
resources. Intentional harvest anchors must continue to bind simulation-owned
|
||||
`ResourceStateRecord` data by stable ID; large decorative populations can stay
|
||||
presentation-only until a gameplay rule needs them.
|
||||
|
||||
## Capture command
|
||||
|
||||
```bash
|
||||
/Applications/Godot.app/Contents/MacOS/Godot \
|
||||
--headless --path "$PWD" \
|
||||
--script res://tools/benchmark_simulation_scaling.gd -- \
|
||||
--host-label=Apple_M1_Max_64_GB \
|
||||
--output=res://docs/benchmarks/simulation_scaling_baseline_02.json
|
||||
```
|
||||
Reference in New Issue
Block a user