ArmA 2 multiplayer scripting

ArmA 2 editing; configs, modeling, missions, textures, terrain etc.

Moderators: Lone Wolf, Snake Man

Post Reply
Snake Man
Commander-In-Chief
Posts: 9338
Joined: 2000-07-31 22:01:01
Gaming Interests: ArmA, ArmA 2, Falcon 4.0 and OFP.
Editing Interests: All, I (try) to edit everything.
Location: PMC
Contact:

ArmA 2 multiplayer scripting

Post by Snake Man » 2010-07-17 14:06:36

Welcome to

ArmA 2 multiplayer scripting

This discussion is about how to script multiplayer (MP) with server and clients. See also our ArmA: Multiplayer mission editing basics topic.

What I want to achieve in this topic is knowledge how to script join in progress (JIP) dedicated server compatible:
  • AI soldiers creation
  • Briefings
  • Objectives created during mission
  • Objectives mission start
  • Objectives on random locations
  • Random weather
Blue = Done.
Red = Not finished.

Probably the most common problem is that JIP players don't see the objectives status same as the players who have been on the server since mission start. This is what we want to learn here.

This is a start of the discussion, I'll update this topic and post here when I learn more. I wish that someone with knowledge would help us out and provide some MP scripting facts :)
PMC Tactical Forum New User Registration please read new info here.

PMC since 1984

Editing knowledge, visit PMC Editing Wiki
The leading, most detailed and comprehensive modification made for the Vietnam War - Vietnam: The Experience homepage
View our videos in PMC Youtube channel

PMC Tactical forum Advanced Search is power.

"ALPHA BLACK TO PAPA BEAR. ALL RUSSIANS ARE TOAST. OVER."

Snake Man
Commander-In-Chief
Posts: 9338
Joined: 2000-07-31 22:01:01
Gaming Interests: ArmA, ArmA 2, Falcon 4.0 and OFP.
Editing Interests: All, I (try) to edit everything.
Location: PMC
Contact:

Re: ArmA 2 multiplayer scripting

Post by Snake Man » 2010-07-19 10:32:31

To start this learning process, here is what I did for mission start.

init.sqf:

Code: Select all

// on server we run...
if (isServer) then
{
    // PMC ai unit creation script
    [] execVM "PMC\PMC_create_ai_units.sqf";
}
// on clients we run...
else
{
    // create briefing objectives
    [] execVM "briefing.sqf";
}; 
When server runs that it starts the AI creation script, when clients run it they only create briefings.

When lateron JIP player joins, he only gets briefing.

Then on the AI creation script we create the AI, then they appear in server and is "broadcasted" into clients.

On our AI creation script we also declare other things, for example:

Code: Select all

// mission end variable
PMC_mcomplete = false;
publicVariable "PMC_mcomplete"; 
This sets variable called "PMC_complete" into boolean false, then it only shows as false or even declared in the server, but next we run publicVariable command, which then broadcasts it over the clients who are connected and the same value is shown to all clients who connect lateron.
PMC Tactical Forum New User Registration please read new info here.

PMC since 1984

Editing knowledge, visit PMC Editing Wiki
The leading, most detailed and comprehensive modification made for the Vietnam War - Vietnam: The Experience homepage
View our videos in PMC Youtube channel

PMC Tactical forum Advanced Search is power.

"ALPHA BLACK TO PAPA BEAR. ALL RUSSIANS ARE TOAST. OVER."

Snake Man
Commander-In-Chief
Posts: 9338
Joined: 2000-07-31 22:01:01
Gaming Interests: ArmA, ArmA 2, Falcon 4.0 and OFP.
Editing Interests: All, I (try) to edit everything.
Location: PMC
Contact:

Re: ArmA 2 multiplayer scripting

Post by Snake Man » 2010-07-19 11:03:18

You generate the "mission" on the server and set whatever global variables you need, then publicVariable them and let the clients update their briefings with the new task(s)

Server-side creation of "objectives", client-side creation of markers and triggers

So far, here's what you know:
  • you now use createSimpleTask & Co
  • they should be run on the players' machines
  • the server should be the one who decides what new task(s) are available
  • write a system that does this, ie generates tasks/missions on the server and lets the clients see that reflected in their briefings
  • It's "same-same" with regards to global variables that keep track of a given sub-mission ("task")
a publicVariable event handler for a global variable called, say, pmc_currentTask

That on clients will do "player setCurrentTask pmc_currentTask"

The result of createTrigger is local to the machine where it's run

So if you need the trigger to be present on client machines, you need a mechanism to accomplish that

(eg the trigger should do a hint or ***Chat or playSound)

The trick there is to not create the trigger unless it's needed; if task is completed, don't create trigger.
PMC Tactical Forum New User Registration please read new info here.

PMC since 1984

Editing knowledge, visit PMC Editing Wiki
The leading, most detailed and comprehensive modification made for the Vietnam War - Vietnam: The Experience homepage
View our videos in PMC Youtube channel

PMC Tactical forum Advanced Search is power.

"ALPHA BLACK TO PAPA BEAR. ALL RUSSIANS ARE TOAST. OVER."

Snake Man
Commander-In-Chief
Posts: 9338
Joined: 2000-07-31 22:01:01
Gaming Interests: ArmA, ArmA 2, Falcon 4.0 and OFP.
Editing Interests: All, I (try) to edit everything.
Location: PMC
Contact:

Re: ArmA 2 multiplayer scripting

Post by Snake Man » 2010-08-04 17:27:22

Okay I have not yet cleaned this stuff up, also few of my functions are not working which even more causes this to be messy. But lets get started.

Random objectives

On the mission editor I place gamelogic's called pmc_<NUMBER>, then I run my PMC_targets.sqf on them to create PMC_targets array.

This is my basic server init script:

Code: Select all

private
[
    "_ran",
    "_tlogic",
    "_tmp"
];

// WAIT for objective creation for clients
PMC_create_objectives = false;
publicVariable "PMC_create_objectives";
PMC_target1 = false;
PMC_target2 = false;
publicVariable "PMC_target1";
publicVariable "PMC_target2";

// collect targets from pmc_? gamelogics
_tmp = [] execVM "PMC\PMC_targets.sqf";
waitUntil
{
    scriptDone _tmp;
};

publicVariable "PMC_opfor_starts";
publicVariable "PMC_blufor_starts";
publicVariable "PMC_targets";

// make the array
PMC_array = [];

// randomize the targets and choose one for the array.
_ran = (floor random (count PMC_targets));
_tlogic = (PMC_targets select _ran);
PMC_array = PMC_array + [_tlogic];
publicVariable "PMC_array";

// Give green light for objective creation for clients
PMC_create_objectives = true;
publicVariable "PMC_create_objectives"; 
I told you it was messy...

Also on this reference purpose I didn't see the need to include PMC_targets.sqf code as "you'll get the point" what it does.

Then on clients we run PMC_create_task.sqf script, this again is very messy and un-optimized.

Client script:

Code: Select all

private
[
    "_markerobj",
    "_targetpoint",
    "_triggerArea",
    "_triggerTimeout",
    "_z"
];

// I dont think we need to do this?
publicVariable "PMC_create_objectives";
publicVariable "PMC_target1";
publicVariable "PMC_target2";
publicVariable "PMC_array";

player sidechat "PMC_create_task waiting...";

// waits until server gives go ahead to create objective for client.
waitUntil {PMC_create_objectives};

player sidechat "PMC_create_task start!";

// size of trigger area
_triggerArea = 50;
// timeout for trigger to activate
_triggerTimeout = 60;

// create tasks in reverse order :)

// objective 2

if (!PMC_target2) then
{
    _targetpoint = getPos (PMC_array select 1);

    _z = createTrigger ["EmptyDetector", _targetpoint];
    _z setTriggerActivation ["WEST SEIZED", "PRESENT", true];
    _z setTriggerArea [_triggerArea, _triggerArea, 0, true];
    _z setTriggerTimeout [0, (_triggerTimeout/2), _triggerTimeout, true];
    _z setTriggerStatements ["this", "'PMC_target2' setMarkerColorLocal 'ColorGreen'; 'PMC_target2' setMarkerTypeLocal 'dot'; PMC_target2 = true; publicVariable 'PMC_target2'; PMC_objective2 setTaskState 'succeeded';", ""];
    
    _markerobj = createMarkerLocal ["pmc_target2", _targetpoint];
    _markerobj setMarkerShapeLocal "ELLIPSE";
    _markerobj setMarkerColorLocal "ColorRed";
    _markerobj setMarkerBrushLocal "Solid";
    _markerobj setMarkerSizeLocal [_triggerArea, _triggerArea];
    
    PMC_objective2 = player createSimpleTask ["Clear objective 2"];
    PMC_objective2 setSimpleTaskDescription ["Clear <marker name='pmc_target2'>objective 2</marker>","Clear objective 2","Clear objective 2"];
    PMC_objective2 setSimpleTaskDestination (getMarkerPos "pmc_target2");
}
// objective 2 has been completed!
else
{
    _targetpoint = getPos (PMC_array select 1);
    _markerobj = createMarkerLocal ["pmc_target2", _targetpoint];
    _markerobj setMarkerShapeLocal "dot";
    _markerobj setMarkerColorLocal "ColorGreen";
    
    PMC_objective2 = player createSimpleTask ["Clear objective 2"];
    PMC_objective2 setSimpleTaskDescription ["Clear <marker name='pmc_target2'>objective 2</marker>","Clear objective 2","Clear objective 2"];
    PMC_objective2 setSimpleTaskDestination (getMarkerPos "pmc_target2");
    PMC_objective2 setTaskState "succeeded";
};


// objective 1

if (!PMC_target1) then
{
    _targetpoint = getPos (PMC_array select 0);
    
    _z = createTrigger ["EmptyDetector", _targetpoint];
    _z setTriggerActivation ["WEST SEIZED", "PRESENT", true];
    _z setTriggerArea [_triggerArea, _triggerArea, 0, true];
    _z setTriggerTimeout [0, (_triggerTimeout/2), _triggerTimeout, true];
    _z setTriggerStatements ["this", "'PMC_target1' setMarkerColorLocal 'ColorGreen'; 'PMC_target1' setMarkerTypeLocal 'dot'; PMC_target1 = true; publicVariable 'PMC_target1'; PMC_objective1 setTaskState 'succeeded';", ""];
    
    _markerobj = createMarkerLocal ["pmc_target1", _targetpoint];
    _markerobj setMarkerShapeLocal "ELLIPSE";
    _markerobj setMarkerColorLocal "ColorRed";
    _markerobj setMarkerBrushLocal "Solid";
    _markerobj setMarkerSizeLocal [_triggerArea, _triggerArea];
    
    PMC_objective1 = player createSimpleTask ["Clear objective 1"];
    PMC_objective1 setSimpleTaskDescription ["Clear <marker name='pmc_target1'>objective 1</marker>","Clear objective 1","Clear objective 1"];
    PMC_objective1 setSimpleTaskDestination (getMarkerPos "pmc_target1");
    player setCurrentTask PMC_objective1;
}
// objective 1 has been completed!
else
{
    _targetpoint = getPos (PMC_array select 0);
    _markerobj = createMarkerLocal ["pmc_target1", _targetpoint];
    _markerobj setMarkerShapeLocal "dot";
    _markerobj setMarkerColorLocal "ColorGreen";
    
    PMC_objective1 = player createSimpleTask ["Clear objective 1"];
    PMC_objective1 setSimpleTaskDescription ["Clear <marker name='pmc_target1'>objective 1</marker>","Clear objective 1","Clear objective 1"];
    PMC_objective1 setSimpleTaskDestination (getMarkerPos "pmc_target1");
    PMC_objective1 setTaskState "succeeded";
}; 
In all of this, there is one major flaw, there is no broadcasting triggers to make objectives show when changed, in the players currently in the mission. Sure all JIP joiners get correct information, but the guys in-game do not.

So in the next improvement I need to add the triggers and publicVariables for them. I just wanted to post what I got now, so you guys don't think this topic is nothing but hot air without anything to show for.
PMC Tactical Forum New User Registration please read new info here.

PMC since 1984

Editing knowledge, visit PMC Editing Wiki
The leading, most detailed and comprehensive modification made for the Vietnam War - Vietnam: The Experience homepage
View our videos in PMC Youtube channel

PMC Tactical forum Advanced Search is power.

"ALPHA BLACK TO PAPA BEAR. ALL RUSSIANS ARE TOAST. OVER."

Snake Man
Commander-In-Chief
Posts: 9338
Joined: 2000-07-31 22:01:01
Gaming Interests: ArmA, ArmA 2, Falcon 4.0 and OFP.
Editing Interests: All, I (try) to edit everything.
Location: PMC
Contact:

Re: ArmA 2 multiplayer scripting

Post by Snake Man » 2010-08-14 23:56:21

In my current test mission, the goal was to create as many enemy groups as possible without need to have them recycled, I believe that number is 144.

Image

As you can see, our dedicated Linux server runs good. I am very happy with the mission / scripts at the moment :)
PMC Tactical Forum New User Registration please read new info here.

PMC since 1984

Editing knowledge, visit PMC Editing Wiki
The leading, most detailed and comprehensive modification made for the Vietnam War - Vietnam: The Experience homepage
View our videos in PMC Youtube channel

PMC Tactical forum Advanced Search is power.

"ALPHA BLACK TO PAPA BEAR. ALL RUSSIANS ARE TOAST. OVER."

Post Reply

Who is online

Users browsing this forum: No registered users and 14 guests