Jump to content
Sign in to follow this  
Kamikadze666

Multiplayer locality argh

Recommended Posts

Is there a comprehensive FAQ or tutorial that deals with multiplayer locality issues? It's the one aspect of OFP scripting I can't understand what to do with, it's giving me nightmares lol. :banghead:

For example, I have a civilian car driven by AI driver who is not part of a team, therefore I presume he is local to the server. I want every player in MP to be able to approach this car and ask the driver to stop. So I attach an action to the car with

_actID1 = _vehicle addaction ["Ask driver to stop", {stopcar.sqs}];

which executes a script that says this:

_gen = _this select 0
_caller = _this select 1
_ran = random 1;

;ask driver to stop
?(_ran <= 0.5):_caller say "38v49"
?(_ran > 0.5):_caller say "38v50"

~1
_gen stop true;

exit

Simple as that. It works on a single machine, of course, even my AI subordinates can do it. But in MP, nope.

Since the car is local to the server and the script is executed by a random client, therefore the car doesn't stop, and nobody but the client can hear himself asking the driver to stop as well. I presume that in order for the car to actually stop and for the sound of the player asking the car to stop be heard, these commands need to be run on every machine. But how? I've no idea. Someone help me out please.

Share this post


Link to post
Share on other sites

Try removing the underlines from the variables on the first command, so it would be:

actID1 = vehicle addaction ["Ask driver to stop", {stopcar.sqs}];

You also need to edit the second script a little. Try redefining the variable _gen directly as the vehicle:

_gen = vehicle

After the first three lines in the second script, add the following line there also:

?! local _caller: exit

That checks for the locality of the "caller".

I'm not sure if this works, as I don't understand the whole context, but I hope it does the trick.

Try reading these multiplayer tutorials at OFPEC and Bi Wiki & this too.

Share this post


Link to post
Share on other sites

Thanks for the help. I just tried it, it did the same thing as before. Besides, it kind of sucks if I had to declare _gen as the vehicle directly, because I wanted the script to be applicable to not one particular vehicle but a whole bunch of them.

I'll go ahead and read the tutorials you linked before I make any further modification though.

Share this post


Link to post
Share on other sites

The world of MP scripting is a bit beyond me with those local, global, commands that can transmit to every clients, commands that can't, server only commands, publicvariable etc...

I had already plenty of annoyances with all those things that work entirely perfectly in SP, but just refuse to work in MP due to a command being local instead of global , or vice versa.

But i remember lots of praise of the CoC Network Service, and maybe in your case, the information not being transmitted to every clients and the server, it sounds like it could really help :

The CoC Network Services originally devised for "in house" use allow Operation Flashpoint scripters to transfer any data necessary to any specific network node in a networked OFP session.

Here is CoC website :

http://www.website.thechainofcommand.net/coc_network_services.htm

Share this post


Link to post
Share on other sites

Here try this...

I would need to experiment with it myself before getting it to work - but at least it's a start...

_gen = _this select 0

_caller = _this select 1

publicVariable "_caller"

~.05

comment "Try the above lines as well..."

_ran = random 1;

publicVariable "_ran"

~.05

;ask driver to stop

?(_ran <= 0.5):_caller say "38v49"

?(_ran > 0.5):_caller say "38v50"

~1

doStop _gen ;

comment "Or try <Don't know if _gen is vehicle or not> ---> vehicle setFuel 0"

comment "Don't forget to use debugging when running these scripts....

Example: player globalChat "Is this working?"

Example: hint format ["Who is %1?",_caller]

Example: hint format ["What is the random number: %1?",_ran]

GlobalChat line to indicate Script is Launching

Hint format - to indicate with a ding - What those 2 variables are...

If speed is an issue with the hint command:

Example: hint format ["Who is %1 and what is the random number: %2?",caller,_ran]"

exit

Ok - Problem - Doing things Randomly via Clients.

Unless you broadcast the Random variable - Server can't update itself or all clients.

References:

http://www.ofpec.com/COMREF/index.php?action=details&id=255&game=All

http://www.ofpec.com/COMREF/index.php?action=details&id=112&game=All

http://www.ofpec.com/COMREF/index.php?action=details&id=359&game=All

http://www.ofpec.com/COMREF/index.php?action=details&id=360&game=All

http://www.ofpec.com/forum/index.php?topic=22956.0

Edited by WW2Weasel

Share this post


Link to post
Share on other sites

I've just tried this, it didn't work either. The symptoms are exactly the same as before. That OFPEC manual though is mighty useful, I've learned some new things. I think I fixed the problem a different way, that is, the script seems to be working in MP now, but.. It's rather clumsy and I'm not sure how stable it is. I'm afraid I've left a lot of holes for it to fuck up all over the place, so tell me what you think.

Here's the new configuration.

I have a script called cars.sqs which includes:

_actID1 = _vehicle addaction ["Ask driver to stop", {L_stopcar.sqs}];
_actID2 = _vehicle addaction ["Ask driver to go", {L_gocar.sqs}];

A user then approaches the car and uses the action menu to call a local script L_stopcar.sqs which contains this:

_gen = _this select 0
_caller = _this select 1
_ran = random 1;

broadcasttarget=_gen;
broadcastcaller=_caller;
broadcastvalue=_ran;
;1 = stopcar, 2 = gocar
broadcasttype=1;
broadcaststart=true;

;debug statement
player globalChat format ["Public broadcast: %1, %2, %3, %4", broadcasttype, broadcastvalue, broadcastcaller, broadcasttarget];

publicVariable "broadcasttype";
publicVariable "broadcastvalue";
publicVariable "broadcastcaller";
publicVariable "broadcasttarget";
publicVariable "broadcaststart";

exit

Then separate from this there is a constantly running global script started through init trigger called P_propagation.sqs which has this:

#main
@(broadcaststart)

;debugstatement
player globalchat format ["Broadcast received: %1, %2, %3, %4", broadcasttype, broadcastvalue, broadcastcaller, broadcasttarget];

?(broadcasttype==1):[broadcastcaller,broadcasttarget,broadcastvalue] exec "P_stopcar.sqs";
?(broadcasttype==2):[broadcastcaller,broadcasttarget,broadcastvalue] exec "P_gocar.sqs";
~0.1
broadcaststart=false;

goto "main";

exit

and Finally there's the P_stopcar.sqs which does this:

_caller = _this select 0;
_gen = _this select 1;
_ran = _this select 2;

?(_ran <= 0.5):_caller say "38v49";
?(_ran > 0.5):_caller say "38v50";

~1
_gen stop true;

exit

This is based on the remote command execution tutorial at OFPEC. link.

The reason why I didn't put the global stopcar/gocar commands in the body of the P_propagation.sqs itself was just because these functions have delays in them, and I don't want the propagation script to wait for them to finish, so I used exec instead. Still, very clumsy. Also note that I still had to actually put a small delay inside the propagation script, right before the broadcaststart variable is set back to "false". This is because for some reason, if this delay is omitted, then the local instance of the script somehow manages to execute itself and set broadcaststart to "false" BEFORE the broadcaststart variable is actually made public through the publicVariable "broadcaststart" command; I have no idea how the system manages to pull this off, but it concerns me definitely as it's one visible place when the script can still screw up.

Share this post


Link to post
Share on other sites

I'm not seeing how you would set broadcasttype=2

Are you handling this with a Global switch outside of script?

Share this post


Link to post
Share on other sites

I would suggest something like this

in sqf file called var.sqf

actions=
[
"who say {38v49};(driver (vehicle who)) stop true;",
"who say {38v50};(driver (vehicle who)) stop true;"
];
true

this may be in init.sqs

var=preprocessFile "var.sqf"
@(call var)
#l
?(action!=-1):call (actions select action);action=-1;
~0.1
goto "l"

l_stopcar.sqs

_caller = _this select 0;
_gen = _this select 1;
_ran = _this select 2;

?(_ran <= 0.5):who = _caller;action=0;
?(_ran > 0.5):who = _caller;action=1;

{publicVariable _x}foreach ["who","action"]

~1

exit

as you see, in such configuration you just broadcast two variables, which decrease probability of any issues in MP. Also, such method is way easier to control because you only 1 scripts to handle mp broadcasting instead of 2.

I hope you will find it helpful :)

Share this post


Link to post
Share on other sites
I'm not seeing how you would set broadcasttype=2
Broadcasttype=2 is set by L_gocar.sqs script which I didn't show here because it's practically identical to the L_stopcar.sqs one except this very fact that it sets broadcasttype to 2 instead of 1.
I would suggest something like this
Ah, sqf files. I wish I was more familiar with them. Never too late to learn I guess, especially since IIRC sqf became a standard after Arma was released. Let me try this and see what happens.

Edit:

Ok, your version works too, with few minor changes. For example, there still have to be at least 3 broadcasted variables, not 2, because the person who is asking the driver to stop doesn't have to be IN a vehicle, he can just be near it. If I transmit only 2 variables (the person and the action), then there is no way to find out which vehicle he's asking to stop.

Aside from that, it seems to work well and looks cleaner so thank you. Oh and one question: when the script does the "call" command, like "call (actions select action)", does it suspend the execution of the script until these commands are executed, or does it branch off and does those commands separately from the main execution cycle? Basically, if a put a delay in the commands specified in var.sqf, will it also delay the main broadcasting script?

Edited by Kamikadze666

Share this post


Link to post
Share on other sites
Aside from that, it seems to work well and looks cleaner so thank you. Oh and one question: when the script does the "call" command, like "call (actions select action)", does it suspend the execution of the script until these commands are executed, or does it branch off and does those commands separately from the main execution cycle? Basically, if a put a delay in the commands specified in var.sqf, will it also delay the main broadcasting script?

Honestly, I don't know but it rather easy to check. It

;init.sqs
check = preprocessFile "check.sqf";
test=true;
call check;
test=true;

in check.sqf

while{1}do{check=false};

then, using radio action see if variable "check" is true or false (hint format["%1",check])

Ok, your version works too, with few minor changes. For example, there still have to be at least 3 broadcasted variables, not 2, because the person who is asking the driver to stop doesn't have to be IN a vehicle, he can just be near it. If I transmit only 2 variables (the person and the action), then there is no way to find out which vehicle he's asking to stop.

Well, you can find nearest car by using command nearestObject (

nearestObject[who,"classname in config"]

, to find out class name use

hint format["%1",typeOf name_of_car_in_editor]

).

Share this post


Link to post
Share on other sites
Honestly, I don't know but it rather easy to check.
Ok I checked it and it appears to be executing separately, so that's good.

As for using "nearestObject", I thought about that, but it just leads to more complications. For example, if I use nearestObject and there's two cars close enough to a player to give him the options for stopping, no matter which one of these option he picks, he will only be able to stop the car that is nearest to him, not the other one. So that's kind of inconvenient. Plus, what if one of those cars is not even one of those which he has a right to stop? It will still stop if it's the closest one. I think I'm fine with 3 variables - the player name, the vehicle name, and the action (which takes values: -1 for do-nothing, 1 for stop1, 2 for stop2, 3 for go1, and 4 for go2).

Thank you all for your help!

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  

×