{"id":"meowtsun/twig","name":"twig","scope":"meowtsun","platform":"roblox","description":"A lightweight ECS for Roblox focused on fast queries","version":"0.1.3","latest":"0.1.3","versions":["0.1.0","0.1.1","0.1.2","0.1.3"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"3aed9d2bd502a3d61059eeadc7734c358098df2fa5a3a35cbcc84b341346116c","likes":1,"downloads":0,"install":"forest install meowtsun/twig","url":"https://forest.dev/p/roblox/meowtsun/twig","files":"https://api.forest.dev/ai/package/roblox/meowtsun/twig/files","readme":"### Twig\r\n\r\nThe Wicked ecs Inspired by Git<br/>\r\nECS focused on being lightweight and having fast query speed.\r\n\r\n- Fast uncached component queries\r\n- Type-safe Luau API\r\n- Low memory overhead\r\n- Batching changes\r\n- Explicit state publication\r\n\r\n### Benchmark\r\n\r\nTwig's compact archetype representation allows unmatched entities to be rejected cheaply, making highly selective queries particularly fast. \r\nyou can find the benchmark [here](https://github.com/Meowtsun/Twig/blob/main/test/query.bench.luau)\r\n\r\n![Twig benchmark](test/data/query_16_components.png)\r\n\r\n### Overview\r\n\r\n```lua\r\nlocal Twig = require(path_to_twig)\r\nlocal world = Twig.world()\r\n\r\nlocal active = Twig.component() :: Twig.component<boolean>\r\nlocal name = Twig.component() :: Twig.component<string>\r\nlocal disabled = Twig.component()\r\n\r\n-- this initial component is optional\r\nlocal entity = world:spawn({\r\n    active.set(true),\r\n    name.set(\"Dummy\"),\r\n})\r\n\r\n\r\n-- query entities with name and active, but without disabled.\r\nfor entity, name, active in world:query(name, active, disabled.none) do\r\n    -- ...\r\nend\r\n\r\n-- Or check membership directly.\r\nif world:withoutComponent(entity, disabled) then\r\n    -- ...\r\nend\r\n\r\n\r\n-- Twig requires you to explicitly stage which component of which entity\r\n-- was changed if you want to observe the change through Twig's signals.\r\n-- You can stage a component even without changing its value.\r\n-- Or, you can simply not stage() at all if you don't need to publish it.\r\nworld:stage(entity, {\r\n    name,\r\n    active,\r\n})\r\n\r\n-- publishIn will run after you flush everything with world:push()\r\nlocal connection = name:publishedIn(world):Connect(function(entity, value)\r\n    connection:Disconnect()\r\nend)\r\n\r\n-- These two do not require a push(); they fire immediately\r\n-- name:createdIn(world) \r\n-- name:removedIn(world) \r\n\r\n-- Effects use the same system as components,\r\n-- but cannot be added to an entity.\r\n-- They are only staged.\r\nlocal recompute_state = Twig.effect()\r\nlocal same_signal_api = recompute_state:publishedIn(world)\r\n\r\n-- Membership does not matter, entity does not need to have this component.\r\n-- This acts like a built-in push signal using the same API.\r\nworld:stage(entity, {\r\n    recompute_state,\r\n})\r\n\r\n-- flush all staged components of this world\r\nworld:push()\r\n```\r\n\r\n### Installation\r\n\r\nInstall Twig through Wally:\r\n\r\n```toml\r\ntwig = \"meowtsun/twig@0.1.3\"\r\n```\r\n","readmeTruncated":false}