World
A World is the container for all ECS data - entities, components, and queries.
Overview
A world is the top-level container for all ECS data. Entities are created within a world, and data is queried based on the existence and shape of entities in that world. Each world is completely independent of all others.
Isolated
Lightweight
Extensible
Creating a World
Create a new world with createWorld():
import { createWorld, addEntity, addComponent } from 'bitecs'
const world = createWorld()
// Add entities and components
const eid = addEntity(world)
addComponent(world, eid, Position)
console.log(eid) // 1Custom Context
Pass an object to createWorld() to use as a custom context. The same reference is returned, so you can access your data directly on the world:
const context = {
time: {
then: 0,
delta: 0,
},
input: {
keys: new Set<string>(),
},
renderer: null as CanvasRenderingContext2D | null,
}
const world = createWorld(context)
// world === context is true!
console.log(world === context) // true
// Access your data in systems
const timeSystem = (world) => {
const now = performance.now()
world.time.delta = now - world.time.then
world.time.then = now
}
const inputSystem = (world) => {
if (world.input.keys.has('Space')) {
// Handle jump...
}
}Custom context keeps all game state in one place. Instead of passing delta time, input state, or renderer references separately to each system, attach them to the world. Systems only need one parameter.
Common Context Patterns
// Game loop timing
const world = createWorld({
time: { delta: 0, elapsed: 0, frame: 0 }
})
// Physics configuration
const world = createWorld({
physics: { gravity: 9.8, friction: 0.1 }
})
// External references
const world = createWorld({
canvas: document.querySelector('canvas'),
assets: new Map(),
audio: new AudioContext(),
})Multiple Worlds
Worlds are independent. Use multiple worlds to separate game states or run parallel simulations:
// Separate worlds for different purposes
const gameWorld = createWorld({ scene: 'game' })
const uiWorld = createWorld({ scene: 'ui' })
const physicsWorld = createWorld({ scene: 'physics' })
// Each has its own entities
addEntity(gameWorld) // 1 (in gameWorld)
addEntity(uiWorld) // 1 (in uiWorld - independent!)
addEntity(gameWorld) // 2 (in gameWorld)- UI vs Game - Keep UI entities separate from game entities
- Level Streaming - Load next level in background world, then swap
- Multiplayer Rooms - Each game room or match runs in its own world
Shared Entity Index
By default, each world has its own entity ID space. If you need multiple worlds to share entity IDs (e.g., entities that exist in multiple worlds), create a shared index:
import { createWorld, createEntityIndex, addEntity } from 'bitecs'
// Create a shared entity index
const entityIndex = createEntityIndex()
// Create worlds that share the same entity ID space
const worldA = createWorld(entityIndex)
const worldB = createWorld(entityIndex)
// Entity IDs are unique across ALL worlds using this index
addEntity(worldA) // 1
addEntity(worldB) // 2
addEntity(worldA) // 3Shared vs Separate Entity IDs
// Without shared index (default) - IDs can collide!
const w1 = createWorld()
const w2 = createWorld()
console.log(addEntity(w1), addEntity(w2)) // 1, 1 (same IDs!)
// With shared index - IDs are unique across worlds
const index = createEntityIndex()
const w3 = createWorld(index)
const w4 = createWorld(index)
console.log(addEntity(w3), addEntity(w4)) // 1, 2 (unique IDs)Combine custom context with a shared entity index - pass them in any order:
// Both work identically
createWorld({ data: 1 }, entityIndex)
createWorld(entityIndex, { data: 1 })Entity Versioning
Enable versioning to detect stale entity references after an entity is removed and its ID recycled:
import { createEntityIndex, withVersioning, getId, getVersion } from 'bitecs'
// Enable versioning with 8 bits for version (default)
const index = createEntityIndex(withVersioning())
// Or specify custom version bits
const index = createEntityIndex(withVersioning(16))
const world = createWorld(index)
const eid = addEntity(world)
console.log(getId(index, eid)) // 1 (base ID)
console.log(getVersion(index, eid)) // 0 (first version)
removeEntity(world, eid)
const newEid = addEntity(world) // Reuses ID 1
console.log(getId(index, newEid)) // 1 (same base ID)
console.log(getVersion(index, newEid)) // 1 (incremented version)World Utilities
Functions for inspecting and managing worlds:
| Function | Description |
|---|---|
resetWorld(world) | Clear all entities, keep component registrations |
deleteWorld(world) | Completely delete a world and free resources |
getWorldComponents(world) | Get all registered components |
getAllEntities(world) | Get array of all entity IDs |
import {
resetWorld,
deleteWorld,
getWorldComponents,
getAllEntities
} from 'bitecs'
// Get all entity IDs currently in the world
const entities = getAllEntities(world)
console.log(`World has ${entities.length} entities`)
// Get all registered components
const components = getWorldComponents(world)
console.log(`${components.length} components registered`)
// Reset world - removes all entities, keeps registrations
resetWorld(world)
console.log(getAllEntities(world).length) // 0
// Completely delete when done
deleteWorld(world)