Jump to content
Sign in to follow this  
naizarak

Q's About Multiplayer Locality, Scripts/Functions

Recommended Posts

I've been having trouble understanding the way code is executed in multiplayer, and how locality works in general. I was under the impression that all scripts are automatically run on the server, and then passed down to clients.

But apparently all connected players execute the same code simultaneously? For example, the BIWiki used the createVehicle script as an example. Apparently each player in the game would call this script, and instead of having a single vehicle, you'd have num_players vehicles. So in this case you'd need to check to see if the calling player is the server, before running the script.

And this is where I'm mixed up - if a server calls a script, then is the result cloned for all clients? If a client calls a script, is the result local only to the client, and not everyone else in the game? If a server calls createVehicle "truck", then will everyone in the game see that truck? If it's called by a single client instead, will it only be visible to that client?

Going from there, if code is run concurrently for all players, how is everything synchronized?

And regarding scripts/functions, am I correct in thinking that functions are essentially scripts that just return data? Is "execVM" basically a script's equivalent of "spawn" for functions? Can scripts be created via "call"?

I've tried searching the BIWiki and other community sources for info, but it's difficult to piece everything together. Doesn't help that I can't really test anything in an MP environment because Steam doesn't support running multiple Arma instances. I feel that I need to get these fundamentals ironed out in my mind before I go even deeper with scripting. Thanks in advance, I'd really appreciate some feedback.

Share this post


Link to post
Share on other sites

I could be wrong but I think you pretty much get it already. If a client creates a vehicle, it will sync to all clients (unless it was specifically created locally) which is why there are "num_player" vehicles. If it is created on the server, they all see them but only the server creates it, so only one is created.

So if you want to create one of something that all clients see, make sure only the server creates it.

Share this post


Link to post
Share on other sites
I could be wrong but I think you pretty much get it already. If a client creates a vehicle, it will sync to all clients (unless it was specifically created locally) which is why there are "num_player" vehicles. If it is created on the server, they all see them but only the server creates it, so only one is created.

So if you want to create one of something that all clients see, make sure only the server creates it.

So hypothetically, if all players had good connections and were guaranteed to be connected for the entire duration of the match, you could run all your scripts on clients and get the same results as if running them on the server?

Also, you mentioned that certain scripts can be explicitly run locally. What would happen in that case? Using the createVehicle "truck" example, if this code were run locally for a client, how would it be represented in game? Would the vehicle only appear on that client's PC, and would no one else be able to see it?

Share this post


Link to post
Share on other sites
So hypothetically, if all players had good connections and were guaranteed to be connected for the entire duration of the match, you could run all your scripts on clients and get the same results as if running them on the server?

Also, you mentioned that certain scripts can be explicitly run locally. What would happen in that case? Using the createVehicle "truck" example, if this code were run locally for a client, how would it be represented in game? Would the vehicle only appear on that client's PC, and would no one else be able to see it?

To the truck thing: yeah, that is how it should play out. Usually the best thing to do is run everything server-side unless it must be client based. Also, any random numbers used for things that should be synced across all clients must be done on the server. Basically, just do it on the server unless you absolutely have to do it otherwise.

Share this post


Link to post
Share on other sites

Multiplayer framework

http://community.bistudio.com/wiki/Multiplayer_framework

and most important for client side scripts calls;

In scripts or fsms call: _handler = [...] call RE; (syntax - see below; RE stands for remote execution)

Format
[nil_or_caller, nil_or_target_object,"loc", script_to_execute, par0, par1...] call RE;

..otherwise.. clients calls will only work for the caller in MP.

Share this post


Link to post
Share on other sites
Multiplayer framework

http://community.bistudio.com/wiki/Multiplayer_framework

and most important for client side scripts calls;

In scripts or fsms call: _handler = [...] call RE; (syntax - see below; RE stands for remote execution)

Format
[nil_or_caller, nil_or_target_object,"loc", script_to_execute, par0, par1...] call RE;

..otherwise.. clients calls will only work for the caller in MP.

replaced with BIS_fnc_MP now...

Share this post


Link to post
Share on other sites

yeah much easier to use imho - although when CBA is back up to full speed (i.e function library) I'll switch back to using that and the extended event handlers..

Share this post


Link to post
Share on other sites

Thanks for the help guys but I'm still a little lost. I've looked through BIWiki, DevHeaven, and OPFEC, but I haven't found any definitive sources of information regarding multiplayer locality. Is there a single reliable source of info out there? Or should I just proceed through trial-and-error experimentation?

Share this post


Link to post
Share on other sites

There is no one significant definitive source on locality. It looks like you have been looking in all of the right places. One particular Biki article that definitely helped me start to piece it all together is this one:

https://community.bistudio.com/wiki/6thSense.eu:EG

If you have not read it, please do!

There is also a corresponding forum thread if you have not seen that either:

http://forums.bistudio.com/showthread.php?65604-ArmA-(MP)-Scripting

There is also this article:

http://community.bistudio.com/wiki/Locality_in_Multiplayer

As far as locality goes, one of the key things to be familiar with when looking at commands in the Biki is the effects locality icon you will often (but not always) find in the upper left hand corner of the article:

If the icon has a E and then either a "G" for global or "L" for local effects. Please note there is often an arguments icon as well do not confuse the two.

If the icon has a "G", it means that effects of this scripting command are broadcasted over the network and happen on every computer in the network.

effects_global.gif

If the icon has an "L", it means that effects of this scripting command are not broadcasted over the network and remain local to the client the command is executed on.

effects_local.gif

Unfortunately, not every command has an icon, but for the most part it is a reliable way of determining the effects of a command.

Here are some attempts at answers to your questions (not necessarily in the order you asked them.):

And this is where I'm mixed up - if a server calls a script, then is the result cloned for all clients? If a client calls a script, is the result local only to the client, and not everyone else in the game? If a server calls createVehicle "truck", then will everyone in the game see that truck? If it's called by a single client instead, will it only be visible to that client?

If a server executes a script the results/effects are broadcasted to all the clients only if the commands in the script have global effects. Otherwise the results only stay on the server. Using createVehicle for an example, if the server executes it, will create the vehicle on the server and then broadcast the results (i.e. a new single vehicle) accessible to all since it has global effects. It only creates one vehicle but everyone can see it and interact with it.

Also, you mentioned that certain scripts can be explicitly run locally. What would happen in that case? Using the createVehicle "truck" example, if this code were run locally for a client, how would it be represented in game? Would the vehicle only appear on that client's PC, and would no one else be able to see it?

Just to clarify, some scripts can be explicitly run locally because they only contain commands with local effects. You can also prevent certain scripts and commands from executing by using isServer or isDedicated or !isServer or !isDedicated condition checks to ensure they only run on servers or clients, but this is more to prevent duplication of effects by preventing commands with global effects running on multiple machines (such as createVehicle on a client and server both being run and resulting in two vehicles). So, createVehicle only run on a client would still produce a vehicle visible/accessible by all clients.

Going from there, if code is run concurrently for all players, how is everything synchronized?

The game engine's netcode would handle how effects are broadcasted, but again, if code is run concurrently and has global effects, it would duplicate on all machines.

And regarding scripts/functions, am I correct in thinking that functions are essentially scripts that just return data? Is "execVM" basically a script's equivalent of "spawn" for functions? Can scripts be created via "call"?

Actually, it is probably more appropriate to say that scripts are functions that do not return data as opposed to functions being scripts that do return data. Here is a quick breakdown on the differences between execVM, spawn, and call (also see this article: https://community.bistudio.com/wiki/Script_(File)#Execution

execVM - Load a script from a sqf file and execute the code within via a new processing thread running in parallel to the executing instance (script or command that executes it) and does not return a value.

spawn - executes code that follow it in between { } in a new processing thread running in parallel to the executing instance. It cannot return a value. Functions the same as execVM except the code does not need to be in a separate file, it essentially creates a new script without a separate file.

call - executes a function that has already been compiled. The executing instance halts until the function is completed. It can return a value (but it does not have to).

So hypothetically, if all players had good connections and were guaranteed to be connected for the entire duration of the match, you could run all your scripts on clients and get the same results as if running them on the server?

Yes, but if the server needs to know about some or all of the results of the scripts on the clients and some or all of the commands in those scripts are local, then the server will not have that information.

Regarding not being able to run a server and client on the same machine, see this thread with instructions on how to possible do this:

http://forums.bistudio.com/showthread.php?147537-Tutorial-How-to-run-ArmA3-server-on-a-dedicated-server

Long story short, this is a trial and error process. Multiplayer scripting can be difficult and locality is the the factor most pertinent to its difficulty, but it can be overcome.

Good luck!

Edited by Loyalguard

Share this post


Link to post
Share on other sites

Loyalguard you're a godsend. You have no idea what it's like to receive an oriented, thorough response after sifting through the ambiguous community pages.

So now I think I have it visualized in my mind, but I just have a couple of follow-up questions to make sure:

1)Is it possible to call a global function on a local data set? If so then how are the results broadcast to other clients?

2)Is it somehow possible to create real in-game objects/actions locally? Is there any scenario where a player-action/object-creation occurs locally for 1 player and not shared with other clients? If so then how is this represented in game?(I'm assuming it's impossible but I want to make sure).

3)As you mentioned certain functions are local - is there a way to broadcast their results and essentially convert them into global functions? The previous posters discussed the "Multiplayer framework", and the "BIS_fnc_MP" function. I actually looked at the fnc_MP function in the Arma 3 function viewer, and to me it appeared as a basic macro. Is it really that simple? Is this where publicVariable is used?

4)What's the difference between "addEventHandler" and "addMPEventHandler"?

Big thanks once again.

Share this post


Link to post
Share on other sites

1) You can either run the script local and share the results via http://community.bistudio.com/wiki/publicVariable or you share the parameters for that script and run it on all clients. It really depends on what you're trying to accomplish.

2) It is. See here http://community.bistudio.com/wiki/createVehicleLocal (A common example for this are ammocrates. Some missions create them local for each player, so everyone has his personal crate that noone else can mess with)

3) Pretty much all things in ArmA have locality. When you enter a car as driver, its physics will be calculated by your pc, meaning it is local to you. This whole thing can be a bit confusing sometimes but it makes sure things run smoothly. Therefor if you want to have a script that influences a specific object it is usually a good idea to make sure it runs on the pc where that object is local. Some commands however only have local effects so if you want others to see them, you'll need to broadcast those.

4) Regular Eventhandlers are only local.

Share this post


Link to post
Share on other sites

Tajin pretty much covered everything. Here are a few additional comments.

3)As you mentioned certain functions are local - is there a way to broadcast their results and essentially convert them into global functions? The previous posters discussed the "Multiplayer framework", and the "BIS_fnc_MP" function. I actually looked at the fnc_MP function in the Arma 3 function viewer, and to me it appeared as a basic macro. Is it really that simple? Is this where publicVariable is used?

The method Tajin described in his response to question 1 (using pubicVariable and public variable event handlers) is one way of making them global and as you note you can also use the MP framework. BIS_fnc_MP in itself is fairly simple, but what you do not see outright are the other functions it uses to make the code global. It uses publicVariable and related commands to accomplish this, but you do not necessarily have to use publicVariable yourself separately to make it work.

If you are creating a mission, using the MP framework is a very good way to make sure the results you need get to the machines that need it, it is not require however.

4)What's the difference between "addEventHandler" and "addMPEventHandler"?

As Tajin noted, some evernnt handlers are local and should be added via addEventHandler. There are certain MP event handlers that must be added with addMPEventHandler. This article link and jump describe which must use the MP version:

https://community.bistudio.com/wiki/ArmA_2:_Event_Handlers#General_MP_Note

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×