Simulation: Energy System (BETA)

Add a regenerating energy/stamina system to your game. Players spend energy to take actions (start battles, enter dungeons) and it refills automatically over time — even while offline.

This is a self-contained recipe. Everything you need — config, client code, and patterns — is on this page.


Where Config Goes

All JSON config on this page goes in your project's server config — either a single config.json file or split across files in a config/ directory. Each file must have a top-level "simulation" key. The CLI uploads config automatically when you rundot deploy.

my-game/
├── config.json                      ← option A: all-in-one (add "simulation" key)
├── config/                          ← option B: split files for complex games
│   └── energy-system.config.json
├── game.config.json                 ← game ID + build settings only (separate)
└── package.json

game.config.json is for CLI metadata only. Simulation config goes in config.json or the config/ directory.


What You'll Build

  • Energy that regenerates 1 point every N minutes, up to a maximum

  • Actions that cost energy (e.g., starting a battle costs 5 energy)

  • Automatic offline catch-up (player returns after 2 hours → energy has regenerated)

  • A cap so energy stops regenerating at max


Server Configuration

Entities

Define the energy state:

Entity
Purpose

energy_current

The player's current energy. Consumed by actions, refilled by regen.

energy_max

Maximum energy capacity. Use this if max energy can increase (e.g., through upgrades).

Regeneration Recipe

This is the core of the energy system — a timed recipe that auto-restarts to produce 1 energy every cycle:

Field
Value
Why

duration

600000

10 minutes per energy point (in milliseconds).

autoRestart

true

Restarts immediately after granting energy.

concurrency

"single"

Only one regen timer runs at a time.

maxOfflineExecutionPeriod

604800000

Catch up to 7 days of offline regen.

maxRestartCondition

energy_current ≤ 20

Stops regenerating when energy is full.

inputs

{}

Regen is free — no cost to the player.

outputs

energy_current: 1

Grants 1 energy per cycle.

Energy-Spending Recipes

Define actions that consume energy:

Key patterns:

  • battle_start costs 5 energy and sets a battle_pending flag

  • battle_start_free is an alternative for tutorials with no energy cost

  • battle_resolve_forfeit refunds energy if the player cancels before the battle starts

Initialization

Start the regen timer when a new player opens the game for the first time:

The onStart lifecycle hook fires the initial_player_state recipe once. It sets energy to full and kicks off the regen timer.


Client-Side Implementation

Step 1: Read Energy State

Step 2: Subscribe to Real-Time Updates

Subscribe to activeRuns: true to get the regen timer's progress. Each active run includes an expiresAt timestamp you can use to show a countdown.

Step 3: Display Regen Countdown

Step 4: Spend Energy with Optimistic UI

Step 5: Check Requirements Before Showing UI


How Offline Catch-Up Works

  1. Player closes the game with 5/20 energy

  2. Player returns 3 hours later (180 minutes)

  3. Regen is 1 energy per 10 minutes → 18 cycles would have completed

  4. But maxRestartCondition caps at 20, so only 15 energy is granted (5 + 15 = 20)

  5. Player sees 20/20 energy on return

The maxOfflineExecutionPeriod of 7 days means if a player is away for a month, only 7 days of catch-up are calculated.


Common Variations

Dynamic Regen Rate

If regen speed increases with level, use a formula for duration:

Premium Energy Refill

Let players buy energy with premium currency:

Ad-Rewarded Energy

Grant energy for watching an ad — call the recipe after a successful ad view:


Best Practices

  • Always validate energy client-side before calling executeRecipeAsync for responsive UX, but trust the server result as authoritative.

  • Use optimistic updates with rollback — deduct energy immediately, restore on server failure.

  • Subscribe to activeRuns to power countdown timers instead of calculating client-side.

  • Set maxOfflineExecutionPeriod to prevent unlimited offline accumulation.

  • Consider a battle_resolve_forfeit recipe to refund energy when players cancel actions.

  • Keep energy_regeneration metadata hidden: true so it doesn't appear in player-facing recipe lists.

Last updated