synpixel/planck_snake_case
YetAnotherClown's Planck, but snake_case
Planck, an ECS Scheduler
An Agnostic Scheduler, inspired by Bevy Schedules and Flecs Pipelines and Phases.
Installation
You can install Planck with Wally
[dependencies]
planck = "yetanotherclown/[email protected]"
What is Planck?
Planck is a standalone scheduler, which allows you to execute code on specific events, with certain conditions, and in a particular order.
This scheduler is library agnostic, which means that it doesn't matter which ECS library your using or if you're even using an ECS. You can use this with Jecs, Matter, ECR, and other Luau ECS Libraries.
Does any of this really matter?
Yes, and no. Your ECS code should be able to run in any order, without any conditions, and without concern for which event it's running on, as long as it is running.
The order of execution, and conditions both serve to optimize your code. Some systems don't need to run every frame, which is why we have conditions. And the actual order of execution is to reduce latency between changes and effects in your ECS world.
Let's say we have system_a
and system_b
. system_a
modifies data in our world which system_b
depends on.
If system_a
runs after system_b
, then system_b
will have to wait a whole frame for the modifications to be made.
This is called being off-by-a-frame, and this is why we care about the order of execution.
What's Next?
You may not completely understand what's written above. That's fine.
For now, you should read the Official Documentation on how to get started with Planck. These concepts will be explained more in depth as you read.
Quick Overview
While it's highly suggested you read the documentation, here is a quick overview of Planck's API.
The Scheduler
This is the core of Planck, this is where you add your Systems and set your Phases, Pipelines, and Run Conditions.
local planck = require("@packages/planck")
local Scheduler = planck.Scheduler
local jecs = require("@packages/jecs")
local World = jecs.World
local world = World.new()
local state = {}
local scheduler = Scheduler.new(world, state)
Systems
Systems are really simple, they are just functions which run on an event or in a loop.
local function system_a(world, state)
-- ...
end
return system_a
And to add it to our Scheduler,
-- ...
local system_a = require("@shared/systems/system_a")
local scheduler = Scheduler.new(world, state)
:add_system(system_a)
Phases
Phases are used to split up your frame into different sections, this allows us to schedule our systems to run at different moments of a given frame.
local planck = require("@packages/planck")
local Scheduler = planck.Scheduler
local Phase = planck.Phase
-- ...
local system_a = require("@shared/systems/system_a")
local my_phase = Phase.new("my_phase")
local scheduler = Scheduler.new(world, state)
:insert(my_phase)
:add_system(system_a, my_phase)
Planck has lots of built-in Phases that should work for most cases, → Built-in Phases
Pipelines
Pipelines are ordered groups of Phases, they make working with larger collections of Phases (which all run on the same event) easier.
local Phase = Planck.Phase
local Pipeline = Planck.Pipeline
local Scheduler = Planck.Scheduler
local PreUpdate = Phase.new()
local Update = Phase.new()
local PostUpdate = Phase.new()
local UpdatePipeline = Pipeline.new()
:insert(PreUpdate)
:insert(Update)
:insert(PostUpdate)
local scheduler = Scheduler.new(world)
:insert(UpdatePipeline, RunService, "Heartbeat")
Tip
The UpdatePipeline
seen here, already exists in Planck! It's a built-in Pipeline that you can use without any setup.
See all Built-in Phases.
Conditions
When we run all our systems every frame, there are a lot of systems that may not actually need to run. Run Conditions allow us to run our Systems, Phases and Pipelines only sometimes.
local function condition(world)
if some_condition then
return true
else
return false
end
end
local scheduler = Scheduler.new(world)
:add_run_condition(system_a, condition)
:add_run_condition(some_phase, condition)
:add_run_condition(some_pipeline, condition)
Conditions can be useful, but you should use them carefully. It's suggested that you read our page on Conditions to see some useful examples and learn when you should use them.
Inspiration
Planck's API design is heavily influenced by the Bevy Engine, with Schedules, RunConditions, and more. Planck also draws inspiration from Flecs for Pipelines and Phases.
We're combining the simple, and beloved API of Bevy with the concept of Pipelines and Phases.