-
Notifications
You must be signed in to change notification settings - Fork 7
Devtools: 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.
- 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.
- The script system is not careful with where you access memory — you can crash the game. Be careful.
- Don't attempt to use Lua. Switching over would be nearly impossible.
- Use the Emacs tool. It allows you to recompile your script as you go. Export, save, and backup often.
- An indent system is used to force clean code.
- To use the tools while playing, open
WMESSAGE.SRCand 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, andIRING.SRChave 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.
-
CTRL-K— Cut (several lines) -
CTRL-C— Copy (single line only) -
CTRL-V— Paste
Always: Export → Recompile → Save
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.
// This line is ignored
#define cookies 7
Place #define at the beginning of the file. It is accessible from anywhere in the file.
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.
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.
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.
if( x + 1 > 0 )
CallMadeUpFunction()
else
CallAnotherMadeUpFunction()
while( x < 100 )
x++
Conditional operators: == != < > <= >= && || ! & |
Avoid infinite loops — SoulFu will freeze.
Always check pointers before use:
target = FindTarget()
if(target)
target.x = 5.0
-
if(x)/else/while(x) -
ToInt/ToFloat -
LocalMessage(X, Y)— printsX : Yto message window -
NetworkMessage/LogMessage -
FindSelf()— returns pointer to current object -
SystemSet/SystemGet -
DebugMessage(X)— printsDEBUG: 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
-
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
-
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
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
-
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
IMANA.Effect(self)
Use <FILENAME WITHOUT EXTENSION>.<Function> to call functions from other .SRC files.
| Prefix | Type |
|---|---|
C |
Creature / object |
I |
Item |
W |
Window |
P |
Particle |
- Source C files: lowercase
- Game data files (in SDF): UPPERCASE
- Game logic:
.SRCextension - Function names: camelCase (
PlaySound, notPLAYSOUND) — exceptions:if,while,else,sqrt,sin,return - Variable names: lowercase
- Don't name variables after script filenames or
#defineconstants — you'll accidentally use the wrong value. - If you find something not described here, check
DEFINE.TXT— it's likely a global define.