tiny ECS engine with a hot-modifiable hotloop. use whatever graphics toolkit you like via ffi. so far i implemented using raylib

Requirements:

  • [Janet] with ffi
  • raylib dynamic library/shared object file (get it [here] and put it into the modules folder or, on linux it is expected in /usr/local/lib/libraylib.so), or built it yourself:
git clone https://github.com/raysan5/raylib.git raylib
cd raylib/src/
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=SHARED # To make the dynamic shared version.

   -- from https://github.com/raysan5/raylib/wiki/Working-on-GNU-Linux

To get this project:

  • get [fossil]
  • open a command line interface and call:
    md mxl
    cd mxl 
    fossil clone https://www.awesemble.de/cgi-bin/fossil/public/myxle myxle.fossil
    fossil open myxle.fossil
    

you can start the demo using the batch file or shellscript. once the repl has quieted down and the window is initialized you may use the REPL as normal. define a component-generator like:

# the sprite system draws the provided texture based on the component generator used in adding the component

(def og-janet-banan
  '(let [entity-id :janet-banan
           it (dyn :instructiontable)
         once-upon-a-texture (get-in it [:once entity-id :result])    # get loaded texture from hotloop environment
         rng (get-in it [:once :rng :result])
         offset (math/rng-int rng)]
    @{:texture (tuple/brackets ;once-upon-a-texture)                # the actual component is a table
      :tint (array/new-filled 4 0xff)
      :position @{:x 0 :y 0}
      :timingoffset offset}))


 #-- some of this will have to be moved into the actual system. though it works for now

the important bit is that this is quoted and will evaluate to a table compatible with the system already defined in mxbanan.janet line 93

# the sprite-circler system fetches the sprite componets' screenposition and modifies it.

(def og-sprite-circler
  '@{:system :sprite})

#-- a much more simple component generator simply linking one component to another

once you have a component generator like that you can add it to an entity (e.g. :banan) and specify what system that is supposed to be processed with (e.g. :sprite defined here mxbanan.janet:95 ):

(component+ :banan :sprite og-janet-banan)

remove them:

(component- :banan :sprite)

and (exit) to teardown the raylib environment.

(os/exit) stops the janet repl like usual

check out modules/myxle.janet for more functions like system+ (overwrites an already existing system with the new and drops all old components) , once (to load textures or reseed your rng)

there are also three collections that can be filled with functions to execute:

  • :pre
  • :post
  • :exit

and three operations on those collections:

  • :push
  • :pop
  • :clear

using this you can unload textures and close the window if any:

  (fnstack-clear :exit)
  (fnstack-push :exit
     '(do
       (pp "unloading texture")
       (rl/unload-texture lenna-t)))
  
  (fnstack-push :exit
     '(do
       (pp "closing window")
       (rl/close-window)))

im using emacs as my ide, instructions for setting emacs up to work with janet are [here]

[License]

this repo is licensed under The Prosperity Public License 3.0.0 so use it or get lost. contributions will be checked and might be applied, you are definetly encouraged to take it apart to learn from it (if you find anything worthwhile...)

if you want to use it commercialy read the License: try it for 30days, then we talk.


On 2023-02-10 18:56:28 UTC anonymous (claiming to be an anonymous cat) added:

this is a test to see how anonymous additions would look like