How to add a new script command

Jump to navigation Jump to search

Adding a new script command can be one of the easiest ways to contribute to the engine, if the implementation of the command itself is simple.

Scripts in plotscr.hsd[edit]

Firstly, consider whether the command can be directly accomplished by adding a script to plotscr.hsd instead of hard-coding it.

  • Previously we preferred to put a lot of the implementation of a new command in plotscr.hsd when we could: for example get enemy stat is a script that calls read enemy data. In hindsight this was often not a good idea. For example, it was a mistake to add the read enemy data command, which now makes it more painful to change the enemy data file format. Also, scripts provide worse error checking, and it often turns out that in future we need to convert a script to a builtin command anyway.
    • However it's generally alright to add more wrappers around commands like read/write general since it seems unlikely that most of that data will change in format.

Built-in commands[edit]

If you need to add a new built-in command:

  • Add a line to the end of the define function block in plotscr.hsd.
    • The format is id, name, number of arguments, default argument values. Number of arguments can be -1 to allow any number. Unfortunately, there's no way to specify which arguments are required. Just set their default values to an invalid value that will throw an error in-game.
    • Use the next available ID number.
  • Change maxScriptCmdID in
  • Add the command to sfunctions in scriptcommands.bas. You'll notice that the commands aren't ordered by ID number, but are in four blocks. It doesn't matter where you put the command; at the end is fine.
    • The return value is scriptret. If you don't set it, it will be 0. If your command can fail (e.g. using an item that the player doesn't have), it's a good idea to set it to true (1) for success, false (0) on failure
      • If the command returns a handle to something it should ideally return 0 on failure, and a non-zero value otherwise. Is 0 is a valid value (e.g. hero party slot), return something invalid instead (e.g. -1).
    • Arguments are available in the retvals() array. Use the valid_* functions to check if an argument should be of a certain (conceptual) type, like an NPC ID/reference. Add a new function if it's a new type.
    • You can also call scripterror directly to signal other mistakes in calling the command. For new commands, in general use error level serrBadOp (which is the default, so can be omitted). Don't use serrBound.
  • Recompile: run scons game

Common checklist[edit]

  • Test it. Ideally, add a test case if possible to autotest.rpg. Edit testgame/autotest.hss and run scons autotest to compile and import the scripts (and also recompile Game if needed) and run autotest.rpg. Don't press any keys while the game is running. If any test fails the tests will end early, and error messages are printed to g_debug.txt.
autotest.hss contains a huge number of tests which are run in order, so you need to be careful not to break other tests by changing the state of the game. For example if you more the hero you probably need to move it back to where it was after the test. This is admittedly not ideal.

See Also[edit]