Difference between revisions of "Multiplayer framework"

From Bohemia Interactive Community
Jump to navigation Jump to search
(Examples)
m (Text replacement - "ArmA( |_)2" to "Arma 2")
 
(10 intermediate revisions by 7 users not shown)
Line 1: Line 1:
[[Category:ArmA_2:_Editor_Modules]]
+
{{Feature arma3|This page is about {{arma2}} and doesn't apply to {{arma3}}. In {{arma3}}, use [[remoteExec]] or [[remoteExecCall]].}}
  
'''Note: this page is a work-in-progress! More info to follow as soon as possible.'''
 
  
=Introduction=
+
 
 +
 
 +
{{SideTOC}}
 +
'''Multiplayer Framework''' (MPF or MPf) is a library that helps MP mission creation, regarding some commands' locality.
 
* library of scripts that are performing non-global script commands globally on network
 
* library of scripts that are performing non-global script commands globally on network
* using publicVariable + addPublicVariableEventHandler (EH that fires for each publicVariabled variable on all clients - excluding calling client) + direct call on calling client
+
* using [[publicVariable]] + [[addPublicVariableEventHandler]] (EH that fires for each publicVariabled variable on all clients - excluding calling client) + direct call on calling client
 
* easy use: R-commands match function of '''single''' non-global scripting commands (eg. MPF 'rHINT' call is doing 'hint' on clients)
 
* easy use: R-commands match function of '''single''' non-global scripting commands (eg. MPF 'rHINT' call is doing 'hint' on clients)
 
* allows execution only on client where target object is local ("loc" switch)
 
* allows execution only on client where target object is local ("loc" switch)
 
* allows persistent calls - are performed on JIP client even if server processed given MPF call before client connected to game ("per" switch)
 
* allows persistent calls - are performed on JIP client even if server processed given MPF call before client connected to game ("per" switch)
  
{{Important|Do not use RE variable in your missions when using MPF. Do not use rHINT, rSIDECHAT etc. (see library below)}}
+
{{Important | Do '''not''' overwrite '''RE''' variable in your missions when using MPF. Do not use rHINT, rSIDECHAT etc [[Identifier]]s (see library below)}}
 +
 
 +
 
 +
== Remote script execution (RE) ==
  
==Remote script execution (RE)==
 
 
On all clients is public variable eventhandler that executes scripts that corresponds to less-than-100-percent-multiplayer-working script commands. One script for one commands, no string sending that will be compiled and executed for the sake of clarity and easiness of creating MP-friendly commands from the engine MP-unfriendly ones.
 
On all clients is public variable eventhandler that executes scripts that corresponds to less-than-100-percent-multiplayer-working script commands. One script for one commands, no string sending that will be compiled and executed for the sake of clarity and easiness of creating MP-friendly commands from the engine MP-unfriendly ones.
  
===Function===
+
=== Function ===
#Script ''remExWrite.sqf'' is called with parameters that says: '''who executes''', '''upon who''', '''[only where local]''', '''which scripted command''' and '''parameters''' for scripted command on target client follow
 
#''remExWrite.sqf'' writes in public variable ''remExField''
 
#Change in ''remExField'' triggers execution of eventhandlers on all clients in the network game (initialized in init.sqf), script ''remExServer.sqf'' interpretes remExField (remExFP resp.)
 
#(if wanted) ''remExServer.sqf'' calls script (given as argument) on client that runs even handler
 
  
Note: remote execution executes script also on calling client (if "loc" flag not set or "loc" set and object is local on caller client)
+
# Script ''remExWrite.sqf'' is called with parameters that says: '''who executes''', '''upon who''', '''[only where local and/or persistent]''', '''which scripted command''' and '''parameters''' for scripted command on target client follow
 +
# ''remExWrite.sqf'' writes in public variable ''remExField''
 +
# Change in ''remExField'' triggers execution of eventhandlers on all clients in the network game (initialized in init.sqf), script ''remExServer.sqf'' interpretes remExField (remExFP resp.)
 +
# (if wanted) ''remExServer.sqf'' calls script (given as argument) on client that runs even handler
  
===Usage===
+
{{Informative | Remote execution executes script also on calling client (if "loc" flag set, or "loc" not set and object is local on caller client)}}
====How-to====
 
#Include functions module in your mission
 
#Wait for global variable "BIS_MPF_InitDone" to be defined (and true)
 
#In scripts or fsms call: _handler = [...] call RE; (syntax - see below; RE stands for remote execution)
 
  
====Format====
+
=== Usage ===
_nic = [nil_or_caller, nil_or_target_object,"loc", script_to_execute, par0, par1...] call RE;
 
_nic = [nil_or_caller, nil_or_target_object,"per", script_to_execute, par0, par1...] call RE;
 
_nic = [nil_or_caller, nil_or_target_object,"loc" + "per", script_to_execute, par0, par1...] call RE;
 
  
*RE...remote execution (short for remExWrite.sqf)
+
==== How-to ====
*"loc"...arbitrary parameter - executes remote script only on machine where ''nil_or_target_object'' is local
+
* Include functions module in your mission
*"per"...arbitrary parameter - executes remote script even on JIP client connectiong *after* this RE call was executed in MP game
+
* Wait for global variable "BIS_MPF_InitDone" to be defined (and true): <code>[[waitUntil]] { !([[isNil]] "BIS_MPF_InitDone"); };</code>
 +
* In scripts or FSMs call: {{Inline code|_handler = [...] [[call]] '''RE''';}} (syntax - see below; RE stands for remote execution)
  
====Examples====
+
==== Format ====
 +
[nil_or_caller, nil_or_target_object, "loc", script_to_execute, par0, par1...] [[call]] '''RE''';
 +
[nil_or_caller, nil_or_target_object, "per", script_to_execute, par0, par1...] [[call]] '''RE''';
 +
[nil_or_caller, nil_or_target_object, "loc" + "per", script_to_execute, par0, par1...] [[call]] '''RE''';
 +
 
 +
* "loc"...arbitrary parameter - executes remote script only on machine where ''nil_or_target_object'' is local
 +
* "per"...arbitrary parameter - executes remote script even on JIP client connectiong *after* this RE call was executed in MP game
 +
* script_to_execute - ''usually'' <tt>r + uppercase command</tt> (see [[#Available Commands|available commands]]) e.g for [[hint]]: rHINT
 +
* RE...remote execution (short for remExWrite.sqf)
 +
 
 +
==== Examples ====
 
Hint on all clients currently connected to the MP game:
 
Hint on all clients currently connected to the MP game:
  _nic = [nil,nil,rHINT,"Enjoy the game."] call RE;
+
  [<nowiki/>[[nil]], [[nil]], rHINT, "Enjoy the game."] [[call]] '''RE''';
  
 
Hint on all clients currently connected to the MP game + executed also on JIP client just after connection
 
Hint on all clients currently connected to the MP game + executed also on JIP client just after connection
  _nic = [nil,nil,"per",rHINT,"Enjoy the game."] call RE;
+
  [<nowiki/>[[nil]], [[nil]], "per", rHINT, "Enjoy the game."] [[call]] '''RE''';
  
 
Hint on client where object ''miles'' is local:
 
Hint on client where object ''miles'' is local:
  _nic = [nil,miles,"loc",rHINT,"Miles is local here."] call RE;
+
[<nowiki/>[[nil]], miles, "loc", rHINT, "Miles is local here."] [[call]] '''RE''';
  
 
Hint on client where number 0 from players group is local. If JIP client connects to this slot, he got also his msg displayed:
 
Hint on client where number 0 from players group is local. If JIP client connects to this slot, he got also his msg displayed:
  _nic = [nil,(units group player) select 0,"loc" + "per",rHINT,"Hint."] call RE;
+
[<nowiki/>[[nil]], ([[units]] [[group]] [[player]]) [[select]] 0, "loc" + "per", rHINT, "Hint."] [[call]] '''RE''';
 +
 
 +
Multiple parameters
 +
[<nowiki/>[[objNull]], BIS_Rodriguez , "per", rKBADDTOPIC, "armstrongs_speech",  "kb\armstrongs_speech.bikb",  ""] [[call]] '''RE''';
 +
{{note | "kb\armstrongs_speech.bikb" becomes (_this select 1) in kbAddTopic.sqf library script}}
 +
 
 +
 
 +
== Implementation ==
  
=Implementation=
 
 
* remExServer
 
* remExServer
 
* remExWrite
 
* remExWrite
Line 57: Line 70:
 
* custom library (division to library and custom library introduced in 1.03)
 
* custom library (division to library and custom library introduced in 1.03)
  
==Library + custom Library==
+
=== Library + custom Library ===
 +
 
 
* library - functionality of single non-global scripting commands
 
* library - functionality of single non-global scripting commands
 
* custom library - enhanced functionality (eg. new parameters to scripting commands or more scripting commands triggered by one MPF call)
 
* custom library - enhanced functionality (eg. new parameters to scripting commands or more scripting commands triggered by one MPF call)
  
<pre>
+
=== Available Commands ===
"move",
+
 
"moveIn",  
+
{| class="wikitable sortable"
"land",
+
! name
"addWPCur", //takes object and for his group on his local sets current WP
+
! [[:Category:Scripting Commands|command]]
"animate",
+
! '''RE''' equivalent
"setDate",
+
! Additional Information
"playmusic",
+
|-
"playsound",
+
| move || [[move]] || rMOVE ||
"switchmove",
+
|-
"playmove",
+
| moveIn || {{n/a}} || rMOVEIN || can replace [[moveInDriver]], [[moveInGunner]], [[moveInCommander]], [[moveInCargo]]
"playmovenow",
+
|-
"playAction",
+
| land || [[land]] || rLAND ||
"playActionnow",
+
|-
"switchAction",
+
| addWPCur || {{n/a}} || rADDWPCUR || takes object and for his group on his local sets current WP
"hint",
+
|-
"hintC",
+
| animate || [[animate]] || rANIMATE ||
"showCommandingMenu",
+
|-
"globalChat",
+
| setDate || [[setDate]] || rSETDATE ||
"globalRadio",
+
|-
"sideChat",
+
| playmusic || [[playMusic]] || rPLAYMUSIC ||
"sideRadio",
+
|-
"groupChat",
+
| playsound || [[playSound]] || rPLAYSOUND ||
"groupRadio",
+
|-
"kbAddTopic",
+
| switchmove || [[switchMove]] || rSWITCHMOVE ||
"kbRemoveTopic",
+
|-
"kbtell",
+
| playmove || [[playMove]] || rPLAYMOVE ||
"kbreact",
+
|-
"deleteWP",
+
| playmovenow || [[playMoveNow]] || rPLAYMOVENOW ||
"setWPdesc",
+
|-
"setWPtype",
+
| playAction || [[playAction]] || rPLAYACTION ||
"createSimpleTask",
+
|-
"taskHint",
+
| playActionnow || [[playActionNow]] || rPLAYACTIONNOW ||
"createDiaryRecord",
+
|-
"removeAllWeapons",
+
| switchAction || [[switchAction]] || rSWITCHACTION ||
"addWeapon",
+
|-
"addWeaponCargo",
+
| hint || [[hint]] || rHINT ||
"addMagazine",
+
|-
"addMagazineCargo",
+
| hintC || [[hintC]] || rHINTC ||
"clearMagazineCargo",
+
|-
"clearWeaponCargo",
+
| showCommandingMenu || [[showCommandingMenu]] || rSHOWCOMMANDINGMENU ||
"endMission",
+
|-
"failMission",
+
| globalChat || [[globalChat]] || rGLOBALCHAT ||
"titleCut",
+
|-
"titleText",
+
| globalRadio || [[globalRadio]] || rGLOBALRADIO ||
"say",
+
|-
"playMusic",
+
| sideChat || [[sideChat]] || rSIDECHAT ||
"switchCamera",
+
|-
"fadeMusic",
+
| sideRadio || [[sideRadio]] || rSIDERADIO ||
"fadeSound",
+
|-
"addAction",
+
| groupChat || [[groupChat]] || rGROUPCHAT ||
"removeAction",
+
|-
"setCaptive",
+
| groupRadio || [[groupRadio]] || rGROUPRADIO ||
"setDir", //caution: works weird (often overwritten by server, tied to setpos)
+
|-
"setObjectTexture",
+
| kbAddTopic || [[kbAddTopic]] || rKBADDTOPIC ||
"execfsm",
+
|-
"execfsm",
+
| kbRemoveTopic || [[kbRemoveTopic]] || rKBREMOVETOPIC ||
"execVM",
+
|-
"spawn",
+
| kbtell || [[kbTell]] || rKBTELL ||
"JIPrequest", //requesting JIP (RE persistent commands) from server by executing this via RE (on server) - parameter: logic local on client
+
|-
"JIPexec", // custom scripting functions
+
| kbreact || [[kbReact]] || rKBREACT ||
"addAction",
+
|-
"skiptime", //bad
+
| deleteWP || [[deleteWaypoint]] || rDELETEWP ||
"setSimpleTaskDescription",
+
|-
"setSimpleTaskDestination",
+
| setWPdesc || [[setWaypointDescription]] || rSETWPDESC ||
"setCurrentTask",
+
|-
"setCurrentTaskArrays",
+
| setWPtype || [[setWaypointType]] || rSETWPTYPE ||
"createTaskSet",
+
|-
"setTaskState",
+
| createSimpleTask || [[createSimpleTask]] || rCREATESIMPLETASK ||
"debugLog",
+
|-
"enablesimulation"
+
| taskHint || [[taskHint]] || rTASKHINT ||
"callVar" (1.03) - calls code that is stored in variable on client
+
|-
</pre>
+
| createDiaryRecord || [[createDiaryRecord]] || rCREATEDIARYRECORD ||
 +
|-
 +
| removeAllWeapons || [[removeAllWeapons]] ||rREMOVEALLWEAPONS ||
 +
|-
 +
| addWeapon || [[addWeapon]] || rADDWEAPON ||
 +
|-
 +
| addWeaponCargo || [[addWeaponCargo]] || rADDWEAPONCARGO ||
 +
|-
 +
| addMagazine || [[addMagazine]] || rADDMAGAZINE ||
 +
|-
 +
| addMagazineCargo || [[addMagazineCargo]] || rADDMAGAZINECARGO ||
 +
|-
 +
| clearMagazineCargo || [[clearMagazineCargo]] || rCLEARMAGAZINECARGO ||
 +
|-
 +
| clearWeaponCargo || [[clearWeaponCargo]] || rCLEARWEAPONCARGO ||
 +
|-
 +
| endMission || [[endMission]] || rENDMISSION ||
 +
|-
 +
| failMission || [[failMission]] || rFAILMISSION ||
 +
|-
 +
| titleCut || [[titleCut]] || rTITLECUT ||
 +
|-
 +
| titleText || [[titleText]] || rTITLETEXT ||
 +
|-
 +
| say || [[say]] || rSAY ||
 +
|-
 +
| playMusic || [[playMusic]] || rPLAYMUSIC ||
 +
|-
 +
| switchCamera || [[switchCamera]] || rSWITCHCAMERA ||
 +
|-
 +
| fadeMusic || [[fadeMusic]] || rFADEMUSIC ||
 +
|-
 +
| fadeSound || [[fadeSound]] || rFADESOUND ||
 +
|-
 +
| addAction || [[addAction]] || rADDACTION ||
 +
|-
 +
| removeAction || [[removeAction]] || rREMOVEACTION ||
 +
|-
 +
| setCaptive || [[setCaptive]] || rSETCAPTIVE ||
 +
|-
 +
| setDir || [[setDir]] || rSETDIR || '''caution:''' works weird (often overwritten by server, tied to [[setPos]]
 +
|-
 +
| setObjectTexture || [[setObjectTexture]] || rSETOBJECTEXTURE ||
 +
|-
 +
| execfsm || [[execFSM]] || rEXECFSM ||
 +
|-
 +
| execVM || [[execVM]] || rEXECVM ||
 +
|-
 +
| spawn || [[spawn]] || rSPAWN ||
 +
|-
 +
| JIPrequest || {{n/a}} || rJIPREQUEST || requesting JIP (RE persistent commands) from server by executing this via RE (on server) - parameter: logic local on client
 +
|-
 +
| JIPexec || {{n/a}} || rJIPEXEC || custom scripting functions
 +
|-
 +
| skiptime || [[skipTime]] || rSKIPTIME || bad
 +
|-
 +
| setSimpleTaskDescription || [[setSimpleTaskDescription]] || rSETSIMPLETASKDESCRIPTION ||
 +
|-
 +
| setSimpleTaskDestination || [[setSimpleTaskDestination]] || rSETSIMPLETASKDESTINATION ||
 +
|-
 +
| setCurrentTask || [[setCurrentTask]] || rSETCURRENTTASK ||
 +
|-
 +
| setCurrentTaskArrays || {{n/a}} || rSETCURRENTTASKARRAYS ||
 +
|-
 +
| createTaskSet || {{n/a}} || rCREATETASKSET ||
 +
|-
 +
| setTaskState || [[setTaskState]] || rSETTASKSTATE ||
 +
|-
 +
| debugLog || [[debugLog]] || rDEBUGLOG ||
 +
|-
 +
| enablesimulation || [[enableSimulation]] || rENABLESIMULATION ||
 +
|-
 +
| callVar || {{n/a}} || rCALLVAR || (1.03) - calls code that is stored in variable on client
 +
|}
 +
 
 +
 
 +
[[Category:Arma 2:_Editor_Modules]]

Latest revision as of 13:14, 2 May 2020

Arma 3 logo black.png
This page is about Arma 2 and doesn't apply to Arma 3. In Arma 3, use remoteExec or remoteExecCall.



Multiplayer Framework (MPF or MPf) is a library that helps MP mission creation, regarding some commands' locality.

  • library of scripts that are performing non-global script commands globally on network
  • using publicVariable + addPublicVariableEventHandler (EH that fires for each publicVariabled variable on all clients - excluding calling client) + direct call on calling client
  • easy use: R-commands match function of single non-global scripting commands (eg. MPF 'rHINT' call is doing 'hint' on clients)
  • allows execution only on client where target object is local ("loc" switch)
  • allows persistent calls - are performed on JIP client even if server processed given MPF call before client connected to game ("per" switch)
Do not overwrite RE variable in your missions when using MPF. Do not use rHINT, rSIDECHAT etc Identifiers (see library below)


Remote script execution (RE)

On all clients is public variable eventhandler that executes scripts that corresponds to less-than-100-percent-multiplayer-working script commands. One script for one commands, no string sending that will be compiled and executed for the sake of clarity and easiness of creating MP-friendly commands from the engine MP-unfriendly ones.

Function

  1. Script remExWrite.sqf is called with parameters that says: who executes, upon who, [only where local and/or persistent], which scripted command and parameters for scripted command on target client follow
  2. remExWrite.sqf writes in public variable remExField
  3. Change in remExField triggers execution of eventhandlers on all clients in the network game (initialized in init.sqf), script remExServer.sqf interpretes remExField (remExFP resp.)
  4. (if wanted) remExServer.sqf calls script (given as argument) on client that runs even handler
Remote execution executes script also on calling client (if "loc" flag set, or "loc" not set and object is local on caller client)

Usage

How-to

  • Include functions module in your mission
  • Wait for global variable "BIS_MPF_InitDone" to be defined (and true): waitUntil { !(isNil "BIS_MPF_InitDone"); };
  • In scripts or FSMs call: No code added! (syntax - see below; RE stands for remote execution)

Format

[nil_or_caller, nil_or_target_object, "loc", script_to_execute, par0, par1...] call RE;
[nil_or_caller, nil_or_target_object, "per", script_to_execute, par0, par1...] call RE;
[nil_or_caller, nil_or_target_object, "loc" + "per", script_to_execute, par0, par1...] call RE;
  • "loc"...arbitrary parameter - executes remote script only on machine where nil_or_target_object is local
  • "per"...arbitrary parameter - executes remote script even on JIP client connectiong *after* this RE call was executed in MP game
  • script_to_execute - usually r + uppercase command (see available commands) e.g for hint: rHINT
  • RE...remote execution (short for remExWrite.sqf)

Examples

Hint on all clients currently connected to the MP game:

[nil, nil, rHINT, "Enjoy the game."] call RE;

Hint on all clients currently connected to the MP game + executed also on JIP client just after connection

[nil, nil, "per", rHINT, "Enjoy the game."] call RE;

Hint on client where object miles is local:

[nil, miles, "loc", rHINT, "Miles is local here."] call RE;

Hint on client where number 0 from players group is local. If JIP client connects to this slot, he got also his msg displayed:

[nil, (units group player) select 0, "loc" + "per", rHINT, "Hint."] call RE;

Multiple parameters

[objNull, BIS_Rodriguez , "per", rKBADDTOPIC, "armstrongs_speech",  "kb\armstrongs_speech.bikb",  ""] call RE;
📝
"kb\armstrongs_speech.bikb" becomes (_this select 1) in kbAddTopic.sqf library script


Implementation

  • remExServer
  • remExWrite
  • library
  • custom library (division to library and custom library introduced in 1.03)

Library + custom Library

  • library - functionality of single non-global scripting commands
  • custom library - enhanced functionality (eg. new parameters to scripting commands or more scripting commands triggered by one MPF call)

Available Commands

name command RE equivalent Additional Information
move move rMOVE
moveIn N/A rMOVEIN can replace moveInDriver, moveInGunner, moveInCommander, moveInCargo
land land rLAND
addWPCur N/A rADDWPCUR takes object and for his group on his local sets current WP
animate animate rANIMATE
setDate setDate rSETDATE
playmusic playMusic rPLAYMUSIC
playsound playSound rPLAYSOUND
switchmove switchMove rSWITCHMOVE
playmove playMove rPLAYMOVE
playmovenow playMoveNow rPLAYMOVENOW
playAction playAction rPLAYACTION
playActionnow playActionNow rPLAYACTIONNOW
switchAction switchAction rSWITCHACTION
hint hint rHINT
hintC hintC rHINTC
showCommandingMenu showCommandingMenu rSHOWCOMMANDINGMENU
globalChat globalChat rGLOBALCHAT
globalRadio globalRadio rGLOBALRADIO
sideChat sideChat rSIDECHAT
sideRadio sideRadio rSIDERADIO
groupChat groupChat rGROUPCHAT
groupRadio groupRadio rGROUPRADIO
kbAddTopic kbAddTopic rKBADDTOPIC
kbRemoveTopic kbRemoveTopic rKBREMOVETOPIC
kbtell kbTell rKBTELL
kbreact kbReact rKBREACT
deleteWP deleteWaypoint rDELETEWP
setWPdesc setWaypointDescription rSETWPDESC
setWPtype setWaypointType rSETWPTYPE
createSimpleTask createSimpleTask rCREATESIMPLETASK
taskHint taskHint rTASKHINT
createDiaryRecord createDiaryRecord rCREATEDIARYRECORD
removeAllWeapons removeAllWeapons rREMOVEALLWEAPONS
addWeapon addWeapon rADDWEAPON
addWeaponCargo addWeaponCargo rADDWEAPONCARGO
addMagazine addMagazine rADDMAGAZINE
addMagazineCargo addMagazineCargo rADDMAGAZINECARGO
clearMagazineCargo clearMagazineCargo rCLEARMAGAZINECARGO
clearWeaponCargo clearWeaponCargo rCLEARWEAPONCARGO
endMission endMission rENDMISSION
failMission failMission rFAILMISSION
titleCut titleCut rTITLECUT
titleText titleText rTITLETEXT
say say rSAY
playMusic playMusic rPLAYMUSIC
switchCamera switchCamera rSWITCHCAMERA
fadeMusic fadeMusic rFADEMUSIC
fadeSound fadeSound rFADESOUND
addAction addAction rADDACTION
removeAction removeAction rREMOVEACTION
setCaptive setCaptive rSETCAPTIVE
setDir setDir rSETDIR caution: works weird (often overwritten by server, tied to setPos
setObjectTexture setObjectTexture rSETOBJECTEXTURE
execfsm execFSM rEXECFSM
execVM execVM rEXECVM
spawn spawn rSPAWN
JIPrequest N/A rJIPREQUEST requesting JIP (RE persistent commands) from server by executing this via RE (on server) - parameter: logic local on client
JIPexec N/A rJIPEXEC custom scripting functions
skiptime skipTime rSKIPTIME bad
setSimpleTaskDescription setSimpleTaskDescription rSETSIMPLETASKDESCRIPTION
setSimpleTaskDestination setSimpleTaskDestination rSETSIMPLETASKDESTINATION
setCurrentTask setCurrentTask rSETCURRENTTASK
setCurrentTaskArrays N/A rSETCURRENTTASKARRAYS
createTaskSet N/A rCREATETASKSET
setTaskState setTaskState rSETTASKSTATE
debugLog debugLog rDEBUGLOG
enablesimulation enableSimulation rENABLESIMULATION
callVar N/A rCALLVAR (1.03) - calls code that is stored in variable on client