Multiplayer Scripting: Difference between revisions
Lou Montana (talk | contribs) m (Fix code typo) |
Lou Montana (talk | contribs) m (Fix a mixup of SP/MP commands) |
||
Line 14: | Line 14: | ||
{{Informative|In Singleplayer, the game acts as a player-hosted server ({{Inline code|[[isServer]]}} returns {{Inline code|[[true]]}}).}} | {{Informative|In Singleplayer, the game acts as a player-hosted server ({{Inline code|[[isServer]]}} returns {{Inline code|[[true]]}}).}} | ||
{{Warning|Some Multiplayer commands do '''not''' work in Singleplayer, such as {{Inline code|[[netId]]}} | {{Warning|Some Multiplayer commands do '''not''' work in Singleplayer, such as {{Inline code|[[netId]]}} !<br /> | ||
The other way around, some Singleplayer commands do not work in Multiplayer (e.g {{Inline code|[[setAccTime]]}}).}} | |||
Revision as of 23:36, 28 January 2019
Template:SideTOC Template:Stub
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.
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.
- commands arguments and effects can be either local or global:
Template:EffArg | a local argument means an argument that is processed on the machine where the command is executed |
Template:EffArg | a global argument means any argument, even a remote one |
Template:EffArg | a local effect means that the effect will only happen on the machine where the command is executed |
Template:EffArg | a global effect means that all the computers will receive it |
See Locality in Multiplayer for more information.
Different machines
Machine | Conditions |
---|---|
Dedicated Server | isDedicated
|
Player Server | hasInterface && isServer
|
Client | hasInterface && not isServer
|
JIP Client | hasInterface && didJIP
|
Headless Client | not hasInterface && not isDedicated
|
- 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:
- 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
Code examples
Code | Argu-ments | Effect | Description |
---|---|---|---|
remoteUnit setDamage 1;
|
Template:EffArg | Template:EffArg | Any unit (local or remote) will die, and all the computers will know |
localUnit addMagazine "30Rnd_556x45_STANAG";
|
Template:EffArg | Template:EffArg | 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";
|
Template:EffArg | Template:EffArg | 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 |
localCamera cameraEffect ["Internal", "Back"];
|
Template:EffArg | Template:EffArg | 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.
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).
Mission object ID
Every object synchronised through the network has a network ID, shortened to netId.
- To get an object's netId, use netId (MP only). SP & MP variant: BIS_fnc_netId
- To get an object from a netId, use objectFromNetId (MP only). SP & MP variant: BIS_fnc_objectFromNetId
- To get a group from a netId, use groupFromNetId (MP only). SP & MP variant: BIS_fnc_groupFromNetId
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 |
---|---|
publicVariable | Set/update a variable value from the local machine to all the other machines (including server) |
publicVariableServer | Set/update a variable value from a client to the server |
publicVariableClient | Set/update a variable value from the local machine (not necessarily the server) to a specific client |
How it works
The server has the variable ABC_Score
to send to everyone:
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 public 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.
Remote Execution
Arma 2 introduced the (obsolete in Arma 3) Multiplayer framework, used as follow:
waitUntil { not isNil "BIS_MPF_InitDone"; }; [nil, nil, rHINT, "Message to everyone!"] call RE;
Arma 3 alpha introduced BIS_fnc_MP (obsolete since Arma 3 v1.50):
["Message to everyone, including JIP players!", "hint", true, true] call BIS_fnc_MP;
Arma 3 (> v1.50):
["Message to everyone, including JIP players!", 0, true] remoteExec ["hint"];
See Arma 3 Remote Execution for more information.
onPlayerConnected/onPlayerDisconnected 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. JIP was introduced in Arma.
Information | Arma 1 | Arma 2 | Arma 3 |
---|---|---|---|
date/time | Template:task/ | Template:task/ | Template:task/ |
date/time + setDate/skipTime | Template:task | Template:task | Template:task/ |
weather (overcast, fog) | Template:task | Template:task/ | Template:task/ |
weather + setOvercast/setFog/setRain/setLightnings | Template:task | Template:task | Template:task/ |
time passed since mission start (time command) | unknown | unknown | Template:task/ |
publicVariable-sent variables (Number, String, Text, Array, Code) | Template:task/ | Template:task/ | Template:task/ |
publicVariable-sent variables (nil) | Template:task | Template:task | Template:task/ |
setVariable-assigned variables (when alternative syntax's public parameter is set to true) | N/A | Template:task/ | Template:task/ |
remoteExec- and remoteExecCall-executed code if JIP prerequisites are met | N/A | N/A | Template:task/ |
See Join In Progress for more information.