vapour 12 Posted June 21, 2010 (edited) Hi I'm having trouble finding anything that explains this clearly enough so that I can get my head around it. I have an example script that I'm not sure if it's going to perform correctly when there's several players in the game. I don't want it turning to custard when there's a dozen of us playing a co-op mission. THE EXAMPLE: I have a couple of scripts that randomly spawn 30 AI enemies and 30 AI friendlies at the beginning of a multiplayer mission. This is to create some good scattered fighting action in a town. The script uses local variables to generate the randomness. It runs great when I test it on my own. If I run this script during a multiplayer game, what actually happens? Does the server run it once and the 60 soldiers appear, or does the script get run once for each client who is playing the game and I end up with 120+ soldiers? Imagine what 720 AI soldiers would be like if there was 12 players! Talk about CPU meltdown. Do I need to make the variables global(public)? Should I be using one the following at the beginning of my scripts?: ? !(local player) : exit OR ? !(local server) : exit If I were to use these, what is actually happenning? Does the "local player" one get sent to each of the clients so that they know the scripts happened and therefore don't repeat the script, or is it the opposite, and that they all go ahead and perform the script indivudually. OR If it's set to "local server", does the server tell each of the clients to perform the script, or does it just do the script once, and all the clients see the result? Any clear and concise help would be much appreciated. THE SCRIPT (If you need to see what I'm talking about): :rolleyes:Please don't laugh at it - this way it makes sense to me. //CREATE GROUPS groupIn1 = createGroup East; groupIn2 = createGroup East; groupIn3 = createGroup East; groupIn4 = createGroup East; groupIn5 = createGroup East; _n=0 _g=0 #LEADERS _n=_n+1 //LEADER GROUP _g=_g+1 ? _g>5: _g=1 ? _g <2 : goto "GROUP1" ? _g <3 : goto "GROUP2" ? _g <4 : goto "GROUP3" ? _g <5 : goto "GROUP4" ? _g <6 : goto "GROUP5" #GROUP1 _group = groupIn1 ; goto "RANDOMPOS" #GROUP2 _group = groupIn2 ; goto "RANDOMPOS" #GROUP3 _group = groupIn3 ; goto "RANDOMPOS" #GROUP4 _group = groupIn4 ; goto "RANDOMPOS" #GROUP5 _group = groupIn5 ; goto "RANDOMPOS" #RANDOMPOS //RANDOM POSITION _x = getMarkerPos "Eastspwn" select 0; _y = getMarkerPos "Eastspwn" select 1; _x = _x+((random 1000)-500); _y = _y+((random 700)-350); //CREATE GROUP LEADER "Ins_Soldier_CO" createUnit [[_x,_y], _group,"",0.8,"Sergeant"]; ? _n<5 : goto "LEADERS" _n=0 _g=0 #SOLDIERS _n = _n+1 //GROUP _g= _g+1 ? _g>5: _g=1 ? _g <2 : goto "GROUPA1" ? _g <3 : goto "GROUPA2" ? _g <4 : goto "GROUPA3" ? _g <5 : goto "GROUPA4" ? _g <6 : goto "GROUPA5" #GROUPA1 _group = groupIn1 ; goto "RANDOMSOL" #GROUPA2 _group = groupIn2 ; goto "RANDOMSOL" #GROUPA3 _group = groupIn3 ; goto "RANDOMSOL" #GROUPA4 _group = groupIn4 ; goto "RANDOMSOL" #GROUPA5 _group = groupIn5 ; goto "RANDOMSOL" #RANDOMSOL //RANDOM SOLDIER TYPE _t = (random 12); ? _t <3 : goto "SOLDIER1" ? _t <4 : goto "SOLDIER2" ? _t <5 : goto "SOLDIER3" ? _t <6 : goto "SOLDIER4" ? _t <7 : goto "SOLDIER5" ? _t <9 : goto "SOLDIER6" ? _t <11 : goto "SOLDIER7" ? _t >10 : goto "SOLDIER8" #SOLDIER1 _type = "Ins_Soldier_1"; goto "RANDOMPOSI" #SOLDIER2 _type = "Ins_Soldier_Sniper"; goto "RANDOMPOSI" #SOLDIER3 _type = "Ins_Soldier_Medic"; goto "RANDOMPOSI" #SOLDIER4 _type = "Ins_Soldier_AT"; goto "RANDOMPOSI" #SOLDIER5 _type = "Ins_Soldier_AR"; goto "RANDOMPOSI" #SOLDIER6 _type = "Ins_Soldier_MG"; goto "RANDOMPOSI" #SOLDIER7 _type = "Ins_Soldier_GL"; goto "RANDOMPOSI" #SOLDIER8 _type = "Ins_Soldier_2"; goto "RANDOMPOSI" #RANDOMPOSI //RANDOM POSITION _x = getMarkerPos "Eastspwn" select 0; _y = getMarkerPos "Eastspwn" select 1; _x = _x+((random 1000)-500); _y = _y+((random 700)-350); //CREATE SOLDIER _type createUnit [[_x,_y], _group]; ? _n<24 : goto "SOLDIERS" Edited June 21, 2010 by Vapour Share this post Link to post Share on other sites
CarlGustaffa 4 Posted June 21, 2010 ? !(isServer) : exit or in sqf format if (!isServer) exitWith {}; should prevent the script from being executed if it's not a server or a host. isServer Share this post Link to post Share on other sites
Big Dawg KS 6 Posted June 21, 2010 You know... I think I've actually forgotten how to read and write SQS. That code makes so little sense to me... hah! :rolleyes: Share this post Link to post Share on other sites
st_dux 26 Posted June 21, 2010 (edited) As far as locality goes, there are two types of scripting commands in the game: local and global. Local commands are only run on clients (or the server) that actually executed the command. If every client executed the command, the result is that it is run once on each client. If only one or some of the clients executed the command, the result is that the clients that did not execute the command will not see any of its effects. Global commands are broadcast over the network to every client regardless of which client (or server) executed the command. If a single client executes a global command, it is run once on every client (unlike a local command, which would only be run once on that client). If multiple clients execute a global command, then it is run multiple times on each client (one time per client or server that executed it) because it is broadcast every time it is executed. This leads to generally undesirable results, and with a high player count, it can lead to disastrous, server-annihilating results. The general rule-of-thumb for MP mission design is to run local commands once on each client and global commands once only on the server (because it is a global command, the result will in turn be broadcast to all clients). As Carl mentioned, isServer is the easiest way to do a server check. You can either do it as he showed to make a whole script run only on the server, or you can use an "if (isServer) then..." control structure if you only want to run a few lines on the server and allow the rest to be run everywhere. This is useful if, for example, you have a mixture of local and global commands, or if you want to come up with a random number but want that number to be consistent across all clients. Edited June 21, 2010 by ST_Dux Share this post Link to post Share on other sites
galzohar 31 Posted June 21, 2010 Commands only run on the computer that ran the command, however some commands result in things that end up getting broadcasted on the network (for example: creating a vehicle, setting an object's position, setting damage). Some commands will take no affect if you try to run them on a machine that is not controlling the unit (for example a client running an addWeapon command for an AI solder that is not under his command will not work as that AI soldier is controlled by the server, or in other words local to the server). init.sqf and all units' init lines run on all machines. Triggers run on all machines that have their condition set to "true", which for some triggers may be for all machines at the same time, while for more complicated conditions or in case of desync a trigger can be true only for some machines and not for others. You can even create a trigger by a script that runs only on one machine and that trigger will then only exist for that one machine and thus will only activate on that specific machine when its condition becomes true, which is useful for radio triggers where you want to know who clicked the trigger. In order to run something only once, such as spawning a fixed amount of AI, you need to use if (isServer) then {....}; and replace the .... with the code that is spawning the AI. That is, in SQF format, which you really should use as it's much easier to write and read. Share this post Link to post Share on other sites
vapour 12 Posted June 21, 2010 Wow! Fantastic information guys. Things are now a lot clearer and starting to make sense to me. Not crystal, but the fog is deffinitly being cleared. Share this post Link to post Share on other sites
pravania 10 Posted June 21, 2010 come on to ts and we'll have a chat Share this post Link to post Share on other sites