Understanding the Engine
The Altruist Engine is a highly optimized game loop that lives inside the Gaming Layer of the Altruist framework. It is specifically designed for games, physics simulations, and other real-time actions that require consistent, frame-based updates.
It provides frame-based execution, ensuring that game logic that uses physics run at a consistent rate to simulate realistic and smooth behaviors.
Note:
When do you need it?
Ask yourself: do you need to run something periodically or simulate real-time behavior on the server? If the answer is yes, read further.
Enabling the Engine
By default, Altruist runs without an internal game loop. To enable the engine, replace .NoEngine()
with .EnableEngine(FrameRate.Hz30)
. This sets up an internal loop running at 30Hz (30 cycles per defined unit).
AltruistBuilder.Create(args)
.SetupGameEngine(setup => setup
.AddWorld(new MainWorldIndex(0, new Vector2(100, 100)))
.EnableEngine(FrameRate.Hz30))
.WithWebsocket(setup => setup.MapPortal<SimpleGamePortal>("/game"))
.WithRedis(setup => setup.AddDocument<Spaceship>())
.WebApp() // for websockets we need a WebApp
.StartServer();
You can increase the frame rate to higher values if needed:
.EnableEngine(FrameRate.Hz60) // 60 cycles per defined unit
or
.EnableEngine(FrameRate.Hz120) // 120 cycles per defined unit
Note:
Higher frame rates improve real-time responsiveness but also increase CPU usage. Choose a frame rate that balances performance and smoothness based on your game's needs.
Note:
Once you enable the engine, responses to clients are no longer sent on demand. Instead, the engine manages the updates, ensuring that only the latest necessary data is delivered. This optimizes bandwidth usage and ensures consistency across all connected clients.
Scheduling Tasks in the Engine
Once the engine is enabled, tasks can be scheduled to run at specific intervals or frequencies.
ScheduleTask()
Using The ScheduleTask
method allows tasks to execute at a specified cycle rate. If no rate is provided, the task runs at the engine’s default frame rate.
engine.ScheduleTask(Save, saveStrategy.SaveRate);
The saveStrategy.SaveRate
is an instance of CycleRate, which defines how frequently a task runs.
Understanding CycleRate
The CycleRate
determines how often a task runs:
Cycle Unit | Meaning |
---|---|
Seconds | 30Hz → Runs 30 times per second (fast) |
Milliseconds | 30Hz → Runs 30 times per millisecond (super fast) |
Ticks | 30Hz → Runs once every 30 CPU ticks (extremely fast) |
Note:
Note: A higher Hz means faster execution for time-based units (Seconds, Milliseconds), but for Ticks, a higher Hz results in slower execution.
Example: Running a Task Faster Than the Engine Rate
If the engine runs at 30Hz, but a regeneration system needs 120Hz, we can specify:
engine.ScheduleTask(RegenerateHealth, new CycleRate(120, CycleUnit.Seconds));
This ensures health regeneration updates occur 4x faster than the engine frame rate, if the engine cycle rate is 30Hz and also defined in seconds.
Note:
If the engine uses a different CycleUnit (e.g., Ticks or Milliseconds), the actual execution frequency will depend on the unit conversion.
Using RegisterCronJob()
For non-frequent periodic updates (e.g., saving player data every minute), use RegisterCronJob
.
engine.RegisterCronJob(Save, saveStrategy.CronExpression);
The CronExpression
follows standard cron syntax e.g.:
Expression | Execution Frequency |
---|---|
"*/1 * * * *" | Every 1 minute |
"0 * * * *" | Every hour |
"0 0 * * *" | Once per day |
Note:
Use case: Scheduled tasks like database backups, leaderboard resets, and daily rewards.
Cycle Attribute
The Cycle
attribute in Altruist is used to annotate methods that you wish to execute on the engine. This attribute allows you to define a schedule for task execution using either cron expressions, frequency in Hertz, or real-time execution. It provides a way to automate method scheduling without manually calling ScheduleTask
.
How It Works
The CycleAttribute
can be used to specify different scheduling strategies based on the method's needs:
CycleAttribute
Properties of - Cron: Defines a cron expression to schedule the method execution.
- Rate: Defines the frequency in Hertz to schedule the method execution.
- Realtime: A boolean flag that determines if the method should execute in real-time, meaning it will match the engine's update frequency.
CycleAttribute
Usage
Example of the Here’s an example of using the Cycle
attribute to schedule a method:
[Cycle(30)] // Executes 30 times per second (30Hz)
public Task UpdateGameState()
{
// Task logic
}
This will ensure that UpdateGameState
is executed at 30Hz.
Understanding the CycleAttribute Properties
1. Cron Expression
A cron expression allows you to specify the method's schedule using a string. This is useful for tasks that need to run at fixed intervals, such as daily or hourly operations.
Example:
[Cycle("0 0 * * *")] // Runs once per day
public Task DailyCleanup()
{
// Task logic
}
In this example, the DailyCleanup
method will be executed once every day at midnight, based on the cron expression 0 0 * * *
.
- Frequency in Hertz
The frequency property allows you to specify how often the method should execute in Hertz (Hz). Hertz refers to the number of cycles per defined unit. For example, 30Hz
means the task will execute 30 times per defined unit.
You can define a method to run at a specific frequency:
[Cycle(120, CycleUnit.Seconds)] // Executes 120 times per second
public Task RegenerateHealth()
{
// Task logic
}
In this case, the ``RegenerateHealth` method will be executed 120 times per second. By default, if no frequency is provided, the task will run at the engine’s default frame rate.
- Real-Time Execution
The Realtime property indicates that the method should match the engine's update frequency. This is useful when you want the method to run in sync with the engine, ensuring it doesn’t get out of sync with the overall game loop.
[Cycle] // Executes in real-time, matching the engine's frame rate
public Task RealTimeUpdate()
{
// Task logic
}
This method will execute at the engine's frame rate, making it ideal for tasks that need to run alongside the main game loop.
Summary
- Enable the engine using
.EnableEngine(FrameRate.HzX)
. - Use
ScheduleTask()
for high-frequency updates. - Use
RegisterCronJob()
for periodic, non-frequent updates. - Specify a
CycleRate
for finer control over execution speed. - Use
[Cycle]
on methods to send to the engine periodically.
By leveraging these scheduling mechanisms, Altruist provides an efficient, scalable way to manage game server updates.