OFPEC Forum

Editors Depot - Mission Editing and Scripting => OFP - Editing/Scripting Multiplayer => Topic started by: General Barron on 31 Mar 2005, 02:32:26

Title: How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 02:32:26
Greetings all,

I've recently started trying my hand at multiplayer editing and scripting. I've read snYpir's excellent MP editing tutorial, which gave me a great start; however, it doesn't go into much detail about scripting in particular, and I haven't been able to find another tutorial that does. One thing that I have found thru tinkering around in MP is that many commands work in very unexpected ways. So my question to all of you MP gurus is the following:

How does each scripting command work in a MP environment?

I want to know about every command possible. I'm not concerend with how the command works in general/SP, since the com ref tells this. I'm more interested in the following questions (plus any others you can think of):

??? Will the effect of the command be seen by all computers (globally), or only by the client it was run on (locally)?

??? What happens when you pass a local object to the command? What about a remote object?

??? How is the AI affected by this command in all of the above situations (if applicable)?

??? Is there anything else that must be done to get the command working properly in MP? Are there any other ways this command behaves differently in MP than in SP?

With that said, I hope to hear from everyone. I'll post new commands as I discover how they work in MP, and if everyone else does the same (and posts what they know already), then as a community we can get this all figured out, and cut down the questions by about 1/2 on this forum :).
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 02:33:04
This post will be modified to contain a list of all commands contributed so far. Please don't post a command that has already been posted, unless you need to correct errors or add to another person's post. In rough alphabetical order:

     Commands posted so far:

action
animate
animationPhase
addAction
camCreate*
createVehicle
cutObj
cutRsc
deleteVehicle
distance
drop*
leader*
move
objStatus
player
publicVariable
random
side*
skipTime
setpos
setvelocity
setdammage
setViewDistance
setFog
setOvercast
setRain
skipTime
titleText
titleCut
titleCut
titleRsc


*command needs more research/clarification


Edit

Check my post on this page here (http://www.ofpec.com/yabbse/index.php?board=7;action=display;threadid=22956;start=30). There I have posted a list created by Spinor of CoC, which lists how most commands work in MP.
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 02:57:41
Leader

In MP this command will always return the original leader of a group, even after he dies (at which time it will return his corpse, which become static objects on the 'civilian' side). Notice that in SP, this command will always return the current leader of a group (so it will always return a living unit when the group has at least one member).

This may not stay true after adding new units to the group via the "join" or "createunit" commands. (need more research)

This command will work on local or remote objects (if a unit is passed). If passed a group, the group must be defined locally.

move

This command will only work if the passed groupname is defined on all computers. This can be a problem if you want to spawn units into groups after the start of the mission, because if you put the following in a unit's init field:
Code: [Select]
groupA = group this; deletevehicle thisThen groupA will NOT be defined on all clients. There MUST be a delay between the group assignment and deleting the unit (figuring this one out caused me great headache).

player

This command will return something different on each computer. It will always return the current body of the player who's computer runs the command. On a dedicated server this command will return null (can be detected by the "isnull" command).

setpos
setvelocity
setdammage

what else?

These commands all work normally in MP, regardless of what computer they are run on, or whether the object affected is local or remote. For example, a client using the "setdammage" command on a unit local to the server WILL injure/heal that unit.

SetFog
SetOvercast
SetRain
Skiptime

The environemental changes from these commands will ONLY take place on the computer where the command is run from. It is entirely possible for one client to see day, while another sees night, for example.

How is the AI affected by this? Does the AI use the environmental settings of the computer it is local to (for vision ranges)?

Camcreate

The effects of this command will only be seen by the computer the command is run from. This means camera cutscenes must be started on each computer individually. Ordinance made with this command that would normally hurt units (such as shells and bullets) will NOT hurt units in MP (for example, a shell will explode but will not cause any damage). Objects and vehicles should NOT be created with this (createvehicle should be used instead).
Title: Re:How do scripting commands behave in MP?
Post by: Fragorl on 31 Mar 2005, 05:05:31
Yay. This thread is long overdue.

Re: Leader. So, if the leader dies, even if a new leader takes his place, the old one (corpse) still remains leader? Also: if normal respawn (like paintball respawn) is activated, and the leader is killed and respawns back into the group (still leader), will the leader command return his new incarnation, or the old corpse?

Re: Init fields. I understand now; an init field is local to whichever computer the unit belongs to.

Re: camcreate. I *think* that you might be wrong about camcreate. I tried running a script in a mp game with 1 client, 1 server, with the line
Code: [Select]
? local server: sh = "shell125" camcreate getpos aawhere server was a game logic, aa was the name of the soldier the server inhabited. The explosion was visible from, and killed, both players.
Here is an updated version of camcreate, which i will delete if it subsequently turns out to be wrong ;)

Camcreate

The effects of this will be seen and felt from all computers, similarly to createvehicle. If camcreate runs only on the server, the results *will* affect all clients; ordinance *will* hurt all clients. If camcreate runs on all clients, the command wil be repeated, once for each client, and once for the server.

Createvehicle

The effects of this are similar to camcreate. Two important distinctions - firstly, createvehicle offsets the object it creates to fit in with nearby objects' collision radii. Camcreate does not. Secondly vehicles created by createvehicle will be usable; vehicles created with camcreate will not be.
Title: Re:How do scripting commands behave in MP?
Post by: nominesine on 31 Mar 2005, 08:36:11
deleteVehicle
works normal in MP, regardles of locality. If a vehicle is deleted on a client machine it's deleted on the server. If it's deleted on the server it's deleted on the clients.

distance
May return a different value on client and server and the result is rather unnpredictable. The reason for this is lag. Since the client machines are somewhat slower than the server it's possible that a condition like unitOne distance unitTwo <50 will be set to true on the server while it is still false on the client machines. Solution: Never, ever measure distance on the clients.

objStatus
Status "ACTIVE", "FAILED", "DONE","HIDDEN" is local and may be different on all machines. Thus it is possible that an objective that is completed on a client will not be registered by the server.
Title: Re:How do scripting commands behave in MP?
Post by: Roni on 31 Mar 2005, 09:36:36
A few observations from my travels . . .

titlecut
The comref says that this command is obsolete but it still works for me and I'm patched to v1.96.  Titlecuts are local to each machine so you can fade one guy to black while all others retain normal vision etc.

particle drops
These USED to be local but it seems that since about v1.91 or so these are now run on all machines.  It used to be very annoying lighting a fire via a script and having it burning on just one machine . . .

setViewdistance
This is local to each machine.  If you wanted, you could blind one guy while all other players had 5 km visibility.

random
Again, local to each machine.  If you're running a script on all machines that uses a random function you will need to make sure that just ONE machine rolls the dice then passes it's results to all other machines via a server routine, otherwise all of your results will be out of whack.


skipTime
Again, is local to each machine.  What's worse, script execution is partially clock speed dependant.  So if the skipTime script has a pause of (say) 0.1 second between cycles then my machine might take 0.10003 seconds to execute while yours takes 0.100037 seconds to do it.  This does add up over time so that two machines running the same script at supposedly the same time will find themselves out of sync in very short order.

The best solution to this problem is to again have one machine carry out the skipTime function then broadcast the resulting time (via the daytime command) to all other machines via a server loop, while all other machines just read the publicVariable each cycle and skipTime accordingly.


That's all I can think of for now.



roni
Title: Re:How do scripting commands behave in MP?
Post by: Chris330 on 31 Mar 2005, 10:03:08
This is the best thread idea for ages. This should be pinned ;) :D
Title: Re:How do scripting commands behave in MP?
Post by: Chris330 on 31 Mar 2005, 10:27:15
I have a question :) In my MP mission which I'm building I have defined several groups using the init lines of the respective units of the groups. I assume from this thread now that it is likely that only the server's machine will recognise these groups.

So my question is where can I execute a script that will define the groups on all machines (including clients). Should I put it in the init.sqs file or something ???
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 10:35:55
Great! Thanks for the feedback so far. I sure hope this thread gets filled to the brim...
Quote
This is the best thread idea for ages.
Yeah, it's so good, it's been thought of 1,000,000 times before... just no one has ever made a really organized post for it I suppose. :D
Quote
Re: Init fields. I understand now; an init field is local to whichever computer the unit belongs to.
I don't think this is true. I've run assignment statements thru an init field (groupA = group this), and the variable is set on all machines. I believe the issue with deleting units from the init field is just one specific oddity in ofp.
Quote
Re: Leader. So, if the leader dies, even if a new leader takes his place, the old one (corpse) still remains leader?
Yes, the corpse will remain the leader. I have not yet done much research into the specifics (like if the leader ever changes), but I did notice that after killing a group leader, his corpse was returned with this command. Since this NEVER happens in SP, I wrote it down, as an example of "other MP issues" that might arise from a command other than locality.

Re: camcreate
I'm pretty sure I've had different results with this command than you suggest, but hopefully some MP experts with WAY more experience than me to set us all straight. :)

Just for completeness:

titlersc
cutobj
cutrsc
titletext
cuttext

These commands all behave like titlecut (above).
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 10:39:27
I have a question :) In my MP mission which I'm building I have defined several groups using the init lines of the respective units of the groups. I assume from this thread now that it is likely that only the server's machine will recognise these groups.

So my question is where can I execute a script that will define the groups on all machines (including clients). Should I put it in the init.sqs file or something ???

You posted this while I was typing up my last post, but I'll clarify the point in a new one.

If you define the group in a unit's init field, it will be defined on all machines. However, if you delete the unit right after you define the group (i.e. no delay in between), it will NOT be defined on all machines.

Incorrect:
Code: [Select]
   groupA = group this; deletevehicle thisCorrect:
Code: [Select]
   groupA = group this; this exec "delete.sqs"delete.sqs:
Code: [Select]
~2
deletevehicle _this
Title: Re:How do scripting commands behave in MP?
Post by: nominesine on 31 Mar 2005, 10:40:47
publicVariable

*** Erroneous theory deleted to avoid confusion - see correct explanation in GB's post below ***

Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 10:53:06
@publicvariable

Err.... I believe you are incorrect about how this command behaves. It does not "declare" a variable as public. Rather, it "broadcasts" the variable to all computers at the time you use the command. So if you had the following script run on the server:
Quote
a = 4
publicvariable "a"
a = 6
Then "a" would be 4 on all computers, except on the server, where it would be 6. Each of those computers could then change their own, personal "a" variable as much as they like. However, once any computer broadcast "a" with the publicvariable command again, then everyone else's "a" would be set to that one value (after which they could be changed again, and so on).

Basically, "publicvariable" should really be thought of as "broadcast public variable".

An important note about this, however, is that there will be a slight delay between when the variable is sent from a machine, and when it is recieved on every other machine (depending on ping). Usually this isn't to worry about, but for time-sensitive data, it could be.
Title: Re:How do scripting commands behave in MP?
Post by: nominesine on 31 Mar 2005, 11:13:26
*** post deleted as above ***
Title: Re:How do scripting commands behave in MP?
Post by: Garcia on 31 Mar 2005, 11:57:09
*leader
move
objStatus
player
random

Random is baaaaaad...if you got, i.e a=(random 100) in a script, then each computer gets it's own a, so the best thing is to either run the script only on server (if possible), or run only the random stuff on the server and publicvariable it to every one else.
Title: Re:How do scripting commands behave in MP?
Post by: Roni on 31 Mar 2005, 12:35:32
Re: publicVariable - In use (if not in fact) there are three different types of variables, not two - private, public and "shared public".

Private variables
As we all know (  :P  ) private variables are local only to the script in which they appear.  So for instance - I could write one script that spawns another script any number of times and have each of these spawned scripts use the same private variable at the same time.  This is not a problem as each variable is only relevant within its own environment.

Example -

;parent.sqs
_x=10
#loop
this exec "offspring.sqs"
_x=_x-1
~1
if _x >0 then goto "loop"

;offspring.sqs
_x=10
#loop
"Shell73" camCreate (getPos player)
_x=_x-1
~1
if _x >0 then goto "loop"



parent.sqs will spawn offspring.sqs ten times and each of these spawned scripts will in turn camCreate a Shell73 on the head of the player ten times (100 Shell73's in total).    :noo:  :beat:

In this case _x is used in the parent script AND in each of the spawned offspring scripts.  At any given time the value of this variable will be different in each and every script, but this won't matter as they are only ever referred to internally.  The _x in parent.sqs has absolutely nothing in common with the _x in any other script that uses that same variable name apart from the label "_x".


Public variables
Unlike private variables, public variables DO care about other scripts, but only if they are running on the same machine !.  In this way you can create a "persistent" variable that can be set by one script (eg init.sqs) and then modify it throughout the mission by running other scripts (eg via addActions, triggers etc).

Example -

;init.sqs
playerCanteens = 12

;drinkWater.sqs
if playerCanteens < 1 then exit
playerCanteens = playerCanteens - 1
<player effects go in here>
:



In this instance init.sqs sets the variable at the outset and each use of the script drinkWater.sqs reduces it.  playerCanteens may also be reduced by other scripts or influences (eg - triggers), but again, only if they are called on that machine.

In fact, the above scripts could be run simultaneously on all machines running in an MP mission and there would be no problem - each machine would update it's own version so that I might be completely out of canteens while you still had nine left, for example.


"Shared Public" variables
This is the same as above, but in this case other machines DO affect the variable.  To make a public variable "shared" all you have to do is execute the command "publicVariable XXX" where XX is the variable to be broadcast.

Taking the above example as a start, if one machine were to broadcast "publicVariable playerCanteens" then the current value of ITS version of playerCanteens would be broadcast to all other machines, instantly updating them to this value.  So if I was empty and you still had nine left, and I broadcast my value then you and every other player in the game would now also be empty.  And I would instantly become very unpopular !     :P   :P

Note that in most cases publicVariables will want to be shared, but not always.

The above sample is a good example of when you WOULD NOT want to broadcast it.  In this case one script works for all players, each running their own version and keeping track of their own canteen levels - there is no need to write one version of the script for each player.

A good example of when you WOULD want to broadcast it would be a scoring script - one machine would update the score then broadcast this to all other machines, the others would just read the broadcast value and update their own version of this variable accordingly.


Server loops and client loops
This brings up the best way to use shared public variables - server loops and client loops.  Check out the following time dilation script -

; timeDilation.sqs

; set time dilation factor
_dilationFactor = 1/1200

; Send client machines to client loop
? !(local server) : goto "clientloop"

; This loop runs continuously on host machine actioning time dilation.
; Time dilation is sent to all client machines via public variable declaration
#serverloop
skipTime _dilationFactor
realTime = daytime
publicVariable "realTime"

; Pause, continue loop
~0.1
goto "serverloop"

#clientloop

; This loop runs continuously on all client machines actioning time dilation.
; Dilation factor is derived continuously from public variable realTime distributed by host machine
? realTime > daytime : skipTime (realTime - daytime)

; Pause, continue loop
~0.1
goto "clientloop"



This script uses a server loop which update the server's game time and broadcasts this to the network, and a client loop which simply receives the server-determined game time and update its own local game time accordingly.  This saves having to write two scripts and makes it easier for a scripter to understand and edit it.


Converting "public" and "private" variables
Once you have defined a variable you can convert for what type to another by simply reassigning it.  For example - you might have a private variable that runs within a script that at its conclusion spits out a public version of the same value.  The syntax is simple - all you do is drop the preceding underscore in the public version (eg - playerCanteens = _playerCanteens)

For instance, you might want to run one single script on 10 different units that returns ten  different values, then takes the highest or lowest one of these values.  Similarly, you might want to run a script on ten different PLAYERS (ie machines), then take the highest or lowest of these results.  In this case, the script would run, the public variable would be assigned, then it would be broadcast to the network. (eg - playerCanteens = _playerCanteens, publicVariable playerCanteens)

Well, that's my latest two cents on the subject.  Once again, I started writing and my fingers got ahead of me.  I apologise in advance for any poorly written or boneheadly obvious info contained in this post.

Cheers all



roni
Title: Re:How do scripting commands behave in MP?
Post by: Fragorl on 31 Mar 2005, 12:50:15
Re: Init fields. I understand now; an init field is local to whichever computer the unit belongs to.

I don't think this is true. I've run assignment statements thru an init field (groupA = group this), and the variable is set on all machines.

oops, i meant to edit that out, once i changed my conclusion about camcreate. Ah well, never mind, let it sit there in all it's incorrect glory for the time being.

Re: camcreate
I'm pretty sure I've had different results with this command than you suggest, but hopefully some MP experts with WAY more experience than me to set us all straight. :)

Yeah, hopefully that will happen. I was just stating my findings after a quick 2-computer lan, I tried to be accurate but i could be wrong. On the othe hand, if 'drop' now runs on all machines, maybe camcreate has been changed too.

skipTime
Again, is local to each machine.  What's worse, script execution is partially clock speed dependant.  So if the skipTime script has a pause of (say) 0.1 second between cycles then my machine might take 0.10003 seconds to execute while yours takes 0.100037 seconds to do it.  This does add up over time so that two machines running the same script at supposedly the same time will find themselves out of sync in very short order.

The best solution to this problem is to again have one machine carry out the skipTime function then broadcast the resulting time (via the daytime command) to all other machines via a server loop, while all other machines just read the publicVariable each cycle and skipTime accordingly.

Now that's a smart solution...

Title: Re:How do scripting commands behave in MP?
Post by: Chris330 on 31 Mar 2005, 14:03:59
Ok I have an interesting question ;) I have a script in my MP mission which calls for a helicopter to extract the squad once two enemy squads are either all dead or all fleeing. I have a trigger which calls the extraction script when the variables attached to the squads become true. So my question is...

Do I have to broadcast the true/false variables to the clients machines in the sensor scripts for the trigger to become active on their machines ???

I'd appreciate your help, and I hope I have made myself clear (I normally dont :D) ;)
Title: Re:How do scripting commands behave in MP?
Post by: nominesine on 31 Mar 2005, 15:05:15
side
A useful command since it returns wich side each client player is in a DM game. Can be used to send different messages to different sides or to make separate briefings for east and west.

Example of a message shown to everyone who is not east:

?side player != east : hint "You must be playing on the west side, because you are not east"

The game reportedly recognizes 6 sides (and one unit can sometimes fall in to two categorys at the same time). The sides are:

East (tested, I never had any problems with it)
West (tested, I never had any problems with it)
Civilian (never tested myself)
Resistance or GUER (tested, had problems)
Enemy (never tested myself)
Friendly (never tested myself)

My experince is that the game don't always accept the syntax "resistance" and "guer" however. Sometimes resistance works, sometimes guer and sometimes neither will work (when making separate briefings for instance). East and West works perfect, though.

Taken from the on line comref:
Quote
The side of a dead unit (or any inanimate object) will always be civilian. The side of a "rouge" unit (one who killed too many friendlies) will be enemy.
However, the side of the unit's GROUP will always remain the same (east/west/res). So often it may be best to use the syntax:
side (group unit)

The comref also states that "friendly" is the side of a unit that is friendly to all other units. I've never tested it but I assume it is equal to "civilian" or "resistance" (if resistance is set to be friendly to both east and west in the editor).
Title: Re:How do scripting commands behave in MP?
Post by: Garcia on 31 Mar 2005, 15:06:33
Createvehicle

The effects of this are similar to camcreate. Two important distinctions - firstly, createvehicle offsets the object it creates to fit in with nearby objects' collision radii. Camcreate does not. Secondly vehicles created by createvehicle will be usable; vehicles created with camcreate will not be.

And 1 vehicle is created for every machine, so if 4 players are playing on a dedicated server, and the script is running for everyone, the amount will be 1+4=5 :P
Title: Re:How do scripting commands behave in MP?
Post by: Mud_Spike on 31 Mar 2005, 18:11:47
The result of this great thread should go in OFPEC's online cmd.ref.


Title: Re:How do scripting commands behave in MP?
Post by: Chris330 on 31 Mar 2005, 18:13:28
Ok I have an interesting question ;) I have a script in my MP mission which calls for a helicopter to extract the squad once two enemy squads are either all dead or all fleeing. I have a trigger which calls the extraction script when the variables attached to the squads become true. So my question is...

Do I have to broadcast the true/false variables to the clients machines in the sensor scripts for the trigger to become active on their machines ???

I'd appreciate your help, and I hope I have made myself clear (I normally dont :D) ;)

Can anyone answer my question ???  I'd appreciate it as I need to sort it for an MP mission I will be playing with my mate 8)
Title: Re:How do scripting commands behave in MP?
Post by: Killswitch on 31 Mar 2005, 18:45:26
Lets' do
shall we?  :)

Command:  action - makes a unit perform an action

Syntax: actor action [ actionstring, target ]

Scope/results: Use it where actor is local. Results/effects seen on all nodes

Example: dude action ["EJECT",somehelo]

Common misuse, giving issues in MP:

* players in MP and his AI loonies not getting ejected from planes. Likely reason: ejection script runs on one machine only. >Bzzzt!<

Best practice
The fix? Make sure that 1) it runs on all machines and 2) enclose the eject action call with
Code: [Select]
? local _dude: _dude action ["EJECT",_transport]or similar locality check.


Command: animate - runs animated parts of a model

Syntax: object animate [ animation, phase ]

Scope/results: one call affects all nodes in MP

Example: myplane animate ["cargodoor", 0.5]

Common misuse, giving issues in MP:

Animated part controlled by the same script running on all machines, each one having a go at calling animate at different times. This leads to the affected vehicle doing some really funky stuff in MP. I recently witnessed a certain radar tower dish do this... while the indended effect was to have it rotate nice and slowly, the multiple animate calls from different players' machines had it jittering and not knowing if it was coming or going... ;D

Best practice
Make sure only one machine (not necessarily the server, mind you) does the animate for a certain animated part at a time. Again, this can be done by a simple locality check, should the object to be animated have a script running on many machines.

Command: animationPhase - return the current phase of an animation. Value returned is a number between 0 and 1.

Syntax:  object animationPhase animation

Scope/results: phase returned might differ between machines. See below for dedicated server gotcha!

Example:  _doorPhase = myplane animationPhase "cargodoor"

Common misuse, giving issues in MP:
OFP feature/bug: sadly, animationPhase ALWAYS returns 0 on dedicated servers

May addons have lots of nifty functionality that uses invisible animations internal to the model as state variables to coordinate these extra features. (cargo loading, towing, rappelling, CAS support feature...the list goes on). In what must be one of the top showstopper bugs/features of OFP, animationState is useless on dedicated servers. In actuality, this breaks a lot of otherwise fantastic functionality in addons out there, rendering them if not useless but at least shaky for MP useage.

Normal OFP clients, arent't affected - the state of an animation is transferred just fine from machine A to all others if/should a script on machine A issue animate on a part. All other machines except the dedicated server can then read the current state of the animation just fine.

Take the example of the jittery radar dish I exemplified above. The rotation of that dish is governed by a script that checks the state of the radar animation in order to keep it spinning. In the current version of the addon with that radar, the rotation script runs on all machines, including the dedicated server, if available. The result is that the rotation monitor script on the deddy basically doesn't do anything since it's waiting in vain for the animation state to change from 0. All player clients, however, have scripts that ever so often detects that the dish has turned one whole revolution and issues another animate call. The end result? A very jittery/shaky radar dish that doesn't really work in MP.


Side note: on camCreate

A camCreated LGB (bomb) on player A:s machine will not be seen on player B's machine. However, the resulting explosion on A's machine will most certainly kill player B should he be unfortunate enough to stand where the bomb lands.  ;D
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 22:57:20
@Chris330

You do indeed pose an interesting question. However, your question doesn't specifically relate to scripting commands, so I'd ask that you start a new thread with your question, instead of trying to get it answered in here.  8)

Some clarification about "side"

There is a difference between the "side" data type (data type as in "string", "object", "group", "number", etc) and what gets displayed when you convert a side into a string. For the data type, case does not matter. For example:
    West == WEST == west == WeSt
However, when you convert a side into a string, it is ALWAYS converted into a very case-specific string (an example of converting a side to a string: hint format["%1", side player]). Here are the ones I know off the top of my head:

    Side       String conversion
     west            "WEST"
     east             "EAST"
 resistance       "GUER"
    civilian           "CIV" (not entirely sure)
    enemy         "ENEMY"

I suspect the reason nomineshine has had problems with using the resistance side, for example, is because he did not recognize the difference between when he was using the side as a SIDE data type, or when he was converting it to a STRING data type. For example, this will always return false, even though it may seem like it would work:
    format["%1", side unit] == resistance
Just for the record, this same sort of "string conversion" via the format command can be done with most other data types as well, such as GROUP, NUMBER, BOOL, etc, and it is the only way to pass additional information to certain commands (such as addeventhandler or createunit). But at this point I'm getting way off track...
Title: Re:How do scripting commands behave in MP?
Post by: Fragorl on 31 Mar 2005, 22:59:37
And 1 vehicle is created for every machine, so if 4 players are playing on a dedicated server, and the script is running for everyone, the amount will be 1+4=5 :P
Likewise with camcreate, I think I found. I reiterate: that was from a test on a 2-person lan, I could be wrong. When I put xyz="t80" camcreate poswherever in an init field, two t80s were created, just like createvehicle would have done in the same position (minus the obvious differences).

OK, as a multiplayer scripting neophyte, I need some clarification as to what 'local' and 'global' mean exactly. This is what I think they mean at the moment:

Global:
When a command is run on a single client, the effects occur on all computers. If the command is run on n clients (plus the server), the effect occurs n times, with each effect visible to all computers.

Local:
When a command is run on a single client, the effects of that command are seen (and felt) only on that client. When the command is run on n clients, the effect occurs once once on all computers.

So,
Global execution + Global command = Repeated execution on all computers
Global execution + Local command = Single execution on all computers
Local execution + Global command = Single execution on all computers
Local execution + Local command = Single execution on one computer

where 'global execution' is for example in an init field, or in a script run from an init field. 'Local execution' is in a script after the conditional '? local <object>'.

Question: does init.sqs run on all clients at the start of a mission, or just the server?
Title: Re:How do scripting commands behave in MP?
Post by: Killswitch on 31 Mar 2005, 23:32:49
Fragorl, your understanding of "global" and "local" with regards to the effects of scripting commands is indeed a sound one.

I believe the confusion out there has arisen from the usage of those terms both for describing the effects of commands and the so-called scope of variables.

"Global" and "local" effect script commands
...and their effects: see Fragorls post just above. That summarises it quite well.


Variable scope ("reach")
This is where the use of the word "global" above conflicts with the normal understanding of "global variables" in the context of programming languages and OFP scripting. In OFP terms that classical terminology goes like this:

A local variable (the ones who have names beginning with an underscore, e.g _myvar) is one that can only be reached by the script that's using it (or functions called from it, but we'll leave that aside for now).

A global variable is one whose value can be reached (read and written to) by all scripts running on one computer.

What do we then call variables that are handled in such a way as to have their values synchronised on all machines using publicVariable? It has been suggested to simply call such variables, well, "public variables".

However, earlier in this thread, Roni used the terms private/public/shared public for these variables, and perhaps that is a terminology better suited to use, since it avoids confusing variable scope with script command scope. Actually, I think private/global/public would be even better.


Quote
Question: does init.sqs run on all clients at the start of a mission, or just the server?
The init.sqs of a mission will be run on all machines, both server and clients, when the mission starts.
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 31 Mar 2005, 23:48:09
Quote
When I put xyz="t80" camcreate poswherever in an init field, two t80s were created, just like createvehicle would have done in the same position (minus the obvious differences).
Init fields are run on each individual computer, so in your case, the camcreate command was run on both computers in the LAN.

Quote
Question: does init.sqs run on all clients at the start of a mission, or just the server?

All computers.

Quote
I need some clarification as to what 'local' and 'global' mean exactly.
I wouldn't split hairs too much on this point. The definitions aren't provided by BIS, so they might differ from person to person. Basically, there are two factors to consider in terms of "locality" in MP:
  Local / Remote objects: an object is only "local" to one computer at a time. A player's 'body', squad, and vehicles under the control of them are local to that player's computer. Objects and units not under any player's control will always be local to the server. You can check to see if an object is local using the "local" command. (As a side note, if you convert an object to a string (hint format["%1", object1]), then it will have "remote" at the end if that object is not local). Some commands might behave differently if you pass them a remote object instead of a local object, which is what this thread is meant to find out.
   Local / Public effects: the effects of some commands will only happen on the computer from which that command was run (or example, the weather commands and skiptime commands). The effects of other commands will be seen by ALL computers, regardless of which computer runs the command (for example, the setdammage command). This is the other main thing I hope to find out with this thread.

Other confusing uses of locality

There are many other ways to use the terms "local" and "global", which is why I'm trying to avoid using them altogether. Using the terms in too many different situations just confuses me, which is why I used "public" instead of "global" above. But here are some other, different places where you could use the term:
    Local/Private & Global variables: I would hope everyone knows the difference between the two in SP. In MP they work exactly the same way, but note that each computer has its own variables (even global ones). The "publicvariable" command, as explained above, will force all computers to set the specified global variable to the value that was on the computer executing the command, at the time it was executed (wordy explaination, see Roni's post above for a better one).
    Scripts/commands running locally: A script (or scripting command) is run on a specific computer. The same script can be run on all computers at the same time, but really each individual computer is running it's own script. They all have the same script, but anything random in the script can cause it to run differently on each computer.
   Scripting commands run from the mission editor can be confusing. Triggers can run on one computer, but not on another, from my understanding. Basically, I would assume that, like scripts, each individual computer gets its own "copy" of the mission's triggers/waypoints/etc, and runs them individually on that machine. I may be wrong on this point though, and I sure as heck would like more clarification, since it definately deals with how scripting commands work in MP.

Anyway, my only point is that the terms global/local can get confusing, and it seems best to think in terms of computers. Basically: "what computer is executing this command?", and also "how will this affect other computers on the network?".

A good way to test mp scripting

This is assuming you have 2+ computers hooked together, near enough to each other that you can observe both without having to walk to a different room. Make a mission on desert island, and use Vektorboson's scripting console (in the ed depot) that can be called via an action added to all players. This way you can type in scripting commands on both computers without having to hop in/out of the mission editor, and those commands will only be executed on the computer it was typed in on. You can also monitor the status of variables, and see how it may be different fom computer to computer.

Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 01 Apr 2005, 00:00:31
    AddAction

The action added will ONLY appear to the computer who executed the command. So if the server adds an action to an object, none of the player's or their AI will be able to see/use the action (unless the server also has a player; i.e. is not dedicated). If a client adds an action to that machine's player, then only THAT player (and AI under his command) will be able to see/use that action. So if you want all players to be able to see and use an action, you have to make sure the addaction command is run on all computers.

When a player uses the action, the attatched script will only be run on that player's computer.
Title: Re:How do scripting commands behave in MP?
Post by: Chris Death on 01 Apr 2005, 10:15:46
While you're at AddAction, i'd like to keep one question open:

There's the case that when one player is standing close to another
player, which has an added Action, and the first player will be able
to execute the action.

Where the script will be executed?

On both player's machines?

On player A machine?

On player B machine?

Sorry, but at the mo i ain't got chance to test it  :(

~S~ CD
Title: Re:How do scripting commands behave in MP?
Post by: nominesine on 02 Apr 2005, 00:50:07
Quote
Triggers can run on one computer, but not on another, from my understanding. Basically, I would assume that, like scripts, each individual computer gets its own "copy" of the mission's triggers/waypoints/etc, and runs them individually on that machine. I may be wrong on this point though, and I sure as heck would like more clarification, since it definately deals with how scripting commands work in MP.

I've had this problem with "not present" triggers:

In a MP DeathMatch I made, there was two triggers checking, respectively, if WEST and RESISTANCE was "not present". Both triggers covered the entire map. When either was true, a triggerbased text informed you that mission was acomplished.

It worked perfectly in the editor and in SP mode. In MP it didn't. When a WEST-player was acting as server, the "west not present" trigger fired instantly on RESISTANCE-player's computer. When RESISTANCE-player was server it worked the other way around ("resistance not present" fired on WEST client).

Since the trigger only fired on the client, I'm quite sure that triggers are unique to every computer in the game. If I remember it correctly, I tried to create an alternative by changing the trigger condition "this" to "local server AND this". Thus preventing the client from firing the trigger. But I abandoned this idea and never tested it (and I suspect it would prevent the clients from ever seeing the text).

I still don't know the solution to the problem, but maybe this example can shed some light on the issue at hand to the Mp gurus.
Title: Re:How do scripting commands behave in MP?
Post by: Garcia on 02 Apr 2005, 19:47:59
Triggers can run on one computer, but not on another, from my understanding. Basically, I would assume that, like scripts, each individual computer gets its own "copy" of the mission's triggers/waypoints/etc, and runs them individually on that machine. I may be wrong on this point though, and I sure as heck would like more clarification, since it definately deals with how scripting commands work in MP.

Don't think computers got it's own copy of the waypoints, but if it's like that, then I would think the units would stop if there was something wrong with one of the waypoints on a computer.
And that triggers are local, that I can confirme. In the mission I'm making (which I mailed you about :P) I've got a trigger with east not present, activated once. When it is activated it changes the first objective to "Done" and shows a hint. And one time we tested it, this trigger was activated for everyone else than me :o Everyone else got a hint saying the first objective was done, and the objective changed, but nothing happened for me. Dunno what went wrong. It only happened once, but that proves that triggers are local.
Title: Re:How do scripting commands behave in MP?
Post by: Zombie on 03 Apr 2005, 14:22:24
I have found that the most important thing you can do in MP maps, is to make a game logic and name it   server   .  This will almost magically solve many MP issues.  As for the createvehicle, only run it on the server, and it will appear on all connected comps.  The first line should be:
?!(local server):exit
  And as stated above, publicvariable is also one of the most important commands
Title: Re:How do scripting commands behave in MP?
Post by: hermano on 06 Jul 2005, 16:53:35
Setdamage (and Setdammage) does not revitalize a dead (non player) unit when there is respawn and the unit was registered as dead (killed eventhandler triggered, alive unit returns false).
It will actually revitalize the unit if it is immediatly triggered when damage unit reaches 1 (but then killed eventhandler won't fire, alive returns true).

Will not work:
Code: [Select]
@!alive _unit
_unit setdamage 0

Will work:
Code: [Select]
@damage _unit >= 1
_unit setdamage 0

Took quite some time and nerves to find out what was wrong.
h

Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 06 Jul 2005, 20:19:25
I knew somebody had to have figured most of this stuff out before. Turns out Spinor from CoC made a nice little reference about commands in MP. I got it from Crashdome, who is supposedly going to fix it up and post it in the ed depot. In the meantime, here it is:

Quote
Compiled by Spinor for Coc
With input from bn880,CrashDome,Dinger

Tested on OFP 1.96 (Non-dedicated server + one client)


Notes:
----------------------------------------------------------------------------------------
local  
  ->   this is a command that is completely local i.e. its argument(s) must be
    local and both its result and/or effect are only local,
    naturally, all mathematical and logical commands belong to this group,
    the same is true for all interface stuff like dialogs etc.


constant
  ->  this denotes a constant value, hence the same on all machines


works on (non)local obj/unit/grp/vehicle
  ->  this command works no matter if the obj/unit/grp/vehicle is local on this
    machine or not; beware though: results/effects may differ due to lag/desynch
    between machines


works on (non)local obj, but has only local effect
  ->  although this command also works on both local and nonlocal objects,
    its effect is only local, i.e. it is not synchronized between machines
    EXAMPLE: sideChat, sideRadio etc.


works only on local obj/unit/grp/vehicle, (temp)
  ->  this command is only funcional if applied on a obj/unit/grp/vehicle
    that is local to this machine;
    temp signifies that the command may be applied to a nonlocal object
    but the effect is only shortlived: it will be removed during synchro




Command List:
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------

#
------------------------------------------------------------------------------------------
- a        local
a - b        local
arrayA - arrayB      local
! a        local
a != b        local
side1 != side2      local
a != b        local
obj1 != obj2      works on (non)local objects
grp1 != grp2      works on (non)local groups
a % b        local
a && b        local
a * b        local
a / b        local
a ^ b        local
a || b        local
stringA + stringB    local
arrayA + arrayB      local
+ a        local
a + b        local
a < b        local
a <= b        local
grp1 == grp2      works on (non)local groups
side1 == side2      local
a == b        local
obj1 == obj2      works on (non)local objects
a == b        local
a > b        local
a >= b        local


A
------------------------------------------------------------------------------------------
abs x        local
accTime       always 1 in MP
acos x        local
unit action action    works only on local unit (tested only with "EJECT")
unit addAction action    works only on local unit, temp
object addEventHandler handler  works on (non)local unit, has local effect (added handler executes only on local machine)
unit addMagazine weaponName  works only on local unit, temp
unit addMagazineCargo magazines  works on (non)local unit, but has only local effect, i.e. added items are only visible on local machine
addMagazinePool Null    non-functional in MP
unit addRating number    works only on local unit, temp
unit addScore score    works on (non)local unit, but has only local effect
unit addWeapon weaponName  works only on local unit, temp
unit addWeaponCargo weapons  works on (non)local unit, but has only local effect, i.e. added items are only visible on local machine
addWeaponPool [name, count]  non-functional in MP
alive obj      works on (non)local unit
unit allowFleeing courage  ?????
unitArray allowGetIn allow  ?????
unit ammo magazine    works on (non)local unit
a and b        local
object animate [animation, phase]  ?????
object animationPhase animation  ?????
asin x        local
soldier assignAsCargo vehicle  ?????
soldier assignAsCommander vehicle  ?????
soldier assignAsDriver vehicle  ?????
soldier assignAsGunner vehicle  ?????
atan x        local
x atan2 y      local
atg x        local


B
------------------------------------------------------------------------------------------
behaviour unit      works on (non)local unit
benchmark       local, returns benchmark of local machine
building buildingPos index  works on (non)local building, i.e. also on clients
buttonAction idc    local
buttonSetAction [idc, action]  local


C
------------------------------------------------------------------------------------------
cadetMode      constant
pars call body      local
call code      local
camera camCommand command  local
camera camCommit time    local
camCommitted camera    local
type camCreate position    local
camDestroy camera    local
camera cameraEffect effect  local
cameraOn      local
camera camSetBank bank    local
camera camSetDir direction  local
camera camSetDive dive    local
camera camSetFov fieldOfView  local
camera camSetFovRange fovRange  local
camera camSetPos position  local
camera camSetRelPos position  local
camera camSetTarget position  local
camera camSetTarget target  local
canFire vehicle      works on (non)local vehicle
canMove vehicle      works on (non)local vehicle
canStand soldier    works on (non)local unit
captive unit      works on (non)local unit
civilian       constant
clearMagazineCargo unit    works on (non)local unit, but has only local effect
clearMagazinePool     non-functional in MP
clearWeaponCargo unit    works on (non)local unit, but has only local effect
clearWeaponPool     non-functional in MP
closeDialog idc      local
combatMode grp      works on (non)local unit/grp
commander vehicle    works on (non)local vehicle
unit commandFire target    works only on local unit, temp
unit commandFollow formationLeader  works only on local unit
unit commandMove position  works on (non)local unit
commandStop unit    works on (non)local unit
unit commandTarget position  works only on local unit
unit commandWatch position  works only on local unit
unit commandWatch target  works only on local unit
comment comment      local
cos x        local
condition count array    local
count array      local
unit countEnemy array    works on (non)local unit
unit countFriendly array  works on (non)local unit
side countSide array    works on (non)local unit
typeName countType array  works on (non)local unit
unit countUnknown array    works on (non)local unit
createDialog name    local
type createUnit unitInfo  works on (non)local spawn group, has global effect, Init line is executed on all machines (with caveats)
type createVehicle pos    has global effect
crew vehicle      works on (non)local vehicle
ctrlEnable [idc, enable]  local
ctrlEnabled idc      local
ctrlSetText [idc, text]    local
ctrlShow [idc, show]    local
ctrlText idc      local
ctrlVisible idc      local
cutObj effect      local
cutRsc effect      local
cutText effect      local


D
------------------------------------------------------------------------------------------
damage object      works on (non)local object, rounding error on nonlocal object
daytime       returns local time of day, can differ between machines (skiptime and desynch!!)
deg x        local
deleteIdentity identityName  non-functional in MP
deleteStatus statusName    non-functional in MP
deleteVehicle object    works on (non)local unit?, causes game freeze in console?
dialog         local
direction object    works on (non)local unit
unit disableAI section    works only on local unit
disableUserInput disable  local
obj1 distance obj2    works on (non)local objects
while do code      local
unit doFire target    works only on local unit
unit doFollow position    works only on local unit
unit doMove position    works on (non)local unit
doStop unit       works on (non)local unit
unit doTarget position    works only on local unit
unit doWatch position    works only on local unit
unit doWatch target    works only on local unit
driver vehicle      works on (non)local vehicle
drop array      local effect


E
------------------------------------------------------------------------------------------
east        constant
ifCode else elseCode    local
enableEndDialog     local effect
enableRadio enable    local effect
enemy         local
vehicle engineOn bool    works only on local vehicle, temp
estimatedTimeLeft timeLeft  ?????
argument exec script    local
exit         local
exp x        local


F
------------------------------------------------------------------------------------------
time fadeMusic volume    local effect
time fadeSound volume    local effect
false         constant
fillWeaponsFromPool person  non-functional in MP
unit fire weaponName    works on (non)local unit, direction of fire not synchronized?
unit fire array      works on (non)local unit, direction of fire not synchronized?
flag unit      ?????
flagowner flag      ?????
fleeing unit      works on (non)local unit
helicopter flyInHeight height  works only on local vehicle
forceEnd       ?????
forceMap show      local
command forEach array    local
format format      local
formation grp      works on (non)local grp
formLeader unit      works on (non)local unit
friendly       local
fuel vehicle      works on (non)local vehicle


G
------------------------------------------------------------------------------------------
getDammage obj      works on (non)local obj, rounding error on nonlocal obj
getDir obj      works on (non)local obj
getMarkerColor marker    local
getMarkerPos markerName    local
getMarkerSize marker    local
getMarkerType marker    local
getPos obj      works on (non)local unit
getWPPos waypoint    works on (non)local group
unit globalChat chatText  works on (non)local unit, but has only local effect
unit globalRadio radioName  works on (non)local unit, but has only local effect
goto label      local
group obj      works on (non)local obj
unit groupChat chatText    works on (non)local unit, but has only local effect
unit groupRadio radioName  works on (non)local unit, but has only local effect
grpNull       local
gunner vehicle      works on (non)local vehicle


H
------------------------------------------------------------------------------------------
handsHit soldier    works on (non)local unit
unit hasWeapon weaponName  works on (non)local unit
hint text      local effect
hintC text      local effect
hintCadet text      local effect


I
------------------------------------------------------------------------------------------
if condition      local
x in array      local
soldier in vehicle    works on (non)local unit/vehicle
fireplace inflame burn    works on (non)local fireplace
inflamed fireplace    works on (non)local fireplace
isEngineOn vehicle    works on (non)local vehicle
isNull grp      works on (non)local grp
isNull obj      works on (non)local obj


J
------------------------------------------------------------------------------------------
unitArray join group    works on (non)local unitArray/group


K
------------------------------------------------------------------------------------------
unit knowsAbout target    works properly only on local unit, targer can be nonlocal


L
------------------------------------------------------------------------------------------
helicopter land mode    works only on local vehicle
lbAdd [idc, text]    local
lbClear idc      local
lbColor [idc, index]    local
lbCurSel idc      local
lbData [idc, index]    local
lbDelete [idc, index]    local
lbPicture [idc, index]    local
lbSetColor [idc, index, color]  local
lbSetCurSel [idc, index]  local
lbSetData [idc, index, data]  local
lbSetPicture [idc, index, name]  local
lbSetValue [idc, index, value]  local
lbSize idc      local
lbText [idc, index]    local
lbValue [idc, index]    local
leader unit      works on (non)local unit
leader grp      works on (non)local grp
group leaveVehicle vehicle  works only on local group/unit
lightIsOn lamppost    ?????
list trigger      triggers are synchronized, hence should returns globally synchronized result, sequence may differ
ln x        local
loadFile filename    local
person loadIdentity name  non-functional in MP
object loadStatus name    non-functional in MP
local obj      returns locality status of obj, hence local result
localize stringName    local result, depending on language setting of machine
vehicle lock lock    works only on local vehicle, temp
locked unit      works on (non)local unit
group lockWP lockWP    works only on local group
log x        local


M
------------------------------------------------------------------------------------------
magazines vehicle    works on (non)local vehicle
mapAnimAdd frame    local
mapAnimClear       local
mapAnimCommit       local
mapAnimDone       local
markerColor markerName    local
markerPos markerName    local
markerSize markerName    local
markerType markerName    local
missionName       global, the same on all machines
missionStart       local, may slightly differ between machines
a mod b        local
group move pos      works only on local group
soldier moveInCargo vehicle  works only on local unit
soldier moveInCommander vehicle  works only on local unit
soldier moveInDriver vehicle  works only on local unit
soldier moveInGunner vehicle  works only on local unit
musicVolume       local


N
------------------------------------------------------------------------------------------
name object      works on (non)local object
nearestBuilding obj    works on (non)local obj
nearestObject pos    also finds nonlocal objects
nil         local
not a        local


O
------------------------------------------------------------------------------------------
object id      correctly points to map object also on clients
objNull       constant
objective objStatus status  local
onBriefingGear sound    local
onBriefingGroup sound    local
onBriefingNotes sound    local
onBriefingPlan sound    local
onMapSingleClick command  local
a or b        local
unitArray orderGetIn order  only works on local unit


P
------------------------------------------------------------------------------------------
pi        constant
pickWeaponPool obj    non-functional in MP
player         local, player on this machine
playersNumber side    returns playable units per side, same on all machines, always zero in SP
soldier playMove moveName  only works on local unit, effect is then global
playMusic name      local effect
playMusic nameAndPos    local effect
playSound name      local effect
position object      works on (non)local obj
preprocessFile filename    local
primaryWeapon vehicle    works on (non)local unit
private variableName    local
private variableNameList  local
publicVariable varName    synchronizes varName on all machines with value on local machine
putWeaponPool obj    non-functional in MP


Q
------------------------------------------------------------------------------------------
queryMagazinePool name    non-functional in MP
queryWeaponPool name    non-functional in MP


R
------------------------------------------------------------------------------------------
rad x        local
random x      local
rating unit      works on (non)local unit
unit removeAction index    only works on local unit
object removeAllEventHandlers handlerType  works on (non)local unit, effect is local
removeAllWeapons unit    only works on local unit
object removeEventHandler handler  works on (non)local unit, effect is local
unit removeMagazine weaponName  only works on local unit
unit removeMagazines weaponName  only works on local unit
unit removeWeapon weaponName  only works on local unit
requiredVersion version    local effect, depending on OFP version on machine
resistance       constant
array resize count    local
group reveal unit    works on (non)local group/unit


S
------------------------------------------------------------------------------------------
saveGame      non-functional in MP
person saveIdentity name  non-functional in MP
object saveStatus name    non-functional in MP
saveVar varName      non-functional in MP
unit say speechName    works on (non)local unit, but is local in its effect
score unit      works on (non)local group/unit, but results can differ between machines due to non-synchro of addScore
scudState scud      ?????
secondaryWeapon vehicle    works on (non)local unit
array select index    local
unit selectWeapon weapon  ?????
array set element    local
setAccTime accFactor    non-functional in MP
vehicle setAmmoCargo ammoCargo  ?????
group setBehaviour behaviour  only works on local unit/group, temp
person setCaptive captive  only works on local unit, temp
group setCombatMode mode  only works on local group, temp
object setDamage damage    works on (non)local obj, rounding error on nonlocal obj
obj setDammage dammage    works on (non)local obj, rounding error on nonlocal obj
obj setDir heading    only works on local obj, temp
person setFace soldier    works on (non)local unit, but effect is only local
person setFaceAnimation blink  works on (non)local unit, but effect is only local
flag setFlagOwner owner    ?????
flag setFlagSide side    ?????
flag setFlagTexture texture  ?????
time setFog fog      local effect, not synchronized!
group setFormation formation  only works on local group, temp
group setFormDir heading  only works on local group, temp
vehicle setFuel ammount    only works on local vehicle, temp
vehicle setFuelCargo ammount  ?????
group setGroupId id    works on (non)local group, but effect is only local
person setIdentity identity  ?????
marker setMarkerColor color  local
markerName setMarkerPos pos  local
marker setMarkerSize size  local
markerName setMarkerType markerType  local
person setMimic mimic    works on (non)local unit, but effect is only local
object setObjectTexture texture  ?????
time setOvercast overcast  local effect, not synchronized
obj setPos pos      works on (non)local unit
index setRadioMsg text    local
time setRain rainDensity  local effect, not synchrinized
vehicle setRepairCargo ammount  ?????
vehicle setSkill skill    only works on local unit, temp
group setSpeedMode mode    only works on local group, temp
setTerrainGrid grid    local effect, not synchronized!
unit setUnitPos mode    only works on local unit
vehicle setVelocity [x, z, y]  only works on local object
setViewDistance distance  local effect, not synchronized!
waypoint setWPPos position  only works on local group
showCinemaBorder show    local
showCompass show    local
showGps show      local
showMap show      local
shownCompass       local
shownGps       local
shownMap       local
shownPad       local
shownRadio       local
shownWarrant       local
shownWatch       local
showPad show      local
showRadio show      local
showWarrant show    local
showWatch show      local
side unit      works on (non)local unit
unit sideChat chatText    works on (non)local unit, but effect is only local
unit sideRadio radioName  works on (non)local unit, but effect is only local
sin x        local
skill person      works on (non)local unit, rounding error on nonlocal unit
skipTime duration    local effect, not synchronized!
sliderPosition idc    local
sliderRange idc      local
sliderSetPosition [idc, pos]  local
sliderSetRange [idc, min, max]  local
sliderSetSpeed [idc, line, page]local
sliderSpeed idc      local
someAmmo unit      works on (non)local unit
soundVolume       local
speed obj      works on (non)local obj
speedMode grp      works on (non)local grp
sqrt x        local
unit stop stop      works only on local unit
stopped unit      works only on local unit
unit switchCamera mode    works on (non)local unit, but effect is only local
lamppost switchLight mode  ?????
soldier switchMove moveName  works on (non)local unit, but when used on nonlocal unit, effect is also only local


T
------------------------------------------------------------------------------------------
tan x        local    
tg x        local
if then else      local
if then codeToExecute    local
time         local, may slightly differ between machines
titleCut effect      local effect
titleObj effect      local effect
titleRsc effect      local effect
titleText effect    local effect
true         constant
typeOf obj      works on (non)local obj


U
------------------------------------------------------------------------------------------
unassignVehicle unit    only works on local unit
unitReady unit      works on (non)local unit
units unit      works on (non)local unit
units grp      works on (non)local grp


V
------------------------------------------------------------------------------------------
vehicle unit      works on (non)local unit
unit vehicleChat chatText  works on (non)local unit, but effect is only local
unit vehicleRadio radioName  works on (non)local unit, but effect is only local
velocity vehicle    works on (non)local unit


W
------------------------------------------------------------------------------------------
waypointPosition waypoint  works on (non)local group
weapons vehicle      works on (non)local unit
west         constant
while condition      local

However, as demonstrated by hermano and many other's posts, there are quite a few little "irks" in the way commands behave in MP, aside from whether they have local or global effects. So please, other input is still extremely welcome. :)
Title: Re:How do scripting commands behave in MP?
Post by: hermano on 07 Jul 2005, 14:22:02
Great list,
thanks General, CrashDome!
By the way, I'm not sure if the info about savestatus is right, it seems to work for vehicles and gamelogics (at least the damage of the vehicle can be saved and restored, for gamelogics also skill  afaik). Won't work for man (and child objects).
h
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 08 Jul 2005, 01:09:27
Great list,
thanks General, CrashDome!
By the way, I'm not sure if the info about savestatus is right, it seems to work for vehicles and gamelogics (at least the damage of the vehicle can be saved and restored, for gamelogics also skill  afaik). Won't work for man (and child objects).
h
Ha! You're sharp. Crashdome even posted a comment about that (in the forums where he posted this). His SOW mod uses savestatus extensively to allow saving across MP missions, so obviously it works in MP. Didn't know about the specific limitations you mentioned though ;)
Title: Re:How do scripting commands behave in MP?
Post by: Fragorl on 08 Jul 2005, 02:31:44
A good find, General Barron!

This list confirms most if not all of the commands that were previously mentioned in this thread, which is always nice :)

EDIT:
I'm still a bit hazy on camcreate versus createvehicle- the list here definitely says they are different, with createvehicle being global, camcreate being local, but I still found them to behave in exactly the same when I ran my 2 person lan test. A shell camcreated on the server-side only killed both players. Placing a "T80" createvehicle ... in the initfield of a unit created 2 t80s, each visible from both players. Substituting createvehicle for camcreate once again produced 2 T80s, each visible from both players.
Title: Re:How do scripting commands behave in MP?
Post by: Garcia on 08 Jul 2005, 03:17:30
Indeed, createvehicle can't be totally global, cause you will get 1 vehicle for every client+server...which is annoying :-\
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 08 Jul 2005, 05:42:26
To really see the difference between the two, you should set up a mission with a scripting console (Vectorboson's is a good one). Commands typed into the console will only be executed on that specific client.

Using the camcreate command will make an object that is only visible on the machine the command was run from. Using the createvehicle command in the same situation will make the object visible on ALL clients.

Quote
A shell camcreated on the server-side only killed both players.

I haven't experienced or confirmed this myself. However, that would be a special exception for the server only. Camcreating shells on clients creates a shell that does no damage.

Quote
Placing a "T80" createvehicle ... in the initfield of a unit created 2 t80s, each visible from both players. Substituting createvehicle for camcreate once again produced 2 T80s, each visible from both players.
Init fields are run on EVERY client. So the camcreate and createvehicle commands were run twice: once on each client, resulting in 2 vehicles total.

Okay, now I get it. The 'camcreate' command should have only made one vehicle visible on each client, since I just said the created object would only be visible where the command was issued.  :-\

I guess I don't have enough MP experience to give straight answers here... However, I know that the camcreate/createvehicle commands are very basic to MP, so the answer to your questions has to be widely known to experienced MP editors. :)
Title: Re:How do scripting commands behave in MP?
Post by: Fragorl on 08 Jul 2005, 07:40:48
yes - that was my point ;)

it sounds to me that one possibility is that somewhere along the line, perhps one of the more recent patches like 191, 195 or 196 made some changes to the commands that they didnt tell us about
Title: Re:How do scripting commands behave in MP?
Post by: hermano on 11 Jul 2005, 14:42:24
Ha! You're sharp. Crashdome even posted a comment about that (in the forums where he posted this). His SOW mod uses savestatus extensively to allow saving across MP missions, so obviously it works in MP. Didn't know about the specific limitations you mentioned though ;)

Thanks ;)
There is another limitation I forgot to mention. Savestatus of an undamaged object will only work if there is no damaged status saved with the same name, calling deletestatus before saving will solve this.
Besides: I'm around the sow forums sometimes and actually plan to join CrashDome in creating a sow campaign, the sow scripts are really fine, the only other scripts of such quality I've seen so far are coc's.
h
Title: Re:How do scripting commands behave in MP?
Post by: Mr.Peanut on 11 Jul 2005, 17:55:24
Must a publicVariable be defined on all machines before it can be broadcast?  That is, if the global boolean variable bVar is defined only on one client and that client broadcasts via publicVariable "bVar", will bVar be then defined on all machines? Must there be a delay between creating(or assigning a new value to) a variable and broadcasting it?
Title: Re:How do scripting commands behave in MP?
Post by: Garcia on 11 Jul 2005, 19:32:07
There should be a small delay at least
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 11 Jul 2005, 20:53:05
Must a publicVariable be defined on all machines before it can be broadcast? Must there be a delay between creating(or assigning a new value to) a variable and broadcasting it?

No and no.
Title: Re:How do scripting commands behave in MP?
Post by: Mr.Peanut on 30 Sep 2005, 19:27:55
Could this thread be pinned? It is sinking...
Title: Re:How do scripting commands behave in MP?
Post by: macguba on 30 Sep 2005, 23:59:06
I don't know anything about MP and I haven't studied the thread, but there is clearly some good stuff here.    

The forum is not the right place for storing information: the Editors Depot is the place for that.   However the forum can be a good place for collecting information, and sharing and discussing experiences of how commands work.    This sort of behaviour is to be encouraged. :thumbsup:

Consequently I've made this thread a sticky temporarily.   However in the fullness of time (say, in the next month or two) I expect somebody to turn the information here into a tutorial.  Giving credit where it is due of course.    However, in the long term if its not useful enough to be a tute, it's not useful enough to be a sticky.
Title: Re:How do scripting commands behave in MP?
Post by: Mr.Peanut on 02 Oct 2005, 15:37:00
Understood mac. It's just that I was searching for this thread the other day and had trouble finding it, it had sunk so quickly.

It seems to me there is still much disagreement over how certain commands behave in MP.  I think it would it be safe to say that with the exception of createVehicleand  deleteVehicle, a command should executed on all clients if you want the effects to be observed on all clients.

Is redundancy an issue with any other commands? I know that the *Radio commands only need be executed on one client to be seen by all, but if a trigger executes a sideRadio command, for example, is the message displayed once or multiple times on each client?  

If I am using setWPPos or move for enemy AI (local to the server), does it cause problems to execute these commands on every client instead of only on the server?

Are there any situations where executing commands on all clients would cause problems other than unnecessary cpu load?  
Title: Re:How do scripting commands behave in MP?
Post by: Killswitch on 03 Oct 2005, 16:01:24
Is redundancy an issue with any other commands?
Yes. See "join" below.
Quote
I know that the *Radio commands only need be executed on one client to be seen by all, but if a trigger executes a sideRadio command, for example, is the message displayed once or multiple times on each client?
I wasn't aware that *Radio behaved differently from *Chat, which definitiely only has effect on the machine where it is issued. In other words: to have all nodes see the output of a *Chat, it has to be run on all nodes (possibly with the exception of a dedicated server, since that would be uneccessary)
Quote
If I am using setWPPos or move for enemy AI (local to the server), does it cause problems to execute these commands on every client instead of only on the server?
There could be problems. Let's say "script X" handles the moving around of a certain group and that script happens to run on all machines. Also, "X" will dynamically adapt the placement of waypoints and ordering of movement based on several external factors. Now, during an MP session, due to desync and packet loss and whatnot, the subset of the current gamestate that X needs to function might be different on different machines. The result would then be script X on machine A moving a waypoint to point P1 whereas the same script on machine B tries to move it to P2.

Therefore, the best practice is to issue these where the affected unit/group is local. (Now, move will only have an effect on the machine where the unit/group that move operates on is local)

Quote
Are there any situations where executing commands on all clients would cause problems other than unnecessary cpu load?
Yes. One example that comes to mind and that is very common is the use of the join command in waypoints or triggers. I have played several missions where the MP player group meets up with some other entity (classical "rescue VIP"-type missions) that then joins the player group. Since the mission maker was unaware of the many pitfalls of MP mission making, the result in-game will be several repeated calls for the VIP to join the squad:
Quote
5, join 1
5, ready
5, join 1
5, ready
5, join 1
5, ready
5, join 1
5, ready
5, join 1
5, ready
Now that's HIGHLY annoying!
Title: Re:How do scripting commands behave in MP?
Post by: mad rabbit on 23 Nov 2005, 17:26:49
I'm so glad this forum was made a sticky, albiet a temporary.  Tyring to find this info over last 2 years has been a nightmare!  Try not knowing this stuff when making a CTI...without 2 computers to trial it on!!

e.g. 1) make script
       2) replicate as needed
       3) found out command has MP issues
       4) edit all 10 scripts to source out to a script that is only executed on server/client

Nice work on getting this topic started and maintained General Barron!  Now if we can convince someone to make the tutorial or even better get HAMMY to include this info in his executable Command Reference 1.91 that would be great.

----------------------

I've taught myself OFP scripting from the ground-up (i.e. I know no other programming type language  :) what better way to learn than OFP) and I've been making a CTI for the last 2 years based on the MFCTI core.  

CTI maps use a lot of arrays, so my question is:

How are arrays effected by locality in a MP setting with a dedicated server?

e.g.
If I have an array defined at the start of a map in a script run on all machines (for CTI scripters this would be "Main\initserver.sqs") but I dynamically edit (contents not size for now) that array with different objects and sub-arrays, how is this handled in a MP setting?

1) global script = defines array
2) local to player script edits array = array contents edited/updated on all computers?
3) local to server script edits array = array edited/updated on all computers?

Now I've learnt the difference between variables, arrays, functions, commands, scripts etc. through various sources but here's the problem I have:

1) 'arrays' can hold 'objects' which can be defined as a 'variable'

e.g. Var1 = vehicle1;subArray = [Var1];mainArray = [subArray]
       i.e. mainArray = [[vehicle1]]

2) Now if Var1 changes to vehicle2 via a local to player script, does the contents of Array1 change?

e.g. local: Var1 = vehicle2
       server: subArray = [Var1]
       mainArray = [[?]]

I know it might seem off-topic in relation to the thread, but in relation to the 'PublicVariable' command, does this have to be done OR can be used (sorry for my lack of understanding in this department) with arrays?

Therefore, is it better to use arrays with multiple contents or mutliple variables that are broadcasted via the 'PublicVariable' command?

I'm of the mind that the former is better than the latter as I've read somewhere that arrays hold the information better whereas using variables can be erroneous in a MP setting?

---------------

Sorry if this is off-topic, but it was in a way in relation to the 'PublicVariable' command so it seemed fitting.  Feel free to move this as a serperate topic.  :)
   
Title: Re:How do scripting commands behave in MP?
Post by: General Barron on 24 Nov 2005, 02:16:35
Good Q's, and I'd say that they are all on topic. I don't have much time for a reply, but I can add more later if needed.

The main issue here is how variables are handled in an MP environment. The answer is the same for all types of variables, including arrays.

Even though the global arrays are initialized at the same time, and with the same data, on every node (computer+server), each node stores its own array, completely separate from the rest. Later changes made to one node's array will NOT affect the other nodes (even though the array has the same name, and is global). The same is true for all other variable types.

Pretty much the only way you can have one node affect the variables on other nodes is with the 'publicvariable' command; which BTW doesn't support arrays, strings, and a few other types.

---------------

What I would HIGHLY recommend to ANYONE using fairly complex MP scripting, is that they use the CoC's Network Services 2 (http://www.thechainofcommand.com/docs/LIBNETWORK/archive/CoC_NS_2_Pack.zip). It has built in functions for sharing arrays across the network, as well as a couple other extremely handy functions. The documentation is a little hard to understand at first, but it is pretty straightforward once you get the hang of it, and it makes things about 1000x easier to script.

Crashdome had started making a tutorial on how to use the NS. I will have to see the status of that tut, and possibly finish it myself. I swear to you NS will make your life easier, especially with something as complex as CTI.
Title: Re:How do scripting commands behave in MP?
Post by: Chris330 on 25 Dec 2005, 04:11:56
Dear all,

I have a question. This is a script I have been writing which works fine on single player but has not been tested on multiplayer. There's no need to get bogged down in the script too much all I need to know is because game logic units are always local to the server, does this mean that their positions are always defined on the server and broadcast to the clients? Or, do I have to instruct the client machine(s) to change the postions of the game logics too, or can I just get away with altering their positions on the server?

The following script has been made assuming that the client machine(s) do not have to update the positions of the game logics. Rather it has been made assuming that the positions of the game logics in the mission are determined and broadcast globally by the server. Have a look at it. I have annotated the bits I need some clarification on (they are only small parts of the script).

Please note it is a camera script which utilises two game logic units. One named cameraeffect1 and one named cameraeffect2.



//I think this bit is now okay as I understand that camcreate
//must be executed on the client machines too. :D
_camoffx = _this select 0
_camoffy = _this select 1
_helo = _this select 2
_cam1 = "camera" camcreate [0,0,0]
_cam1 cameraeffect ["internal", "back"]
_cam1 camsettarget cameraeffect1
_cam1 camsetrelpos [0,0,0]
_cam1 camcommit 0


#start
?not local server : goto "checkserverready"
//If this is not the server machine then goto the loop that
//waits for the server to finish the maths
_BankPitch = _helo call GetBankPitch
_Pitch = _BankPitch select 1
_sinangle = sin(_Pitch)
_cosangle = cos(_Pitch)

;evaluate where camsetrelpos command should set the camera to for _camoffy
e = (_sinangle) * (_camoffy)
a = (_cosangle) * (_camoffy)
//broadcast the camsetrelpos variables to the client(s)
publicvariable "a"
publicvariable "e"


;get heading of helicopter and evaluate x and y offsets for the game logics for _camoffx
_heading = getdir _helo
_angle = 360 - _heading
_xa = (cos (_angle)) * _camoffx
_ya = (sin (_angle)) * _camoffx

;Get position co-ordinates of helicopter
_xh = getpos _helo select 0
_yh = getpos _helo select 1

//The interesting bit. Will this automatically update the
//game logics' positions on the client?
;Position the game logics
cameraeffect2 setpos [(_xh + _xa),(_yh + _ya),0]
_dist = _helo distance cameraeffect2
_height = sqrt ((_dist^2)-(_camoffx^2))
cameraeffect1 setpos [(_xh + _xa),(_yh + _ya),_height]
cameraeffect1 setdir _heading
logiccomplete = true


//Client waits for server to finish then camsetrelpos variables
//are issued.
#checkserverready
?logiccomplete : goto "camerapositioning"
goto "checkserverready"

#camerapositioning
_cam1 camsetrelpos [0,a,e]
_cam1 camcommit 0
~0.001
logiccomplete = false
?camend : goto "finish"
goto "start"

#finish
_cam1 CameraEffect ["TERMINATE", "BACK"]
CamDestroy _cam1

exit

  8)