DOCS v0.1.13 github

@hatch:ecs v0.2.2

Entity-component-system for Wren. World storage + fluent Query.with(C).without(C) filters, component-instance bundles for one-call spawns, typed Resources and Events<T>, deferred Commands for safe mid-loop mutation, hierarchy via setParent / childrenOf, onAdd / onRemove lifecycle hooks, and a Schedule with before / after ordering for system dispatch. Pure Wren — composes with @hatch:game's frame loop, runs anywhere Wren runs.

stable system updated Apr 30, 2026 source ↗
README
$ hatch add @hatch:ecs

MOD ecs

CL Parent

NEW Parent.new(entity)

GET Parent.entity

GET Parent.toString

CL Children

NEW Children.new()

GET Children.list

GET Children.count

GET Children.toString

FN Children.contains(e)

FN Children.add(e)

FN Children.remove(e)

CL Bundle

NEW Bundle.new(components)

GET Bundle.components

GET Bundle.count

CL Resources

NEW Resources.new_()

GET Resources.clear

GET Resources.count

FN Resources.insert(resource)

FN Resources.insertAs(klass, value)

FN Resources.get(klass)

FN Resources.has(klass)

FN Resources.remove(klass)

CL Events

NEW Events.new_()

GET Events.clear

FN Events.push(event)

FN Events.drain(klass)

FN Events.peek(klass)

FN Events.count(klass)

CL Commands

NEW Commands.new_()

GET Commands.ops

GET Commands.count

GET Commands.clear

FN Commands.spawn()

FN Commands.spawnWith(components)

FN Commands.attach(entityRef, component)

FN Commands.detach(entityRef, klass)

FN Commands.despawn(entityRef)

CL PendingSpawn_

NEW PendingSpawn_.new_(buffer, opIndex)

GET PendingSpawn_.resolved

GET PendingSpawn_.index

FN PendingSpawn_.resolve(id)

CL Query

NEW Query.new_(world)

GET Query.iterate

GET Query.count

FN Query.with(klass)

FN Query.without(klass)

FN Query.each(block)

CL Schedule

NEW Schedule.new()

GET Schedule.resolve_

GET Schedule.count

GET Schedule.labels

FN Schedule.add(label, fn)

FN Schedule.remove(label)

FN Schedule.after(label, other)

FN Schedule.before(label, other)

FN Schedule.has(label)

FN Schedule.run(world, ctx)

CL World

NEW World.new()

GET World.count

GET World.entities

GET World.componentTypes

GET World.resources

GET World.events

GET World.flushEvents

GET World.query

GET World.commands

GET World.toString

FN World.countOf(klass)

FN World.spawn()

FN World.spawnWith(components)

FN World.despawn(e)

FN World.attach(e, component)

FN World.attachAll(e, components)

FN World.detach(e, klass)

FN World.has(e, klass)

FN World.get(e, klass)

FN World.set(e, component)

FN World.onAdd(klass, fn)

FN World.onRemove(klass, fn)

FN World.fireAdd_(klass, e, component)

FN World.fireRemove_(klass, e, component)

FN World.query(klasses)

FN World.queryFiltered_(withList, withoutList)

FN World.passesWithout_(id, withoutList)

FN World.each(klasses, block)

FN World.setParent(child, parent)

FN World.unparent(child)

FN World.parentOf(child)

FN World.childrenOf(parent)

FN World.applyCommands(cmds)

FN World.resolveEntity_(ref, resolved)

FN World.clear()