Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Ukendio/jecs/llms.txt

Use this file to discover all available pages before exploring further.

This example demonstrates the core concepts of jecs: creating a world, defining components, spawning entities, and querying them in a system.

Core Concepts

jecs follows the Entity Component System (ECS) pattern:
  • Entities are unique identifiers
  • Components are data containers
  • Systems are functions that query and process entities with specific components

Complete Example

Here’s a complete example showing how to create entities with Position and Velocity components, then update their positions in a query:
local jecs = require("@jecs")
local world = jecs.world()

local Position = world:component()
local Velocity = world:component()
local Name = world:component()

local Vector3
do
	Vector3 = {}
	Vector3.__index = Vector3

	function Vector3.new(x, y, z)
		x = x or 0
		y = y or 0
		z = z or 0
		return setmetatable({ X = x, Y = y, Z = z }, Vector3)
	end

	function Vector3.__add(left, right)
		return Vector3.new(left.X + right.X, left.Y + right.Y, left.Z + right.Z)
	end

	function Vector3.__mul(left, right)
		if typeof(right) == "number" then
			return Vector3.new(left.X * right, left.Y * right, left.Z * right)
		end
		return Vector3.new(left.X * right.X, left.Y * right.Y, left.Z * right.Z)
	end

	Vector3.one = Vector3.new(1, 1, 1)
	Vector3.zero = Vector3.new()
end

-- Create a few test entities for a Position, Velocity query
local e1 = world:entity()
world:set(e1, Name, "e1")
world:set(e1, Position, Vector3.new(10, 20, 30))
world:set(e1, Velocity, Vector3.new(1, 2, 3))

local e2 = world:entity()
world:set(e2, Name, "e2")
world:set(e2, Position, Vector3.new(10, 20, 30))
world:set(e2, Velocity, Vector3.new(4, 5, 6))

-- This entity will not match as it does not have Position, Velocity
local e3 = world:entity()
world:set(e3, Name, "e3")
world:set(e3, Position, Vector3.new(10, 20, 30))

-- Create an uncached query for Position, Velocity.
for entity, p, v in world:query(Position, Velocity) do
	-- Iterate entities matching the query
	p.X += v.X
	p.Y += v.Y
	p.Z += v.Z

	print(`{world:get(entity, Name)}: \{{p.X}, {p.Y}, {p.Z}}`)
end

-- Output:
--  e2: {14, 25, 36}
--  e1: {11, 22, 33}

Breaking It Down

Creating the World and Components

local jecs = require("@jecs")
local world = jecs.world()

local Position = world:component()
local Velocity = world:component()
local Name = world:component()
First, create a world instance and define your components. Components are created using world:component() and act as type identifiers.

Spawning Entities

local e1 = world:entity()
world:set(e1, Name, "e1")
world:set(e1, Position, Vector3.new(10, 20, 30))
world:set(e1, Velocity, Vector3.new(1, 2, 3))
Entities are created with world:entity() and components are attached using world:set(entity, component, value).

Querying Entities

for entity, p, v in world:query(Position, Velocity) do
	-- Only entities with BOTH Position and Velocity match
	p.X += v.X
	p.Y += v.Y
	p.Z += v.Z
end
The query world:query(Position, Velocity) only matches entities that have both components. Entity e3 is excluded because it only has Position.

Key Takeaways

  • Use world:component() to define component types
  • Use world:entity() to create entities
  • Use world:set(entity, component, value) to attach components
  • Use world:query(...) to iterate entities with specific components
  • Queries only match entities with all specified components

Next Steps

Networking

Learn client-server replication patterns for multiplayer games

Spatial Systems

Implement efficient spatial queries using voxel grids