Jump to content
Sign in to follow this  
bhaz

Deciphering the BIS missions

Recommended Posts

I've been going through lately looking at how BIS make their missions, there's one thing managing to confuse the hell out of me.

Right at the start of their initJIPcompatible.sqf files, there is the line:

if (isnull player) exitwith {};

Yet, in the script, there is code that runs serverside.

So I fired up a dedicated server, ran the mission, and wtf - it works?

Which brought along my second test, I added this inside the server block:

testVariable = player;
publicVariable "testVariable"

and this to run on all clients:

waitUntil {!(isNil "testVariable")};
hint Format["%1", testVariable];

Funny enough - player was not null, on a dedicated server. The player slot it was using was also unselectable in the lobby.

Can someone explain this to me before my head explodes?

Share this post


Link to post
Share on other sites

The if isnull player thing, just means if the player isn't active quit the script. It's used for AIs, all clients will run it, but AIs won't be players till someone JIPs into them, so it doesn't run that script till it's a player, but the unit is still active.

Also, Nil and Null are not the same thing.

Share this post


Link to post
Share on other sites

TL;DR version - read the bold :)

The if isnull player thing, just means if the player isn't active quit the script. It's used for AIs, all clients will run it, but AIs won't be players till someone JIPs into them, so it doesn't run that script till it's a player, but the unit is still active.

Also, Nil and Null are not the same thing.

It's not that line of code that I'm questioning, I understand that it's meant to run the script on clients that have an active player.

What I was referring to, is that the script only runs if the player exists locally on the machine the script is run on, AND has server-side commands - specifically, the ones that make the calls to RE, adding the diary entries and executing the FSM files.

Biki - MP Locality

According to this, the player object is meant to be null on dedicated servers. In BIS' missions, player is actually referring to a specific AI unit --- even on the dedicated server.

It's even showing in the server logs:

class Session

{
   mission="COOP 05 Hike In The Hills";
   island="Takistan";
   gameType="COOP";
   duration=235.00101;
   class Player1
   {
       name="__SERVER__";
       killsInfantry=0;
       killsSoft=0;
       killsArmor=0;
       killsAir=0;
       killsPlayers=0;
       customScore=0;
       killsTotal=0;
       killed=0;
   };
   class Player2
   {
       name="Bhaz";
       killsInfantry=-1;
       killsSoft=0;
       killsArmor=0;
       killsAir=0;
       killsPlayers=0;
       customScore=0;
       killsTotal=-1;
       killed=0;
   };
};

Here is the entire script for reference:

/*******************************************************************************
*    I N I T   F I L E   v 2 . 0
*    Multiplayer compatible
*    All commands except the commands in "isserver" block will be executed
*    on server AND clients.  
******************************************************************************/  
scriptName "initJIPcompatible.sqf: 1";
if (isnull player) exitwith {};

/*******************************************************************************
*    COLOR CORRECTION - POSTPROCESS
*    https://wiki.bistudio.com/index.php/Post_efekty_dokumentace_(Post_effects_documentation) 
******************************************************************************/  
"colorCorrections" ppEffectAdjust [1, 1.02, -0.005, [0.0, 0.0, 0.0, 0.0], [1, 1, 0.7, 0.65],  [0.199, 0.587, 0.114, 0.0]];
"colorCorrections" ppEffectCommit 0;
"colorCorrections" ppEffectEnable TRUE;

"filmGrain" ppEffectEnable FALSE;

if (isServer) then //COMMANDS IN FOLLOWING BLOCK WILL BE EXECUTED ONLY ON SERVER 
{
   /***********************************************************************
    *    MISSION'S MAIN SCOPE INITIALIZATION
    *    All mission's variables(except handlers) should be stored 
    *    into this logic
    **********************************************************************/  
   _missionScopeGroup = createGroup sideLogic; 
   "Logic" createUnit [[10,10,0], _missionScopeGroup, "BIS_missionScope = this"];
   publicVariable "BIS_missionScope";

   //HQ initialisation
   BIS_grpBHQ = createGroup west;
   "US_Soldier_EP1" createUnit [[0, 15000, 0], BIS_grpBHQ, "BIS_BHQ = this", 0, "COLONEL"];
   BIS_grpBHQ setGroupID [localize "STR_EP1_callsign_sweeper"];
   publicVariable "BIS_BHQ";

   /***********************************************************************
    *    MISSION'S MAIN FSM AND GROUP SPECIFIC FSMs EXECUTION
    *    + SQF script execution  
    **********************************************************************/
   BIS_missionFlow = execFSM "mission.fsm";
   BIS_grpMainFSM = BIS_grpMain execFSM "grpMain.fsm";

   /***********************************************************************
    *    MISSION VARIABLES INITIALISATION
    *    Use setVariable/getVariable commands to set/get variables   
    **********************************************************************/
    BIS_missionScope setVariable ["BIS_useAITasks", TRUE, TRUE];

   /*******************************************************************************
    *    TASKS
    *    from MISSION ANALYSIS -> SCENARIO TEXTS -> TASKS
    *    createTaskSet  
    ******************************************************************************/
   [] spawn {
       waitUntil {!(isNil "BIS_fnc_init")};

       _nic = [objNull, leader player, "per", rCREATETASKSET, "objPatrol", [{localize "STR_EP1_initJIPcompatible.sqf0_4"}, {localize "STR_EP1_initJIPcompatible.sqf1_4"},  {localize "STR_EP1_initJIPcompatible.sqf2_4"}]] call RE;

   };

   /***********************************************************************
    *    GLOBAL CAMPAIGN VARIABLES INITIALISATION
    *    Only GLOBAL CAMPAIGN variables with prefix BIS_    
    *    Used variables are listed on the bottom of this page:
    *    https://wiki.bistudio.com/index.php/Category:ArmA2_Expansion_Campaign  
    **********************************************************************/

   /***********************************************************************
    *    DIARY RECORDS
    *    from MISSION ANALYSIS -> SCENARIO TEXTS -> DIARY 
    *    createDiaryRecord 
    **********************************************************************/  
    {
       _nic = [objNull, _x, "per", rCREATEDIARYRECORD,  {localize "STR_EP1_initJIPcompatible.sqf3_3"}, {localize "STR_EP1_initJIPcompatible.sqf4_3"}] call RE;
       _nic = [objNull, _x, "per", rCREATEDIARYRECORD,  {localize "STR_EP1_initJIPcompatible.sqf5_2"},  {localize "STR_EP1_initJIPcompatible.sqf6_3"}] call RE;
       _nic = [objNull, _x, "per", rCREATEDIARYRECORD,  {localize "STR_EP1_initJIPcompatible.sqf7_3"},  {localize "STR_EP1_initJIPcompatible.sqf8_3"}] call RE;
       _nic = [objNull, _x, "per", rCREATEDIARYRECORD,  {localize "STR_EP1_initJIPcompatible.sqf9_3"},  {localize "STR_EP1_initJIPcompatible.sqf10_2"}] call RE;
       _nic = [objNull, _x, "per", rCREATEDIARYRECORD,  {localize "STR_EP1_initJIPcompatible.sqf11_2"},  {localize "STR_EP1_initJIPcompatible.sqf12_2"}] call RE;
   } forEach units BIS_grpMain;

   /***********************************************************************
    *    ZORA SETTINGS
    *    https://wiki.bistudio.com/index.php/Zora 
    **********************************************************************/

   /***********************************************************************
    *    ALICE RESPECT SETTINGS
    *    https://wiki.bistudio.com/index.php/Alice 
    **********************************************************************/

   /***********************************************************************
    *    ACM SETTINGS
    *    https://wiki.bistudio.com/index.php/Ambient_Combat 
    **********************************************************************/        

   /***********************************************************************
    *    ADDITIONAL STUFF
    **********************************************************************/

   testVariable = player;
   publicVariable "testVariable"
};

/*******************************************************************************
*    TASKHANDLER
*    Run outside the isserver block 
******************************************************************************/
waitUntil {!(isNil "BIS_fnc_init")};

[player, [
   ["objPatrol", 4],
   ["objVillage", 2],
   ["objCache", 1],
   ["objRTB", 3]
]] call BIS_fnc_taskHandler;


// Stop displaying loading screens
waitUntil {count simpleTasks player > 0};
endLoadingScreen;

waitUntil {!(isNil "testVariable")};
hint Format["%1", testVariable];

Share this post


Link to post
Share on other sites

Ooh, that, yeah that's a bug. The dedicated server takes the first slot in BIS default missions if a player doesn't, thereby breaking the missions.

Share this post


Link to post
Share on other sites

Let me guess, it doesnt happen in hosted server?

Good ol BIS with their hosted only testing. :)

Share this post


Link to post
Share on other sites
Let me guess, it doesnt happen in hosted server

In a hosted server it's the opposite, you're forced into that specific slot and cannot change.

---------- Post added at 09:57 AM ---------- Previous post was at 09:50 AM ----------

Found it!

class Item0
{
   position[]={2303.5667,206.03181,5394.689};
   azimut=-32.195801;
   special="NONE";
   id=39;
   side="WEST";
   vehicle="US_Soldier_TL_EP1";
   player="PLAYER COMMANDER";
   [color=Red]forceInServer=1;[/color]
   leader=1;
   lock="UNLOCKED";
   rank="SERGEANT";
   skill=0.60000002;
   init="BIS_grpMain = group this; group this setGroupId [(localize ""STR_EP1_callsign_sweeper"") + "" 2""]; this assignAsDriver BIS_mainCar; this moveInDriver BIS_mainCar";
   synchronizations[]={37,35,36};
};

Some kind of hidden option, didn't catch it cause it's not available in our GUI.

Only problem with removing it, is that the player becomes a null object on the dedicated server, causing all the commands inside the isServer block to not run. The client side of the script is waiting for the server side to finish, and never gets the endLoadingScreen command - effectively crashing all clients.

Perhaps it was a cheap fix to begin with?

Share this post


Link to post
Share on other sites
Perhaps it was a cheap fix to begin with?

That seems very likely.

The question is, what are you trying to do exactly? Why not just pick all the useful stuff from their files instead of copy paste all of it?

Share this post


Link to post
Share on other sites

Not trying to make anything in particular, just interested in what they did - seems very different to community missions, how they keep all the mission variables strictly serverside and handle it all with FSM and multiplayer framework RE calls etc.

Share this post


Link to post
Share on other sites
Not trying to make anything in particular, just interested in what they did - seems very different to community missions, how they keep all the mission variables strictly serverside and handle it all with FSM and multiplayer framework RE calls etc.

That's coz they understand all that junk! heheheh :confused:;):p

Share this post


Link to post
Share on other sites

I would like to know why they did that junk at all. It doesn't make any sense for me that BIS made their offical missions (like the new BAF coop missions) unplayable on dedicated servers. Is that a bug or a feature? I guess they never tested their own missions on a dedicated server ...

Share this post


Link to post
Share on other sites

I made my own missions - and they are working. Even on dedicated servers. At least in most cases ... ;) But that is not the point. I still wonder why BIS releases coop missions which only work in a hostet session ... :confused:

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  

×