NSSTC / sim-ecs

Batteries included TypeScript ECS
https://nsstc.github.io/sim-ecs/
Mozilla Public License 2.0
84 stars 12 forks source link

improve world.maintain() #25

Closed minecrawler closed 1 year ago

minecrawler commented 3 years ago

Currently, when calling world.maintain(), the whole world is re-evaluated and sorted, which means a lot of overhead in general.

A first measure would be to only work on the current state instead of everything, which would also mean that on each state change the state would have to be maintained.

Another remedy would be to add changes to a queue and work on the queue when maintain() is called, so that only real changes are worked on.

I think bringing both these changes together can bring down the maintain-cost by a lot and distribute it to several points in time, which reduces stutters and hick-ups, especially when doing lots of entity adds and removes.

vmwxiong commented 3 years ago

Could maybe copy the whole world, then asynchronously work on it over time, a little bit each tick?

Not familiar with what maintain does though, just spitballing from what you said here.

minecrawler commented 3 years ago

Not familiar with what maintain does

This ECS works with the optimization, that each system carries a cache containing all entities it has to work on. This makes execution very fast, since you don't have to join or match anything, the dataSet is already available when system.run() executes.

There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton

So, you still have to make sure to keep the caches in sync with whatever happens in your world, and that's where world.maintain() comes into play. It syncs entities in the world with the systems' caches. This allows you to prepare changes to the world during one step and then sync them on the transition to the next step, which guarantees that all systems always work on the same entities per step. Having that work stretch out over several steps would mean that you unexpectedly have to wait for entities to hit your systems, instead of having them in there the next step guaranteed.

And that's also why I think that the only optimization for stretching out work would be to focus the syncing on systems which are actually in use (which is defined by the state - if you don't work with states, per default, all systems will run).

minecrawler commented 1 year ago

world.maintain was removed in favor of auto-syncing changes in cache at save points