Write a one-line formula in a Conditional Branch or Control Variables — safe, server-side, and RPG Maker-friendly.
Event Expressions
Most event logic needs no formula: a Conditional Branch can already test a switch, a variable, an item, a skill or a quest. When a test needs several values at once — "at least 3 wolf pelts and 50 gold, or the Hunter quest done" — or a Control Variables needs a value worked out from others, write an expression instead.
Expressions are a small, safe formula language. They are not JavaScript: an expression can only read the values listed below, can never change anything, and is checked and run by your game server for the player the event is running for.
Where to author it#
Open any map in Zones, switch to the Events layer and double-click an event (or open a Common Event). In the page's command list:
| Command | Where the expression goes |
|---|---|
| Conditional Branch | Tab 4 → Script → Expression. The branch runs when the expression is true (see Truthy values) |
| Control Variables | Operand → Script → Expression. The result is used as the number to set, add, subtract, multiply, divide or modulo |
Both use the same Expression box. It checks what you type against the language on this page a moment after you stop typing — see What the editor checks. The language reads like JavaScript and accepts RPG Maker's common spellings, but it is not JavaScript.
A third place exists for events the AI or an import wrote: a Conditional Branch → Variable whose Compare To is Expression compares the variable against a formula instead of a number. The editor shows that choice only on a command that already uses it; pick Constant or Variable to go back to a plain comparison.
Setting one up#
- Add a Conditional Branch and open tab 4.
- Pick Script and type the test in the Expression box, for example
item("wolf_pelt") >= 3 && gold >= 50. Wait for the line under the box to say This expression can run. - Put what should happen in the branch, and what happens otherwise in Else.
- Press Save in the event editor. A new expression that cannot run stops the save: a red message names the page and the command, and the editor stays open with your edits.
- Save the map, then Publish so your game server runs the new page.
- Walk up to the event in game (or run a Playtest) and check both outcomes.
What the editor checks#
An expression the game cannot read never stops anything in play: a condition quietly counts as false and a value as 0. So Studio checks expressions in three places, before a player ever meets one.
The Expression box#
| Part | What it does |
|---|---|
| Expression | The formula. Checked about a third of a second after you stop typing, and straight away when you open an event |
| Line under the box | ✓ This expression can run, or ✕ the problem and where it is, for example Unexpected ")" (at character 5). A blank box says Nothing typed yet. Screen readers are told each change |
| Marked text | When there is a problem, the expression is repeated with the part the problem starts at highlighted |
| You can write / You can read | The operators and the values the language knows — the same lists as on this page |
| Expression guide | Opens this page |
While there is a problem, or the box is blank, the line also says what the game would do with it as it stands: counts as false for a condition, counts as 0 for a value.
Saving#
Saving refuses a new expression that cannot run. The same rule applies wherever an event is saved:
| Where you save | What happens |
|---|---|
| Save in the event editor | A red message, and the editor stays open on the event with your edits kept |
| Save in Common Events | The message shows in the Common Events window; the events before the refused one are saved, the rest stay unsaved |
| Saving the map (or autosave) | Tiles you painted are saved; the map's events and placed objects are not. The message shows once and the editor stops retrying until you fix the event. This only happens for an event that reached the map without going through the event editor's Save — for example one pasted from a map that never held that expression |
| The AI writing an event | The AI is told which command and why, and what the language supports, before anything is written |
- The message names the event, the page and the command, then the problem: Not saved: an expression cannot run (in game it would count as false). Event “Gate” › page 2 › command 5 (Conditional Branch → Script): Unknown function "hour" (at character 1) in “hour() >= 9”.
- Fix the expression (or delete the command) and save again.
- A blank Script condition or Script operand counts as one that cannot run.
What is not refused:
- Expressions that were already saved on that map (or in that common event) before you opened it. A map save sends every event on the map, so an old problem on an event you did not touch never blocks your work.
- The scripts an RPG Maker import brings in, the first time the imported map is saved. RPG Maker scripts are JavaScript; the ones this language cannot read are kept as they are so you can rewrite them when you get to them.
- Restoring from History or undoing an AI change. What comes back is what was saved before.
Edit one of those old expressions and it is checked like any other: change an imported $gameParty.members().length > 2 to something the language still cannot read and the save is refused until it can run.
Project Health#
Tools → Project Health lists every event and common event that already holds an expression the game cannot run — see Project Health. Use it after importing an RPG Maker project to find the script conditions that need rewriting. Nothing is rewritten for you.
What you can write#
| You write | Meaning |
|---|---|
12, 3.5, "text", 'text', true, false | Numbers, text and yes/no values |
+ - * / % | Arithmetic. + with any text joins them as text |
< <= > >= | Comparisons |
== / != | Equal / not equal, loosely ("5" == 5 is true) |
=== / !== | Equal / not equal, exactly ("5" === 5 is false) |
&& || ! | And, or, not. The right side is only worked out when it is needed |
( ) and a ? b : c | Grouping, and "if a then b otherwise c" |
What you can read#
| Value | What it reads |
|---|---|
var(n) | Variable n — the same numbered variables Control Variables writes |
switch(n) | Whether switch n is ON |
selfSwitch("A") | This event's self switch A–F, or a self variable by its id |
item("id") | How many of that item the player carries |
skill("id") | The player's level in that skill |
stat("hp") | One of level, hp, maxHp, mp, maxMp, stamina, maxStamina, x, y, facing |
state("id") | Whether the player has that status effect |
quest("id") | The quest's status as text: "none" (never started), "active", "completed" or "failed" |
level gold hp maxHp mp maxMp stamina maxStamina x y facing | The same player values without stat(…). x and y are the tile the player stands on; facing is 8 up, 6 right, 2 down, 4 left (diagonals 9, 3, 1, 7) — see Player Location in Events |
timer | Seconds left on the event timer (0 when it is stopped) |
timeOfDay | The world's time of day as text: "dawn", "morning", "noon", "afternoon", "dusk" or "night" |
hour | The in-game hour, 0–23. A bare name: hour >= 9, not hour() |
weather | The weather where the player stands, as text (for example "clear") |
Ids go in quotes — they are the ids shown in the database editors, not the display names.
Helpers#
| Helper | Result |
|---|---|
random(a, b) | A whole number from a to b, both included |
min(a, b, …) / max(a, b, …) | The smallest / largest of up to 16 values |
abs(n) floor(n) ceil(n) round(n) trunc(n) | Sign and rounding |
clamp(n, lo, hi) | n held between lo and hi |
number(v) / string(v) | Turn a value into a number / text |
RPG Maker spellings#
Imported events keep working when their script uses the common RPG Maker calls:
| RPG Maker | Same as |
|---|---|
$gameVariables.value(n) | var(n) |
$gameSwitches.value(n) | switch(n) |
$gameParty.gold() | gold |
Math.floor, Math.ceil, Math.round, Math.abs, Math.min, Math.max, Math.trunc | The helpers above |
Math.randomInt(n) | A whole number from 0 to n − 1 |
The shorter v(n) and s(n) also work. When you import an RPG Maker project, $gameVariables.value(12) is rewritten to read the imported variable 5012, the same as every other variable reference.
Examples#
| Goal | Expression |
|---|---|
| Enough pelts and gold | item("wolf_pelt") >= 3 && gold >= 50 |
| Night-only, or anyone who finished the watch quest | timeOfDay == "night" || quest("night_watch") == "completed" |
| Wounded players only | hp < maxHp / 2 |
| A reward that grows with level (Control Variables → Set) | clamp(level * 10, 10, 200) |
| A 1-in-4 chance | random(1, 4) == 1 |
Truthy values#
A branch runs its then side when the expression comes out as: true, any number other than 0, or any non-empty text. false, 0 and "" run Else.
A Control Variables operand needs a number: true counts as 1, false as 0, and text as its number ("12" → 12) or 0 when it isn't one.
Gotchas#
- A new mistake stops the save; an old one does not. Studio refuses to save a new expression it cannot read — a typo, an unknown name, raw JavaScript like
$gameParty.members().length. Expressions saved before Studio checked them, and scripts an RPG Maker import brought in, still save; in game they make the branch take Else and the operand 0, and the game server logs one warning naming the event. Find them all in Tools → Project Health. hour,gold,leveland the other player and world values take no parentheses.hour() >= 9is refused (Unknown function "hour"); writehour >= 9. Onlygold()is accepted both ways.- The checker reads the formula, not your project.
item("wolf_pelt")passes whether or not an item with that id exists, andvar(900)passes whether or not variable 900 is defined. A wrong id reads as 0 in game. - Expressions only read.
=is refused (use==to compare); to change a variable, use Control Variables with the expression as its operand. - Dividing by zero gives 0, never infinity.
- Limits: up to 2,000 characters, 512 tokens and 48 levels of nesting per expression, and 5,000 steps per run; text built by an expression is capped at 1,000 characters. Past a limit, the expression counts as a mistake (above).
- The Script event command still does not run. Only the Script condition and the Script operand use expressions; a free-standing Script command (RPG Maker's code block) is kept for reference and skipped. The command list marks it Not run, and Project Health lists the events that hold one.
- Converting an event to an NPC conversation reports expressions. A conversation cannot evaluate one, so a branch with a working expression makes the event partial — see Event → Conversation.
- No feature flag. Expressions are part of events and always available.