Jump to content
Sign in to follow this  
*TEK*TONI

Dedicated / publicVariable...still not able to get it right

Recommended Posts

Hello Gents,

hope I do not bother anybody by bringing up something which was aswell already discussed. But doesn´t matter what I found, MPF, threads and bis.wiki and so on, I still can´t get it right. Hope you can help.

My missions are all designed to work only on Dedicated Servers, multiplayer for a nine member unit, which is working with JIP and respawn/revive. F2 is a great framework, but JIP in relation with tasks is something which is not really featured.

Anyway, now my mainproblem: Syncronising tasks!

Nearly all my missions contain between 3-5 tasks. So in the init.sqf I put:

task1 = false; publicVariable "task1";
task2 = false; publicVariable "task2";
task3 = false; publicVariable "task3";
task4 = false; publicVariable "task4";
task5 = false; publicVariable "task5";
task6 = false; publicVariable "task6";

In the editor I created triggers to react on fullfilled tasks. For example "task1":

expCond="!alive igla_north";
expActiv="task1 = true; publicVariable "task1"; nul = execVM "tskObj1_completed.sqf";

tskObj1_completed.sqf looks like this:

tskObj1 setTaskState "SUCCEEDED"; // Ob1 has been completed
[tskObj1] call mk_fTaskHint; // tell the player

sleep 7; // wait before giving the player a new task

player setCurrentTask tskObj2; // assign obj2 to the player
[tskObj2] call mk_fTaskHint; // show the player that he received a new task

[tskObj1], [tskObj2] and so on are defined in the briefing.sqf...

The problem now is that not all players have the objectives syncronized correctly during and after the mission (in-game on map or debriefing). Furhter research showed me that using publicVariable is not enough. Now I have to declare them. :confused:

How? And is there more to do to get in finally working? I found following thread, but either I didn´t understand fully or something is missing.

http://forums.bistudio.com/showthread.php?t=80956&highlight=publicvariable

My problem with MPF and bis.wiki is that I´m not able to reproduce what´s written there, so if you guys are willing to help, please approach with an example if possible. Thanks in advance!!!

Just to be on the safe side. Here is my briefing.sqf or better my f_briefing_usmc.sqf, since I´m using F2 framework.

// Sixt Objective
tskObj6 = player createSimpleTask ["Sixt: Find and destroy vehicle service"];
tskObj6 setSimpleTaskDescription ["Find and destroy vehicle service <marker name='mkrWest2'>South</marker>.", "Sixt: Destroy service area", "Destroy service area"];
tskObj6 setSimpleTaskDestination (getMarkerPos "mkrWest2");

// Fifth Objective
tskObj5 = player createSimpleTask ["Fifth: Find and destroy little factory"];
tskObj5 setSimpleTaskDescription ["Find and destroy little factory <marker name='mkrWest2'>South</marker>.", "Fifth: Destroy little factory", "Destroy little factory"];
tskObj5 setSimpleTaskDestination (getMarkerPos "mkrWest2");

// Fourth Objective
tskObj4 = player createSimpleTask ["Fourth: Find and destroy Opfor camp"];
tskObj4 setSimpleTaskDescription ["Find and destroy military basecamp <marker name='mkrWest2'>West</marker>.", "Fourth: Find and destroy camp", "Find and destroy camp"];
tskObj4 setSimpleTaskDestination (getMarkerPos "mkrWest2");

// Third Objective
tskObj3 = player createSimpleTask ["Third: Destroy Arti Radar"];
tskObj3 setSimpleTaskDescription ["Destroy Arti Radar <marker name='mkrWest'>West</marker>.", "Third: Destroy Arti Radar", "Destroy Arti Radar"];
tskObj3 setSimpleTaskDestination (getMarkerPos "mkrWest");

// Secondary Objective
tskObj2 = player createSimpleTask ["Secondary: Destroy Container"];
tskObj2 setSimpleTaskDescription ["Destroy Container <marker name='mkrEast'>East</marker>.", "Secondary: Destroy Container", "Destroy Container"];
tskObj2 setSimpleTaskDestination (getMarkerPos "mkrEast");

// Primary Objective
tskObj1 = player createSimpleTask ["Primary: Destroy AA Gun"];
tskObj1 setSimpleTaskDescription ["Find and Destroy a AA Gun <marker name='mkrNorth'>North</marker>.", "Primary: Destroy AA Gun", "Destroy AA Gun"];
tskObj1 setSimpleTaskDestination (getMarkerPos "mkrNorth");
player setCurrentTask tskObj1;

Thanks for taking time reading this....

Share this post


Link to post
Share on other sites

Init.sqf is run on all clients, so there is no reason to use publicVariable there. The same thing goes for triggers. In fact, your usage of publicVariable in the above examples is completely frivolous.

Could you give a more specific explanation of the actual problem? When you say that "not all players have the objectives synchronized," do you mean that the timing is off or that some players aren't getting the objective updates at all? Are all players not getting it, or only some?

Also, what's the point of the task1, task2, etc. true/false variables?

Share this post


Link to post
Share on other sites

ST DUX - Thanks for your reply!!!

Could you give a more specific explanation of the actual problem? When you say that "not all players have the objectives synchronized," do you mean that the timing is off or that some players aren't getting the objective updates at all? Are all players not getting it, or only some?

During the mission, for example after 5 tasks have been fullfilled, when all my crewmember checked the objectives in their in-game menu (thrue the map), each of them had different informations. One player had only 2 objectives indicated as done, the second player only 4, another one only 3 green indicated fullfilled objectives.....and so and so on...

The taskhint, after each objective was fullfilled, was visible for all of them at the same time. I remember that one player dropped off during the session and he had to JIP. But still, all the others have been online all the time.

This brings me to your second question: What's the point of the task1, task2, etc. true/false variables?

From what I understood researching for a solution to make tasks for multiplayer-sessions work right on a dedicated server, (achieving that all clients are allways (JIP / respawn-revive) up to date with the tasks information and that the missions ends on all clients at the same time), I have to use publicVariable to get it right! Obviously I´m doing something wrong. I´m scripting now for a lil bit more than one year, but I never achieved to manage the problems which we´re talking about in this thread. I know it´s one thing to "play" with the editor and it is another thing, to get missions to work on a decidated server. I´m completely stucked!

What do I need to do, to make it work? Is it a big difference if I include JIP/respawn-revive or if I give the player only one life? Would it be the same method of setting up tasks and to have all players always up to date regarding tasks? I really tried to find my way in the forums and the wikis, but obviously without success.

If there is a mission, a template, a description or even some needed scripts, it would be important to me to take account of multiple tasks/objectives.

Thanks in advance gents...

Share this post


Link to post
Share on other sites

You have a simple error in the update chain:

Trigger

Condition: !alive something

onAct: execvm "tsk.sqf"

tsk.sqf

taskobj settaskstate

That's perfectly fine, task gets updated for everyone that get's the trigger fired on their machine.

JIP comes in, it receives task1 variable. What does it do with it? Nothing.

Share this post


Link to post
Share on other sites

hello SHK, thanks for your help.

So you´re saying to get rid of puclicVariable and make following chances:

onAct: execvm "tsk.sqf" instead of nul = execVM "tskObj1_completed.sqf"

What about task1 = false/true in the init.sqf and in the trigger? Should I leave it like it is or get rid of it aswell or put "task1 = true" in the task.sqf and leave the init.sqf like it is?

Share this post


Link to post
Share on other sites

No, what I'm saying is that it's useless to set and pubvar variables to JIPs if you don't even use them. You should first figure out how the whole thing works before worrying what to write where.

Share this post


Link to post
Share on other sites

To piggyback on what shk is saying, your task1, task2, etc. variables aren't actually doing anything, so you may as well get rid of them. The game doesn't recognize those variable names as anything special; the variables that you're actually using for the tasks are tskObj1, tskObj2, and so on -- these are the only ones that matter.

As far as the problem goes, your results are too inconsistent to say for sure, but it definitely sounds like a respawn/revive or JIP issue. My guess is that revived or JIP players are getting older objective triggers fired and that setCurrentTask in assigning them objectives that have already been completed.

Try naming each trigger and adding "deleteVehicle nameOfTrigger" at the end of the On Activation expression (i.e., after the part where you call the objective-updating script). This will make the trigger delete itself after executing, guaranteeing that it will not be triggered again to mess with the objectives. A side-effect of this, however, is that JIP players will not have the proper objective status if they join after the first task has been completed. If you require it, there is a workaround for this, too.

Share this post


Link to post
Share on other sites

@ SHK

You should first figure out how the whole thing works before worrying what to write where.

This is actually what I´m trying man, but since I´m stucked, I´m asking herewith kindly for support to understand how it works. I thought publicVariable would be the key. It probably is, but not the way I tried.

Today I discovered a similar thread where you proposed a double trigger method. http://forums.bistudio.com/showthread.php?t=100548

In combination with what you proposed and what ST DUX said, my publicVariable is actually tskObj1, tskObj2, and so on, which are defined in the briefing.sqf. So please be so kind and give me another comment if I´m wrong or right with following.

init.sqf:

tskObj1 = false;

tskObj2 = false; and so on....

trigger:

Condition: not alive whatever

OnAct: tskObj1 = true; execvm "tskObj1_completed.sqf"

@ ST DUX

I understand now that the way I´m using pubVar´s is wrong. But insn´t the use of pubVar´s required, to make the server "tell" all clients what the deal is? If so, what is your opinion about what I just asked SHK?

To use "deleteVehicle nameOfTrigger" sounds like a good idea, but as you say, at the end there are still some side-effects. So I still wouldn´t be where I would like to get.

What would be the workaround please?

Since I don´t wanna strain you guys and as I mentioned a bit further above, if you know which mp-mission with JIP/respawn is working properly, I could try to download this one and use it as kind of template. Of course not something like Domination, the way this is set up, is way to high for me.

Share this post


Link to post
Share on other sites

Pubvar is required. As you can see from the other thread, the task states are actually set with the pubvar'd variables.

It doesn't matter if you do it (=catching and using the pubvar'd variables) in triggers or in scripts.

Sorry for not typing it out straight away, but there is a perfect quote for this.

"Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime."

Edited by Shuko

Share this post


Link to post
Share on other sites

Sorry for not typing it out straight away....

No problem man, I know exactly what you´re talking about.

Ok, so they are required. Also you say it doesn´t matter if I catch them and use them in triggers and scripts, but I still don´t know, how to really set my mission up, to make it work properly.

Regarding the other thread, task states are set with pubvard´d variables. What/how exactly is pubvar making a pubvar? Is it defined (in my case) automatically by the briefing.sqf, since the "name" of my tasks (tskObj1) is one.

Is a determination of a pubvar not necessary at all, but it´s helpful to point it out by stating it somewhere? Please see this questions in relation with the other thread.

Double trigger method is pretty basic:

Trigger 1

Condition: !alive officer (or whatever the task condition should be)

onAct: tsk1 = true; publicvariable "tsk1"

Trigger 2

Condition: tsk1

onAct: task1 settaskstate "succeeded"

Since tsk1 is publicvariabled it will be synced for JIPs and will fire the 2nd trigger, which updates the status.

Would this mission have somewhere (maybe init.sqf) stated "tsk1 = false;" or is this not necessary at all? Would this double trigger method be the way to make a mp-mission work properly on a decicated server?

It´s not the case that I´m to lazy to try it out, but maybe you know that something additional needs to be done aswell.

Share this post


Link to post
Share on other sites

It's always a good practice to initialize/define variables, and more or less a must if you use them in scripts. At the moment, however, trigger fields don't mind checking for undefined variables. That's why the trigger example doesn't have init.sqf.

A "pubvar" can be any variable with any name. A variable becomes a PV once you broadcast it with the publicvariable command. The latest value will be synced to JIPs. It does not automatically update to anyone, so you have to PV it again if you change the value.

In your mission, you could, for example, try something like this:

init.sqf

Remove the "task1 = false; publicVariable "task1";" lines. Then add:

if (!isnil "task1") then {

tskObj1 setTaskState "SUCCEEDED";

player setCurrentTask tskObj2;

};

if (!isnil "task2") then {

tskObj2 setTaskState "SUCCEEDED";

player setCurrentTask tskObj3;

};

... and so on. It does nothing for the players who are present at the start. It checks if a "task1" etc variables are defined, which would in this case mean that it has been pubvar'd (=task object completed). It's just an untested example, it might require additional waiting/conditions.

Share this post


Link to post
Share on other sites

Dont use : publicVariable "task1"; in the init! just use that when completly the objectives. Becuase when some1 joins the game it resets to the objective to the first public varible it comes across which is that one. which makes it = false.

So no matter if its complete when the person joins they will get the false

Share this post


Link to post
Share on other sites

There are some major misconceptions being passed around in this thread.

1. Setting some variable called "task1" or "tskObj1" or anything else like that to a boolean value (i.e., true or false) has no bearing whatsoever on the status of that task. The only way to alter a task state is through the setTaskState command. This has a local effect, and it cannot be broadcast via publicVariable.

2. You do not need to use publicVariable on variables that are changed on all clients, and doing so can have negative results. Think about it: If you set a variable in init.sqf, and every client runs init.sqf when the mission starts, then why would you need to have each client broadcast that value to the other clients? The same thing is true for triggers: Every client loads up the triggers in the mission, so when a trigger is fired, it fires on all clients. Using publicVariable in either of these cases is incorrect (unless you're using it within a control structure, e.g., an "if (isServer)" statement, that is limiting the code to only running on a single client or server).

As for the JIP workaround, *TEK*TONI, there a few ways that you could do it. The first one that comes to my mind is to use the remote execution function (RE) built into the game with the "per" (persistent) parameter. In your task scripts (which ideally should be consolidated into one script), change:

taskObj1 setTaskStatus "Succeeded";

to:

[nil,taskObj1,"per",rSETTASKSTATE,"Succeeded"] call RE;

More info on remote execution can be found here.

Share this post


Link to post
Share on other sites

Ok gents. now I´m a bit confused.

From what I understood, what SHK said, is the workaround of what MATTXR posted.

So I don´t need to worry about what MattXR stated, because with the method of using if (!isnil "task1")........., JIP player logging in during a mission, are getting the correct value pV´ed again.

Please tell me that I´m right. Am I?

If what I´m saying is correct, SHK´s reply sounds in theory like a pretty good method of having JIP gamer, up to date with the needed task/missionstatus.

SHK, you mentioned eventually additional conditions to take in account, but I can´t think of anything else. If the pV-value gets always synced when needed, it should work. I hope so much that this is going to be a proper solution.

I´ll give it a try as soon as I can. Will post again after some testing! Thanks a lot guys for the kind support, honestly!

---------- Post added at 23:21 ---------- Previous post was at 23:00 ----------

Wow, wow, wow.....

I discovered ST DUX´s post right after I replied mine! I was hoping that HSK´s method would have been right.

ST DUX, thanks for posting/helping here! Your included link leads to a site, which I described a bit further above with MPF (multiplayer-framework). I read all of it, but I fell like not beeing able to use the stated infos. To chance gives scripts or values is one thing, but to create a higher-level-script is a different thing. At least for me its a higher-level. I would love to see a full example to see how it´s done for real.

At least I know now what the missing part is.....to get it right.

Share this post


Link to post
Share on other sites
ST_Dux version is the best way to do it :) the built in MP frame work is good forgot about that when u PMed me lol!! silly me 101 things to think about lol! i will do ya an example mission few days :) :) Edited by MattXR

Share this post


Link to post
Share on other sites

:wave: Hola Senior MattXR

how could I forget, it was very kind from you to help a foreigner out! But I must confess that I didn´t pay attention to your name, sorry for that!

The next 2 days after we "spoke" I tried to addapt your given frame work, but I must have done something wrong. Except one thing, everything worked. But what didn´t work, was the debriefing. The tasks listed there, showed up multiplied by the respawn lives. Since you took your time to explain stuff to me the days before, I didn´t wanted to tax your patience. So I decided to ask here for some help.

Since you´re going to send me this example mission, which is actually extremly kind by the way, this thread seems to find it´s end here. Special thanks to all of you Gentlemen!

Share this post


Link to post
Share on other sites

Mission-critical variables are better left to the server to handle, and clients should then update tasks based on the values of those variables. So if you use if (isServer) then {//initialize variables and publicVariable them}; instead you'll be making a great step in the right direction. Then all you need is a script/code that actually runs a waitUntil {!isNil "someVar"}; waitUntil {someVar}; relevantTaskName setTaskState "Succeeded"; That way each client updates the tasks when needed, but only the server actually decides whether a task is complete.

Of course SHK's framework should take care of all of those things for you if you understand how to use it, and it's probably easier to understand how to use it than to actually learn how to make those things yourself, but you'll still need some clue as to how scripts work in order to get it working, as you've probably noticed already ;)

Edited by galzohar

Share this post


Link to post
Share on other sites

@ GALZOHAR

thank you for the explanation! Indeed, I still need to understand how scripts work. Sometimes it would be nice to have somebody right next to you who is teaching/explaining things "on the fly", but as Mick Jagger said: "You can´t always get what you want."

I guess kinda all of you guys went thrue this.

I´m looking forward to MattXR´s example-mission. I´m hoping for a properly working framework which is allowing me to build in my missions. This might not be the very best way to learn, but it´s better than beeing stucked. On the other side, there are still manyy different topics/questions, so there is enough substance to go for... ;)

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  

×