{"id":"dubalda/mercs","name":"mercs","scope":"dubalda","platform":"roblox","description":"ECS for Luau and Roblox built on inverted bitsets, with a jecs-like API","version":"0.1.2","latest":"0.1.2","versions":["0.1.0","0.1.1","0.1.2"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"e785efd6d4000b9b820e917a346cbd250ae9c550887c86954f4251716c1358a6","likes":0,"downloads":0,"install":"forest install dubalda/mercs","url":"https://forest.dev/p/roblox/dubalda/mercs","files":"https://api.forest.dev/ai/package/roblox/dubalda/mercs/files","readme":"# mErCS\nECS (an entity component system) for Luau and Roblox built on inverted bitsets\n\nInstead of archetypes, every component, tag and pair keeps a bitset of the entities that have\nit. Adding or removing a component never moves an entity and never creates an archetype, so\nfrequent structural changes — state tags, relationships, spawning and despawning — stay O(1),\nmemory does not grow with the number of component combinations, and there is nothing to clean\nup. The API follows [jecs](https://github.com/Ukendio/jecs); moving jecs code over takes a few\nmechanical changes (see [Migrating from jecs](docs/jecs-comparison/README.md#migrating-from-jecs)).\n\nStatus: pre-release. Tested with the standalone `luau` 0.703 CLI (interpreter and native code\ngeneration) and in Roblox Studio with the Benchmarker plugin and the jabby debugger; the full\nStudio check (`studio/`) is pending.\n\n## Why\n\n| | jecs 0.11 | mErCS |\n|---|---|---|\n| add / remove a component | moves the entity, copies all its columns | sets a bit and a value: O(1) |\n| new combination of components | creates an archetype, kept until `world:cleanup()` | nothing to create |\n| pair with many targets | an archetype per target | one small record per pair, freed with its target |\n| components per world | 256 via `world:component()` | no limit |\n| a synthetic game frame (interpreter / native) | 5.22 / 4.58 ms | 2.46 / 1.62 ms |\n| heap growth in a long session with changing targets | +15 MB after 5000 frames | +0.4 MB, flat |\n| memory per entity with 4 components | 320 B | 130 B |\n\nIn Roblox Studio (the Benchmarker plugin, native code) mErCS takes 0.53× of the jecs time to\nspawn entities, 0.17× to remove a component, 0.22× for a hierarchy with relationships and\n0.10× for batch changes; see the [results and screenshots](docs/jecs-comparison/README.md#roblox-studio-benchmarker).\n\nBeyond jecs: `query:each` (the fastest loop), OR terms, batch operations on query matches,\nchange tracking by ticks, disabled entities, hierarchies of any depth.\n\n## Installation\n\nCopy `src/init.luau` into your project as a ModuleScript (for example\n`ReplicatedStorage.mErCS`; `src/jabby.luau` is an optional child module for the jabby\ndebugger), or sync the repository with Rojo (`default.project.json`), or depend on it through\nWally (`mercs = \"dubalda/mercs@0.1.2\"`). The module has no dependencies; `--!native` is enabled\nat the top of the file.\n\n## Quick start\n\n```luau\nlocal ecs = require(ReplicatedStorage.mErCS)\nlocal world = ecs.world()\n\nlocal Position = world:component() :: ecs.Component<Vector3>\nlocal Velocity = world:component() :: ecs.Component<Vector3>\nlocal Frozen = world:entity() -- any entity can be used as a tag\n\nlocal e = world:entity()\nworld:set(e, Position, Vector3.zero)\nworld:set(e, Velocity, Vector3.xAxis)\n\n-- the fastest loop: a callback per entity\nworld:query(Position, Velocity):without(Frozen):each(function(entity, position, velocity)\n    world:set(entity, Position, position + velocity)\nend)\n\n-- or a for-in loop, as in jecs\nfor entity, position, velocity in world:query(Position, Velocity) do\n    world:set(entity, Position, position + velocity)\nend\n\n-- relationships\nlocal parent = world:entity()\nworld:add(e, ecs.pair(ecs.ChildOf, parent))\nprint(world:parent(e) == parent) --> true\nworld:delete(parent) -- deletes e as well (ChildOf cascades)\n\n-- one change to every match of a query\nworld:query(Position):with(Frozen):remove_all(Velocity)\n```\n\n`examples/basics.luau` is a runnable tour: `luau examples/basics.luau`.\n\n## Documentation\n\nThe [documentation site](https://dubalda.github.io/mErCS/) holds the API reference (built\nfrom the doc comments of `src/`) and these pages:\n\n- [Guide](docs/guide/README.md) — worlds, components, queries, batch operations, relationships,\n  hooks, change tracking, the jabby adapter, types.\n- [Comparison with jecs](docs/jecs-comparison/README.md) — design, differences, benchmarks,\n  migrating from jecs.\n- [Development](docs/development/README.md) — layout, tests, checks, benchmarks, Roblox Studio,\n  CI and releases.\n\n## License\n\nMIT\n","readmeTruncated":false}