Hi all, I recently started tinkering with PICO-8 which is amazing, but coming from a Unity background, I'm still wrapping my head around it. I've been trying to put together a little ecs framework for me to use in prototypes which is more Unity-like than some of the ecs snippets I've seen on this forum (I'm sure those are better once you're used to the way PICO-8 does things, I'm just trying to make a stepping stone). I thought for the purposes of devs like me wanting to learn things in a bit more of a familiar way, I might as well share what I've learned. Unlike the ecs frameworks I've seen so far which use pattern matching for running methods, I've tried to make the "components" here self contained, and then adding that functionality to the entity table. With no custom components (which need to be made to actually use this) it comes to 108
tokens
Very rough library code below:
-- all the entities in the game entities = {} -- entity "constructor" - returns an entity which is really just a table of components with -- a run() and a draw() method function mk_entity() local e = {} e.components = {} -- basically override the indexer of the entity table to allow for syntax like -- 'player.transform' instead of 'player.components.transform' setmetatable(e, { __index = function(entity,component_name) if (entity.components[component_name]) then return entity.components[component_name] else return nil end end }) -- iterates through our components and calls their run() method if they have one e.run = function() for c_name,c in pairs(e.components) do if (c["run"]) then c.run(e) end end end -- iterates through our components and calls their draw() method if they have one e.draw = function() for c_name,c in pairs(e.components) do if (c["draw"]) then c.draw(e) end end end add(entities,e) return e end -- component "constructor" which is a table with a name (which is a key for this component on the entity) function mk_component(component_name,entity) c = {} entity.components[component_name] = c return c end |
And here's some example usage
-- an example component with some fields and methods function add_transform(entity, x, y) t = mk_component("transform",entity) t.x = x t.y = y t.w = 10 t.h = 8 t.run = function () t.x += 1 end t.draw = function () print(t.x .. ' ' .. t.y .. ' ' .. t.w .. ' ' .. t.h) printh(t.x .. ' ' .. t.y .. ' ' .. t.w .. ' ' .. t.h) end end --example usage function _init() player = mk_entity() add_transform(player,32,60) printh(player.transform) end -- update all entities function _update() for entity in all(entities) do entity.run() end end -- draw all entities function _draw() cls() for entity in all(entities) do entity.draw() end end |
Hope this helps someone!
[Please log in to post a comment]