branchrust_reboot/main/parallel_validatemovecancel
124 Commits over 92 Days - 0.06cph!
Clean: minor changes to GamePhysics
- Renamed batch methods to be plural
- Split GamePhysics.CheckSphere<T> to separate OverlapSpheres
- added profiling scopes
Tests: unit tests
Update: move RemoveTerrainMask to GamePhysics
Tests: unit tests
Update: move GenerateCheckCapsuleQueries to GamePhyics and utilize
Tests: ran unit tests
Update: split GamePhysics.CheckCapsule<T>
- forbid CheckCapsule(batch) from returning ColliderHits - this is to better represent relationship to non-batched CheckCapsule
Tests: unit tests
▊ ██▌▋▉▌█ █▅▉▆▇▌█▅▄▋▊▅▄▋▌▆▌▋▄▆▉▉▋▅▅▊ ▅ ▊▆▋▄▄▊▅ ▆▋▋▅▆▍ ▋▌▊▊▌█▋ ▍▊▆▄▍█▉ ▌▍██▅▊▊ ▋▌▆▋▉ ▉▌█▄ ▉ ▊▉▅▉▋▌▅▇▋▌▆▄▄▋▄▊▄▇▇▇▆▄▉▆▍▍█▌▆ ▍▍ ▉▊▋▇█▆ ▄▅▅▆ ▄█▌ █▋▋▉▊▍█ █▅ ▊▆▊▄ ▌▉ ▋█▆▅▋▌ ▋▇ ▇▇▊▇▄▅▆ ▄▅▉▊▌▆▅▍▆▇▉█▇▍█ ▊▇▇█ ▇▊▄▍▊ ▍▋▇ █▅▄▉▇▆▌ ▊▄▅▇ ▄▇▉▉▄▌▆█
▇ ▇▊▍█▆▊█ ▋▄▆▇▋▉▊▇▅▄▆▋▅▆█▇█▋▄▊▋▆▉█▉▇ ▆ ▄▊▆▊▅▍▇ ▆▆▇▌█▋▇ ▍▄▇▊ ▉▍▄▍ ▇ █▊▆▍▋▉█▌▌█▆▉▋▌█▅▌▌▄▆▄▊▇▇▆▋▆▆▌▍▇ ▆▅▇▌▍▍▍▉▋▋▉ ▍▄█ ▋ ▆▅▌█▋▅ ▄▊▇▋ ▇▌▋ ▍▆▅▍▍▄▄█▇ ▄█▆▌ ▆▆██ ▊▇▌█ █▄ █▇▅▅▅█▄▄▊▄ ▆ ▊█▊▉▄▍█ ▇▍ ▄█▆▌▌▌▆▌▄▄▄▆▉ ▆▋▊▋ ▍▌▍▇▄ ▌ ▆▊▊▋ ▌▍▊▇█▄█▄
Update: adding GamePhysics.CheckCapsule(batch)
Last factored out func - should be able to complete refactor shortly
Tests: none, will integrate to tests next
Bugfix: fixing native allocation leaks in tests
Tests: ran the tests with leak detections enabled
Update: GamePhysics.CheckCapsule<T>(batch) internalized layermask handling
There's room for optims, but not going to pursue them for now - will test later how the perf deteriorates with the new APIs.
Tests: ran relevant unit tests
Update: GamePhysics.CheckSphere(batch) now able to handle mask validation internally
- Renamed GamePhysics.IgnoreCollision to MasksToValidate (prev name could be misleading and confusing)
- undid sphere command building as that wasn't meshing well with MasksToValidate flow
- Added UtrilityJobs.GatherJob<T> (will need to go through other code and clean up similar/same jobs)
I still need to update GamePhysics.CheckCapsule, and replace inlined code with new versions
Tests: all relevant unit tests
Clean: simplify NativeList.CopyFrom<T>(ReadOnly)
Tests: none, trivial change
Update: Rewrite GamePhysics.HandleIgnoreCollision(batch) to allow for explicit control of what exclusion volumes to check
Tests: ran updated test
Update: adding GamePhysics.HandleIgnoreWater
- comes with it's own consistency test
Going to use those to try to refactor some of the existing code and hopefully shrink it
Tests: ran new test
Tests: adding tests that generate various "HandleIgnoreCollision" scenarios
- added TestHandleIgnoreTerrainConsistency
Covers both TerrainCollisionTrigger and WaterVisibilityTrigger.
Tests: ran the new unit test, checked that all paths all covered.
Optim: GamePhysics.HandleIgnoreTerrain - replace const seting managed loop with a Burst job
Saves 0.1ms on 10k test
Tests: ran unit test
Optim: allocate smaller buffers for WaterCollision.GetIgnoreIndirect
- Added a couple profiling scopes
Tests: unit tests
Bugfix: when we're missing TerrainCollision or WaterCollision, run all of the physics checks for trigger volumes
- Added UtilityJobs namespace, moved FillJob<T> to it
- Added a utility extension to NativeList<T> to copy from NativeArray<T>.ReadOnly (surprised it's missing)
Tests: all relevant unit tests
Clean: remove GamePhysics.OverlapSphere(batch) and GamePhysics.OverlapCapsule(batch)
- These have been inlined into CheckSphere<T> and CheckCapsule<T>
- Also updated CoarseQueryGrid.CheckJobIndirect(capsule) (returns JobHandle, works on a NativeList) since I missed it in previous commit
Tests: ran all unit tests
Update: CoarseQueryGrid - add non-indirect CheckJob API
- Also changed the API to return a JobHandle and accept a NativeList
Helps avoid extra busy work when we run direct work
Tests: ran unit tests
Bugfix: prevent WaterCollision.GetIgnore from returning garbage values
Another case that's the same as previous
Tests: none, trivial change
Clean: move all CoarseQueryGridJobs to it's own namespace
- rename the jobs to avoid duplication with namespace
Tests: compiles in editor
Bugfix: make sure TerrainCollision.GetIgnore doesn't return garbage values
Same bug as in WaterCollision that I fixed last friday.
Tests: none, trivial change
Bugfix: WaterCollision.GetIgnoreIndirect properly fills entire result set
Tests: ran unit tests + staging demo playback
Tests: adding TestWaterIgnoreConsistency to further narrow down what is going wrong
Tests: ran new unit test, it does fail as begrudgingly expected
▇ ▋▊▇▍█▋ ▅▍▅▊▍▋ ▍██▅▍▉▊▋ ▅▋▌▆▉ ▋▉ ▅█▊▅▋▌ ▌█▌▆ ▉▆▌█▉▆▉ ▌▉▍▅ ▋▉▍▋ ▋▋▆▄▋▅█▋▅▄█▉ ▉▆▌▅▍▉ ▌█▇▋▇▉ █▇▇▄▋▇▇▍ ▊▇▄▅▉ █▄ ▅▄█▊▇ ▅▋▄▊▋▌ ▅▅▋▉█▍ ▇▋▊█▋▇▍ ▋▊▉▌▅▆ ▊▊▉█ ▊▇▌▅ ▍ █▊▆▋▆▍ ▆▆▅▅▍▄▋▋▋▊█▋▉▌ ▋▉▌▍█▄ ▅▉▊▄▅▉ ▋█ ▇▍▆▍ ▅▍▉█ ▇▋▅▅▍ ▌▋ ▌▆▊▇▇▆ ▌ ▋▇▇▆▋▊▉▅ ▍█▇▇█▌ █▉▉▉▆▆▅▅▋▆ ▅▇▋▌▌ ▉▅ █▅█▆ ▌▉▌▅▍▍▆▌ ▋▌▉█▍ █▊ ▄▌▄▍▋▊▉▄▅ █▌▋▆ █▆▌▅▍▉ ▉▍▋▇▇▇▍▆▄ █▉▌ ▌▇▅█ ▇█ ▅▋▊▆█ ▋▋ ▄▅▍█ █▍ █▉ ▇▌▋▇▉▊▊ ▋▇█ ▊▊▊▄ ▇▅▍▌▇▍▅▍▆█▄▊▆▅▍ ▌▉█▅▇███ ▅▌▌▉▍ ▆▋▌▅ ▄▄▌▌█▊▉ █▇▇▊▆▆▍▇█▌ █▍▅▉▆ ▉ ▌▊▋▄▉█▆▋█▊▍▉▆▇▅▇▍▍▊▄▄▌ ▆▌▌ █▅▅ ▋▌▋▊▌█▍▅ ▋▉▍▄▄
▇ ▍▉█▊▇█▉ ▅▊▊▍▍▍▇▄█▋▍▋▋█▌▌▍ ▋ ▍▇ ▋▍▅▄█▇▋█ ▌▊▉▅▅▄ █▊█▉▋▉▍▊▍▊▄▄▅ ▍▅▋█ ▌█▅▌ ▅▉ ▊▉▊▆ ▌▆ ▌▅▋ ▉▊▄ ▅█▇▄ ▇▇▄▄▉▄█▅▌▆▄ ▅▋▋▄▅▆ ▅▋▄▅ ▇▄█▄█▆█ █▌▄▇
▅ █▅▌▅▌▄▉ ▊▆▌▊▊▋▍▊█▆▉▄▅▉▋▊▋▄▊▌█▇ ▊ ▌▊▄▉ ▍▌█▉ ▇▍ ▊▉▇▄▄▊█▋▅▉▆▆▉▋▉▊▉▄▅▆▅▅▇▉▍▍▊ ▅▄▋▍▋▆▅ █ ▍█▉▋█ ▆▅ ▇▋█▉▄▆▄▆▇▇▇▄▋ ▉▆▋▅▄▄▆ ▋▇▉█ ▄█▇▊▆▄▆▋
Optim: FinalizeTickParallel - use a burst job to gather players to validate for tick history
- Cleaned up a bunch of code by switching to NativeList from NativeArray
- more TickInterpolatorCache usage
Tests: staging demo playback
▍ ▅▉▅▉▌█ ▉▊▆▍▇▅▉▇▊▄▇▇▍▄▉█▌ ▄ ▍▋▍▆▌▋▋ █▌▋▉▆▍▅▋ ▌█▍ █▌▍▍▆▍ ▄▉▊█▍ ▅▇▊▋ ▅▊▅▉▇ ▋▉▅▍▇▋▋▇▄▅▉ ▅▉▉ ▄▍▄▍ █▍ ▅▆ ▅▇█▊█▌ ▉▌█▊▆▅▅ ▌▋▄▉█▆▋▉ █▍▌▉▋▊▋ ▅▊▊▊▅ ▉▇▌█ ▊▇▌▌▆ ▊▍▍█▇▅▆▄ █▍▋█ ▋▊█▊▅ ▊▆▋ ▋▌▄▊▍▊█ ▌▉▍▅ ▇▌▆▋▍▍▄█
▇ ▊▄▄▇▉▆ ▄▄█▆█▋▍▌█▍▆▆▄▇▇▉▄▉▋█▌ ▌▌▌ ██▊▄▇ ▅▉▆▍▍▄▅ ▌▆▉▆▅█▇ ▄▇▌▍▅▍▄▄▉ ▊▄█ ▆▆▉▋▄▄ ▍ █▇▇▍▆▄▇ ▆▋ ▌▍█▆ ▇█▌▉▊█▉ ▄▇▅▄ ▊▌▉▌▍ ▇█▉▅ ▆▄▄▊█▉ ▌▌ ▋▇▅▊▅▌▄▋▇▍ ▅▉█▌▅▆▇ ▆▇ ▉█▆█▇█ ▆▍▇█▆▅ ▄▉▋ ▆▍▍▇ ▉▄█▅▉ ▇▆▍▋ ▇▌▋▆▅▅▇ ▇█ ▍▋▅ ▌▌▋▇▅▌▄▍ ▋▉▅▆▍▊▆ ▄▇ ▋▄▅█▉▊▉▊▍▍▌▆▇▋▄▆▆ ▊▆▋▋██▅ ▄▍▌ ▊▉▆ ▉▌▇▄▋▌▊ ▊▆▅▆▊▅ ▍▆▋▇▋▅▄▋ ▄ ▄▆▉▇▊▍█▊ ▌▌ ▅▋█▍▌▇▄▆▉▉█▄▉▅ ▆▉▍ ▆▉▄██▉ █▌ ▄▉█▆▋▅▊▇▇▉█▉▆▌▄▋ ▌▉▅ ▊▍▋█▄▅▍ ▆▄▌▇▊
▅ ▇█▇▋▉▊ ▄▄█▇▆▆▌▆█▊▆▄▍▇▇▆▆ ▋ ▉▉▌▊▇▍▇ ▆ █▆▄█▅▍█▌▌▉▍▄ ▉▉▄▊▇▄▋▄▇▉ ▋▄▆▊ ▅ ▍▋█▊▉▍▄▋▉▆▍█▇▊▅█▌▆▆ ▆▄▉▅▇ ▇▅ ▇▌ ▍█▍▆ █ ▋█▄█▌█▄█▋▉█▇▉██ ▆▄ ▍▋▍█ ▄█▊▄▇▇▊ ▅▋▄▆▊▍ ▉▅▄ ▄▍▌▆ ▋▆▄ ▊▍▋▋ ▍▊▌▉▅▇▄▊▄ █▇ ▉▄▇▇▍█▅▊▊▌▆▅▄▄ ▌▊▋▌ █▍▅▊▉ ▋█▌ ▉▅▇▍▌▅▊ ▊▇▌▌ ▇▆▉█▇▅▍▊
▋ ▉▋▋▌▊▍ ▍▅▌▆▆▆▉█▉▋▉▆▅▌▊█▍ █ ▇▉▆▍▌▇▉ █ ▌▍▆█▉ ▍▄ ▊▄▍▋▆▅▋ ▄█▌▊▌ ▉▆▋▄ ▅▌▆█▄ ▋▍▆▉▋▋▇▊▅▄▅ ▊▆█▋▋ ▋▊▇ ▊█▋ ▄▆█▍ ▆ ▅▌▅▊▆▉▄▍▄▊▅▉▇▇ █▆ ▌█▆▇ ▌▍▆▇▅▍▋ ▉▄▌▄▅▋▉ ▅▋▄ ▇▍▄▅ ▉▊▄▉ ▄▍ ▆▄▉▆▋▅▊▇▅▉▋ █▇▋█▍▆▉▍ ▌▋▆▋ ▅ █▉▆▅▆▇ ▆▌▄▄█ ▉█▊▆ ▄▄ ▆▍▅▇▍▊▆▋▊█▉▉▆▅▄▇ ▇▋▆▌ ▉▄▌▇ ▍▇▆▇
▌ ▉▌▄▅▋▇ ▇▄▊▊▍▉▊ ▉▍▉▄▌▉▉█▉▍▋█▍▊▆▅▄▄▊█▍▉█▍ ▄ █▊ ▇▆▋▇ ▅ ▍▌▋▊▊ ▆▅▌▇▇▍ ▌▇▊▌▊▅▌▉▊▇▄▋ ▄█▊▍█▍▆ ▆▋▊ ▊▉ ▅▌▊ ▉▌▌▌ ▅ ▊▉▉▊▇▊▍▆▇▆▊▌▌▄ ▋▅ ▄▆▋▌ ▅▄▆▆▊▅▊▋▉▇▋▋▉▍ ▄▉▍▍ ▊▋▍▄▍▉▄▋ ▊▄▅ ▉█▉▅ ▍▄▊▆
▇ ▄██▆▉▉ ▇▇██▌█▆▅▅▇▇▆▄▊▅▌▇ ▊ ▇▄▄▅█▍▆ ▋▍▆▉▅▍▆▍▋▆▊▆▋▌██▊▋▅▇▅▇▍▆ ▆ ▅▋ ▌██▅ ▌▉▆▄ ▉ ▍▉▍▇▅▆▆ ██▉▉▌▌▉██▇▉▄█ ▄▄▇▍▅▇█ ▆▄▋▋█ ▋▍▉ ▄▋▋ ▆▌▄▉ ▋ ▋▊▍▄▍▄▋▉▍▅▉▉ ▌▆ ▍▅▋▌ ▍▇▋▌▅▄▌▄▇▋▊▇▅█ █▇▉▇ ▆▇▉▆ ▇ ▆▋▆▆█▊▋ ▋▉▉ ▄▄▅▄▌█▌▅
▄ ▉▅▌▋▄▅▇ ▌▄▊█▅▍▋▊▆▍▍█▄▅▌▅█ ▉ ▋▊▌▋█▄▍▊▅▄▆▋▆▅▉▍▋▍▇▆ ▇▆█▅ ▋▍█▌▉▍▋▍▇ ▅▇▉█▄▉▉█▉▌▋█▉▋▋ ▌▅█ ▌▋▆▆█▅▋▄▉▊▄▅▅▆▆▇▄▋▄█▋▇▌▋ ▌▇ ▋▊▆▅ ▊▄ ▇█▌▆ ▅▍▌▇ ▋▍ ▄ ▍▇█▊█ ▅▅▊ ▍▌▋▋▉▍ █▇▄▇▄ ▌▇▍▄▋▊▇▍▆ ▄▌▊▊▋▇▌▇▇▊▇▉▄▉▊▅▊ ▋▇ ▇▊▉▌▍ ▊▅ ▊▍ ▇ ▋▄▄▆▌▊▄▅▄▍▅▄▄ ▄▇▄▉ ▋▌▆▌▄ ▍▄▊ ▉█▄▊▍▊▋ ▌▄▊▊ ▆▆▅▌▉▄▊▌
▍ ▄▌▊▊▊▅ ▋▆▇▆▋▆▍█▉▄▍▅▅ ▅ ▄▍▍ ▊▍▋▊▌ █▋█▇ ▌▍ ▋▆▍▆▊ ▆▌▅▊▄▊▉ ▌▊▆ ▇▌▇▍▋▌▅▌▄▋▍█▍▌▉▌█▇▍▊▇▄▋ █▌▇▌▆▌ ▍█▍▄▉▄▍ ▄▇▅ ▅▊ ▇▍▉ ▋▋▍▇▄▆ ▆▅▌▍ ▍ ▆▅▍▄ ▇▍ ▍▍▅▇▍ █▇ ▋▊▋▅ ▅▌▄▍▅▅▋▅█▉▅▊▋▆ ▄▄▊▌ ▋▅▆▌ ▅▋▇ ▌▅▋▇▉▊▇ █▄▍▄ ▍▍▅▍▅▍▍█
▄ ▅▆▊▅▇▌▅ ▊▌▇▅▇▅▋█ █▅█▉ ▄▄▉▊▊▋ ▇▌ ▄▇▆▇▋▇▊▅▊█▌▄█ ▌▆▋ ▍▍▋▌▊▆▆▇▄▉█▍▉▉▍█▄▍▅▇ ▊▍▇▍ █▊▋▄▇█▅ ▅▌▌▋▊▍█▅▋▄▍ ▇▆▌▋▉ ▅█▇▍█ ▋▌▅▍▉ ▌▇▄█▆▄▉█▇▅▋▋▇▉▉▋█▇▋▊▅▄▋▄▊ ▉▍█▊█ ▍▋▋▄▅▅▅ ▇▋▌▋▋▉▉
▄ ▉▌▆▆▊▍ ▅█▅▌▊▍▅▇▆▉▍█▋▌▉▆▍ █ █▊▊ █▊▉▌▍▇▍▄▄▄█▌▍▇▅▉▌▆▄▌█▍▄█▉▅▄█▇ ▌▋ ▌ ▄▆▋▋▊▄ ▊▊▅▇▅▉█▉ ▌██ ▋▄▆ ▇▋ ▅█▊▄▆▌▆ ▉▋▅▇▊▌▊ ▊▇ ▌▌▉█▊▅ ▋█▄▄▆▊ ▍▉▋▉█ ▆ ▅▆▄▉▋▌█ ▉▉▍▆▋▊▆ ▌▅▌▆ ▊▌▅▍▋▅▄ ▅▉▊▊ ▅█▋ ▅▊█▇▆▇▄▋▄▄▊ ▌▆▆▇▄ ▋▌▋▉▌▊▅▆▉▍█ ▉▆▌▍█ ▉█ ▊▄▌█ ▌█▅▌▌▄ ▇▌▍▌▌▉▌▌▇▍▍ ▉█▆▌▇▌▉ ▉▆ ▅▅▆▌ ▉▆▆▆ ▍▆ ▇▍▋▅ ▌▊▄▊▋▋▍▅▄ ▉▉▄▊▉▊▉▊▊▇▊▍▅ ▊▄▆▉ ▆▊▌▅▉ ▍ ▋▇▇▅▇▆▋ ▋▆▍▅ ▋▆█▊▊▉█ ▊▋▉▅
▇ ▄▇▅▍▆▊ ▊▌▆▅▋█▉▌▄█▌▆▌▅▇█▆ ▍ ▆▇▉▄▊ ▊▉▍▅▆▌▌▊▊▄▄▍▆▍▆▌▇▋▍▇█▅▍▅▄▄ ▊▄▅ ▋ ▍▅▊ ▅▊▊▋▇▆▄▆▌▅▆▋ ▆▅ █▍▅▌▉ ▉▋▆█▉▌▄▆▅▌█▌▄▍ ▇▄▇▉▄▄ █▍▅▊▄ ▋▇▌ ▍▆▅ ▄▍▇▊▌▍▅▄ ▍▆▄▌▇▇▇▅ ▌▌▄▅▇▄▋▅▉▊▊█▌ █▆▆▌▋█▌▊ ▆▉▅▅ ▉▅▌▇▄ ▋▆▊ ▉▉▄▌▅▋▍ ▆▆▄▅ ▇▊▆█▄▌▍▊
▄ ▍▉▅▊▄▇ ▊▄▅▌▋▌▆▄▇▊▅▍█▆▍▄▇ ▉ ▆▆▌ ▆▇▉ ▌▇▌▇▆▆▅▆▄▇▄▆ ▇▌ █ ▊▉▊█▌▌ ▋▆▆▅▍▅▉█▋▉ █▋▊ ▄█▄▍ ▌▄█▍▌ ▄▆▊ ▊█ ▅▉▋ ▆▋▉▊ ▄▄ ▉▅▆▅▉▋▇▋▊ ▉▋▌▄▉▊▋█▇▍▍ ▅▄█▆▋ █▌▄ ▇▊ ▅▄▍▇▉▋ ▉▍▍▅ █▇▊▅▍▊ ▄▄▅█▇▆▊▄▌█▋▍▇▄ ▌▇█▍ ▇▋▌▊▄ ▍ ▆█▇▌█▌█ ▇▇▄▇ ▌▍▍▇▌▇▍▉
▋ ▌▋▅▇▋▅ ▊▇▍▉▌▆▍▆▊▋█▉▍██▊█ ▆ ▅▆▅▇▅▇▅ ▋██ ▊▊▉▌▅▉▅▆▋█▅▌▇▆▊▅▉▊██▆ ▆▆▍▅▉ ▍▆ ▆▊▇ ▅▋▉▊▍▅▊▇█▆▆▌▍▄▇▍▍▋▍ ▋▉▆▍▅██▊▊▉ ▊▌▍ ▅▄▄▄▌▊ ▊▄▍▆ ▄▆▄▇▇ ▌▌▊▄ ▉▇▌▌▌ ▋▇ ▆▉ ▉▍▋▌▇▆▋ ▌▄▆▅▆▄▌▌▇▆▋ ▅▄ ▄▋▌▍▉▇▊▆▆▅▇█ ▇▅▉▍ █▆▌▋▉ █ ▌▉▉▋▉█▄ ▉▉▍▅ ▅█▋▅▌▆▄▊
Update: adding HandleIgnoreTerrain that works on a batch of positions
- also ninja-fixing a bug in batch overload of HandleIgnoreCollisions that screwed layermasks - good thing it wasn't used anywhere
Tests: ran unit tests
█ ▌▅▋▅▅▅▉ ▅▉▌▉▇ ▋▊▇▇█▍▉▋▆▌ ▅▉▌▇▆▇ █▍ ▌▇▄▆▅▊▄▌▆▄▄▄▆▌▄▅█▉▍███▊ ▌▅▍▄ ▆▆ ▋▍▆▋▊▍▅ ▇▉▉▋ ▆▉ ▋█▊▆▊ ▆█▋▍▊▇▍█ █▋▅▄▅▊▋▊█▅▌▆▉▍▌▋▌▄▆ ▅▌▋▅▅▍ ▇▋▌▉▋ ▆▌ ▌▅▉ █▅▉ █▄▉▍▆ ▇▌▍▄▇ ▉▍▅ ▊▅▋▊▊▊▍▄▋▍▍▅▊ ▌▄█ ▇██▉ ▆▊▅▊
▊ ▄▅▄▆▋▇▄ ▉▋▆ ██▄▉▆▌█ ▉▉▍▄▊ ▊▆ ▉▅▅▋▍▅ █▅▊▊▉▌▅▊▌▄ █▊▋▄▊▋▆ ▇▆▍▉▄ ▍▆▉▇█▋ ▋▉▅▆▊▊▋▆▋▇ ▄▇ ▊▋▋█▉█▍▉ ▊▌▍▌ ▉▍▉█ ▅█▄▅ ██▌▆▍ ▅▍▄▆ ▇▍ ▌▇▌ ▆▌▆ ▉▋▅█ ▌▅ ▍▉▆▋▊▅▇ ▄▇▆▌▍▆▌▉▉▇█▌▇▆ ▌▅▉▊▋ ▋▅▊▋▍▋▉▇▍▋▊▇▇ ▍▌▆ ▊▉█▌▍▍▋▄▇▊ ▊▉▌▄ █▋▅▍▇▅▇▉▇ ▅█▍ ▍▋▌▍ ▅▌█▍ ▆ ▊▄▋▋▋ █▊ ▇▆▅▄█ ▌▆▍ ▆▇▉▋ ▌▄▅▇█ ▄▄▍▅▇ █▋▄▌▌ ▋▊▇▅▉▋▋▅▄ ▄█▉▄█▍▋ ▌▆▋▄▅█ ▋▇ ▊▋▉█▄ ▌▇▍▉ ▄█ ▆▍▆▄▄▅▌▅▆▄▉▄█▆▊▊█▇▌▊▇▌ ▍█▌ ▅▆▅▆ ▊▉▍▍▍ ▊▋▉ ▆▊▍▆▇█▇ ▅▋▄▆█▆▌ ▉▋▇▅▇▍▋▅ ▌▍▋▌ ▊▉▊▄█▉ ▌▄▆ ▊▌█▄▇▊▇▅
▉ ▌▇▅█▆▉▄ ▄▇▆▆▊▍ ▋▋▅▍█▍█▄▄ ▆▌▍▋ ▊▊▋▊▇ ▉▉▆ ▇▉█▍▉▄▇▇▆▍▅▇▅▍▊█▋▅▅██ ▌▄▆ ▉▉▌▇▇▊▌▋▄▊▇▅▋▍▍▍▅▋▋▇▋▊▊▋▍ ▆▌▆█ ▅▋ ██ ▅█▄ ▅▍▍▊▄▇▆ █▉█▋ ▌ ▅▅▇▋▅ ▋▉ ▍▌▄█▅▋▊▇▍▍▌▊▉▉ ▌▋▅▌ ▄▆ █▇▅ ▆██▄▅▆▌ ▄▇▋▊▉▅▅▉▌▌█▄▆ ▉▊ ▌▅ ▆▆█▅▌▅ █ ▅▉▋▌▄ ▊▋ █▅▅▌▉▍▍▍▋▊▊▄ ▆▌▇ ▄▉▉ ▊▇▋ ▌▌▊▅ ▆▆▉▍█
▋ █▌▍▋▅▋ █▆▋▆▉▇ ▅▆▇▌▊ ▄▅███▄▇▇▌▇█▊▅█▉ ▆▄▋▅ ▆█▄█ ▅▋▊▄▌▆▍█▋▋ ▄▅▄█▇▄▌▉█▆█ ▍▉ ▊▋▄▅▅▉▆▊▆▄▊▇ ▊▌▍ █▄▍▍▋▌▄▆█▋▊▋▇▊▄▋ ▄▅▅▍▆▌▄▋▍ █ ▄ ▋▅█▅ ▊▅▌▄▇▇█ ▆▋ ▉▉▊▇█▌▍▍ ▆▆▉▅▉▍▋▊▍▅▄▇▌▇▄▄▊ ▄▉█▊▊ █▊▍ █▇▊ ▅▊▇▄ ▉▅▉▌▌▄ ▅▆▅ ▇▇▅█▍▌ ▆█▊▋ ▇▆█▇▉ ▌▍▅ ▄▉▄█▇▋▍ ▋▋▋▆▅▉▍▇▇▆▇▆▅▄▉▅ ▅▉▌ ▍▌▄ ▋▍▍ ▌▌▄▊ ▄▌▄▇
Merge: from parallel_validatemove/stable_playercache
Promoting stable player cache version as main dev direction
Tests: none, no conflicts
Bugfix: fix transform cache rebuild loop
Previously threw away dirty indices too early, missing on some player cache changes
Tests: played back the staging demo - no more error logs about transfomr cache inconsistency
Clean: fixing broken whitespaces that I spotted with the merge
Tests: none, trivial change
Merge: from main
Tests: none, no conflicts