I think you’re describing an array of structures, and you’re one step away from greatly increasing the performance — if you just reverse the storage and have a struct of arrays with the same semantics, the whole thing would be much more cache friendly (unless, of course, there is value boxing in play, which could be avoided at least for some values in Common Lisp, but is generally a PITA for performance).
The comparison of the syntax for defintions also might be fruitful, I still haven’t figured the perfect way to define entities, components and systems in code. Here’s how your example will look using my library now:
(ecs:bind-storage)
;; provided myentity, position and sprite components are defined elsewhere
(ecs:make-object `((:myentity) (:position :x 1 :y 1) (:sprite "path/to/sprite")))
(defsystem render
(:components-ro (position sprite))
(draw-sprite :x position-x :y position-y sprite-path))
Note how in defsystem
macro I just write the body of code to process the single entity with no looping logic (it is kinda embeeded into macro itself). I also use quasiqoute to build an object spec to be passed to make-object
(kinda similar to your create-world
, but for single object). I can’t remember, does Scheme has quasiquoting?
cannot query on component values
This is correct for most of ECS implementations there are, but I went ahead and implemented hashtable-based indices in my library, akin to the ones in relational databases. They allow to answer the question “which entity or entities has this specific value as this component’ slot?” I think it might come in handy in implementing things like entity names or prefabs. I’m already using those to e.g. distinguish different images in texture atlas: https://github.com/lockie/mana-break/blob/0.0.1/src/atlas.lisp#L13-L18