Game scripting - step by step onboarding tutorial.

ohlidalp

Infamous Developer
Administrator
Developer
Once again I'd like to get more people interested in making scripts for the game. Scripting is not easy to learn but it's worth it. Classic modding only gives you so many options, and for any addition or improvement, you have to wait until devs have time and energy. Not so with scripting - the game already offers pretty much anything you will need, and even if not, extending the scripting is much less work for the developers than with any other modding fileformat.

This thread will give you bite-sized steps to follow, from the simplest and most intuitive to the more involved. You don't need to know anything about programming and you will not be taught here either - instead you'll find out what tools and tricks the game offers to have fun learning later.

This is an outline. I'll expand on every step in later posts with examples and screenshots:
  1. How to use the game console.
    Open it from top menu / tools / show console or by hotkey '`' (the '~' key on top left of keyboard, under Esc). There, in the "Command" box below, type "as" followed by whatever and hit "Submit" button or Enter. The game will try running whatever as a script - so you'll likely get an error. For example, typing just "as" is fine, "as blabla" produces an error "No matching symbol 'blabla'" :) To erase the text in console, use "clear" command. To see all commands, use the 'Commands' menu on top of the console window, or type "help" command. Pressing the 'Up' hotkey while typing will bring back the previous submitted command. Tip: you can actually use the console from main menu, but know that the menu listens to arrow keys and Enter key, so open "credits" window first, otherwise you'll exit your game by accident - happened to me several times :)
  2. Your first working console script.
    Type "as game.openUrlInDefaultBrowser('http://www.rigsofrods.org');" and submit - game will minimize and your web browser will jump up with Rigs of Rods website open. If nothing happened, make sure the "http://" or "https://" bit isn't missing, it doesn't work otherwise. Congrats, you've just made the game do something you can't do via any modding or UI. Strictly speaking, there are some hyperlinks here and there, like repo links in RepositoryUI, but those don't let you open any website you want.
  3. More useful console scripts.
    Type "as game.log('Hello Rigs of Rods');" and submit - you'll see the message repeated in the console. If you close the console window quickly enough, you'll see the message in the chatbox area (bottom left of screen) until it disappears. This is how messages are displayed in the chatbox (or console if it's open). You'll be using this a lot while scripting.
    A more complicated example: copypaste this into the console: "as game.showMessageBox("hello box","hello Rigs of Rods", false, "a", true, false, "b");" and submit - this will open a message box. To find out what all the parameters mean, see game.showMessageBox() in docs.
    One more fun example: "as game.spawnObject("sign-deer", "myDeer01", game.getPersonPosition(), vector3(0,0,0), "!supress", false);" will add a road sign where your character is currently standing! To remove it again, do "as game.destroyObject("myDeer01");"
  4. Enter the Script editor.
    Now that you know some script snippets that actually do stuff in the game, you'll need some bigger textbox to input and edit them, ideally with the option to save and load. In the game top menu, select Tools/Browse gadgets... and in the Loader UI, select "script editor". This will open a window which works like a text editor: there are line numbers on the left in bright yellow color (the other numbers are just funny decorations, you can disable them using the View menu) and on the right, there is the editable text with pre-created example script. There's a "[>>] RUN" button on the top bar - press it and it wil run the script and change to "[X] STOP". Don't worry about the example script being so complicated - unlike the console, the editor can only run a complete programs, not just one-off snippets, but there isn't much to understand. Just know that hitting RUN with completely empty script is OK - the script will load, it will just be completely useless, never actually doing any work. To reset the Tutorial script to original, just close it - it will immediatelly reopen with exactly the startup content.
  5. Seeing and stopping scripts.
    Go back to the console window and open the "Script monitor" menu - you will see a table with heading 'ID | Filename | Options' and 2 horizontal sections: 'Active' and 'Recent'. If you're in menu, both will be empty. If on terrain, you'll see one script, usually with filename "default.as" and options "(terrain)". If script editor gadget is running, you'll see it as additional script with filename "script_editor.gadget" and options "Reload/Stop/Autoload". Yes, gadgets are actually scripts themselves and futher down this tutorial, you'll learn to make your own! The buttons stop or restart the script - try it! The Autoload checkbox will make the script start automatically next time you run the game. Finally, if you also run the example script in script_editor, you'll see it too.
    One thing to take note of is the ID column in the script monitor - this shows the "Script Unit ID" (or NID for short - yes it's a little strange but both SID and SUID were already taken, so I used the next letter: uNit ;-). If the example in script editor is running, you will see the bottom bar say "RUNNING (NID: 123)" where 123 is the same value as the ID in the script monitor. When you know the NID, you can ask the game about the script details, change it's settings or stop it.
to be continued due to character limit...
 
Outline continued due to character limit:
  1. ^ prev post
  2. ^ prev post
  3. ^ prev post
  4. ^ prev post
  5. ^ prev post
  6. Your first complete script.
    Delete everything that's in the editor window, then paste "void frameStep(float dt) { ImGui::Text("NID=" + thisScript); }" and hit RUN. A window titled "Debug" will appear with text "NID=123" on it. Again, the 123 will be the same value as seen in the bottom bar of the script editor "RUNNING (NID: 123)" and in the 'Script Monitor' menu of the console window. This is how a script knows it's own NID. Note this won't work when using "as whatever" in console, console snippets don't have the built-in `thisScript` variable.
    Unlike the window of the example script, this Debug window can't be closed - the [X] button is not there. It's a special window that appears whenever the programmer doesn't create it's own window. That's what the default example script it's for- most of the time a programmer wants a window anyway and if not, they can just delete it.
  7. Understanding that script.
    To understand what's going on, there are just 2 parts to see: the `void frameStep(float dt) { *** }` part and the rest. This `frameStep` piece tells the game to run the code for every frame. If you change anything about it, the script may still run but it won't find the expected `frameStep` function and will consider it an ordinary function that you want to run yourself. You can try this: rename it to `frameBlep`. Script runs but no window appears. Now add `void frameStep(float dt) { frameBlep(dt); }` below it and violá - window appears again because you completed the code.
  8. Adding buttons to the UI
    Showing button is the easy part: put `ImGui::Button("boo")` somewhere in the frameStep function body. But to make the button actually boo boo when you press it, you need to know another programming feature - conditions. Long story short, add `if (true) { ImGui::Text("condition passed"); } if (false) { ImGui::Text("condition failed"); }` anywhere in frameStep body and see for yourself, it's pretty much just english.
    Hardcoding conditions like this would be pretty useless, but you can use them to check result of a function that returns true or false, like `ImGui::Button()` does. So try this in frameStep: `if ( ImGui::Button("boo") ) { game.showMessageBox("boo box","Boo Boo!", false, "a", true, false, "b"); }` :)
  9. Saving and loading scripts.
    The save/load menus in script editor are somewhat quirky. You always start with a Tutorial.as script but this isn't a file on disk, just a tab name in the editor.
    The editor always saves files to your "Documents\My Games\Rigs of Rods\scripts" directory - go to "Save file" menu, change the pre-filled name to Savedscript1.as and hit save. The menu will show green "File saved OK" text. If such file already existed, you'll get a red "Error saving file!" text and you must either use different name or check the "overwrite" checkbox. In the same menu, the script file will appear in "RecentScripts:" and "LocalScripts:" sections below. Beware (this is kind of a bug) that the tab you saved is still "Tutorial.as" and next time you want to save it, you must enter the same name again and check "overwrite". Alternatively, instead of typing the name, you can click the [Select] button next to the desired filename - this will fill the 'File' textbox with that name, but you still need to do Save/overwrite yourself.
    Loading scripts is quite straightforward: open the "Open file" menu and load a previously saved script using the [Load] button. If you've just placed a file in "Documents\My Games\Rigs of Rods\scripts" manually and you don't see it, use a trick to refresh the menu - open any other script or close the Tutorial.as tab which triggers reopening it. The menu only refreshes when a script is loaded.
    This part of the editor needs improvement, I know.
  10. Actually learning programming
    This is your homework! ;) For a technical reference to the scripting language, visit official AngelScript docs - these however don't teach anything, just show existing programmers how things are done there. I've looked on the web and Youtube and I didn't find any good beginner material for AngelScript - it's mostly UE5 or other engine because AngelScript is made to be embedded in games.
    Therefore, I suggest a trick: follow the W3Schools C++ course because C++ is nearly the same as AngelScript, except you output things using `game.log()` or `ImGui::Text()` rather than `cout <<` and you use `void frameStep(float dt)` instead of `int main()` to make things run. Let me know how this worked for you or if you found any better learning material.
  11. Using everything the game can offer
    Go to RoR developer portal - it's mainly focused on scripting, although it documents the internals, too. There's also my older thread AngelScript quickstart guide. Finally, be sure to check out the "Examples" menu in the script editor!
Have fun!
 
Back
Top