Remote control / Metagame interface

From Running With Rifles Wiki
Jump to: navigation, search

This page is work in progress, at this point working just as an info dump.

In general, anything stated below may change at any point during game development, there's certainly some room for cleanup/consistency improvements in there. The information on this page is representative of 1.65. Note that parts of the examples below haven't specifically been tested, so there may be typos in there.

Script flows and interactions[edit | edit source]

Campaign game modes[edit | edit source]

The package_config.xml file in the root folder of a game mod references the campaign_entry_script, which can be an angel script file of your choosing. Scripts load as follows (each script #includes the next):

  1. scripts/start_campaign.as This is the default campaign_entry_script, which links to your mod's source folder and script files, if any.
  2. scripts/my_gamemode.as Imports standard RWR game mechanics and introduces the ability to extend the game's behaviours. This script includes numerous other scripts:
    1. scripts/gamemodes/campaign/gamemode_campaign.as Specifies general functions like load and save. Also loads scripts/gamemodes/invasion/gamemode_invasion.as, which is given its own section, below.
    2. scripts/my_stage_configurator.as Sets faction names, links to faction config files, and specifies faction colours on the game hud and map.
    3. scripts/my_item_delivery_configurator.as Lists weapons that are given as rewards for drop off missions and weapons that are tracked on drop off to armouries for the purpose of unlocking them for the player's faction
    4. scripts/my_vehicle_delivery_configurator.as Similar to the item delivery configurator, lists rewards that will be randomly chosen when tracked vehicles are dropped off at a friendly armoury.

IMPORTANT if your mod's folder structure doesn't contain these .as files, the ones in vanilla/scripts will be used instead. To simplify things — and save you losing your work when the game's scripts are updated — you may want to copy the entire scripts folder from vanilla into your mod's script folder, remove the include reference to the vanilla scripts folder from start_campaign.as (or replace it with the path to your mod's scripts folder) and then go ahead modifying scripts within your mod, only.

Important files[edit | edit source]

  • scripts/gamemodes/invasion/gamemode_invasion.as
- of particular note in this file is the method postBeginMatch(), which includes various addTracker() calls. If you add any Classes that extend the abstract class Tracker (scripts/internal/tracker.as), you will need to reference them here as well as ensuring you #include the associated .as file here as well.
  • scripts/internal/tracker.as starts with an update method, which is constantly triggered by the game engine. The float time value passed to this method is the time that has passed since update was last called. Functions found inside the update method can use this value to manage timed events; indeed, the functions stored here — handle*Event() — are the entry point to many of the other script files used in the game.
- Use a find files containing ... search of the vanilla/scripts folder (or your mod's scripts folder if you've copied the vanilla scripts into your mod's folder structure) to see how these functions of the scripts/internal/tracker.as update method operate.
- It's also a very good time to note that game events will generally be logged in rwr_game.log. For finer detail about what methods of what classes are being called as various game events trigger, add your own _log("my text here", 1); inside the functions you're working with. When you've found your way and are starting to script more confidently, you'll be creating your own variables through scripts and will move onto doing things like _log("the value of myVariable is: " + myVariable, 1); or _log(bombCount + " artillery rounds were fired by faction " + factionID + "'s " + vehName + " and hit " + hitVeh + "at " + pos1, 1);.

Metagame Interface[edit | edit source]

A quick intro to how game scripts work in RWR can be seen by entering the lobby/training mission and typing /_test in chat. That will attempt to launch media/packages/(mod|vanilla)/scripts/start_tester.as, which enables trackers/basic_command_handler.as, a simple chat command listener. Try tailing the rwr_game.log file to see how this all fits together.

  • Linux: tail -f ~/.running_with_rifles/rwr_game.log
  • Windows: get-content "$env:APPDATA\running with rifles\rwr_game.log" -wait
  • Mac: tail -f '/Users/<username>/Library/Application Support/RunningWithRifles/rwr_game.log'

When the basic_command_handler angel script is operating, you can issue numerous commands to it via text chat. For example, typing /test will result in the commander chat saying "test yourself", while typing /_m29 will spawn a magnum revolver near the player. Take a look through the file to see the other commands the listener is programmed to respond to and give them a shot in the game chat.

  • Important note: When the /_test system is executed, it replaces the active metagame (i.e. the scripts from your mod) and enables a new metagame, under which the basic command handler script inputs and outputs occur. Any other scripts that were running at this point may stop working until you restart. Again, you can tail the rwr_game.log to see this happening.

Commands, i.e. inputs to RWR[edit | edit source]

The sections below detail XML commands or metagame calls that can be executed in one or more of the following methods:

  • From an Angel Script (*.as) file found in the scripts folder of the mod, e.g.:
string command = "<command class='value' key1='value1' key2='value2' />";
m_metagame.getComms().send(command);
  • With init_match.xml, usually in a map folder, to run a number of commands at the start of a match
  • When a radio call is made, if the call supplies <command>s inside its <round>s
  • As a <result class="xml_command"><command ... /></result> in events in grenade or vehicle specifications
  • As a local player by typing /_execute file.xml with file.xml in RWR root folder, the file consisting of a <command /> or <commands><command>...</commands>
  • From server console by typing execute file.xml, like above

start_game[edit | edit source]

<command 
  class="start_game" 
  vehicles="1" 
  soldier_capacity_model="variable"
  soldier_capacity_variance="0.3"
  max_soldiers="100" 
  player_ai_compensation="0" 
  player_ai_reduction="0" 
  xp_multiplier="1.0"
  rp_multiplier="1.0"
  initial_xp="0.1"
  initial_rp="200"
  randomize_respawn_items="0"
  base_capture_system="any" 
  clear_profiles_at_start="0"
  team_kills_as_score="0"
  defense_win_time="-1"
  friendly_fire="0">

  <faction initial_occupied_bases="2" initial_over_capacity="0" ai_accuracy="0.94" capacity_multiplier="1.0" capacity_offset="10" />
  <faction initial_occupied_bases="-1" initial_over_capacity="0" ai_accuracy="0.94" capacity_multiplier="1.0" capacity_offset="10" />
</command>

restart_game[edit | edit source]

  • takes same parameters as start_game, with undefined values from the current game

change_game_settings[edit | edit source]

  • takes same parameters as start_game
  • currently can affect player_ai_compensation, player_ai_reduction, max_soldiers, base_capture_system and faction settings

change_map[edit | edit source]

<command 
  class="change_map" 
  map="media/packages/vanilla/maps/map5">
  
  <overlay path="media/overlays/mod1" />
  <overlay path="media/overlays/mod2" />
  <overlay path="media/overlays/mod3" />

  <map_config>
  <faction file="green.xml" />
  <faction file="grey.xml" />
  <weapon file="all_weapons.xml" />
  <projectile file="all_throwables.xml" />
  <call file="all_calls.xml" />
  <vehicle file="all_vehicles.xml" />
  <carry_item file="all_carry_items.xml" />
  </map_config>
</command>
  • map config can be omitted, will use the map_config.xml provided by the map

start_server[edit | edit source]

<command 
  class="start_server" 
  server_name="dedicated" 
  server_port="1238" 
  register_in_serverlist="0" 
  client_faction_index="-1"
  persistency="forever"
  url="http://runningwithrifles.com"
  comment="halp me" >
</command>

set_game_timer[edit | edit source]

<command 
  class="set_game_timer" 
  time="600" 
  faction_id="0" >
</command>
 <command 
   class="set_game_timer" 
   time="-1" >
 </command>

update_score_display[edit | edit source]

<command 
  class="update_score_display" 
  id="0"                            // this is the faction_id
  text="123" >
</command>

commander_ai[edit | edit source]

<command 
  class="commander_ai" 
  faction="1"
  base_defense="0.8"
  border_defense="0.2"
  active="1">
</command>

soldier_ai[edit | edit source]

<command 
  class="soldier_ai" 
  faction="1">
        <parameter class="willingness_to_charge" value="1.0" />
</command>

make_query[edit | edit source]

<command
  class="make_query"
  id="my_query_tag1">

  <!-- generally, you should query as little data as possible, this is just a test -->
  
  <data class="factions" /> 
  <data class="bases" /> 

  <data class="players" /> 
  <data class="characters" faction_id="0" /> 
  <data class="characters" faction_id="1" /> 
  
  <data class="vehicles" faction_id="1" key="cargo_truck.vehicle" /> 
  <data class="vehicles" type_id="42" />
  <!-- a vehicle's 'type_id' is determined by its line position in all_vehicles.xml. The first vehicle type referenced receives type_id '0' -->
  <!-- note a gotcha here is multiple 'special_crate' vehicles are defined in one file, and each vehicle key receives its own type_id... thus the type_id count is thrown out by .xml files in the /vehicles folder where multiple <vehicle> definitions are included. -->

  <data class="hitboxes" faction_id="0" /> 

  <!-- info about specific character, you need to find out id from elsewhere, like characters-query or from incoming events -->  
  <!-- <data class="character" id="0" /> -->
  <!-- <data class="vehicle" id="0" /> -->
</command>
  • data classes available
    • general
    • faction
    • factions
    • bases
    • players
    • characters
    • character
    • vehicles
    • vehicle
    • hitboxes
    • item_containers
    • resources
    • saved_data

In most cases it is not necessary to create queries yourself. The file scripts/internal/query_helpers.as contains utility functions for the most common queries.

xp_reward[edit | edit source]

<command 
  class="xp_reward" 
  character_id="1"
  reward="5.0">

  <!-- 1.0000 equals 10000 XP -->
  <!-- 0.0001 equals 1 XP -->
  <!-- 0.1000 equals 1000 XP, one full rank step -->

</command>

rp_reward[edit | edit source]

<command 
  class="rp_reward" 
  character_id="1"
  reward="10000">
</command>

add_custom_stat[edit | edit source]

<command 
  class="add_custom_stat" 
  character_id="1"
  tag="??">
</command>

This appears to be used when applying an achievement to a character (e.g. blow up 15 barbecues --> "burninator")

kick_player[edit | edit source]

<command 
  class="kick_player" 
  player_id="0">
</command>

update_player[edit | edit source]

<command 
  class="update_player" 
  player_id="0"
  color="#FF0000"
  faction_id="1">
</command>

add_hitbox_check[edit | edit source]

<command 
  class="add_hitbox_check" 
  id="item_supply2_weapon_rack"
  instance_type="vehicle"
  instance_id="1" >
</command>
<command 
  class="add_hitbox_check" 
  id="item_supply2_weapon_rack"
  instance_type="character"
  instance_id="1" >
</command>

remove_hitbox_check[edit | edit source]

<command 
  class="remove_hitbox_check" 
  id="item_supply2_weapon_rack"
  instance_type="vehicle"
  instance_id="1" >
</command>

update_vehicle[edit | edit source]

<command 
  class="update_vehicle" 
  id="0"
  locked="1"
  health="0.5">
</command>

remove_vehicle[edit | edit source]

<command 
  class="remove_vehicle" 
  id="0">
</command>

chat[edit | edit source]

<command 
  class="chat" 
  text="hello world!"
  faction_id="-1"
  player_id="-1"
  position="512 0 512">
</command>
<command 
  class="chat" 
  key="map start with completed map"
  faction_id="-1"
  player_id="-1"
  position="512 0 512">
</command>
<command class='chat'
  key='loot objective'
  priority='1'
  faction_id='0'>
<replacement key='%base_name' text='Ranch' />
<replacement key='%map_name' text='Keepsake Bay' />
<replacement key='%number_of_bases' text='0' />
</command>

notify[edit | edit source]

<command 
  class="notify" 
  text="hello world!">
</command>

set_world_situation[edit | edit source]

<command 
  class="set_world_situation">
  <faction id="0" name="Green" color="0 1 0" />
  <faction id="1" name="Grey" color="0.5 0.5 0.5" />
  <faction id="2" name="Brown" color="1 1 0" />
  <faction id="3" name="Blue" color="0 0 1" />

  <region id='0' name='map1' position='240.318 118.728' size='339.76 297.573' texture_rect='0.00279018 0.00111607 0.317383 0.276646'>
    <occupant id="0" value="1.0"/>
  </region>
  <region id='1' name='map2' position='332.227 172.969' size='587.612 372.154' texture_rect='0.351562 0.317104 0.895647 0.661691'>
    <occupant id="0" value="0.5"/>
    <occupant id="1" value="0.5"/>
  </region>
  <region id='2' name='map3' position='253.878 391.44' size='376.674 247.852' texture_rect='0.00279017 0.317104 0.351563 0.546596'>
    <occupant id="2" value="0.8"/>
    <occupant id="3" value="0.2"/>
  </region>
  <region id='3' name='map4' position='595.898 432.874' size='314.146 360.854' texture_rect='0.351563 0.661691 0.642439 0.995815'>
    <occupant id="2" value="1.0"/>
  </region>
  <region id='4' name='map5' position='383.454 584.297' size='311.886 252.372' texture_rect='0.00279018 0.661691 0.291574 0.895368'>
    <occupant id="1" value="1.0"/>
  </region>
  <region id='5' name='map6' position='176.283 539.096' size='328.46 341.267' texture_rect='0.351562 0.00111608 0.655692 0.317104'>
    <occupant id="3" value="1.0"/>
  </region>
</command>

faction_resources[edit | edit source]

<command 
  class="faction_resources" 
  faction_id="0"
  clear_weapons="1">
  <weapon key="ak47.weapon" />
</command>
<command 
  class="faction_resources" 
  faction_id="0"
  soldier_group_name="miniboss">
  <projectile key="hand_grenade.projectile" enabled="0" />
</command>
<command 
  class="faction_resources" 
  faction_id="0"
  clear_calls="1">
  <call key="tank_drop.call"/>
</command>
<command 
  class="faction_resources" 
  faction_id="0">
  <carry_item key="vest2.carry_item" enabled="0" />
</command>

set_marker[edit | edit source]

<command 
  class="set_marker" 
  faction_id="0"
  id="0"
  enabled="1"
  atlas_index="0"
  text="squad alpha rally point"
  position="512 0 512"
  color="#ff0000"
  range="10.0">
</command>

set_match_status[edit | edit source]

<command 
  class="set_match_status" 
  faction_id="0"
  lose="1">
</command>
<command 
  class="set_match_status" 
  faction_id="1"
  win="1">
</command>

set_metagame_event[edit | edit source]

<command 
 class='set_metagame_event'
 name='character_kill'
 enabled='1' />

Enable the character kill method handleCharacterKillEvent to be processed through scripts/tracker.as

set_spotting[edit | edit source]

<command 
  class="set_spotting" 
  vehicle_id="1"
  faction_id="0">
</command>

Show the vehicle with id '1', belonging to faction '0', on the map.

create_instance[edit | edit source]

<command 
  class="create_instance" 
  faction_id="0"
  position="512 0 512"
  offset="0 0 0"
  character_id="0"
  instance_class="carry_item"
  instance_key="suitcase.carry_item" >
</command>
<command
  class="create_instance"
  faction_id="0"
  position="512 0 512"
  instance_class="character"
  instance_key="default" />
</command>

update_static_object[edit | edit source]

<command
  class="update_static_object"
  key="wall_door"
  destroyed="1" >
</command>

create_call[edit | edit source]

<command 
  class="create_call" 
  faction_id="0"
  position="512 0 512"
  key="cover_drop.call">
</command>

update_inventory[edit | edit source]

<command 
  class="update_inventory" 
  character_id="0"
  container_type_class="stash"
  add="1"
  instance_class="carry_item"
  instance_key="painting.carry_item">
</command>
<command 
 class='update_inventory'
 character_id='0'
 container_type_class='backpack'>
 <item class='carry_item' key='painting.carry_item' />
</command>

update_character[edit | edit source]

<command
  class="update_character"
  id="123"
  dead="1" />
</command>

update_camera[edit | edit source]

<command
  class="update_camera"
  position="512 0 512"
  look_at="??" />
</command>

set_comms[edit | edit source]

<command 
  class="set_comms" 
  faction_id="1"
  enabled="0">
</command>

set_soldier_spawn[edit | edit source]

<command 
  class="set_soldier_spawn" 
  faction_id="1"
  enabled="0">
</command>

set_soundtrack[edit | edit source]

<command
  class="set_soundtrack"
  enabled="1"
  filename="mysound.wav">
</command>

save_data[edit | edit source]

<command 
  class="save_data">
  <root>
  <foo bar="0" />
  </root>
</command>

Events, i.e. outputs from RWR[edit | edit source]

- Don't forget to tail the rwr_game.log file to see these events being output as they occur

match_result[edit | edit source]

<match_result>
  <win_condition type="map_capture" faction_id="0" faction_name="Greenbelts" />
</match_result>

faction_lost[edit | edit source]

<faction_lost>
  <lose_condition type="time_expired" faction_id="1" faction_name="Graycollars" />
</faction_lost>

comms_change_event[edit | edit source]

<comms_change_event
  faction_id="0"
  state="0" />

vehicle_holder_change_event[edit | edit source]

<vehicle_holder_change_event
  vehicle_id="0"
  holder_id="0"
  owner_id="1" />

vehicle_destroyed_event[edit | edit source]

<vehicle_destroyed_event
  vehicle_id="0"
  character_id="0" />

base_owner_change_event[edit | edit source]

<base_owner_change_event
  base_id="0"
  owner_id="0" />

chat_event[edit | edit source]

<chat_event
  player_id="0"
  player_name="pasik"
  message="OMG JEEP"
  global="1" />

player_connect_event[edit | edit source]

<player_connect_event>
  <player 
  name="pasik" 
  player_id="0"
  faction_id="0"
  profile_hash="........."
  ip="192.168.1.5"
  port="43243"
  character_id="123" />
</player_connect_event>

player_disconnect_event[edit | edit source]

<player_disconnect_event>
  <player 
  name="pasik" 
  player_id="0"
  faction_id="0"
  profile_hash="........."
  ip="192.168.1.5"
  port="43243"
  character_id="123" />
</player_disconnect_event>

player_kill[edit | edit source]

<player_kill>
  <killer
  name="pasik" 
  player_id="0"
  faction_id="0"
  profile_hash="........."
  ip="192.168.1.5"
  port="43243"
  character_id="123" />
  <target
  name="JackMayol" 
  player_id="1"
  faction_id="1"
  profile_hash="........."
  ip="xxx.xxx.xxx.xxx"
  port="43221"
  character_id="124" />
</player_kill>

player_die[edit | edit source]

<player_die>
  <target
  name="JackMayol" 
  player_id="1"
  faction_id="1"
  profile_hash="........."
  ip="xxx.xxx.xxx.xxx"
  port="43221"
  character_id="124" />
</player_die>

player_spawn[edit | edit source]

<player_spawn>
  <player
  name="JackMayol" 
  player_id="1"
  faction_id="1"
  profile_hash="........."
  ip="xxx.xxx.xxx.xxx"
  port="43221"
  character_id="125" />
</player_spawn>

hitbox_event[edit | edit source]

<hitbox_event hitbox_id="blahblah" instance_type="character" instance_id="125" />
<hitbox_event hitbox_id="blahblah" instance_type="vehicle" instance_id="125" />

item_drop_event[edit | edit source]

<item_drop_event 
  character_id="0" 
  item_class="0"
  item_type_id="0"
  target_container_type_id="0"
  item_key="ak47.weapon"
  position="512 0 512"
  player_id="0" />

call_request_event[edit | edit source]

<call_request_event
  character_id="0"
  faction_id="0" 
  call_id="0"
  call_key="cover_drop.call"
  target_position="968.851 16.7647 400.99"
  player_id="0" />

This event is only emitted when the call has the attribute notify_metagame set to "1" like

<call key="cover_drop.call" notify_metagame="1">
  <!-- defition goes here -->
</call>

user_quit_event[edit | edit source]

<user_quit_event />

Troubleshooting / bug smashing[edit | edit source]

rwr_game.log error messages[edit | edit source]

loading faction resources in <mod_folder_path>/factions/<file_name>
<some_text>
CHECK: characters or character element not found 
execution halted

This error indicates you have made reference to a non-existent character file in factions/<faction>.xml.
Ensure the file exists in the factions folder, is spelled correctly, matches the case and launch the game again.


loading faction resources <mod_folder_path>/factions/common.resources
loading faction resources in <mod_folder_path>/factions/<another_file>.resources
loading faction resources in 
CHECK: resources element not found
execution halted

This error indicates you have made reference to a non-existent resources file. The actual file causing the error (typo, doesn't exist, or trying to load a non-existent resource) will be the file loaded after <another_file>.resources is listed in factions/<faction>.xml.


loading calls in <mod_folder_path>/calls/<call_name>
loading calls in 
CHECK: calls or call element not found
execution halted

Similar to the error above, this error indicates you have made reference to a non-existent call file in calls/all_calls.xml. Calls are generally processed in the order they are listed in all_calls.xml, so check which call was the last to load before the error occurred and the error will most likely be to do with the next referenced file.


<filename.as> (line_num, col) : ERR  : No matching signatures to '<text>'

Does <filename>.as include the file that contains the class, constructor, method, etc. referenced in text?

Issues that don't show up in rwr_game.log[edit | edit source]

  • Commander briefing at start of mission fails to appear
- This generally indicates you have made a syntax error early on in /languages/en/default_shared.character, such as a missing forward slash '/' at the end of a <comment key="blah" text="blah blah" /> tag. Every line after the one(s) with a syntax issue will fail to be read at start time, resulting in the comment keys used in the commander briefing failing to appear.
- You may also notice unprivileged calls (xp < 1000) don't result in a text bubble advising "I don't have a radio yet" or other text string appropriate to the <comment key="no radio equipment"... />. These comment tags start from line 110, so your syntax error is going to be before this line.

Creating your own Class[edit | edit source]

Extending the Tracker Class[edit | edit source]

  1. Create a new file within the scripts/trackers folder named something like myClass.as
  2. #include the .as scripts your class relies on (e.g. calls to _log() require log.as or another file that includes it to be listed here).
  3. Define your class with class MyClass : Tracker { ... }
  4. Specify its constants and variables e.g. protected Metagame@ m_metagame;
  5. Add the constructor e.g. MyClass(Metagame@ metagame) { @m_metagame = @metagame; }
  6. Add your custom methods protected void doSomethingMethod(const XmlElement@ block) { ... }
  7. Finally, add common class methods:
/* These first two are often commented out, but are left in here as a reference, should you choose to use them
// --------------------------------------------
void init() {
}

// --------------------------------------------
void start() {
}
End comment*/

// --------------------------------------------
bool hasEnded() const {
	// always on
	return false;
}
// --------------------------------------------
bool hasStarted() const {
	// always on
	return true;
}
// --------------------------------------------
void update(float time) {
	// add your custom update scripts in here like:
	// incrementing or decrementing counters
	// testing for something based on the counter value e.g. <= 0
	// writing something to the log (warning! will spam the log - update methods are called multiple times per second)
}
// ----------------------------------------------------