Difference between revisions of "Multiplayer Scripting"

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Clearer distinction between machine network ID and object ''network'' ID + clearer publicVariable-JIP link)
(Add more details about the different machines, add setVariable description, move remoteExec/Call up)
Line 41: Line 41:
 
See [[Locality in Multiplayer]] for more information.
 
See [[Locality in Multiplayer]] for more information.
  
=== Different machines ===
+
=== Different machines and how to target them ===
 
{|class="bikitable"
 
{|class="bikitable"
 +
|+ Valid for {{arma3}}
 
!Machine
 
!Machine
 
!Conditions
 
!Conditions
Line 59: Line 60:
 
|-
 
|-
 
|[[Arma 3 Headless Client|Headless Client]]
 
|[[Arma 3 Headless Client|Headless Client]]
|{{Inline code|not [[hasInterface]] && not [[isDedicated]]}}
+
|{{Inline code|not [[hasInterface]] && not [[isServer]]}}
 
|}
 
|}
 +
'''For an extended version for all games, click "Show text"'''
 +
<spoiler>
 +
{|class="bikitable" style="line-height: normal; text-align: center"
 +
!Targeted machine
 +
!{{ofp}}
 +
!{{arma}}
 +
!{{arma2}}
 +
!{{arma3}}
 +
|-
 +
!'''Dedicated Server'''<br />
 +
<small>A server without a human player behind it</small>
 +
|[[local]] myLogic && [[player]] != [[player]]
 +
|[[isServer]] && [[player]] != [[player]]
 +
|[[isDedicated]]
 +
|[[isDedicated]]
 +
|-
 +
!'''Player Server'''<br />
 +
<small>A server hosted by a player</small>
 +
|[[local]] myLogic && [[player]] == [[player]]
 +
|[[isServer]] && [[not]] [[isDedicated]]
 +
|[[isServer]] && [[not]] [[isDedicated]]
 +
|[[isServer]] && [[not]] [[isDedicated]]
 +
|-
 +
!'''Server'''<br />
 +
<small>Any server, dedicated or hosted</small>
 +
|[[local]] myLogic
 +
|[[isServer]]
 +
|[[isServer]]
 +
|[[isServer]]
 +
|-
 +
<!--
 +
!'''Player-controller machine'''<br />
 +
<small>Any machine controlled '''with''' a human player behind it</small>
 +
|[[player]] == [[player]]
 +
|[[player]] == [[player]]
 +
|[[player]] == [[player]]
 +
|[[hasInterface]]
 +
|-
 +
-->
 +
!'''Client'''<br />
 +
<small>A player connected since the lobby</small>
 +
|[[player]] == [[player]] && [[not]] [[local]] myLogic
 +
|[[not]] [[isServer]] && [[player]] === [[player]]
 +
|[[not]] [[isServer]] && [[player]] === [[player]]
 +
|[[hasInterface]] && [[not]] [[isServer]]
 +
|-
 +
!'''JIP Client'''<br />
 +
<small>A player connected in the middle of a mission</small>
 +
|''N/A''
 +
|[[not]] [[isServer]] && [[player]] != [[player]]
 +
|[[not]] [[isServer]] && [[player]] != [[player]]
 +
|[[hasInterface]] && [[didJIP]]
 +
|-
 +
!'''Headless Client'''<br />
 +
<small>A client without a human player behind it<br />
 +
(used to offload server calculations)</small>
 +
|colspan="3"|''N/A''
 +
|[[not]] [[hasInterface]] && |[[not]] [[isServer]]
 +
|}
 +
</spoiler>
 +
 
* If you want to know if the current machine is a server (Dedicated Server or Player Server), use {{Inline code|[[isServer]]}}.
 
* If you want to know if the current machine is a server (Dedicated Server or Player Server), use {{Inline code|[[isServer]]}}.
 
* If you want to know if the current machine has a player (Player Server included), use {{Inline code|[[hasInterface]]}}.
 
* If you want to know if the current machine has a player (Player Server included), use {{Inline code|[[hasInterface]]}}.
{{Warning|a [[Arma 3 Headless Client|Headless Client]] '''can''' be [[Join In Progress|JIP]]!}}
+
{{Warning|A [[Arma 3 Headless Client|Headless Client]] '''can''' be [[Join In Progress|JIP]]!}}
  
 
=== General information about locality ===
 
=== General information about locality ===
Line 86: Line 148:
 
* locality will change from server to client when a player gets in an empty vehicle
 
* locality will change from server to client when a player gets in an empty vehicle
 
* locality can also change in the event of a [[Team Switch]] or usage of [[selectPlayer]]
 
* locality can also change in the event of a [[Team Switch]] or usage of [[selectPlayer]]
 +
{{Informative|Since {{arma3}} the [[Arma 3: Event Handlers#Local|"Local" Event Handler]] triggers when an object's locality is changed.}}
  
 
=== Code examples ===
 
=== Code examples ===
Line 142: Line 205:
  
  
== PublicVariable commands ==
+
== Sending information across network ==
  
 +
=== Remote Execution ===
 +
 +
Since {{arma3}} v1.50, [[remoteExec]] and [[remoteExecCall]] efficient engine network commands are available:
 +
["Message to everyone, including JIP players!", 0, true] [[remoteExec]] ["hint"];
 +
See [[Arma 3 Remote Execution]] for more information.
 +
 +
{{Important|The two methods below are considered '''OBSOLETE''' since {{arma3}} v1.50!}}
 +
 +
{{arma3}} alpha introduced [[BIS_fnc_MP]]:
 +
["Message to everyone, including JIP  players!", "hint", true, true] call BIS_fnc_MP;
 +
 +
{{arma2}} introduced the (obsolete in {{arma3}}) [[Multiplayer framework]]:
 +
waitUntil { not isNil "BIS_MPF_InitDone"; };
 +
[nil, nil, rHINT, "Message to everyone!"] call RE;
 +
 +
=== PublicVariable commands ===
 
PublicVariable commands allow to send '''global''' variables to specified machines.
 
PublicVariable commands allow to send '''global''' variables to specified machines.
 
* Network reception is guaranteed
 
* Network reception is guaranteed
Line 166: Line 245:
 
|}
 
|}
  
=== How it works ===
+
==== How it works ====
The server has the variable {{Inline code|ABC_Score}} to send to everyone:
+
The server has the variable {{Inline code|ABC_Score}} to broadcast:
 
  ABC_Score = 5; {{codecomment|// sets the value}}
 
  ABC_Score = 5; {{codecomment|// sets the value}}
 
  [[publicVariable]] "ABC_Score" {{codecomment|// publishes the variable (do not forget the quotes!)}}
 
  [[publicVariable]] "ABC_Score" {{codecomment|// publishes the variable (do not forget the quotes!)}}
Line 178: Line 257:
  
  
== Remote Execution ==
+
=== setVariable command ===
 
+
Available since {{arma2}} the '''public''' version of the [[setVariable]] command allows you to store a variable into an object and spread this variable across the network.
{{arma2}} introduced the (obsolete in {{arma3}}) [[Multiplayer framework]], used as follow:
+
{{Feature arma3|In {{arma3}} it is possible to broadcast the [[nil]] value, thus deleting the variable from the target.}}
waitUntil { not isNil "BIS_MPF_InitDone"; };
 
[nil, nil, rHINT, "Message to everyone!"] call RE;
 
 
 
{{arma3}} alpha introduced [[BIS_fnc_MP]] (obsolete since {{arma3}} v1.50):
 
["Message to everyone, including JIP  players!", "hint", true, true] call BIS_fnc_MP;
 
 
 
{{Important|These two methods above are considered '''OBSOLETE''' since {{arma3}} v1.50 introduced two engine commands: [[remoteExec]] and [[remoteExecCall]].}}
 
 
 
 
 
'''{{arma3}} (&gt; v1.50):'''
 
["Message to everyone, including JIP players!", 0, true] remoteExec ["hint"];
 
See [[Arma 3 Remote Execution]] for more information.
 
  
  
== onPlayerConnected/onPlayerDisconnected events ==
+
== Player connection events ==
  
 
The following commands will execute given code when a player is connecting or disconnecting. This code will run for players connecting in the lobby '''and''' for [[Join In Progress|JIP]] players!
 
The following commands will execute given code when a player is connecting or disconnecting. This code will run for players connecting in the lobby '''and''' for [[Join In Progress|JIP]] players!
 
* [[Arma 3: Event Handlers/addMissionEventHandler#PlayerConnected|addMissionEventHandler["PlayerConnected"]]]
 
* [[Arma 3: Event Handlers/addMissionEventHandler#PlayerConnected|addMissionEventHandler["PlayerConnected"]]]
 
* [[Arma 3: Event Handlers/addMissionEventHandler#PlayerDisconnected|addMissionEventHandler["PlayerDisconnected"]]]
 
* [[Arma 3: Event Handlers/addMissionEventHandler#PlayerDisconnected|addMissionEventHandler["PlayerDisconnected"]]]
{{Informative|Before {{GVI|arma3|1.57}} use [[BIS_fnc_addStackedEventHandler]] for [[onPlayerConnected]]/[[onPlayerDisconnected]].}}
+
{{Informative|Before {{arma3}} v1.57, use [[BIS_fnc_addStackedEventHandler]] for [[onPlayerConnected]]/[[onPlayerDisconnected]].}}
  
  

Revision as of 01:38, 30 January 2019

This page aims to explain notions and specificities of Multiplayer Scripting and its differences with Singleplayer Scripting.


The basics

  • In Multiplayer, players are connected to a server.
    • The server is a machine that distributes information among clients, such as unit positions, vehicle speeds, etc.
    • The server can be either a dedicated machine, or hosted by a player; in the latter it means the server can have a player unit.
  • A machine connected to a server is called a client.
    • Clients can join a mission after it started: they are considered "JIP" and scripting should be adapted to them. See the Join In Progress chapter for more information.
In Singleplayer, the game acts as a player-hosted server (isServer returns true).
Some Multiplayer commands do not work in Singleplayer, such as netId !
The other way around, some Singleplayer commands do not work in Multiplayer (e.g setAccTime).


Locality

Definitions

  • LOCAL is an attribute for the machine where the command/script/function is executed.
    • to check if an argument is local, use the local command
  • REMOTE means non local. All player-controlled soldiers are remote units to a dedicated server, for example.
    • to check if an argument is remote, simply use not local myObject
  • commands arguments and effects can be either local or global:
Arguments of this scripting command have to be local to the client the command is executed on a local argument means an argument that is processed on the machine where the command is executed
Arguments of this scripting command don't have to be local to the client the command is executed on a global argument means any argument, even a remote one
Effects of this scripting command are not broadcasted over the network and remain local to the client the command is executed on a local effect means that the effect will only happen on the machine where the command is executed
Effects of this scripting command are broadcasted over the network and happen on every computer in the network a global effect means that all the computers will receive it

See Locality in Multiplayer for more information.

Different machines and how to target them

Valid for Arma 3
Machine Conditions
Dedicated Server isDedicated
Player Server hasInterface && isServer
Client hasInterface && not isServer
JIP Client hasInterface && didJIP
Headless Client not hasInterface && not isServer

For an extended version for all games, click "Show text" Show text


  • If you want to know if the current machine is a server (Dedicated Server or Player Server), use isServer.
  • If you want to know if the current machine has a player (Player Server included), use hasInterface.

General information about locality

  • about player:
    • a player's unit is always local to the (human) player's machine
    • a dedicated server doesn't have a player unit (isNull player returns true)
    • to know if a certain unit is a player, use isPlayer
  • groups and AI:
    • an AI group with a player-leader will be local to the player's computer
    • a subordinate player being in a player-lead group will remain local to its computer (see bulletpoint #1)
  • objects:
    • a driven vehicle is always local to the machine of its driver (not the commander's, not the gunner's)
    • terrain objects (buildings, vegetation, roads etc.) are local everywhere (local nearestBuilding player returns true on every client)
    • editor-placed objects and empty vehicles are local to the server
    • editor-placed triggers are created on every machine unless specified otherwise ("Server Only" Eden Editor option ticked)
    • units created with createUnit will be local to the computer that issued the command
    • objects and vehicles created with createVehicle will be local to the computer that issued the command

Locality changes

  • if the player-leader dies, the AI is transferred to the machine where the new leader is local (server in case of AI, client in case of another player)
  • joining AI units will change locality to the new leader's computer
  • locality will change from server to client when a player gets in an empty vehicle
  • locality can also change in the event of a Team Switch or usage of selectPlayer
Since Arma 3 the "Local" Event Handler triggers when an object's locality is changed.

Code examples

Code Argu-ments Effect Description
remoteUnit setDamage 1; Arguments of this scripting command don't have to be local to the client the command is executed on Effects of this scripting command are broadcasted over the network and happen on every computer in the network Any unit (local or remote) will die, and all the computers will know
localUnit addMagazine "30Rnd_556x45_STANAG"; Arguments of this scripting command have to be local to the client the command is executed on Effects of this scripting command are broadcasted over the network and happen on every computer in the network Only a local unit can have its inventory edited with this command, but all the machines will be notified: if a player looks into the localUnit inventory, the added magazine will be there
remoteUnit setFace "Miller"; Arguments of this scripting command don't have to be local to the client the command is executed on Effects of this scripting command are not broadcasted over the network and remain local to the client the command is executed on Any unit (local or remote) can get its face changed, but the new face will not be propagated through the network. Only the local machine's player will see the effect of the command
This command should ideally be executed on every machine, for example with:
[remoteUnit, "Miller"] remoteExec ["setFace", 0, true];
See Remote Execution paragraph for more information.
localCamera cameraEffect ["Internal", "Back"]; Arguments of this scripting command have to be local to the client the command is executed on Effects of this scripting command are not broadcasted over the network and remain local to the client the command is executed on Only a local camera can be entered, and of course only the local machine will see through this camera


Network ID

Network IDs identify machines and network objects. They can be used to target proper machines with remote execution; see Remote Execution chapter for more information.

A machine ID (ownerID) is not to be confused with an object's network ID (netId).

Machine network ID

Every machine, including the server, has a network ID.
A server has an ID of 2, every new client has the next number (the first client will be number 3, second client number 4, etc.)

  • To get the current machine's ID, use clientOwner.
  • To get the machine's ID of an object's owner, use owner object (MP only).
  • To get the machine's ID of a group's owner, use groupOwner object (MP only).

Object network ID

Every object synchronised through the network has a network ID, shortened to netId.


Sending information across network

Remote Execution

Since Arma 3 v1.50, remoteExec and remoteExecCall efficient engine network commands are available:

["Message to everyone, including JIP players!", 0, true] remoteExec ["hint"];

See Arma 3 Remote Execution for more information.

The two methods below are considered OBSOLETE since Arma 3 v1.50!

Arma 3 alpha introduced BIS_fnc_MP:

["Message to everyone, including JIP  players!", "hint", true, true] call BIS_fnc_MP;

Arma 2 introduced the (obsolete in Arma 3) Multiplayer framework:

waitUntil { not isNil "BIS_MPF_InitDone"; };
[nil, nil, rHINT, "Message to everyone!"] call RE;

PublicVariable commands

PublicVariable commands allow to send global variables to specified machines.

  • Network reception is guaranteed
  • Short variable names should be used for network performance
  • These commands shouldn't be used intensely for the same reason
Command Effect JIP synchronised
publicVariable Set/update a variable value from the local machine to all the other machines (including server) Ico ok.png
publicVariableServer Set/update a variable value from a client to the server Ico none.png
publicVariableClient Set/update a variable value from the local machine (not necessarily the server) to a specific client Ico none.png

How it works

The server has the variable ABC_Score to broadcast:

ABC_Score = 5;				// sets the value
publicVariable "ABC_Score"	// publishes the variable (do not forget the quotes!)

This sends the variable name and value to the clients.

  • If the variable is not yet declared on their machine, it will declare it as well.
  • If the variable already exists, the value is overridden by the server's value.
  • If the variable changes again on the server, it has to be manually publicVariable'd once again!
  • A JIP player will synchronise server's publicVariable'd variables before executing init.sqf. See Initialization Order for more information.
    • A JIP player will not synchronise publicVariableClient-received variables after he disconnects/reconnects. Only server-known public variables sent with publicVariable will be synchronised.


setVariable command

Available since Arma 2 the public version of the setVariable command allows you to store a variable into an object and spread this variable across the network.

Arma 3 logo black.png
In Arma 3 it is possible to broadcast the nil value, thus deleting the variable from the target.


Player connection events

The following commands will execute given code when a player is connecting or disconnecting. This code will run for players connecting in the lobby and for JIP players!


Client state

A client state is the client's connection state. It can be obtained with getClientState and getClientStateNumber commands on both server and clients.

getClientStateNumber getClientState Description
0 "NONE" No client (or singleplayer)
1 "CREATED" Client is created
2 "CONNECTED" Client is connected to server, message formats are registered
3 "LOGGED IN" Identity is created
4 "MISSION SELECTED" Mission is selected
5 "MISSION ASKED" Server was asked to send / not send mission
6 "ROLE ASSIGNED" Role was assigned (and confirmed)
7 "MISSION RECEIVED" Mission received
8 "GAME LOADED" Island loaded, vehicles received
9 "BRIEFING SHOWN" Briefing was displayed
10 "BRIEFING READ" Ready to play mission
11 "GAME FINISHED" Game was finished
12 "DEBRIEFING READ" Debriefing read, ready to continue with next mission


Join In Progress

A JIP player will have many information synchronised by the game before accessing the mission itself. JIP was introduced in Armed Assault.

Information Arma 1 Arma 2 Arma 3
date/time Ico ok.png Ico ok.png Ico ok.png
date/time + setDate/skipTime Ico none.png Ico none.png Ico ok.png
weather (overcast, fog) Ico none.png Ico ok.png Ico ok.png
weather + setOvercast/setFog/setRain/setLightnings Ico none.png Ico none.png Ico ok.png
time passed since mission start (time command) unknown unknown Ico ok.png
publicVariable-sent variables (Number, String, Text, Array, Code) Ico ok.png Ico ok.png Ico ok.png
publicVariable-sent variables (nil) Ico none.png Ico none.png Ico ok.png
setVariable-assigned variables (when alternative syntax's public parameter is set to true) N/A Ico ok.png Ico ok.png
remoteExec- and remoteExecCall-executed code if JIP prerequisites are met N/A N/A Ico ok.png

See Join In Progress for more information.


See also