Skip to content

Devtools: Scripting

xmeadow edited this page Mar 13, 2026 · 1 revision

Scripting

The great majority of the game's logic is in scripting. Unless you want to fix bugs or turn SoulFu into a completely different game, you will deal with scripting, not C programming.

Notes from Aaron Bishop (Dunlar)

  1. The script system was the very first thing written for this game. It works as intended. If there is a problem, it is 99.99% likely to be in the script itself.
  2. The script system is not careful with where you access memory — you can crash the game. Be careful.
  3. Don't attempt to use Lua. Switching over would be nearly impossible.
  4. Use the Emacs tool. It allows you to recompile your script as you go. Export, save, and backup often.
  5. An indent system is used to force clean code.
  6. To use the tools while playing, open WMESSAGE.SRC and change the first line to: #define CHEAT (SystemGet(SYS_DEVTOOL, 0, 0) && SystemGet(SYS_KEYDOWN, 99, 0)) — then press Recompile. Hold C while playing to pop up the tools. WSTATUS.SRC, WSPAWN.SRC, and IRING.SRC have similar cheats built in.

Some of the most important scripts are GENERIC, STANDARD, ITEMREG, and MAPGEN. The starting point for the script system is WSTART.SRC, Spawn() function.

Emacs Editor Shortcuts

  • CTRL-K — Cut (several lines)
  • CTRL-C — Copy (single line only)
  • CTRL-V — Paste

Always: Export → Recompile → Save


Basics

The script system is essentially a mini version of C with a few peculiarities. It is case insensitive — GOOD, good, and GoOd are all the same.

Comments

// This line is ignored

Defines

#define cookies 7

Place #define at the beginning of the file. It is accessible from anywhere in the file.

Functions

int ModelSetup()
  • First part (int): return type
  • Second part (ModelSetup): function name (a–z only)
  • Third part (()): arguments

Function contents must be indented with two spaces.

Variables

int number
number = 1

Types: int (integer, -32768 to 32767) or float (large range, less precision). Use float only when necessary.

An int can also store text strings and pointers:

int text
text = "Hello world!"

int file
file = "FILE:MYFILE.DAT"

Multiple declarations:

int text, number

Variables start with an unknown value — always initialise before use.

Arithmetic Operations

number = 9 + 1   // add
number = number - 1   // subtract
number = number / 3   // divide (remainder discarded for int)
number = number * 3   // multiply
number = 14 % 3  // modulus (remainder), result: 2
number++         // increment
number--         // decrement

Shifts: << Y multiplies by 2^Y, >> Y divides by 2^Y. Faster than multiplication/division.

Control Flow

if( x + 1 > 0 )
  CallMadeUpFunction()
else
  CallAnotherMadeUpFunction()

while( x < 100 )
  x++

Conditional operators: == != < > <= >= && || ! & |

Avoid infinite loops — SoulFu will freeze.

Pointer Safety

Always check pointers before use:

target = FindTarget()
if(target)
  target.x = 5.0

Predefined Basic Functions

  • if(x) / else / while(x)
  • ToInt / ToFloat
  • LocalMessage(X, Y) — prints X : Y to message window
  • NetworkMessage / LogMessage
  • FindSelf() — returns pointer to current object
  • SystemSet / SystemGet
  • DebugMessage(X) — prints DEBUG: X
  • sqrt / sin
  • FileOpen(X, Y) — returns pointer to file X with action Y
  • FileReadByte(X, Y) — reads byte from file X at position Y
  • FileWriteByte(X, Y, Z) — writes byte Z to file X at position Y
  • FileInsert(X, Y, Z, A) — inserts/removes bytes (devtool only)
  • Spawn / GoPoof(X) / Dismount
  • RollDice(X, Y) — returns random value 0 to Y-1, X times
  • PlaySound / PlayMegaSound / DistanceSound / PlayMusic
  • UpdateFiles(MODE)UPDATE_END, UPDATE_RECOMPILE, UPDATE_SDFSAVE

Predefined String Functions

  • String(X) — returns pointer to one of 16 global strings (0–15)
  • StringGetNumber / StringClear / StringClearAll()
  • StringAppend / StringCompare
  • StringChopLeft / StringChopRight
  • StringSetValue(X, Y, Z) — overwrites byte in string X at position Y with Z
  • StringRandomName / StringSanitize / StringLanguage
  • StringUppercase / StringLowercase
  • StringAppendNumber(X, Y, Z) — converts number Y to string, appends to X

Window Functions

  • WindowBorder(X, Y, Z, A, B, C) — creates a window (X=draggable, Y=x pos, Z=y pos, A=width, B=height, C=border type)
  • WindowString / WindowMinilist / WindowSlider / WindowImage
  • WindowTracker / WindowBook / WindowInput / WindowEmacs
  • WindowMegaImage / Window3DStart / Window3DEnd
  • Window3DPosition / Window3DModel / Window3DRoom
  • ModelAssign / ParticleBounce / WindowEditKanji

Fast Functions

Called by the game automatically — implement as needed:

  • Spawn() — called when script object is created
  • Refresh / Event / AIScript / ButtonEvent
  • GetName / Unpressed / FrameEvent / ModelSetup
  • DefenseRating / Setup / DirectUsage / EnchantUsage

Extra Functions

  • IndexLocalPlayer / FindBinding
  • FindTarget / FindOwner
  • FindIndex / FindByIndex(X) — returns pointer to character at index X
  • FindWindow / FindParticle
  • AttachToTarget / GetDirection / DamageTarget
  • ExperienceFunction / AdquireTarget / FindPath
  • ButtonPress / AutoAim / RoomHeightXY / return

Calling External Script Functions

IMANA.Effect(self)

Use <FILENAME WITHOUT EXTENSION>.<Function> to call functions from other .SRC files.


Conventions

Filename Conventions

Prefix Type
C Creature / object
I Item
W Window
P Particle
  • Source C files: lowercase
  • Game data files (in SDF): UPPERCASE
  • Game logic: .SRC extension
  • Function names: camelCase (PlaySound, not PLAYSOUND) — exceptions: if, while, else, sqrt, sin, return
  • Variable names: lowercase

Tips

  • Don't name variables after script filenames or #define constants — you'll accidentally use the wrong value.
  • If you find something not described here, check DEFINE.TXT — it's likely a global define.

Clone this wiki locally