Examples & benchmarks
Playable scenes in examples/ and the headless benchmark harness in tests/bench/ are integration references for the ECS.
Running
godot --headless --path . res://examples/SpriteSwarm2D.tscn
godot --headless --path . res://examples/VerifyDemos.tscn
godot --headless --path . res://tests/bench/BenchRunner.tscn -- --bench=all --n=50000 --frames=600
godot --headless --path . res://tests/unit/UnitRunner.tscnThe benchmark runner warms up (120 frames by default) and records avg/p50/p95/min/max, FPS and per-frame GC delta to CSV under user://bench/.
Benchmark status: read the numbers correctly
The currently published measurements are mostly Debug headless with the dummy renderer. Release measurements are limited (for example, selected physics measurements via configuration/DLL swap). There is not yet a full Release export with a visible scene behind every render benchmark.
Consequently, dummy-driver render timings measure managed ECS/upload preparation, not real GPU/driver cost. They must not be presented as proof of final on-screen FPS or draw-call performance.
The old rule "always measure in Release" has been replaced by this distinction: use Release for production gates whenever a valid Release run exists, and label Debug/headless/dummy-driver measurements explicitly as preliminary engineering signals.
Current benchmark filters
Use the filters exposed by the current runner rather than the older combined names. Current suites include:
integrate_scalar,integrate_simd,integrate_paralleljobs_scalar,jobs_pooled,jobs_dedicatedrender3d_sync,render3d_upload,render3d_fallbackrender2d_syncphysics_ecs,physics_arenaserialize_save,serialize_load
Consult docs/BENCHMARKS.md and docs/BENCHMARKS_RESULTS.md in the plugin repository for the exact command lines, environment and result tables.
Published gates
The gates below are engineering targets, not claims that every target has been met.
| Gate | Target | Current status |
|---|---|---|
| Integrate 100k | < 2 ms, parallel ≥ 4× scalar | Debug signal meets the target; Release confirmation is still required. |
| 50k 3D bulk render | > 60 FPS, draw calls = groups, sync < 1 ms | Not validated as a real GPU/driver Release gate. Dummy-driver numbers are logic-only and can invert node-vs-bulk ratios. |
| 50k 2D bulk render | > 60 FPS, one MultiMesh per texture | Current code performs one bulk MultimeshSetBuffer upload per group; final real-renderer gate still needs validation. |
| 10k node-vs-bulk | ≥ 10× slower node path | The 10k node control is excluded from the all headless queue because it is intentionally expensive; do not call this a measured 10× gate. |
| Physics 10k | broad+narrow < 1.5 ms | Not met. Current Release signal is about 11.7 ms in the dense stress case and 7.4–8.6 ms in the arena configuration. Deterministic parallelism is a major improvement, but the candidate-pair workload remains the bottleneck. |
| Serialize 100k | save/load < 200 ms, stable replay hash | Published Debug signal is comfortably under the time target; replay, round-trip and corrupt-stream tests pass. Release confirmation is still desirable. |
The physics optimization direction is pair-count reduction rather than blindly optimizing the per-pair kernel: relative-velocity culling was tried and reverted, while the SIMD sphere kernel showed no end-to-end improvement because the narrowphase is memory-bound.
Demo coverage
The demos cover bulk 2D/3D rendering, culling/LOD, hybrid ECS/Godot physics, arcade physics, snapshot round-trips and headless verification. VerifyDemos should be treated as an integration smoke test, not as a substitute for real Release/GPU benchmarks.