Log In  
Follow
KatrinaKitten
Follow

20y/o trans lesbian. I enjoy programming, D&D, and anime among other things.
Gamedev beginner, though not for lack of trying.

Here's a tiny entity-component-system framework for anyone who might need such a thing! It weighs in at only 108 tokens as of v1.0. This framework assumes (but does not technically require) the strictest definition of the concept, that being that entities and components define no behavior internally but rather are acted upon by externally defined systems that function on the data contained in the entity/components themselves.

The implementation of systems is a slightly refined version of @selfsame's earlier implementation, which treated the "components" simply as keys of the entity, rather than modular objects in their own right. It's also been slightly token-optimized, at 38 instead of 47, but assumes at least the table structure implemented by the entity factory function. I highly recommend @selfsame's version if you need something even more lightweight than this, at the cost of a little flexibility.

If you really need to be stingy about tokens, you can even leave out the component factory function to save 16 tokens, at a minimum of 0 extra tokens per component creation. It's mostly included for simplicity and clarity, but is not strictly required to function.

Copy and paste the code below into a new tab of your project to get started - I'd very much appreciate if you leave the credit comment at the top, but I won't be mad if you don't =)

--tiny ecs v1.1
--by katrinakitten

function ent(t)
 local cmpt={}
 t=t or {}
 setmetatable(t,{
  __index=cmpt,
  __add=function(self,cmp)
   assert(cmp._cn)
   self[cmp._cn]=cmp
   return self
  end,
  __sub=function(self,cn)
   self[cn]=nil
   return self
  end
 })
 return t
end

function cmp(cn,t)
 t=t or {}
 t._cn=cn
 return t
end

function sys(cns,f)
 return function(ents,...)
  for e in all(ents) do
   for cn in all(cns) do
    if(not e[cn]) goto _
   end
   f(e,...)
   ::_::
  end
 end
end

From there, you can use the system like so. Keep in mind that the + and - operators on entities are destructive and modify the existing entity, regardless of whether you use += or -=; since they result in the same token count, I highly recommend you still use the assignment variants unless you're really in a performance crunch, for the sake of clarity.

local entity    = ent({ ... })
local component = cmp("name", { ... })
local component = { _cn="name", ... }  --if cmp is not included

entity += component  --add a component
entity -= "name"     --remove a component

if entity.name then
 --executes only if the "name" component exists
 --access component properties via
 entity.name.property
end

local system = sys({ "name", ... }, function(e, ...)
 --will execute for each entity with all listed components
 --varargs will be passed through from system call
end)

system({ entity, ... })
system({ entity, ... }, "some args", ...)

Here's a simple demo of using this system with the following test code (outdated - v1.0):

function _init()
 local e1=ent({ x=0,y=0 })
 local e2=ent({ x=0,y=0 })
 e1+=cmp("test",{state="cmp1"})
 e2+=cmp("test",{state="cmp2"})

 local s=sys({"test"},function(e,s)
  ?s..e.cmp.test.state
 end)

 s({e1,e2},"before: ")
 e2-="test"
 s({e1,e2},"after: ")
end

Cart #gazihisifi-0 | 2020-07-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

Changelog:

  • v1.1 (BREAKING)
    • Changed access pattern from e.cmp.name to e.name
    • This reduces access cost but may clobber entity properties, so be careful!
  • v1.0
    • Initial release
P#80110 2020-07-30 03:24 ( Edited 2020-07-31 22:23)

Cart #refebeziw-5 | 2020-07-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

Hey all! This is my first little Pico-8 experiment, and like I almost always do with any game engine, a Snake clone was first on the list. I'm not a great artist, so excuse the lack of polish in the sprites ^^

Points by fruit type:

  • Apple - 1 point
  • Plum - 1 point
  • Blueberry - 1 point
  • Peach - 1 point
  • Blackberry - 1 point
  • Bronze apple - 2 points
  • Silver apple - 5 points
  • Golden apple - 10 points

Each fruit you eat will increase the length of your tail by 1 tile.
Going off the edge of the screen will wrap you around to the other side.
Don't run into your tail, and try to survive as long as you can!

My high score as of version 1.4 is 88 - see if you can beat me!

Changelog:

  • v1.4
    • Slowed snek down slightly (12 moves/s -> 10/s)
    • Added SFX on game start
    • Switched from table to sprite flags for fruit scores
    • Major token optimization
    • Removed unnecessary blank map area
    • Commented game code
    • Added changelog to cart file
  • v1.3
    • Improved the main menu significantly
    • Added a simple "Game Over" message
    • Major internal improvements
  • v1.2
    • Added a main menu!
    • Added persistent high scores
    • Added another fruit variation (blackberry)
    • Condensed and optimized a bunch of stuff
  • v1.1
    • Added new fruits (plum, blueberry, peach, bronze/silver apples)
    • Changed background color to allow for more fruit variations
    • Optimized code slightly, particularly drawing cod
  • v1.0
    • Initial release
P#79811 2020-07-23 19:06 ( Edited 2020-08-01 04:18)

Follow Lexaloffle:        
Generated 2020-08-10 21:49 | 0.112s | 4194k | Q:42