Generalmonimo 0 Posted September 9, 2019 Public variables are giving me headaches. I tried for hours to make them work in my scripts. Now i wrote a simple test mission to demonstrate what i'm doing and hope someone can point me to what i'm missing here. Hosting this with editor in MP mode. initServer.sqf: systemChat "Init Server"; Counter= 0; publicVariable "Counter"; while {true} do { sleep 10; systemChat "Update"; Counter= Counter + 1; publicVariable "Counter"; }; initPlayerLocal.sqf: systemChat "Init Player"; "Counter" addPublicVariableEventHandler { hint (str Counter); }; I expected to see a hint with a number increasing its value every 10 seconds. This didn't happen. Output from systemChat as expected: InitServer InitPlayer Update Update Update ... Share this post Link to post Share on other sites
Schatten 284 Posted September 9, 2019 @Generalmonimo, your computer is the server too when you host the mission in MP mode, so your code won't work in this case. Use this code instead: if (isServer) then { call pubVarEventHandler; } else { publicVariable "Counter"; }; Share this post Link to post Share on other sites
Generalmonimo 0 Posted September 9, 2019 To clarify: I want to send data from the server to all clients (including me). This data for now is a counter but in my actual script it will be an updated scoreboard. All calculations (in this case incrementing the counter) will be done on the server (thus initServer.sqf) in the 'main'-loop. To send the data to the client i use publicVariable and i was expecting the event handler for the client (local Player, which while i'm hosting is also me) to fire and show the hint. The isServer condition in my case should be irrelevant because for initServer.sqf it is always true and for initPlayerLocal.sqf always false. Share this post Link to post Share on other sites
Schatten 284 Posted September 9, 2019 @Generalmonimo, when you host the mission in MP mode "server" vars and "client" vars are in the same namespace, so code attached with addPublicVariableEventHandler never fire on your computer, this is why you need to manually call event handler. 25 minutes ago, Generalmonimo said: The isServer condition in my case should be irrelevant because for initServer.sqf it is always true and for initPlayerLocal.sqf always false. Yea, my mistake. Try this code: publicVariable "Counter"; if (hasInterface) then { call pubVarEventHandler; }; 1 Share this post Link to post Share on other sites
killzone_kid 1330 Posted September 9, 2019 Quote This EH will not fire on the machine that executed broadcast with publicVariable command, only on the machines that receive the broadcast https://community.bistudio.com/wiki/addPublicVariableEventHandler 1 Share this post Link to post Share on other sites
Generalmonimo 0 Posted September 9, 2019 Thanks guys, that indeed was the problem. Share this post Link to post Share on other sites
fn_Quiksilver 1636 Posted September 10, 2019 I find using the remoteExec framework and discarding the publicvariable/addpublicvariableeventhandler/publicvariableserver/publicvariableclient system entirely, to be the simplest. for example private _counter = 0; while {true} do { sleep 10; systemChat "Update"; _counter = _counter + 1; // remoteExec instead of publicVariable [ Counter, { if (hasInterface) then { hint str _this; }; } ] remoteExec ['call',0]; }; Share this post Link to post Share on other sites
killzone_kid 1330 Posted September 10, 2019 dont use remote exec, use serverTime 1 Share this post Link to post Share on other sites
engima 328 Posted September 14, 2019 Given alternatives reflect different needs and maybe different philosophies. publicVariable: This is how you ”set a variable value on the other machines”. You also have the possibility to take some action when the value is set, using publicVariableEventHandler. remoteExec: This is how you ”execute a function on other machines”. Personally I don’t really like this, because if you use it frequently the code tend to be hard to read. The code can make the impression that execution is ”jumping” between clients in an uncontrolled manner. Event based remote executions: The publicVariable event handling philosophy I find much better, but the syntax is somewhat obscured. So what I do is that I use remoteExec, but I only call ”On” functions all collected in one reciever file. And these ”On” functions always just reflect source machine (server or client) events, and then routes the event to the correct execution path within the target machine. It is never a direct function call. Here’s an example. I never call ”createSomeVehicle”, or ”showMyMessage” on another machine. What I do is telling what is happening on the source machine, like ”onVehicleNeeded” or ”onLocationTaken”. This way I never mix the control flow responsibilities between different machines and methods. And if you want anything more to happen than just a message being shown when a location is taken, simply add one line of code in the onLocationTaken ”event handler.” Share this post Link to post Share on other sites