mr.peanut 1 Posted April 7, 2006 In my init.sqs I have called a script that randomises a variable on the server and then publicvariables it. The clients wait until they receive the updated variable and then use it to skiptime. What I have noticed, in the transition from debugging locally, to debugging on a dedicated server, is that the script only works if it is removed from the init.sqs and placed in a trigger that fires at game start. Do publicVariables not broadcast properly until the game begins? Share this post Link to post Share on other sites
Chris Death 0 Posted April 7, 2006 :edit - i should better read twice before replying soz - been a hard day yesterday - look for CrashDome's reply ~S~ CD Share this post Link to post Share on other sites
crashdome 3 Posted April 7, 2006 You want an easy way to sync time across the network? Here is a little 'secret': <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">if (local server) then {_skip = random 1000;call Format[" ""logic"" createunit [[0,0,0],grpNull,""skipTime %1""] ",_skip]} This is from memory, so mention if there are errors Share this post Link to post Share on other sites
mr.peanut 1 Posted April 12, 2006 Well what I had was a script to randomise mission weather and start time. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">x3 = -99 if (local server) then {x1 = random 0.40; x2 = random 1; x3 = random 10;{publicVariable _x} forEach ["x1","x2","x3"]} Â Â @(x3 != -99) 0 setFog x1 0 setOverCast x2 skipTime x3 _x1_0 = x1 _x2_0 = x2 x2 = -99 if (local server) then {x1 = random 0.40; x2 = random 1;{publicVariable _x} forEach ["x1","x2"]} Â Â @(x2 != -99) _x1 = (x1 - _x1_0)/360 _x2 = (x2 - _x2_0)/360 _i = 0 #loop _i = _i + 1 10 setFog (_x1*_i + _x1_0) 10 setOverCast (_x2*_i + _x2_0) ~10.5 if (_i < 360) then {goto "loop"} exit All of the variables being made public were defined in my init.sqs. However, when I called the above script from my init.sqs it never worked. Â The time and weather were always the same. It worked on my own computer as a non-ded server but not on a ded server. Â When I called the code from a trigger that fired as soon as the mission began, it worked most of the time. Â The dedicated server can be a bit network laggy, often causing sync problems for triggers etc. Â This has made me paranoid about executing the publicVariable command from the init.sqs, especially when passing randomised mission parameters. Share this post Link to post Share on other sites
crashdome 3 Posted April 12, 2006 Then why not eliminate publicvariable altogether? If you have seen my suggestion, I suggest trying and playing around with it. It takes advantage of a very powerful exploit and works great. If you are into doing more with network variables I also suggest Chain of Command's Network Services Add-on or Script package. Share this post Link to post Share on other sites
Chris Death 0 Posted April 12, 2006 Well what I had was a script to randomise mission weather and start time.<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">x3 = -99 if (local server) then {x1 = random 0.40; x2 = random 1; x3 = random 10;{publicVariable _x} forEach ["x1","x2","x3"]} Â Â @(x3 != -99) 0 setFog x1 0 setOverCast x2 skipTime x3 _x1_0 = x1 _x2_0 = x2 x2 = -99 if (local server) then {x1 = random 0.40; x2 = random 1;{publicVariable _x} forEach ["x1","x2"]} Â Â @(x2 != -99) _x1 = (x1 - _x1_0)/360 _x2 = (x2 - _x2_0)/360 _i = 0 #loop _i = _i + 1 10 setFog (_x1*_i + _x1_0) 10 setOverCast (_x2*_i + _x2_0) ~10.5 if (_i < 360) then {goto "loop"} exit All of the variables being made public were defined in my init.sqs. However, when I called the above script from my init.sqs it never worked. Â The time and weather were always the same. It worked on my own computer as a non-ded server but not on a ded server. Â When I called the code from a trigger that fired as soon as the mission began, it worked most of the time. Â The dedicated server can be a bit network laggy, often causing sync problems for triggers etc. Â This has made me paranoid about executing the publicVariable command from the init.sqs, especially when passing randomised mission parameters. Just a guess; did you initialize the variables: x1, x2 and x3 or did you only define them in the server only line? ?(answer == yes): Â ~S~ CD Share this post Link to post Share on other sites
mr.peanut 1 Posted April 12, 2006 As I said in my previous post, variables x1,x2,x3 were all defined in my init.sqs. I think this is probably an issue with server lag. If the server lags too much publicVariable commands issued before the game starts are either not properly broadcasted or received. The fact that the exact same code works from a trigger suggests this. My recommendation is not to use the publicVariable command until the mission has started. If you call a script from the init.sqs that uses publicVariable put a @time>0 in it. Share this post Link to post Share on other sites
mr.peanut 1 Posted April 12, 2006 You want an easy way to sync time across the network?Here is a little 'secret': <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">if (local server) then {_skip = random 1000;call Format[" ""logic"" createunit [[0,0,0],grpNull,""skipTime %1""] ",_skip]} This is from memory, so mention if there are errors So even though the logic is created only on the server, the init code is executed on all clients? That is weird. I guess the same approach could be used for sync'ing weather etc. with the advantage that the script need only run on the server. Any suggestions on how to sync a camera? Share this post Link to post Share on other sites
UNN 0 Posted April 13, 2006 Quote[/b] ]As I said in my previous post, variables x1,x2,x3 were all defined in my init.sqs. I think this is probably an issue with server lag.  If the server lags too much publicVariable commands issued before the game starts are either not properly broadcasted or received. You know OFP launches init scripts in MP, using two stages? The first stage is while you are waiting for everyone to Green up. The second is when the game starts for real. During the first stage OFP executes all the commands in the init.sqs, until it either comes across a ~ or reaches the end of the script. If it does find a ~, then it waits until the game has started before executing the rest of the script. There are also some issues with, when the Local command returns a valid result. If you execute the local command to soon, it may not return a correct value. But I'm not to sure about those. You might find your script runs ok if you add a slight pause at the very start. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">~1 x3 = -99 if (local server) then {x1 = random 0.40; x2 = random 1; x3 = random 10;{publicVariable _x} forEach ["x1","x2","x3"]}   @(x3 != -99) 0 setFog x1 0 setOverCast x2 skipTime x3 _x1_0 = x1 _x2_0 = x2 x2 = -99 if (local server) then {x1 = random 0.40; x2 = random 1;{publicVariable _x} forEach ["x1","x2"]}   @(x2 != -99) _x1 = (x1 - _x1_0)/360 _x2 = (x2 - _x2_0)/360 _i = 0 #loop _i = _i + 1 10 setFog (_x1*_i + _x1_0) 10 setOverCast (_x2*_i + _x2_0) ~10.5 if (_i < 360) then {goto "loop"} exit  This way it will only run the rest of init.sqs once the game has started. Anyway, worth a try? To debug the publicvariables you could always add side chats to the @ commands: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">@Call {Player SideChat Format ["x3 %1",x3]; (x3 != -99)} <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">@Call {Player SideChat Format ["x2 %1",x2]; (x2 != -99)} Share this post Link to post Share on other sites
crashdome 3 Posted April 13, 2006 @UNN Â I was going to post that until I finally reached your post. Not many people know this and it can be used to a great advantage!! For example, our SOW script packages loads data during the first 'stage' as you call it thus making it appear as if you are just waiting a bit longer for the mission to load even though it is actually our scripts running. Also, the ~ isn't the only thing that will trigger a halt. Calling another script from within the init.sqs will also. That is why I always use functions (call loadFile) to initializeother variables for a complex set of scripts. @Mr Peanut Yes! The init line is executed on all clients! Spinor discovered this one back in the late days of CoC. bn880 and he did some tests and found out that even strings could be passed using this method (< 4k worth)! Not many people realized the gravity of this at the time. Even BIS's own command 'publicVariable' which is supposed to do the same thing by design has limits this simple little init-line exploit hurdles over like nobody's business. This all justs scratches the surface. You REALLY need to look at CoC's Network Services Add-on. It will make MP weather and time syncronization look like peanuts You could use it to make the cameras do whatever you want to whomever you want. A big benefit to CoC_NS IMO is also that all clients and servers are stored in an array on all machines... Want to send a message to a specific client only if they are a specific unit? want to send a message to a guy whose name is "Bob"? Want to send a message to only the guys who joined up after the first four??? etc... etc... Share this post Link to post Share on other sites
Metal Heart 0 Posted April 13, 2006 I guess you have tried publicvariable "x1";publicVariable "x2";publicVariable "x3"; instead of forEach. Or "publicVariable _x" forEach ["x1","x2","x3"]; instead of {publicVariable _x} forEach ["x1","x2","x3"]; ... I think that the forEach command will interpret this array ["x1","x2","x3"] as an array of strings instead of array of variables x1,x2,x3. Share this post Link to post Share on other sites
crashdome 3 Posted April 13, 2006 publicvariable takes a string as its argument Share this post Link to post Share on other sites
mr.peanut 1 Posted April 13, 2006 Thanks everyone for your answers.  They confirm what I suspected.  The comment about the tilda ~ wrt init.sqs is especially interesting. I often call other scripts from the init.sqs to batch initialise units; now I see that these do not actually get executed until the game starts. Furthermore, they prevent the rest of the init.sqs from completing. I can see the advantage of using functions instead as they will have to complete sequentially and will not hang the init (if I understand correctly). As for the CoC Net... For my purposes it is using a sledgehammer to drive a tack. I am making this mission for a server on which the addons are pretty static (LOL server).  A while back I suggested a pbo be made of the CoC Netcode and be made a mandatory addon on the server, but no one listened.  There are a real variety of pings and bandwidths on the server and desync is often an unpleasant reality that creates  unexpected bugs, especially with triggers. Share this post Link to post Share on other sites
crashdome 3 Posted April 13, 2006 As for the CoC Net... For my purposes it is using a sledgehammer to drive a tack. I am making this mission for a server on which the addons are pretty static (LOL server).  A while back I suggested a pbo be made of the CoC Netcode and be made a mandatory addon on the server, but no one listened.  There are a real variety of pings and bandwidths on the server and desync is often an unpleasant reality that creates  unexpected bugs, especially with triggers. I would disagree and I can think of a few others that would also disagree that CoC_NS is a sledgehammer. Rather it is more like a toolbox. Would you go work on your car with only a screwdriver?  {edit: even if it is just a loose screw - you might bring your whole toolbox out, right?} Also, CoC_NS comes in script form where all you need to do is copy the folders/files to your mission folder. This effectively eliminates the need for it as an add-on. It will increase your mission about 200k or so, but you will find that once you start using NS for one thing... next it'll be another thing... then another... and so on until it becomes something you use for all MP missions (like myself). Share this post Link to post Share on other sites
mr.peanut 1 Posted April 13, 2006 I wasn't criticizing CoC NS, I just meant I am too lazy too learn to use it for one small problem. Our server has a mission size limit of 800kb and 200kb is a good slice of this. Maybe for my next mission I'll use of it. What is a good example mission that illustrates its uses beyond player to player communication? Is there one on the CoC site? Share this post Link to post Share on other sites
mr.peanut 1 Posted April 13, 2006 Well, call me stupid, but the example provided with CoC_NS is mind-numbing. Although the docs describe in detail the functions, there is no simple example of how to use them. I can see how to broadcast a variable, but can not see how they are received. The docs say the receive function is internal and called by PA/client.sqs, but there are no docs on what the hell this script is. Share this post Link to post Share on other sites
Metal Heart 0 Posted April 13, 2006 Quote[/b] ]publicvariable takes a string as its argument Yes I know but does it work when said strings (the variable names) are passed to it by forEach and not the script it self? I think that's the problem in the original script. Wouldn't you have to use call and format commands for it to work? Like "call {format ["publicvariable %1",_x]}" foreach ["x1","x2","x3"]; or something like that. Share this post Link to post Share on other sites
mr.peanut 1 Posted April 13, 2006 Quote[/b] ]publicvariable takes a string as its argument Yes I know but does it work when said strings (the variable names) are passed to it by forEach and not the script it self? I think that's the problem in the original script. Wouldn't you have to use call and format commands for it to work? Like "call {format ["publicvariable %1",_x]}" foreach ["x1","x2","x3"]; or something like that. Trust me.. it does work. There is nothing wrong with the script itself. As I said, the script works well from a trigger, just not from the init.sqs . Â I have read that by using forEach in this manner all the variables are sent in one packet, which makes it a more efficient use of bandwidth. Share this post Link to post Share on other sites
crashdome 3 Posted April 13, 2006 Quote[/b] ]publicvariable takes a string as its argument Yes I know but does it work when said strings (the variable names) are passed to it by forEach and not the script it self? I think that's the problem in the original script. Wouldn't you have to use call and format commands for it to work? Like "call {format ["publicvariable %1",_x]}" foreach ["x1","x2","x3"]; or something like that. actually what you suggest would effectively make them NOT strings anymore.... so what your suggesting as a solution is actually creating the problem @Mr. Peanut go here: http://www.sinewsofwar.com/Downloads/tabid/77/Default.aspx You will see an "Intro to NS" tutorial... it is very much unfinished and generally in need of major revision (only covers small chunk of NS). However, it might help you get started since there are a few code examples. [EDIT] I was wrong about the file size... NS is in fact 40k in size when using script folders. Also, within the document which was written awhile ago...I spoke about using PublicVariable instead of CoC_NS to sync time/weather. I have since changed this opinion to using the initline of a create'd logic. thus eliminating PublicVariable altogether.. just wanted to address that before you read this. Share this post Link to post Share on other sites
Metal Heart 0 Posted April 14, 2006 Ok, I still don't get why it wouldn't work. Even if that quoted script was run as a separate script from init.sqs, it should get run once the game starts right? Quote[/b] ]I have read that by using forEach in this manner all the variables are sent in one packet, which makes it a more efficient use of bandwidth. I doubt there's any difference, you're not publishing the array but the elements in the array one by one with forEach. Besides, such a tiny amount of data is negligible anyway, maybe it would make a difference if you had like several kilobytes of stuff to send (and didn't have to care about hogging the connection, like in the start of the game or something). Share this post Link to post Share on other sites
crashdome 3 Posted April 14, 2006 In theory the first script should work. In fact, in a non-ded server environment it does. When publicVariable was first available, I used it to send large amounts of data to other clients. I sent three integers to every client about 100 times so that I could syncronize 100 [a,b,c] arrays. What I found when running on a ded server is that about 5-6 arrays woould be empty on the clients and it would be completely random... i.e. client 1 would have arrays 5,10,40 missing, but client 2 would have arrays 23,49,67 missing.. etc.. The more players there were, the more empty arrays due to values not getting broadcast. It literally broke my whole idea I had spent a year or more on. (Maybe that's why I am so bitter about pV!! ) When CoC came out with NS, I replaced the publicVariable system and rewrote it to include even MORE data. I never dropped an array since. My point is that publicvariable is and always will be unreliable - even in situations where it should work. Share this post Link to post Share on other sites
mr.peanut 1 Posted April 18, 2006 My point is that publicvariable is and always will be unreliable - even in situations where it should work. Agreed. PV sucks, especially if you have a lot of clients with laggy connections. ps. thanks for the CoC_NS docs link. I will peruse. Share this post Link to post Share on other sites
mr.peanut 1 Posted April 18, 2006 Also, within the document which was written awhile ago...I spoke about using PublicVariable instead of CoC_NS to sync time/weather. I have since changed this opinion to using the initline of a create'd logic. thus eliminating PublicVariable altogether.. just wanted to address that before you read this. CrashDome, By the statement above are you saying to sync time/weather you use the createunit gamelogic trick you posted earlier? Â Is this because you can include it in the init.sqs so it is executed immediately without a slight delay? But what if you are syncing weather many times, hundreds of times? Won't you end up creating hundreds of game logics? Share this post Link to post Share on other sites
Metal Heart 0 Posted April 18, 2006 Quote[/b] ]The more players there were, the more empty arrays due to values not getting broadcast. I'd guess they are broadcast but not checked if the client actually received. The randomness would also sound like it's just the normal packet loss that happens on the internet. Share this post Link to post Share on other sites