Stunts

"The scene does not start when I press the button. The button is how I keep up with the scene." — Stage-caller Vesh Antilles

What a stunt is

A stunt is a cue sheet — the list a stage manager calls a show from. You write down the beats of your scene in order, load it, and then walk it with three bound keys. Nothing fires on a timer.

That last part is the whole point. A scripted chain that dumps a table, a blackout and an announcement on people in the same second gives them nothing to play against. A cue sheet puts every beat behind a keypress, so the scene moves when you judge the room is ready.

The sheet lives on your machine, not the server. You author it locally, and you can hand the file to another DM.

Getting set up

bind RIGHTARROW "stuntaction"
bind UPARROW    "stuntnext"
bind DOWNARROW  "stuntprev"

/stunt binds prints those for you to paste.

Key Does
stuntaction Fires the current cue, then moves to the next one
stuntnext Moves the cursor forward. Fires nothing.
stuntprev Moves the cursor back. Fires nothing.

Sitting and pressing stuntaction repeatedly walks the whole sheet. stuntnext and stuntprev let you skip a beat or back up without committing to it.

A sheet ships with the mod as an example. Try it with /stunt load example, then /stunt show.

Writing a sheet

Sheets are plain text at stunts/<name>.cfg in your StoryForce folder. Comments start with // or #. There is no header — just cue lines.

1|add model models/map_objects/desert/table.md3 320 -80 24 0 90 0 100|A table fades in
2|cs A table stands where there was none|Point it out
3|fade out; wait 900; teleport ian window; wait 600; fade in|Ian slips to the window

Each line is <number>|<commands>|<description>.

The number is a label, not the order. Cues always run in file order. The number is what /stunt show prints and what /stunt goto jumps to, so you can renumber freely without the sheet rearranging itself underneath you.

The description is optional and is what you see in the console and on the HUD when you step onto the cue. Leave it off and you get the command text instead.

Several commands in one cue

Separate them with ;. Use wait <ms> to put a beat between them:

3|fade out; wait 900; teleport ian window; wait 600; fade in|Ian slips to the window

That is one keypress. You still choose when the beat starts — you just don't have to hand-time the three commands inside it.

; always separates commands, so it cannot appear inside message text. Write a comma or a dash instead — cs The door opens; the guard turns would try to run "the guard turns" as a command.

Cues you cannot take back

Put a ! at the start of the line and the cue needs two presses — the first arms it and warns you, the second (within two seconds) fires it:

!10|changemap mp/ffa5|THE JUMP - confirm twice

Worth doing for anything irreversible: a map change, npc remove all, the finale. A key held a moment too long shouldn't detonate your scene.

Managing a sheet

Command Does
/stunt load <name> Load stunts/<name>.cfg
/stunt list List your sheets
/stunt show Print the sheet with a marker on the current cue
/stunt goto <n> Jump the cursor to a cue
/stunt reload Re-read the file after editing, keeping your place
/stunt stop Abort a cue that is mid-play
/stunt dry 1 Rehearsal mode — print cues instead of firing them

/stunt goto is how you cope when players go somewhere you didn't plan for: skip ahead, drop back, pick the sheet up wherever it now makes sense.

/stunt dry 1 walks the sheet printing what it would send. Do this once before a session — it is the only way to catch a mistyped command before there is an audience.

Recording a sheet

Rather than writing a sheet by hand, you can perform it once:

/stunt record alley
   ... place things, fade, move people ...
/stunt record stop

Everything you do gets written out as cues. For placement commands the recorder fills in the exact coordinates, which is the part that makes a sheet replayable.

Command Does
/stunt record <name> Start recording
/stunt record stop Write the file
/stunt record mark <text> Give the cue you just recorded a description
/stunt record undo Drop the last cue (use when the server rejected a command)
/stunt record wait <ms> Add a pause after the last cue's commands
/stunt record join Merge the last two cues into one
/stunt record cancel Throw the recording away

ESC-menu buttons are not recorded. The menus send commands by a route the recorder can't see. Record from the console, from your binds, or from the in-world placement modes (Entities → Models, Effects, Lights, Sounds, NPCs) — those are captured perfectly, with exact coordinates already baked in. Chat is never recorded either, which is deliberate: no account name or password can end up in a file you hand to someone else.

The file is rewritten after every cue, so a crash loses nothing, and an open recording is saved automatically if you change map or quit.

Placement and coordinates

Commands like /add model place things at your crosshair. A cue that just says add model cinematics/table will put the table wherever you happen to be looking when the cue fires — which is rarely where you meant.

Two ways to avoid that:

  1. Record the sheet (above). Coordinates get filled in for you.
  2. Give coordinates by handadd model <path> <x> <y> <z> <pitch> <yaw> <roll> <scale>. Read positions off /list and /telemark.

A few commands have no coordinate form at all — /poi, /mypoi, /add spawnpoint, /add lock and /npc spawn. The recorder marks those in the file so you know they will replay wherever you are standing or looking.

Things worth knowing

Stepping back does not undo. stuntprev moves the cursor. The table stays spawned, the fade stays up. If a scene needs resetting, make that a cue:

9|scene load alley_start|RESET the set

Cues can contain any command, including stunt commands. That gives you a few tricks for free:

  • End a sheet with stunt load act2 to roll straight into the next one.
  • Put say_director Cue 7 fired in a cue so your co-DM follows along on Director Notes.
  • Make a panic cue — fade in; camera stop — and /stunt goto it when something breaks.

Command pacing depends on the server. Servers limit how fast a client can send commands. StoryForce servers ship with this set low so cues fire promptly, but on a server that hasn't been configured, a wait shorter than about a second will be stretched. The game tells you when you load a sheet if that applies, so you are never guessing.

On screen

The cue you are on appears in the StoryForce indicator row as [Stunt 3/12: Ian slips to the window], alongside [DIRECTOR] and the rest. It turns red while a guarded cue is waiting for its second press.

Turn it off with sf_stunthud 0.