Rank
70
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
Traction
No public download signal
Freshness
Updated 2d ago
Crawler Summary
Comprehensive guide for using bitECS v0.4.0, a flexible, minimal, data-oriented ECS library for TypeScript. Use when building games or simulations with Entity Component System architecture, creating entity hierarchies, defining components, querying entities, or working with serialization. --- name: bitecs description: Comprehensive guide for using bitECS v0.4.0, a flexible, minimal, data-oriented ECS library for TypeScript. Use when building games or simulations with Entity Component System architecture, creating entity hierarchies, defining components, querying entities, or working with serialization. --- bitECS v0.4.0 Agent Skill This skill provides comprehensive guidance for using bitECS, a flexibl Capability contract not published. No trust telemetry is available yet. Last updated 4/15/2026.
Freshness
Last checked 4/15/2026
Best For
bitecs is best for be, serve, only workflows where OpenClaw compatibility matters.
Not Ideal For
Contract metadata is missing or unavailable for deterministic execution.
Evidence Sources Checked
editorial-content, GITHUB OPENCLEW, runtime-metrics, public facts pack
Comprehensive guide for using bitECS v0.4.0, a flexible, minimal, data-oriented ECS library for TypeScript. Use when building games or simulations with Entity Component System architecture, creating entity hierarchies, defining components, querying entities, or working with serialization. --- name: bitecs description: Comprehensive guide for using bitECS v0.4.0, a flexible, minimal, data-oriented ECS library for TypeScript. Use when building games or simulations with Entity Component System architecture, creating entity hierarchies, defining components, querying entities, or working with serialization. --- bitECS v0.4.0 Agent Skill This skill provides comprehensive guidance for using bitECS, a flexibl
Public facts
4
Change events
1
Artifacts
0
Freshness
Apr 15, 2026
Capability contract not published. No trust telemetry is available yet. Last updated 4/15/2026.
Trust score
Unknown
Compatibility
OpenClaw
Freshness
Apr 15, 2026
Vendor
Kadajett
Artifacts
0
Benchmarks
0
Last release
Unpublished
Key links, install path, and a quick operational read before the deeper crawl record.
Summary
Capability contract not published. No trust telemetry is available yet. Last updated 4/15/2026.
Setup snapshot
git clone https://github.com/Kadajett/bitECS-agent-skill.gitSetup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.
Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.
Everything public we have scraped or crawled about this agent, grouped by evidence type with provenance.
Vendor
Kadajett
Protocol compatibility
OpenClaw
Handshake status
UNKNOWN
Crawlable docs
6 indexed pages on the official domain
Merged public release, docs, artifact, benchmark, pricing, and trust refresh events.
Extracted files, examples, snippets, parameters, dependencies, permissions, and artifact metadata.
Extracted files
0
Examples
6
Snippets
0
Languages
typescript
Parameters
bash
npm i bitecs
ts
import { createWorld, resetWorld, deleteWorld, getAllEntities, getWorldComponents } from 'bitecs'
// Basic world creation
const world = createWorld()
// World with custom context
const world = createWorld({
time: { delta: 0, elapsed: 0, then: 0 },
components: {
Position: { x: [] as number[], y: [] as number[] }
}
})
// Shared entity index between worlds
const entityIndex = createEntityIndex()
const worldA = createWorld(entityIndex)
const worldB = createWorld(entityIndex)
// Combined: custom context + shared entity index (any order)
createWorld({ data: 1 }, entityIndex)
createWorld(entityIndex, { data: 1 })
// World utilities
resetWorld(world) // Reset world state
deleteWorld(world) // Delete world and free resources
getAllEntities(world) // Get all entities in world
getWorldComponents(world) // Get all registered componentsts
import {
addEntity,
removeEntity,
entityExists,
getEntityComponents,
createEntityIndex,
addEntityId,
removeEntityId,
isEntityIdAlive
} from 'bitecs'
// Basic entity operations
const eid = addEntity(world)
removeEntity(world, eid)
// Entity utilities
entityExists(world, eid) // Check if entity exists
getEntityComponents(world, eid) // Get all components for entity
// Direct entity index operations
const index = createEntityIndex()
const id = addEntityId(index)
removeEntityId(index, id)
isEntityIdAlive(index, id)ts
const eid1 = addEntity(world) const eid2 = addEntity(world) removeEntity(world, eid1) const eid3 = addEntity(world) // eid1 === eid3 (recycled)
ts
const Removed = {}
const markEntityForRemoval = (world, eid) => {
addComponent(world, eid, Removed)
}
const removeMarkedEntities = (world) => {
for (const eid of query(world, [Removed])) {
removeEntity(world, eid)
}
}ts
import { createEntityIndex, withVersioning, getId, getVersion, incrementVersion } from 'bitecs'
// Version bits options:
// 8 bits: 16M entities / 256 recycles
// 10 bits: 4M entities / 1K recycles
// 12 bits: 1M entities / 4K recycles (default)
// 14 bits: 262K entities / 16K recycles
// 16 bits: 65K entities / 65K recycles
const entityIndex = createEntityIndex(withVersioning(8))
const world = createWorld(entityIndex)
const eid1 = addEntity(world)
removeEntity(world, eid1)
const eid2 = addEntity(world)
// eid1 !== eid2 (different versions)
// Version utilities
getId(entityIndex, eid) // Extract entity ID without version
getVersion(entityIndex, eid) // Extract version from entity ID
incrementVersion(entityIndex, eid) // Increment version of entity IDFull documentation captured from public sources, including the complete README when available.
Docs source
GITHUB OPENCLEW
Editorial quality
ready
Comprehensive guide for using bitECS v0.4.0, a flexible, minimal, data-oriented ECS library for TypeScript. Use when building games or simulations with Entity Component System architecture, creating entity hierarchies, defining components, querying entities, or working with serialization. --- name: bitecs description: Comprehensive guide for using bitECS v0.4.0, a flexible, minimal, data-oriented ECS library for TypeScript. Use when building games or simulations with Entity Component System architecture, creating entity hierarchies, defining components, querying entities, or working with serialization. --- bitECS v0.4.0 Agent Skill This skill provides comprehensive guidance for using bitECS, a flexibl
This skill provides comprehensive guidance for using bitECS, a flexible, minimal, data-oriented Entity Component System (ECS) library for TypeScript.
Use this skill when:
npm i bitecs
bitECS 0.4.0 provides three modules:
| Module | Import | Purpose |
|--------|--------|---------|
| Core | bitecs | Main ECS toolkit |
| Serialization | bitecs/serialization | Binary serialization utilities |
| Legacy | bitecs/legacy | Backward compatibility with 0.3.x API |
A world is a container for ECS data. Entities are created in a world and data is queried based on the existence and shape of entities in a world. Each world is independent of all others.
import { createWorld, resetWorld, deleteWorld, getAllEntities, getWorldComponents } from 'bitecs'
// Basic world creation
const world = createWorld()
// World with custom context
const world = createWorld({
time: { delta: 0, elapsed: 0, then: 0 },
components: {
Position: { x: [] as number[], y: [] as number[] }
}
})
// Shared entity index between worlds
const entityIndex = createEntityIndex()
const worldA = createWorld(entityIndex)
const worldB = createWorld(entityIndex)
// Combined: custom context + shared entity index (any order)
createWorld({ data: 1 }, entityIndex)
createWorld(entityIndex, { data: 1 })
// World utilities
resetWorld(world) // Reset world state
deleteWorld(world) // Delete world and free resources
getAllEntities(world) // Get all entities in world
getWorldComponents(world) // Get all registered components
Entities are unique numerical identifiers (entity IDs or eids). They are unique across all worlds unless worlds share an entity index.
import {
addEntity,
removeEntity,
entityExists,
getEntityComponents,
createEntityIndex,
addEntityId,
removeEntityId,
isEntityIdAlive
} from 'bitecs'
// Basic entity operations
const eid = addEntity(world)
removeEntity(world, eid)
// Entity utilities
entityExists(world, eid) // Check if entity exists
getEntityComponents(world, eid) // Get all components for entity
// Direct entity index operations
const index = createEntityIndex()
const id = addEntityId(index)
removeEntityId(index, id)
isEntityIdAlive(index, id)
Entity IDs are recycled immediately after removal:
const eid1 = addEntity(world)
const eid2 = addEntity(world)
removeEntity(world, eid1)
const eid3 = addEntity(world)
// eid1 === eid3 (recycled)
For more control over entity lifecycle, implement manual recycling:
const Removed = {}
const markEntityForRemoval = (world, eid) => {
addComponent(world, eid, Removed)
}
const removeMarkedEntities = (world) => {
for (const eid of query(world, [Removed])) {
removeEntity(world, eid)
}
}
Prevents collision issues with recycled IDs by adding version numbers:
import { createEntityIndex, withVersioning, getId, getVersion, incrementVersion } from 'bitecs'
// Version bits options:
// 8 bits: 16M entities / 256 recycles
// 10 bits: 4M entities / 1K recycles
// 12 bits: 1M entities / 4K recycles (default)
// 14 bits: 262K entities / 16K recycles
// 16 bits: 65K entities / 65K recycles
const entityIndex = createEntityIndex(withVersioning(8))
const world = createWorld(entityIndex)
const eid1 = addEntity(world)
removeEntity(world, eid1)
const eid2 = addEntity(world)
// eid1 !== eid2 (different versions)
// Version utilities
getId(entityIndex, eid) // Extract entity ID without version
getVersion(entityIndex, eid) // Extract version from entity ID
incrementVersion(entityIndex, eid) // Increment version of entity ID
Warning: When using versioning with TypedArrays, ensure arrays are large enough as versioned IDs can be much larger than the base entity ID.
Components are modular data containers representing specific attributes of an entity. Any valid JavaScript reference can serve as a component.
// SoA with regular arrays (recommended for minimal memory footprint)
const Position = {
x: [] as number[],
y: [] as number[],
}
// SoA with TypedArrays (recommended for threading and eliminating memory thrash)
const Position = {
x: new Float64Array(10000),
y: new Float64Array(10000),
}
// AoS (performant for small shapes with < 100k objects)
const Position = [] as { x: number; y: number }[]
// Array of TypedArrays
const Position = Array.from({ length: 10000 }, () => new Float32Array(3))
// Tag component (no data)
const Flying = {}
import {
addComponent,
addComponents,
removeComponent,
removeComponents,
hasComponent,
getComponent,
setComponent,
set,
registerComponent,
registerComponents
} from 'bitecs'
// Add single component
addComponent(world, eid, Position)
// Add with initial data (requires onSet observer)
addComponent(world, eid, set(Position, { x: 10, y: 20 }))
// Add multiple components
addComponents(world, eid, Position, Velocity, Mass)
addComponents(world, eid, [Position, Velocity, Mass])
addComponents(world, eid,
set(Position, { x: 10, y: 20 }),
set(Velocity, { x: 1, y: 1 }),
Health
)
// Remove components
removeComponent(world, eid, Position)
removeComponent(world, eid, Position, Velocity)
removeComponents(world, eid, Position, Velocity)
// Check component presence
hasComponent(world, eid, Position)
// Get component data (triggers onGet observers)
const data = getComponent(world, eid, Position)
// Set component data (triggers onSet observers)
setComponent(world, eid, Position, { x: 10, y: 20 })
// Register components explicitly (automatic on first addComponent)
registerComponent(world, Position)
registerComponents(world, [Position, Velocity, Mass])
addComponent(world, eid, Position)
// SoA access
Position.x[eid] = 0
Position.y[eid] = 0
Position.x[eid] += 1
// AoS access
Position[eid] = { x: 0, y: 0 }
Position[eid].x += 1
// Array of TypedArrays
const pos = Position[eid]
pos[0] += 1
// Components stored on world for clean access
const world = createWorld({
components: {
Position: Array(1e5).fill(3).map(n => new Float32Array(n))
}
})
const { Position } = world.components
Queries retrieve entities based on their components, relationships, or hierarchies.
import { query, And, Or, Not, All, Any, None, Hierarchy, Cascade, asBuffer, isNested, noCommit } from 'bitecs'
// Basic query
const entities = query(world, [Position, Mass])
// Query operators
query(world, [Position, Velocity]) // AND (default)
query(world, [And(Position, Velocity)]) // Explicit AND
query(world, [All(Position, Velocity)]) // Alias for AND
query(world, [Or(Position, Velocity)]) // OR
query(world, [Any(Position, Velocity)]) // Alias for OR
query(world, [Position, Not(Velocity)]) // NOT
query(world, [Position, None(Velocity)]) // Alias for NOT
// Complex combinations
query(world, [
Position, // Must have Position
Or(Health, Shield), // Must have Health OR Shield
Not(Stunned, Paralyzed) // Must NOT have Stunned AND must NOT have Paralyzed
])
// Options object approach
query(world, [Position], { commit: false }) // Skip pending removals
query(world, [Position], { buffered: true }) // Returns Uint32Array
query(world, [Position], { commit: false, buffered: true }) // Combined
// Query modifier approach
query(world, [Position], isNested) // Safe nested iteration
query(world, [Position], noCommit) // Alias for isNested
query(world, [Position], asBuffer) // Returns Uint32Array
query(world, [Position], asBuffer, isNested) // Combined modifiers
When iterating over query results, calling another query will flush pending removals. Use isNested or noCommit for safe nested iteration:
for (const entity of query(world, [Position, Velocity])) {
// Use nested to prevent removals during iteration
for (const inner of query(world, [Mass], isNested)) {
// Safe nested iteration
}
}
Query entities in topological order (parents before children):
import { Hierarchy, Cascade, getHierarchyDepth, getMaxHierarchyDepth } from 'bitecs'
const ChildOf = createRelation()
// All entities with Position in hierarchy order
for (const eid of query(world, [Position, Hierarchy(ChildOf)])) {
// Parents processed before children
}
// Entities at specific depth level
for (const eid of query(world, [Position, Hierarchy(ChildOf, 2)])) {
// Only entities at depth 2
}
// Cascade is an alias for Hierarchy
query(world, [Position, Cascade(ChildOf)])
// Hierarchy utilities
getHierarchyDepth(world, eid, ChildOf) // Get depth of entity
getMaxHierarchyDepth(world, ChildOf) // Get max depth in hierarchy
Relationships define how entities relate to each other.
import {
createRelation,
withStore,
makeExclusive,
withAutoRemoveSubject,
withOnTargetRemoved,
withValidation,
getRelationTargets,
Wildcard,
Pair
} from 'bitecs'
// Basic relation
const ChildOf = createRelation()
// Relation with data store
const Contains = createRelation(
withStore(() => ({ amount: [] as number[] }))
)
// Or with options object:
const Contains = createRelation({
store: () => ({ amount: [] as number[] })
})
// Auto-remove subject when target is removed
const ChildOf = createRelation(withAutoRemoveSubject)
// Or: createRelation({ autoRemoveSubject: true })
// Exclusive relation (subject can only relate to one target)
const Targeting = createRelation(makeExclusive)
// Or: createRelation({ exclusive: true })
// Custom callback when target removed
const Following = createRelation(
withOnTargetRemoved((subject, target) => {
console.log(`${subject} lost target ${target}`)
})
)
// Validation
const ValidatedRelation = createRelation(
withValidation((target) => target > 0)
)
const inventory = addEntity(world)
const gold = addEntity(world)
const silver = addEntity(world)
// Add relationships
addComponent(world, inventory, Contains(gold))
Contains(gold).amount[inventory] = 5
addComponent(world, inventory, Contains(silver))
Contains(silver).amount[inventory] = 12
// Query relationships
const children = query(world, [ChildOf(parent)])
// Get relation targets
const targets = getRelationTargets(world, inventory, Contains) // [gold, silver]
// Find all entities with any Contains relationship
query(world, [Contains('*')])
query(world, [Contains(Wildcard)])
// Inverted wildcard: find all entities related TO a specific target
const earth = addEntity(world)
addComponent(world, earth, OrbitedBy(moon))
addComponent(world, earth, IlluminatedBy(sun))
query(world, [Wildcard(earth)]) // Entities related to earth
// Find all parents (entities that have children)
query(world, [Wildcard(ChildOf)])
// Find all children (entities that have parents)
query(world, [ChildOf(Wildcard)])
Prefabs are reusable entity templates.
import { addPrefab, IsA } from 'bitecs'
// Create prefab
const Animal = addPrefab(world)
addComponent(world, Animal, Vitals)
Vitals.health[Animal] = 100
// Inheritance with IsA relation
const Sheep = addPrefab(world)
addComponent(world, Sheep, IsA(Animal)) // Inherits Vitals
addComponent(world, Sheep, Contains(Wool))
// Instantiate from prefab
const sheep = addEntity(world)
addComponent(world, sheep, IsA(Sheep))
hasComponent(world, sheep, Contains(Wool)) // true
// Query instances
query(world, [IsA(Animal)]) // Returns all animals
Note: Prefabs do not appear in queries themselves. For inheritance to work with component values, you must define onSet and onGet observers:
observe(world, onSet(Vitals), (eid, params) => {
Vitals.health[eid] = params.health
})
observe(world, onGet(Vitals), (eid) => ({
health: Vitals.health[eid]
}))
Observers react to component changes.
import { observe, onAdd, onRemove, onSet, onGet } from 'bitecs'
// Observe component additions
const unsubscribe = observe(world, onAdd(Position), (eid) => {
console.log(`Entity ${eid} gained Position`)
})
// Observe component removals
observe(world, onRemove(Health), (eid) => {
console.log(`Entity ${eid} lost Health`)
})
// Complex observation patterns
observe(world, onAdd(Position, Not(Velocity)), (eid) => {
console.log(`Entity ${eid} has Position but no Velocity`)
})
// onSet: Called when setComponent or set() helper is used
observe(world, onSet(Position), (eid, params) => {
Position.x[eid] = params.x
Position.y[eid] = params.y
console.log(`Position set for ${eid}:`, params)
})
// onGet: Called when getComponent is used
observe(world, onGet(Position), (eid) => ({
x: Position.x[eid],
y: Position.y[eid]
}))
// Computed values
observe(world, onSet(Health), (eid, params) => {
return { value: Math.max(0, Math.min(100, params.value)) }
})
// Network synchronization
observe(world, onSet(Inventory), (eid, params) => {
syncWithServer(eid, 'inventory', params)
return params
})
// Unsubscribe when done
unsubscribe()
Systems define entity behavior. bitECS doesn't enforce a specific implementation, but recommends simple chainable functions:
const moveBody = (world) => {
for (const entity of query(world, [Position, Velocity])) {
Position.x[entity] += Velocity.x[entity] * world.time.delta
Position.y[entity] += Velocity.y[entity] * world.time.delta
}
}
const applyGravity = (world) => {
const gravity = 9.81
for (const entity of query(world, [Position, Mass])) {
Position.y[entity] -= gravity * Mass.value[entity] * world.time.delta
}
}
const timeSystem = (world) => {
const now = performance.now()
world.time.delta = (now - world.time.then) / 1000
world.time.elapsed += world.time.delta
world.time.then = now
}
// Game loop
const update = (world) => {
timeSystem(world)
moveBody(world)
applyGravity(world)
}
// Browser
requestAnimationFrame(function animate() {
update(world)
requestAnimationFrame(animate)
})
// Node
setInterval(() => update(world), 1000/60)
Import from bitecs/serialization.
For regular arrays, use type tags to specify serialization format:
| Tag | Description |
|-----|-------------|
| u8(), i8() | 8-bit unsigned/signed integers |
| u16(), i16() | 16-bit unsigned/signed integers |
| u32(), i32() | 32-bit unsigned/signed integers |
| f32() | 32-bit floats |
| f64() | 64-bit floats (default) |
| str() | UTF-8 strings |
| array(type) | Arrays of specified type |
TypedArrays (Uint8Array, Float32Array, etc.) don't need tags.
For Structure of Arrays component data:
import { createSoASerializer, createSoADeserializer, f32, u8, str, array } from 'bitecs/serialization'
const Position = { x: f32([]), y: f32([]) }
const Velocity = { vx: f32([]), vy: f32([]) }
const Health = new Uint8Array(1e5)
const Meta = { name: str([]), tags: array(str) }
const components = [Position, Velocity, Health, Meta]
const serialize = createSoASerializer(components)
const deserialize = createSoADeserializer(components)
// Set data
Position.x[eid] = 10.5
Position.y[eid] = 20.2
Health[eid] = 100
Meta.name[eid] = 'Player'
Meta.tags[eid] = ['hero', 'active']
// Serialize entities
const buffer = serialize([eid])
// Deserialize
deserialize(buffer)
// ID mapping for network/save systems
const idMap = new Map([[1, 10]]) // Map entity 1 to 10
deserialize(buffer, idMap)
const serialize = createSoASerializer(components, {
diff: true, // Only serialize changed values
buffer: new ArrayBuffer(1 << 20), // 1MB backing buffer (default: 100MB)
epsilon: 1e-3 // Float comparison threshold (default: 0.0001)
})
const deserialize = createSoADeserializer(components, { diff: true })
const Inventory = {
pages: array(array(u8)) // Array of arrays of u8
}
Inventory.pages[eid] = [
[1, 2, 3], // Page 1
[10, 20], // Page 2
[100, 101, 102] // Page 3
]
For Array of Structures component data:
import { createAoSSerializer, createAoSDeserializer, f32, u8, str, array } from 'bitecs/serialization'
const Position = Object.assign([], { x: f32(), y: f32() })
const Health = u8()
const Meta = Object.assign([], { name: str(), tags: array(str) })
const serialize = createAoSSerializer(components, { diff: true })
const deserialize = createAoSDeserializer(components, { diff: true })
const buffer = serialize([0, 1])
// ID mapping
const idMap = new Map([[0, 10], [1, 11]])
deserialize(buffer, idMap)
Tracks entity/component additions and removals:
import { createObserverSerializer, createObserverDeserializer } from 'bitecs/serialization'
const Networked = {} // Tag component for network entities
const serializer = createObserverSerializer(world, Networked, [Position, Health], {
buffer: new ArrayBuffer(1 << 20) // Optional backing buffer
})
const deserializer = createObserverDeserializer(world, Networked, [Position, Health], {
idMap: new Map() // Optional initial ID mapping
})
// Add components
addComponent(world, eid, Networked)
addComponent(world, eid, Position)
addComponent(world, eid, Health)
// Serialize changes
const buffer = serializer()
// Deserialize on receiver
deserializer(buffer)
// Or with override ID map
deserializer(buffer, new Map([[1, 100]]))
Captures complete world state:
import { createSnapshotSerializer, createSnapshotDeserializer, f32, u8 } from 'bitecs/serialization'
const Position = { x: f32([]), y: f32([]) }
const Health = u8([])
const serialize = createSnapshotSerializer(world, [Position, Health])
const deserialize = createSnapshotDeserializer(world, [Position, Health])
// Capture full state
const buffer = serialize()
// Restore state
deserialize(buffer)
// Or with ID mapping
deserialize(buffer, new Map([[1, 10]]))
bitECS is designed to work efficiently with worker threads.
const MAX_ENTS = 1e6
const world = createWorld({
components: {
Position: {
x: new Float32Array(new SharedArrayBuffer(MAX_ENTS * Float32Array.BYTES_PER_ELEMENT)),
y: new Float32Array(new SharedArrayBuffer(MAX_ENTS * Float32Array.BYTES_PER_ELEMENT))
}
}
})
Returns SAB-backed Uint32Array for thread sharing:
const entities = query(world, [Position, Mass], asBuffer)
// Main thread
const worker = new Worker('./worker.js')
worker.postMessage({
entities: query(world, [world.components.Position], asBuffer),
components: world.components
})
worker.on('message', ({ removeQueue }) => {
for (let i = 0; i < removeQueue.length; i++) {
removeEntity(world, removeQueue[i])
}
})
// Worker thread (worker.js)
const MAX_CMDS = 1e6
const removeQueue = new Uint32Array(new SharedArrayBuffer(MAX_CMDS * Uint32Array.BYTES_PER_ELEMENT))
self.onmessage = ({ data }) => {
const { entities, components: { Position } } = data
let removeCount = 0
for (let i = 0; i < entities.length; i++) {
const eid = entities[i]
Position.x[eid] += 1
Position.y[eid] += 1
removeQueue[removeCount++] = eid
}
self.postMessage({ removeQueue: removeQueue.subarray(0, removeCount) })
}
const WORKER_COUNT = 4
const workers = Array(WORKER_COUNT).fill(null).map(() => new Worker('worker.js'))
let completedWorkers = 0
workers.forEach(worker => worker.on('message', () => {
completedWorkers++
if (completedWorkers === WORKER_COUNT) {
processQueues()
completedWorkers = 0
}
}))
function processEntitiesParallel(world) {
const entities = query(world, [Position], asBuffer)
const partitionSize = Math.ceil(entities.length / WORKER_COUNT)
for (let i = 0; i < WORKER_COUNT; i++) {
const start = i * partitionSize
const end = Math.min(start + partitionSize, entities.length)
workers[i].postMessage({
entities: entities.subarray(start, end),
components: world.components
})
}
}
Important: ECS API functions (addEntity, removeEntity, addComponent, etc.) cannot be used directly in workers. Use message queues to send commands back to the main thread.
| Function | Signature | Description |
|----------|-----------|-------------|
| createWorld | (context?, entityIndex?) => World | Create a new world |
| resetWorld | (world) => World | Reset world state |
| deleteWorld | (world) => void | Delete world and free resources |
| getAllEntities | (world) => number[] | Get all entities in world |
| getWorldComponents | (world) => ComponentRef[] | Get all registered components |
| Function | Signature | Description |
|----------|-----------|-------------|
| addEntity | (world) => number | Add new entity |
| removeEntity | (world, eid) => void | Remove entity |
| entityExists | (world, eid) => boolean | Check if entity exists |
| getEntityComponents | (world, eid) => ComponentRef[] | Get entity's components |
| Function | Signature | Description |
|----------|-----------|-------------|
| createEntityIndex | (options?) => EntityIndex | Create entity index |
| withVersioning | (versionBits?) => options | Configure versioning |
| addEntityId | (index) => number | Add ID to index |
| removeEntityId | (index, id) => void | Remove ID from index |
| isEntityIdAlive | (index, id) => boolean | Check if ID is alive |
| getId | (index, id) => number | Extract entity ID |
| getVersion | (index, id) => number | Extract version |
| incrementVersion | (index, id) => number | Increment version |
| Function | Signature | Description |
|----------|-----------|-------------|
| addComponent | (world, eid, component) => boolean | Add component to entity |
| addComponents | (world, eid, ...components) => void | Add multiple components |
| removeComponent | (world, eid, ...components) => void | Remove components |
| removeComponents | (world, eid, ...components) => void | Alias for removeComponent |
| hasComponent | (world, eid, component) => boolean | Check component presence |
| getComponent | (world, eid, component) => any | Get component data |
| setComponent | (world, eid, component, data) => void | Set component data |
| set | (component, data) => ComponentSetter | Create component setter |
| registerComponent | (world, component) => ComponentData | Register component |
| registerComponents | (world, components) => void | Register multiple |
| Function | Signature | Description |
|----------|-----------|-------------|
| query | (world, terms, ...modifiers) => QueryResult | Query entities |
| And / All | (...components) => OpReturnType | AND operator |
| Or / Any | (...components) => OpReturnType | OR operator |
| Not / None | (...components) => OpReturnType | NOT operator |
| Hierarchy / Cascade | (relation, depth?) => HierarchyTerm | Hierarchy ordering |
| asBuffer | QueryModifier | Return Uint32Array |
| isNested / noCommit | QueryModifier | Safe nested iteration |
| commitRemovals | (world) => void | Commit pending removals |
| registerQuery | (world, terms, options?) => Query | Register query |
| removeQuery | (world, terms) => void | Remove query |
| Function | Signature | Description |
|----------|-----------|-------------|
| getHierarchyDepth | (world, eid, relation) => number | Get entity depth |
| getMaxHierarchyDepth | (world, relation) => number | Get max depth |
| ensureDepthTracking | (world, relation) => void | Initialize tracking |
| Function | Signature | Description |
|----------|-----------|-------------|
| createRelation | (...modifiers) => Relation | Create relation |
| withStore | (createStore) => modifier | Add data store |
| makeExclusive | (relation) => Relation | Make exclusive |
| withAutoRemoveSubject | (relation) => Relation | Auto-remove subject |
| withOnTargetRemoved | (callback) => modifier | Target removed callback |
| withValidation | (validateFn) => modifier | Add validation |
| getRelationTargets | (world, eid, relation) => number[] | Get targets |
| Pair | (relation, target) => component | Create pair |
| Wildcard | Relation | Wildcard relation |
| IsA | Relation | Inheritance relation |
| isRelation | (component) => boolean | Check if relation |
| isWildcard | (relation) => boolean | Check if wildcard |
| Function | Signature | Description |
|----------|-----------|-------------|
| addPrefab | (world) => EntityId | Create prefab entity |
| Function | Signature | Description |
|----------|-----------|-------------|
| observe | (world, hook, callback) => unsubscribe | Subscribe to changes |
| onAdd | (...terms) => ObservableHook | Addition hook |
| onRemove | (...terms) => ObservableHook | Removal hook |
| onSet | (component) => ObservableHook | Set hook |
| onGet | (component) => ObservableHook | Get hook |
| Function | Signature | Description |
|----------|-----------|-------------|
| createSoASerializer | (components, options?) => (entities) => ArrayBuffer | SoA serializer |
| createSoADeserializer | (components, options?) => (buffer, idMap?) => void | SoA deserializer |
| createAoSSerializer | (components, options?) => (entities) => ArrayBuffer | AoS serializer |
| createAoSDeserializer | (components, options?) => (buffer, idMap?) => void | AoS deserializer |
| createObserverSerializer | (world, tag, components, options?) => () => ArrayBuffer | Observer serializer |
| createObserverDeserializer | (world, tag, components, options?) => (buffer, idMap?) => void | Observer deserializer |
| createSnapshotSerializer | (world, components, buffer?) => () => ArrayBuffer | Snapshot serializer |
| createSnapshotDeserializer | (world, components) => (buffer, idMap?) => void | Snapshot deserializer |
| f32, f64, u8, u16, u32, i8, i16, i32 | (array?) => TypedArray | Type tags |
| str | (array?) => string[] | String type tag |
| array | (type) => array | Array type tag |
// Good: Focused components
const Position = { x: new Float32Array(MAX_ENTS), y: new Float32Array(MAX_ENTS) }
const Velocity = { x: new Float32Array(MAX_ENTS), y: new Float32Array(MAX_ENTS) }
const Flying = {} // Tag
// Avoid: Monolithic components
const Entity = { x: [], y: [], vx: [], vy: [], health: [], name: [] }
isNested for nested queries to prevent removal issuesasBuffer for threading or when you need Uint32Array// Good: Query once
const moveSystem = (world) => {
const entities = query(world, [Position, Velocity])
for (const eid of entities) {
Position.x[eid] += Velocity.x[eid]
}
}
// Avoid: Query in loop
for (let i = 0; i < 1000; i++) {
const entities = query(world, [Position]) // Inefficient
}
const Removed = {}
const removeSystem = (world) => {
for (const eid of query(world, [Removed])) {
removeEntity(world, eid)
}
}
asBuffer queries for thread-safe entity lists| 0.3.x | 0.4.0 |
|-------|-------|
| defineComponent({ x: Types.f32 }) | { x: [] as number[] } or { x: new Float32Array(n) } |
| addComponent(world, Component, eid) | addComponent(world, eid, Component) |
| defineQuery([A, B]) then query(world) | query(world, [A, B]) |
| enterQuery(query) | observe(world, onAdd(...), cb) |
| exitQuery(query) | observe(world, onRemove(...), cb) |
| Changed(Component) | observe(world, onSet(Component), cb) |
| Types.eid for references | createRelation() |
For gradual migration, use bitecs/legacy:
import {
defineComponent,
defineQuery,
enterQuery,
exitQuery,
Types,
addComponent // Uses old parameter order
} from 'bitecs/legacy'
const world = createWorld({
enteredMovers: [] as number[],
exitedMovers: [] as number[]
})
observe(world, onAdd(Position, Velocity), (eid) => world.enteredMovers.push(eid))
observe(world, onRemove(Position, Velocity), (eid) => world.exitedMovers.push(eid))
const movementSystem = (world) => {
// Process entered
for (const eid of world.enteredMovers.splice(0)) {
console.log(`${eid} started moving`)
}
// Process exited
for (const eid of world.exitedMovers.splice(0)) {
console.log(`${eid} stopped moving`)
}
}
const ChildOf = createRelation(withAutoRemoveSubject)
// Create hierarchy
const parent = addEntity(world)
const child = addEntity(world)
addComponent(world, child, ChildOf(parent))
// Process in order
for (const eid of query(world, [Transform, Hierarchy(ChildOf)])) {
// Parents processed before children
updateWorldTransform(eid)
}
const Contains = createRelation(withStore(() => ({ amount: [] as number[] })))
const chest = addEntity(world)
const gold = addEntity(world)
addComponent(world, chest, Contains(gold))
Contains(gold).amount[chest] = 100
// Get all items in chest
const items = getRelationTargets(world, chest, Contains)
import { createObserverSerializer, createObserverDeserializer, createSoASerializer, createSoADeserializer } from 'bitecs/serialization'
const Networked = {}
const components = [Position, Velocity, Health]
// Server
const observerSerializer = createObserverSerializer(world, Networked, components)
const dataSerializer = createSoASerializer(components)
const sendUpdate = () => {
const entities = query(world, [Networked])
const observerPacket = observerSerializer()
const dataPacket = dataSerializer(entities)
broadcast({ observer: observerPacket, data: dataPacket })
}
// Client
const observerDeserializer = createObserverDeserializer(world, Networked, components)
const dataDeserializer = createSoADeserializer(components)
const receiveUpdate = ({ observer, data }) => {
observerDeserializer(observer)
dataDeserializer(data)
}
Machine endpoints, protocol fit, contract coverage, invocation examples, and guardrails for agent-to-agent use.
Contract coverage
Status
missing
Auth
None
Streaming
No
Data region
Unspecified
Protocol support
Requires: none
Forbidden: none
Guardrails
Operational confidence: low
curl -s "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/snapshot"
curl -s "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/contract"
curl -s "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/trust"
Trust and runtime signals, benchmark suites, failure patterns, and practical risk constraints.
Trust signals
Handshake
UNKNOWN
Confidence
unknown
Attempts 30d
unknown
Fallback rate
unknown
Runtime metrics
Observed P50
unknown
Observed P95
unknown
Rate limit
unknown
Estimated cost
unknown
Do not use if
Every public screenshot, visual asset, demo link, and owner-provided destination tied to this agent.
Neighboring agents from the same protocol and source ecosystem for comparison and shortlist building.
Rank
70
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
Traction
No public download signal
Freshness
Updated 2d ago
Rank
70
AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs
Traction
No public download signal
Freshness
Updated 5d ago
Rank
70
Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!
Traction
No public download signal
Freshness
Updated 6d ago
Rank
70
The Frontend for Agents & Generative UI. React + Angular
Traction
No public download signal
Freshness
Updated 23d ago
Contract JSON
{
"contractStatus": "missing",
"authModes": [],
"requires": [],
"forbidden": [],
"supportsMcp": false,
"supportsA2a": false,
"supportsStreaming": false,
"inputSchemaRef": null,
"outputSchemaRef": null,
"dataRegion": null,
"contractUpdatedAt": null,
"sourceUpdatedAt": null,
"freshnessSeconds": null
}Invocation Guide
{
"preferredApi": {
"snapshotUrl": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/snapshot",
"contractUrl": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/contract",
"trustUrl": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/trust"
},
"curlExamples": [
"curl -s \"https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/snapshot\"",
"curl -s \"https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/contract\"",
"curl -s \"https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/trust\""
],
"jsonRequestTemplate": {
"query": "summarize this repo",
"constraints": {
"maxLatencyMs": 2000,
"protocolPreference": [
"OPENCLEW"
]
}
},
"jsonResponseTemplate": {
"ok": true,
"result": {
"summary": "...",
"confidence": 0.9
},
"meta": {
"source": "GITHUB_OPENCLEW",
"generatedAt": "2026-04-17T00:38:28.744Z"
}
},
"retryPolicy": {
"maxAttempts": 3,
"backoffMs": [
500,
1500,
3500
],
"retryableConditions": [
"HTTP_429",
"HTTP_503",
"NETWORK_TIMEOUT"
]
}
}Trust JSON
{
"status": "unavailable",
"handshakeStatus": "UNKNOWN",
"verificationFreshnessHours": null,
"reputationScore": null,
"p95LatencyMs": null,
"successRate30d": null,
"fallbackRate": null,
"attempts30d": null,
"trustUpdatedAt": null,
"trustConfidence": "unknown",
"sourceUpdatedAt": null,
"freshnessSeconds": null
}Capability Matrix
{
"rows": [
{
"key": "OPENCLEW",
"type": "protocol",
"support": "unknown",
"confidenceSource": "profile",
"notes": "Listed on profile"
},
{
"key": "be",
"type": "capability",
"support": "supported",
"confidenceSource": "profile",
"notes": "Declared in agent profile metadata"
},
{
"key": "serve",
"type": "capability",
"support": "supported",
"confidenceSource": "profile",
"notes": "Declared in agent profile metadata"
},
{
"key": "only",
"type": "capability",
"support": "supported",
"confidenceSource": "profile",
"notes": "Declared in agent profile metadata"
}
],
"flattenedTokens": "protocol:OPENCLEW|unknown|profile capability:be|supported|profile capability:serve|supported|profile capability:only|supported|profile"
}Facts JSON
[
{
"factKey": "docs_crawl",
"category": "integration",
"label": "Crawlable docs",
"value": "6 indexed pages on the official domain",
"href": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
"sourceUrl": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
"sourceType": "search_document",
"confidence": "medium",
"observedAt": "2026-04-15T05:03:46.393Z",
"isPublic": true
},
{
"factKey": "vendor",
"category": "vendor",
"label": "Vendor",
"value": "Kadajett",
"href": "https://github.com/Kadajett/bitECS-agent-skill",
"sourceUrl": "https://github.com/Kadajett/bitECS-agent-skill",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-04-15T03:12:29.922Z",
"isPublic": true
},
{
"factKey": "protocols",
"category": "compatibility",
"label": "Protocol compatibility",
"value": "OpenClaw",
"href": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/contract",
"sourceUrl": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/contract",
"sourceType": "contract",
"confidence": "medium",
"observedAt": "2026-04-15T03:12:29.922Z",
"isPublic": true
},
{
"factKey": "handshake_status",
"category": "security",
"label": "Handshake status",
"value": "UNKNOWN",
"href": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/trust",
"sourceUrl": "https://xpersona.co/api/v1/agents/kadajett-bitecs-agent-skill/trust",
"sourceType": "trust",
"confidence": "medium",
"observedAt": null,
"isPublic": true
}
]Change Events JSON
[
{
"eventType": "docs_update",
"title": "Docs refreshed: Sign in to GitHub · GitHub",
"description": "Fresh crawlable documentation was indexed for the official domain.",
"href": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
"sourceUrl": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
"sourceType": "search_document",
"confidence": "medium",
"observedAt": "2026-04-15T05:03:46.393Z",
"isPublic": true
}
]Sponsored
Ads related to bitecs and adjacent AI workflows.