For an introduction what a world is and how it fits into the overall picture, see The World / Scenegraph System.
This documentation focuses on the C++
ezWorld class. The functionality exposed through other mechanisms, such as TypeScript, may be more limited in scope, but ultimately maps to the C++ implementation.
Game objects are allocated, destroyed and accessed through the world. For these details, see the chapter about game objects.
World modules are bigger systems that manage aspects like particle effects, the PhysX integration, wind (TODO) and so on. Component managers are a special type of world modules that take care of updating the various component types.
Each world has its own simulation state, to not affect other worlds.
Every world can be actively simulated, or paused.
ezWorld::SetWorldSimulationEnabled() is used to toggle this.
Each world has its own
ezClock which can be retrieved through
ezWorld::GetClock(). The clock is used to speed up or slow down the simulation or to set a fixed update rate. The clock keeps track of the ‘game time’, so when a component needs to know the current time, it should query this from the world’s clock.
Random Number Generator
When a component needs a random number, it should query this from the world via
ezWorld::GetRandomNumberGenerator(). Components or better, component managers can of course also have their own random number generator, for example when they need multi-threaded access to it, or when they want to control the seed value for determinism. The particle systems, for example, do this to achieve deterministic results.
The default coordinate system in EZ is:
That makes it a left-handed coordinate system. You can query these axis in the space of a game object, if you need to.
The coordinate system can be changed through
ezCoordinateSystemProvider can potentially return a different coordinate system at different locations, so you could implement a provider that changes the coordinate system to follow a sphere.
Although components are supposed to not hard-code assumptions about which axis is ‘forward’, etc, using a non-default coordinate system is not well tested. Using a dynamic coordinate system even less so.
Read / Write Access Control
Some aspects of the world are updated in a multi-threaded fashion. For instance, rendering generally happens in parallel to other updates. To prevent you from accessing the world in a problematic way, you need to lock the world for reading or writing when you work with it.
From within a component update function you don’t need to worry, you always have write access to the world while components are being updated. However, if for example you want to load a level or otherwise set it up procedurally at launch, you need to lock it for write access:
In developer builds the world will check that you have properly locked it when you try to do certain operations. Therefore, the best way to know where to add such locks, is simply to run your code without a lock and see whether the engine asserts. If so, you can just traverse your callstack to find a reasonable place to insert the lock.