Really Rather Good Battles In Space: Galactic Conflict 4320 - 4359 AD

A guide to creating custom missions

=============

Sections:
1. Step-by-step guide
2. Mission script reference
3. AI script reference
4. Other editable files

=============

1. Step-by-step guide:

1) create a new folder in the game's "missions" sub directory, naming the folder "My Mission" or whatever you want

2) copy all of the contents of one of the pre-existing missions into your new folder to use as a template for your new mission

3) You now have a folder with the following directories. You probably want to delete anything already in them:
images - for character portraits, background images and foreground images
music - for music
sound - chiefly for voiceover sound files, you can also make scripts play other sounds if you want
unitdata - for unit data files
unitpictures - for unit images

The game also has global directories for each of these in the main game directory. When loading a mission the game will first look for files in the mission's directories, and then if a file is not found it will try looking in the global directories (though sounds cannot be loaded from the global sound directory).

In the root of your mission's folder you will have the following other files:

mission.dat - included mission sides, mission briefing, starting view position, music track list, and other general information about the mission. the number before each side is it's alliance flag - sides with the same number are allied and will not fight each other.

*.dat - there is another .dat file for each side in the mission, which lists which units that side starts off with

mission.nut - this script controls dialog, player tasks, victory conditions, and other general mission events. See the "Mission script reference" further down this file for details. mission.nut is also able to control the player's ships in the same way as the per-fleet ai squirrel scripts control the computer fleets, which can be useful in cut scenes. See the "AI script reference" further down this file for details.

*.nut - there is another .nut file for each fleet in the mission (other than the player's fleet), which controls the AI for that fleet. See the "AI script reference" further down this file for details. Note that complicated or poorly written AI scripts can use up very large amounts of processor time, be careful.

4) to edit the ship starting positions in your custom mission, start the game from a command prompt like this:
rrgbis.exe -edit "My Mission"
You can save any changes you make by pressing F10, or display the current view coordinates by pressing F8.

5) to play your custom mission, start the game from a command prompt like this:
rrgbis.exe -mission "My Mission"
If you are using Windows you can create a file called "My Mission.bat", and then copy in the above line before saving it. You can then run your mission by double clicking the .bat file.

6) note that you can turn on "debug mode" by changing "Debug" from 0 to 1 in settings.dat, found in the game's directory in Windows or in ~/.rrgbis in Linux. See readme.txt for a list of the extra hot key commands this enables.

7) if your custom level causes error messages to appear on the screen, or if the game simply crashes, open the file "rrgbis-log.txt" to see any error messages logged by the game

8) the scripting language used by most of the files you can edit is Squirrel, a manual for the language is available here:
http://squirrel-lang.org

=============

2. Mission script reference:

play_script_sound(soundfile)
play the specified sound file

add_portrait(title, image, side)
side is a number from 0 to 1 less than the number of sides. the portrait border will use the color of the specified side (i.e. side 0 is the first side listed in mission.dat)

set_portrait(title)
new dialog will use the portrait with the given title

portrait_text(text, <optional sound file>)
display new dialog with specified text. NOTE: the sound argument is ignored

wait(frames)
suspend script for a specified time in frames (30 frames is one second)

wait_for_portrait()
suspend script until dialog has finished playing

wait_for_task(task, frames)
suspend script until the specified task takes places or the timeout in frames is reached. a timeout of -1 means wait for infinite time. if all of the big ships on a side die (and all their torpedo bomber squadrons are either dead or have landed on a planet), or if a custom ai task is fired, the script will be woken up regardless of the task set.
(random note: if mission_complete() has been called then all of the big ships on a side dying will no longer wake up the script)

These are the available task types:

"all_big_selected"
"number_hotkeyed"
"ships_moving_down"
"missions_open"
"two_fighter_squadrons_selected"
"recon_target_open"
"recon_launched"
"freighter_found"
"bombers_coming_in"
"attack_bomber_launched"
"enemy_under_attack"
"all_big_ships_dead" (though this will always wake up a script regardless of the actual task waited for)
"custom_ai_task_0" (though this will always wake up a script regardless of the actual task waited for)
"custom_ai_task_1" (though this will always wake up a script regardless of the actual task waited for)
"custom_ai_task_2" (though this will always wake up a script regardless of the actual task waited for)
"custom_ai_task_3" (though this will always wake up a script regardless of the actual task waited for)
"custom_ai_task_4" (though this will always wake up a script regardless of the actual task waited for)

Scripts waiting for a custom ai task can be woken up by the per-fleet ai scripts.

wakeup_reason()
returns the reason for the script being woken up, using one of the strings listed above

which_side_dead()
if the script was woken up due to all of a sides big ships dying, this function returns the id of the dead side (0 is the 1st side listed in mission.dat, 1 the 2nd, etc)

suspend()
suspend the script with no specified wakeup message

mission_complete()
increase the maximum mission number that the player can enter to one more than the mission number specified in the side data file, and instantly save the player's profile to disk. Furthermore sides losing all their big ships will no longer send wakeup events to the mission script

end_mission()
go back to the mission select screen

toggle_radar_sharing()
toggle whether allied sides share their radar information (default is true). When turned off the alert messages ("enemy capital ship spotted" etc) are also turned off, on the assumption that if radar sharing is off its because your allies are about to turn on you and when they do you don't want a huge number of "enemy capital ship spotted" etc messages.

change_side_flag(flag)
change the allegiance flag of a side to the specified number

player_failed_mission(message)
mission ends and displays the given failure message

pause_world()
pause the game world, but you can continue adding dialog and setting tasks

unpause_world()
unpause the game world

cut_scene_on()
player can no longer control their units

cut_scene_off()
player control returned

planetary_bombardment_anim()
every single planet in the mission will be covered in bombardment explosions

planetary_invasion_anim()
all capital ships will start launching drop ships towards the first squadron/unit listed in side 1's data file

end_anim()
stop playing the animation

ion_pulse_anim()
all of the foreground pictures will draw an ion pulse animation on top of themselves. this is a one-off animation, you do not need to call end_anim() afterwards

set_viewpoint(x, y)
sets the viewpoint

=============

3. AI script reference:

global arrays:

my_squads
an array of all of the squads this ai script controls. squads are automatically deleted from the array when they are killed, which means that any particular index - e.g. my_squads[2] - might change or indeed disappear during the course of the battle

player_squads
an array of all the player controlled squads

side_1_squads
squads on sides other than this side and the player's side are stored in arrays called side_x_squads, where x is that fleet's number in the misson data file (e.g. the first fleet listed is side_0_squads, etc, though actually side_0_squads is always player_squads)

squad functions - these have to be called on a particular squad, e.g. player_squads[0].highlight():

select()
adds the squad to a list for later manual orders

highlight()
adds the squad to a list for later mission launch

is_moving()
returns true if the squad is currently moving

ready_for_launch()
returns true if the squad is in its hangar and fully refueled

get_in_hangar()
returns true if the squad is inside its hangar

get_type()
returns a number indicating the squads type:
FIGHTER 0
BOMBER 1
FRIGATE 2
CAPITAL 3
FREIGHTER 4
DEFENCE_NODE 5
PLANET 6

get_pos()
returns an array, array[0] is the squad's x position, array[1] is the squad's y position

get_distance(other_squad)
returns the squad's distance to the other squad, e.g. my_squads[0].get_distance(player_squads[3])

get_distance_to_point(x, y)
returns the squad's distance to the given point

global ai script functions:

order_move(x, y)
orders all squadrons that have been selected to move to the given coordinates, and then clears the selected squadrons list. For use with big ships only.

order_halt()
orders all squadrons that have been selected to immediately stop moving, and then clears the selected squadrons list. For use with big ships only.

add_waypoint(x, y)
adds a waypoint to a list for later mission launch

launch_mission(type)
launches all currently highlighted small ship squadrons, and then clears the highlighted squadrons list. Mission types are "recon", "patrol" and "attack".

order_recall()
orders all squadrons that have been selected to defend their parent capital ships, and then clears the selected squadrons list

order_return()
orders all squadrons that have been selected to return to their hangar bay, and then clears the selected squadrons list

ai_suspend()
suspends the ai script for 10 frames

world_frame_counter()
returns the current world frame counter

wakeup_mission_script(which_task)
wakes up the mission script, and sets the wake up reason to the specified number. E.g. wakeup_mission_script(3) wakes up the mission script and sets the wake up reason to "custom_ai_task_3".

is_cut_scene_on()
returns true if a cut scene is currently playing

=============

4. Other editable files:

The following files are easy to edit but when edited they affect all missions, not just your custom mission, so be careful and make backups:

unitdata/equip.dat:
This contains the power, range, recharge time etc for the different engines, weapons, armour, shields. The different stats are not consistent across different equipment/weapon types, e.g. small shield recharge is frames between recharge  of 1 point, capital ship shield recharge is points recharged every frame.

data/aiscripts/*.ai:
These contain the ai scripts that control small ships when they are on a mission.  They are written using a crazy custom scripting language, if you really want to edit these then see the scripting guide for the language at http://galaxyhack.sourceforge.net. However, the language is a bit of a mess to begin with and has had a few confusing custom extensions and rules added for Really Rather Good Battles In Space, so if you really want to mess with this sort of script you should probably just play GalaxyHack.



