Jump to content

Working Dayz Epoch Headless Client for Zed Spawn and FSM


Goober

Recommended Posts

It seems the HC disconnects and reconnects every few minutes with no explanation in the rpt logs.

After a quick google search I discovered that others were having this issue as well. Does anyone here have any insights on this behavior?

 

I believe the instructions here tell you to prevent the player monitor from running on the HC.  The problem is that this includes some essential setup tasks inclusing generating/assigning a characterID to the character.  If you look in the player monitor FSM the serverside section will boot players with a null characterID after a timeout period.

 

The simplest fix for this is to allow the player monitor to run for the HC.

Link to comment
Share on other sites

Been playing with this today. I used david's version as a base for testing.

 

I got some AI choppers running off the headless client.

 

Without the player monitor running on the HC as said above the HC gets disconnected and the choppers spawn over and over every so often. 

 

On the first test with the player monitor running on the HC after 2 minutes or so  they froze in mid air and I see  "lost HC:" In the server's rpt log.

 

On the second attempt I added a 180 sec sleep to the start of the chopper script and they seem to be running fine and there shots are logging to the HC's rpt and not the servers so they seem to be running off it.

 

Still lots to test but this dose seem promising.

 

If anyone wants to try out my choppers here is the script I'm working on It's basically the group of choppers from Dayz origins made to work on chernarus

/*
	TayTay
	Origins
	Style
	Choppers v0.2
	Credits to Dami for teaching me shit.
*/
sleep 180;
raidchopper = {
//sleep 125;
private["_AISgroupg14g","_modelarrayg14g","_startposg14g","_position","_positiong14g","_rndCountg14g","_rnd","_bodynameig14g","_soldermodelg14g","_spawnTaviGroupLeaderg14g","_TavianaSquadg14g","_object1AI1","_wp14p1","_wp14p2","_wp14p3","_spawnAISg14g"];
_overwatch = true; //for taser
TTSBD = 300; //Time before bodys get cleaned up.

_TTLock = false; //Set to false to stop players gettin in the choppers


TTSkins = "BanditW1_DZ";

TTAiCleanUp = {
    sleep TTSBD;
    hideBody _this;
    sleep 10;
    deleteVehicle _this;
}; //Leave Alone


_TTSPS = [-833.42865, 8513.7236,0]; //start poss > west side off map


//Add some non random locations
_TTRandomWayPoint = [getMarkerPos "center",0,5000,10,0,2000,0] call BIS_fnc_findSafePos; //Leave Alone
_TTSetLocation1 = [4531.8242, 10478.185]; //NWA
_TTSetLocation2 = [12141.653, 12660.052]; //NEA
_TTSetLocation3 = [9570.8574, 8826.7754]; //Gorka
_TTSetLocation4 = [3833.9221, 8900.7949]; //Vybor
_TTSetLocation5 = [2014.7589, 7328.7847]; //Myshkino
_TTSetLocation6 = [2766.2703, 5359.6353]; //Zelenogorsk
_TTSetLocation7 = [8522.542, 6665.3511];  //Guglovo
_TTSetLocation8 = [6539.7939, 6088.8657]; //Vyshnoye
_TTSetLocation9 = [10108.719, 5475.8906]; //Staroye
_TTSetLocation10 = [9163.1133, 3845.1802]; //Pusta
_TTSetLocation11 = [4453.8809, 6417.7495]; //Pogorevka
_TTSetLocation12 = [4199.2217, 2722.9285]; //Balota

_TTFindLocation =
//I also add one extra random for each location I add
[
_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,_TTRandomWayPoint,
_TTSetLocation1,
_TTSetLocation2,
_TTSetLocation3,
_TTSetLocation4,
_TTSetLocation5,
_TTSetLocation6,
_TTSetLocation7,
_TTSetLocation8,
_TTSetLocation9,
_TTSetLocation10,
_TTSetLocation11,
_TTSetLocation12
] call BIS_fnc_selectRandom;

_TTSDB = {
    if (!isNil "dayz_serverObjectMonitor") then {dayz_serverObjectMonitor set [count dayz_serverObjectMonitor, _this];};
    if (!isNil "PVDZE_serverObjectMonitor") then {PVDZE_serverObjectMonitor set [count PVDZE_serverObjectMonitor, _this];};
    _this setVariable ["ObjectID", "1", true];
    _this setVariable ["ObjectUID", "1", true];
};

private["_AISgroupg14g","_modelarrayg14g","_startposg14g","_position","_positiong14g","_rndCountg14g","_rnd","_bodynameig14g","_soldermodelg14g","_spawnTaviGroupLeaderg14g","_TavianaSquadg14g","_object1AI1","_wp14p1","_wp14p2","_wp14p3","_spawnAISg14g","_object1AI1"];

    east setFriend [west,0];
    east setFriend [sideLogic,1];
	
    //_object1AI1 = "UH1H_DZE" createvehicle _TTSPS;
    _object1AI1 = createVehicle ["UH1H_DZ",  _TTSPS, [], 0, "NONE"];
    _object1AI1 setvelocity [0,0,1];
    _object1AI1 setFuel 1;
    _object1AI1 spawn _TTSDB;


	
/*
    _pos = getPos _object1AI1;
    _dir = getDir _object1AI1;
    _dis = 25;
    _poss = [(_pos select 0)+_dis*sin(_dir),(_pos select 1)+_dis*cos(_dir),(_pos select 2)+1];

*/

    //_object2AI2 = "UH1H_DZE" createvehicle _poss;
    _object2AI2 = createVehicle ["UH1H_DZ",[((getpos _object1AI1 select 0)+15),((getpos _object1AI1 select 1)+15),0], [], 0, "NONE"];
    _object2AI2 setvelocity [0,0,1];
    _object2AI2 setFuel 1;
    _object2AI2 spawn _TTSDB;
	//_object3AI3 addeventhandler ["fired", {(_this select 0) setvehicleammo 1}];
    //_object2AI2 setVehicleLock "LOCKED";

/*	
    _pos = getPos _object2AI2;
    _dir = getDir _object2AI2;
    _dis = 25;
    _poss = [(_pos select 0)+_dis*sin(_dir),(_pos select 1)+_dis*cos(_dir),(_pos select 2)+1];

*/	
	
    //_object3AI3 = "UH1H_DZE" createvehicle _poss;
    _object3AI3 = createVehicle ["UH1H_DZ",[((getpos _object2AI2 select 0)+15),((getpos _object2AI2 select 1)+15),0], [], 0, "NONE"];
    _object3AI3 setvelocity [0,0,1];
    _object3AI3 setFuel 1;
    _object3AI3 spawn _TTSDB;
	//_object3AI3 addeventhandler ["fired", {(_this select 0) setvehicleammo 1}];
    //
	
if (_TTlock) then {
_object1AI1 setVehicleLock "LOCKED";
_object2AI2 setVehicleLock "LOCKED";
_object3AI3 setVehicleLock "LOCKED";
};
 
    _AISgroupg14g = createGroup east;
	
/*
	
    _pos = getPos _object3AI3;
    _dir = getDir _object3AI3;
    _dis = 10;
    _pos = [(_pos select 0)+_dis*sin(_dir),(_pos select 1)+_dis*cos(_dir),(_pos select 2)+1];

*/

    _rndCountg14g = 9; 

    for "_x" from 1 to _rndCountg14g do {
        _bodynameig14g = format ["TavianaGuardg14g%1",_x];

        if(_x == 1) then {
            _soldermodelg14g = TTSkins; 
            _soldermodelg14g createunit [[((getpos _object2AI2 select 0)-5),((getpos _object2AI2 select 1)-15),0], _AISgroupg14g, "_spawnTaviGroupLeaderg14g = this; _TavianaSquadg14g = group this;"];
            _spawnTaviGroupLeaderg14g enableAI "TARGET";
            _spawnTaviGroupLeaderg14g enableAI "AUTOTARGET";
            _spawnTaviGroupLeaderg14g enableAI "MOVE";
            _spawnTaviGroupLeaderg14g enableAI "ANIM";
            _spawnTaviGroupLeaderg14g enableAI "FSM";
            _spawnTaviGroupLeaderg14g allowDammage true;
            _spawnTaviGroupLeaderg14g setCombatMode "YELLOW";
            _spawnTaviGroupLeaderg14g setBehaviour "STEALTH";
            _spawnTaviGroupLeaderg14g setFormation "ECH LEFT";
            _spawnTaviGroupLeaderg14g setSkill ["aimingAccuracy",1];
            _spawnTaviGroupLeaderg14g setSkill ["aimingShake",1];
            _spawnTaviGroupLeaderg14g setSkill ["aimingSpeed",1];
            _spawnTaviGroupLeaderg14g setSkill ["commanding",1];
            _spawnTaviGroupLeaderg14g setSkill ["endurance",1];
            _spawnTaviGroupLeaderg14g setSkill ["spotDistance",1];
            _spawnTaviGroupLeaderg14g setSkill ["spotTime",1];
            _spawnTaviGroupLeaderg14g setSkill ["courage",1];
            _spawnTaviGroupLeaderg14g setSkill ["reloadSpeed",1];
            _spawnTaviGroupLeaderg14g setSkill ["general",1];

            _spawnTaviGroupLeaderg14g addweapon "glock17_EP1";
            _spawnTaviGroupLeaderg14g addMagazine "17Rnd_9x19_glock17";
            _spawnTaviGroupLeaderg14g addMagazine "17Rnd_9x19_glock17";
            _spawnTaviGroupLeaderg14g addMagazine "17Rnd_9x19_glock17";
            _spawnTaviGroupLeaderg14g addMagazine "ItemBandage";
            _spawnTaviGroupLeaderg14g addMagazine "ItemBandage";           
            _spawnTaviGroupLeaderg14g addweapon "Binocular";
            _spawnTaviGroupLeaderg14g addweapon "ItemCompass";
            _spawnTaviGroupLeaderg14g addweapon "ItemMap";
            _spawnTaviGroupLeaderg14g addweapon "ItemHatchet";
            _spawnTaviGroupLeaderg14g addweapon "ItemKnife";
            _spawnTaviGroupLeaderg14g addweapon "ItemMatchbox";

            _spawnTaviGroupLeaderg14g addweapon "Sa58V_EP1";
            _spawnTaviGroupLeaderg14g addMagazine "30Rnd_762x39_SA58";
            _spawnTaviGroupLeaderg14g addMagazine "30Rnd_762x39_SA58";
            _spawnTaviGroupLeaderg14g addMagazine "30Rnd_762x39_SA58";
            _spawnTaviGroupLeaderg14g addMagazine "30Rnd_762x39_SA58";
            _spawnTaviGroupLeaderg14g addMagazine "30Rnd_762x39_SA58";
            _spawnTaviGroupLeaderg14g addMagazine "30Rnd_762x39_SA58";
            _spawnTaviGroupLeaderg14g selectWeapon "Sa58V_EP1";
            _spawnTaviGroupLeaderg14g addEventHandler ["Fired", {_this call player_fired;}];
            _spawnTaviGroupLeaderg14g addmpeventhandler ["killed", {(_this select 0) spawn TTAiCleanUp}];
            _spawnTaviGroupLeaderg14g disableConversation true;
            _spawnTaviGroupLeaderg14g setdamage 0.01;
			if (_overwatch) then {
			_spawnTaviGroupLeaderg14g addeventhandler ["HandleDamage",{_this call DDOPP_taser_handleHit;}];
			};

            _spawnTaviGroupLeaderg14g moveInTurret [_object1AI1, [0]];


            _wp14p1 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p1 setWaypointType "MOVE";
            _wp14p1 setWaypointBehaviour "COMBAT";
            _wp14p1 setWaypointCombatMode "RED";
            _wp14p1 setWaypointSpeed "NORMAL";

            _wp14p2 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p2 setWaypointType "MOVE";
            _wp14p2 setWaypointBehaviour "COMBAT";
            _wp14p2 setWaypointCombatMode "RED";
            _wp14p2 setWaypointSpeed "NORMAL";
	
	
            _wp14p3 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p3 setWaypointType "MOVE";
            _wp14p3 setWaypointBehaviour "COMBAT";
            _wp14p3 setWaypointCombatMode "RED";
            _wp14p3 setWaypointSpeed "NORMAL";

            _wp14p4 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p4 setWaypointType "MOVE";
            _wp14p4 setWaypointBehaviour "COMBAT";
            _wp14p4 setWaypointCombatMode "RED";
            _wp14p4 setWaypointSpeed "LIMITED";

            _wp14p5 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p5 setWaypointType "MOVE";
            _wp14p5 setWaypointBehaviour "COMBAT";
            _wp14p5 setWaypointCombatMode "RED";
            _wp14p5 setWaypointSpeed "LIMITED";

            _wp14p6 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p6 setWaypointType "MOVE";
            _wp14p6 setWaypointBehaviour "COMBAT";
            _wp14p6 setWaypointCombatMode "RED";
            _wp14p6 setWaypointSpeed "LIMITED";

            _wp14p7 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p7 setWaypointType "MOVE";
            _wp14p7 setWaypointBehaviour "COMBAT";
            _wp14p7 setWaypointCombatMode "RED";
            _wp14p7 setWaypointSpeed "LIMITED";

            _wp14p8 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p8 setWaypointType "MOVE";
            _wp14p8 setWaypointBehaviour "COMBAT";
            _wp14p8 setWaypointCombatMode "RED";
            _wp14p8 setWaypointSpeed "LIMITED";

            _wp14p9 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p9 setWaypointType "MOVE";
            _wp14p9 setWaypointBehaviour "COMBAT";
            _wp14p9 setWaypointCombatMode "RED";
            _wp14p9 setWaypointSpeed "LIMITED";

            _wp14p10 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p10 setWaypointType "MOVE";
            _wp14p10 setWaypointBehaviour "COMBAT";
            _wp14p10 setWaypointCombatMode "RED";
            _wp14p10 setWaypointSpeed "LIMITED";

            _wp14p11 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p11 setWaypointType "MOVE";
            _wp14p11 setWaypointBehaviour "COMBAT";
            _wp14p11 setWaypointCombatMode "RED";
            _wp14p11 setWaypointSpeed "LIMITED";

            _wp14p12 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p12 setWaypointType "MOVE";
            _wp14p12 setWaypointBehaviour "COMBAT";
            _wp14p12 setWaypointCombatMode "RED";
            _wp14p12 setWaypointSpeed "LIMITED";

            _wp14p13 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p13 setWaypointType "MOVE";
            _wp14p13 setWaypointBehaviour "COMBAT";
            _wp14p13 setWaypointCombatMode "RED";
            _wp14p13 setWaypointSpeed "LIMITED";

            _wp14p14 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p14 setWaypointType "MOVE";
            _wp14p14 setWaypointBehaviour "COMBAT";
            _wp14p14 setWaypointCombatMode "RED";
            _wp14p14 setWaypointSpeed "LIMITED";

            _wp14p15 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p15 setWaypointType "MOVE";
            _wp14p15 setWaypointBehaviour "COMBAT";
            _wp14p15 setWaypointCombatMode "RED";
            _wp14p15 setWaypointSpeed "LIMITED";

            _wp14p16 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p16 setWaypointType "MOVE";
            _wp14p16 setWaypointBehaviour "COMBAT";
            _wp14p16 setWaypointCombatMode "RED";
            _wp14p16 setWaypointSpeed "LIMITED";

            _wp14p17 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p17 setWaypointType "MOVE";
            _wp14p17 setWaypointBehaviour "COMBAT";
            _wp14p17 setWaypointCombatMode "RED";
            _wp14p17 setWaypointSpeed "LIMITED";

            _wp14p18 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];;
            _wp14p18 setWaypointType "MOVE";
            _wp14p18 setWaypointBehaviour "COMBAT";
            _wp14p18 setWaypointCombatMode "RED";
            _wp14p18 setWaypointSpeed "LIMITED";

            _wp14p19 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p19 setWaypointType "MOVE";
            _wp14p19 setWaypointBehaviour "COMBAT";
            _wp14p19 setWaypointCombatMode "RED";
            _wp14p19 setWaypointSpeed "LIMITED";

            _wp14p20 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p20 setWaypointType "MOVE";
            _wp14p20 setWaypointBehaviour "COMBAT";
            _wp14p20 setWaypointCombatMode "RED";
            _wp14p20 setWaypointSpeed "LIMITED";

            _wp14p21 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p21 setWaypointType "MOVE";
            _wp14p21 setWaypointBehaviour "COMBAT";
            _wp14p21 setWaypointCombatMode "RED";
            _wp14p21 setWaypointSpeed "LIMITED";

            _wp14p22 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p22 setWaypointType "MOVE";
            _wp14p22 setWaypointBehaviour "COMBAT";
            _wp14p22 setWaypointCombatMode "RED";
            _wp14p22 setWaypointSpeed "LIMITED";

            _wp14p23 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p23 setWaypointType "MOVE";
            _wp14p23 setWaypointBehaviour "COMBAT";
            _wp14p23 setWaypointCombatMode "RED";
            _wp14p23 setWaypointSpeed "LIMITED";

            _wp14p24 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p24 setWaypointType "MOVE";
            _wp14p24 setWaypointBehaviour "COMBAT";
            _wp14p24 setWaypointCombatMode "RED";
            _wp14p24 setWaypointSpeed "LIMITED";

            _wp14p25 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p25 setWaypointType "MOVE";
            _wp14p25 setWaypointBehaviour "COMBAT";
            _wp14p25 setWaypointCombatMode "RED";
            _wp14p25 setWaypointSpeed "LIMITED";

            _wp14p26 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p26 setWaypointType "MOVE";
            _wp14p26 setWaypointBehaviour "COMBAT";
            _wp14p26 setWaypointCombatMode "RED";
            _wp14p26 setWaypointSpeed "LIMITED";

            _wp14p27 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p27 setWaypointType "MOVE";
            _wp14p27 setWaypointBehaviour "COMBAT";
            _wp14p27 setWaypointCombatMode "RED";
            _wp14p27 setWaypointSpeed "LIMITED";

            _wp14p28 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p28 setWaypointType "MOVE";
            _wp14p28 setWaypointBehaviour "COMBAT";
            _wp14p28 setWaypointCombatMode "RED";
            _wp14p28 setWaypointSpeed "LIMITED";

            _wp14p29 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p29 setWaypointType "MOVE";
            _wp14p29 setWaypointBehaviour "COMBAT";
            _wp14p29 setWaypointCombatMode "RED";
            _wp14p29 setWaypointSpeed "LIMITED";

            _wp14p30 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p30 setWaypointType "MOVE";
            _wp14p30 setWaypointBehaviour "COMBAT";
            _wp14p30 setWaypointCombatMode "RED";
            _wp14p30 setWaypointSpeed "LIMITED";

            _wp14p31 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p31 setWaypointType "MOVE";
            _wp14p31 setWaypointBehaviour "COMBAT";
            _wp14p31 setWaypointCombatMode "RED";
            _wp14p31 setWaypointSpeed "LIMITED";

            _wp14p32 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p32 setWaypointType "MOVE";
            _wp14p32 setWaypointBehaviour "COMBAT";
            _wp14p32 setWaypointCombatMode "RED";
            _wp14p32 setWaypointSpeed "LIMITED";

            _wp14p33 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p33 setWaypointType "MOVE";
            _wp14p33 setWaypointBehaviour "COMBAT";
            _wp14p33 setWaypointCombatMode "RED";
            _wp14p33 setWaypointSpeed "LIMITED";

            _wp14p34 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p34 setWaypointType "MOVE";
            _wp14p34 setWaypointBehaviour "COMBAT";
            _wp14p34 setWaypointCombatMode "RED";
            _wp14p34 setWaypointSpeed "LIMITED";

            _wp14p35 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p35 setWaypointType "MOVE";
            _wp14p35 setWaypointBehaviour "COMBAT";
            _wp14p35 setWaypointCombatMode "RED";
            _wp14p35 setWaypointSpeed "LIMITED";

            _wp14p36 = _TavianaSquadg14g addWaypoint [_TTFindLocation, 0];
            _wp14p36 setWaypointType "CYCLE";
            _wp14p36 setWaypointBehaviour "COMBAT";
            _wp14p36 setWaypointCombatMode "RED";
            _wp14p36 setWaypointSpeed "LIMITED";	


        } else {


            _soldermodelg14g = TTSkins;
            _soldermodelg14g createunit [[((getpos _object2AI2 select 0)-5),((getpos _object2AI2 select 1)-15),0], _AISgroupg14g, "_spawnAISg14g = this;"];
            _spawnAISg14g enableAI "TARGET";
            _spawnAISg14g enableAI "AUTOTARGET";
            _spawnAISg14g enableAI "MOVE";
            _spawnAISg14g enableAI "ANIM";
            _spawnAISg14g enableAI "FSM";
            _spawnAISg14g allowDammage true;
            _spawnAISg14g setCombatMode "YELLOW";
            _spawnAISg14g setBehaviour "STEALTH";
            _spawnAISg14g setSkill ["aimingAccuracy",1];
            _spawnAISg14g setSkill ["aimingShake",1];
            _spawnAISg14g setSkill ["aimingSpeed",1];
            _spawnAISg14g setSkill ["commanding",1];
            _spawnAISg14g setSkill ["endurance",1];
            _spawnAISg14g setSkill ["spotDistance",1];
            _spawnAISg14g setSkill ["spotTime",1];
            _spawnAISg14g setSkill ["courage",1];
            _spawnAISg14g setSkill ["reloadSpeed",1];
            _spawnAISg14g setSkill ["general",1];
            if(_x == 2) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveindriver _object1AI1;
            };

            if(_x == 3) then {
                _spawnAISg14g addweapon "DMR";
                _spawnAISg14g addMagazine "20Rnd_762x51_DMR";
                _spawnAISg14g addMagazine "20Rnd_762x51_DMR";
                _spawnAISg14g addMagazine "100Rnd_762x51_M240";
                _spawnAISg14g selectWeapon "DMR";
                _spawnAISg14g moveInTurret [_object1AI1, [1]];
            };


            if(_x == 4) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveindriver _object2AI2;
            };

            if(_x == 5) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x51_M240";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveInTurret [_object2AI2, [0]];
            };
            if(_x == 6) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x51_M240";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveInTurret [_object2AI2, [1]];
            };
            if(_x == 7) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveindriver _object3AI3;
            };

            if(_x == 8) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x51_M240";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveInTurret [_object3AI3, [0]];
            };
            if(_x == 9) then {
                _spawnAISg14g addweapon "Pecheneg_DZ";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x54_PK";
                _spawnAISg14g addMagazine "100Rnd_762x51_M240";
                _spawnAISg14g selectWeapon "Pecheneg_DZ";
                _spawnAISg14g moveInTurret [_object3AI3, [1]];
            };
            _spawnAISg14g setVariable ["bodyname",_bodynameig14g,false];		
            _spawnAISg14g setVariable ["delmeplease",_bodynameig14g,false];
            _spawnAISg14g addEventHandler ["Fired", {_this call player_fired;}];
            _spawnAISg14g addEventHandler ["killed", {(_this select 0) spawn TTAiCleanUp}];
            _spawnAISg14g disableConversation true;
            _spawnAISg14g setdamage 0.01;
			if (_overwatch) then {
			_spawnAISg14g addeventhandler ["HandleDamage",{_this call DDOPP_taser_handleHit;}];
			};

        };     
    };
};
_iog14g = [] call raidchopper;

just execute it with 

if (!isServer && !hasInterface) then
{
	execVM "choppers.sqf";
};

Link to comment
Share on other sites

Right I understand the executing of scripts on the headless client like AI, but could someone explain to me the process of how the stuff with zombies is meant to work?

I'm really not sure what it's meant to be doing so I cant really tell if it's working or not. :unsure:

Zombies spawn with or without the HC connected so I cant really tell if its doing anything at all.  :wacko:

I'm going to spend the day looking through everything tomorrow and get to grips with it as this seems like a great little project. ( I would of today but me and my friend had a great time with 100+ choppers & jets to shoot at today.  :lol: )

 

Edit

Ok helps if i read the first post right..

So I understand how its supposed to work but is there any way to tell if they are loaded on the HC?

Link to comment
Share on other sites

So I understand how its supposed to work but is there any way to tell if they are loaded on the HC?

 

Not directly, which is the point to this.  It is supposed to be seamless.

 

You could put some code in the zombie spawning scripts which writes something to the log files (or maybe even the HC console ... not sure how to do that) when it is an HC that is spawning them.  Or you could put very low spawn quantities for default when a player client is controlling spawning and high spawn quantities when it is an HC.

 

As you have shown in an earlier post, you can get some crazy AI going on HC before you start causing server fps drop, but quantifying the improvement that HC zombie spawning gives is more difficult.  It should have some positive effect on the player client machines and maybe some on server communications.  But my theory is that if you have sufficient network speed and a properly tuned server config (CPU speed, affinities, file access speeds, # of guaranteed messages versus non-guaranteed messages, etc...) you will see little numeric server improvement.

 

SO why do this?  Because sometimes lag problems are not a simple, single machine issue.  Because player client spawning and control is far less consistent an experience than HC.  Because it further showcases what can be done with and how to begin applying HC to DayZ coding.

 

(Thank you for tolerating my diatribe.)

 

Goober

Link to comment
Share on other sites

I've created a new post out of respect for the original thread and Goober, so further discussions that are specific to EHC should be done at to keep the original thread on track.

Big thanks to OP Goober for being a bro.

Link to comment
Share on other sites

Really don't understand why you and the handful of other people working on headless clients don't all just work together? So much more work could be achieved and bug fixes wouldn't be a problem then really. Please take this into consideration and reach out to all the others working on the same project would make so much more sense and we all would probably have a seamless headless client now. Either way appreciate what you and the rest of the guys have done keep up the good work!

Link to comment
Share on other sites

  • 1 month later...

I've got an Idea, how i wanted to manage restarts and all the other Stuff in Future, it would also be useful for productive Headless Client support.

The Idea is to have a simple Management Tool (now called the Tool), which provides a Port for communication and is able to kill/start the Server.

To communicate with this Tool, the Server will use an dll, which creats an connection to this tool and transfers all the Informations.

 

This would make it possible, to create such a flow:

  1. Tool is getting started
  2. Tool starts the Server and is watching its State
  3. A User arrives and initialises the Server
  4. The Server tells the Tool, that it is running
  5. The Tool now starts the Headless Client
  6. Now everthing will run for x Hours until its Time to restart the Server
  7. The Server tells the Users that they have to disconnect
  8. The HC gets killed by the Tool
  9. The Server gets killed
  10. Goto 2

Watching the State could happen via an heartbeat signal that the Server sends every x seconds/minutes to the Tool.

As response the Tool will tell the Server in how many minutes it is going to get killed, which will be displayed to the User.

 

After the Server started, it has for example 15 Minutes to send the first heartbeat Signal, if it does not, the Server will be restarted, because most likely something went wrong while initialising. The same will happen, if the Server misses to send x heartbeat signals, because this could only be caused by an hung server, which did not terminate after it crashed.

If the Server Termintes, it will also get restarted. If the Server got killed and there is still the HC running, it will also be killed.

 

Depending on the Language, such a solution would take guessed something around 1000 lines of Code. (if you go without an gui)

 

Additionaly it would also help to restart the Server out of time with Warning the User, that the restart will happen in for example 15 Minutes.

Link to comment
Share on other sites

  • 5 weeks later...

I believe the instructions here tell you to prevent the player monitor from running on the HC.  The problem is that this includes some essential setup tasks inclusing generating/assigning a characterID to the character.  If you look in the player monitor FSM the serverside section will boot players with a null characterID after a timeout period.

 

The simplest fix for this is to allow the player monitor to run for the HC.

 

Hey Macdog

 

Can you help me out with the headless client?  I have been trying to get this going for some time now.  the HC keeps getting disconnected.

Do you mind sharing how you were able to get the HC to run server side?

Link to comment
Share on other sites

thats a fairly broad/open question mate!  the post you quoted simply states you need to let the HC execute the playermonitor code.  Its called in the mission init.sql file.  Depending on whose instructions you have followed you may have prevented that code from running on the HC by changing

if (!isServer) then

to 

if ((!isServer) && (hasInterface) then

on the statement that wraps around the playermonitor section.  The simplest fix is to not prevent anything running on the HC, although if you want to optimise you can be more selective.

 

Does that help?

Link to comment
Share on other sites

thats a fairly broad/open question mate!  the post you quoted simply states you need to let the HC execute the playermonitor code.  Its called in the mission init.sql file.  Depending on whose instructions you have followed you may have prevented that code from running on the HC by changing

if (!isServer) then

to 

if ((!isServer) && (hasInterface) then

on the statement that wraps around the playermonitor section.  The simplest fix is to not prevent anything running on the HC, although if you want to optimise you can be more selective.

 

Does that help?

Thanks that did help!

 

Now with the HC staying logged in, shouldn't all the Zeds be handled by the HC?  I am finding that if I kick the HC the zeds don't disappear.  also there doesn't seem to be allot of zeds like i would expect.

Link to comment
Share on other sites

So how do you define in the HC setup which server functions are supposed to be offloaded to the HC?  For instance, if I wanted to run it just to offload AI functions off the main CPU core.

 

This is a fairly involved subject and there are various approaches.  I have tried a few and have come to my own conclusion in terms of what works best.

 

  1. Run everything from the HC.  You can get most function to work, but a pure HC only implementation will not work properly with a lot of functions from the various mission systems.  Especially when it comes to spawning objects into the game, and for those objects to persist.  In some cases you can get around this using anti-hack tweaks but that will weaken your protection.  This method also requires a lot of battleye exceptions, also not good.
  2. Run everything from server (ie, normal mission pack install) and use setOwner to assign the AI units to the HC.  Played with this option briefly, but has some known game engine limitation, such as waypoints being lost.
  3. Hybrid.  Run most code from HC, and offload certain tasks (such as spawning objects) to the server.  I used this method with reasonable success for some time but ultimately is more complicated and error prone than the next option.
  4. Hybrid.  Run the mission system from the server, and execute AI modules from the HC.  This for me has been the most stable method by some margin and allows all typical features to be used.  It requires very few (if any) anti-hack bypasses, all the mission logic runs on the server (which is usually as per the design of the mission pack) and only specific scripts are executed on the HC.

 

With the hyrbid options you do need to build a basic framework to enable the server and HC to work together well.  This is what I have done at a high level:

 

On the server

  • I took Goobers server side HC detection routine and adapted and simplified for my needs.  His code was better in that it could cope with multiple HCs however it did have some bugs.  Since multiple HC is a very niche requirement I decided to re-write it slightly but with the ability to detect only a single HC.  This is not a problem unless you plan to have over 200 AI (maybe more) and also would suggest you are running HCs from various machines (as you can only really run 1 per windows instance easily).
  • I installed and configured a mission pack of choice in the normal way in my server PBO.  Currently for me that is Wicked AI 2.1.x.
  • I then adjusted various elements of the mission logic so that it would check from the presence of an HC (see first point) and only start a mission if a valid HC existed.  Hint, there is more to this than just having an HC connected to the server, you also need to know that the HC has had a chance to precompile the necessary scripts.
  • I then modify all of the scripts that define the functions for spawning AI so that rather than actually doing anything, they parse all the parameters received from the original spawn request in the specific mission file and send it to the HC using <ID> publicVariableClient [spawn parameters]
  • I also do something similar for certain functions such as those that clean up AI when missions end (this bit is more complex, but not that bad actually).
  • You also should setup a routine on the server (mine runs every minute) that counts AI units controlled by the server and immediately deletes them.  This is because if the HC crashes whilst managing AI, the AI will remain and their control passes back to the server, instantly killing you server FPS!

On the HC

  • First, everything that runs on the HC does so via a specific client side addon (PBO) that I have signed with my own key.  They key is enabled on my server, so in theory anyone could connect to my server and run my addon, but I dont release my signed addon to the public so its a non-issue (unless i get hacked of course.  and by hacked this isnt an arma2 hacked, it would be a "proper" hack (well correct term is crack) of my dedicated server).  This way, the only reference to my HC anywhere in the mission file that all players download is a single statement in the init.sqf that checks for a !hasInterface and runs \z\addons\macdogHC\init.sqf.
  • First thing is to get the HC side of Goobers HC detection/management code installed in the custom HC addon described above working.  This is to let the server know an HC is attached, and I have adapted it for my purposes somewhat.
  • Then I install and configure the mission pack in my custom addon, making sure to set the configuration options that affect AI as I want them in the config file.  Then disable the actual mission system, so when launched (ie, via \z\addons\macdogHC\WAI\init.sqf) doesnt actually start launching missions.
  • I then setup a bunch of publicEventHandlers so that when the server executes a <ID> publicVariableClient spawn_group for example, the HC will run \z\addons\macdogHC\WAI\compile\spawn_group.sqf with the parameters originally specified in the specific mission definition running on the server.
  • I have to do something similar for the mission clean up scripts as I alluded to in the server section above, but this is more selective.

And that's it really.  It works very reliably IMO, yes very occasionally Arma2OA.exe can crash, and I don't have a monitoring system in place to detect and relaunch the client.  So if I don't spot it (usually the case now as I have alomst zero time for epoch these days) there are no missions until next restart.  I used to have the HC running as a service which did address this, but the move to steam only has really made running the client in a server like way much more difficult so I have to run the client interactively which is a shame.

 

I also have animated heli/c130 crashes running of the HC.  They dont suffer from the stutter that you get when you run them server side, and are indistinguishable from player flown aircraft.  I used to have jet crashes run this way, but it meant white listing them in my anti-hack.  I could have edited infistars code to allow the jet crashes but still catch illegal jet spawns, but would require me tinkering every time he released a new version so was just too much effort.

Link to comment
Share on other sites

Hi macdog,

This is some very interesting stuff you have achieved! One of our goals for future Wicked AI versions is better default support for headless clients. Since it seems you pretty much got that working with the latest Wicked AI i'd like to ask you to share that knowledge on the HC Testbranch i have just created.

Cheers,

 

f3cuk

Link to comment
Share on other sites

Hi macdog,

This is some very interesting stuff you have achieved! One of our goals for future Wicked AI versions is better default support for headless clients. Since it seems you pretty much got that working with the latest Wicked AI i'd like to ask you to share that knowledge on the HC Testbranch i have just created.

Cheers,

 

f3cuk

Thanks. Sorry, but right now I don't even have time to manage my server properly let alone this. What I can do is send you the code and answer questions about how it all works etc.. Happy for you to then maintain the HC branch. I actually don't think it would add much overhead to maintain both, and eventually I think you could get to this being a add-on module configured from the global condig file all under the single master branch.

Link to comment
Share on other sites

Yes that would be perfect. If you do a pull request on the HC branch with all of your files we can start looking into it and work on making it part of Wicked AI (without having to maintain a second branch, just a simple true/false in the config would suffice).

Thanks for sharing!

Link to comment
Share on other sites

I then modify all of the scripts that define the functions for spawning AI so that rather than actually doing anything, they parse all the parameters received from the original spawn request in the specific mission file and send it to the HC using <ID> publicVariableClient [spawn parameters]

 

macdog,

 

I did that with DZMS, but all the DZMS code is in the mission file, and it runs only on the unique Headless Client.

 

On DZMS the isServer checks was changed to give true to Headless Clients and all \z\addons\dayz_server\DZMS references was changed to hc\DZMS to use the DZMS on the mission files.

 

All DMZS runs on the Headless Client. I did a quick search and not saw any code asking for a specific server variable.

 

The Headless Client player is on the midle of the map.

 

It works ok, But the AI shot to a completely wrong direction, where there is no one.

 

Do you had this problem with your Headless Client bots?

Link to comment
Share on other sites

Sorry for the triple combo! HAHAHA!

 

The fix for the bots shoting in the wrong direction.

MinErrorToSendNear=0;

MinErrorToSend=0;

on basic.cfg.

 

This will recuce the position error for away moving objects to zero to all clients, including the Headless Client.

 

AS FUCKIN EXPECTED!

 

But those high precision MinError decrease fps a lot and increase bandwidth usage.

 

Default values are:

MinErrorToSendNear=0.01;

MinErrorToSend=0.001;

But people connomly use less precise values like:

MinErrorToSendNear=0.05;

MinErrorToSend=0.004;

I'm using that, and bots precision is bad.

 

My next test:

 

0 - Set default MinError values.

1 - Put HC client on one side of the map (Chernarus).

2 - Spawn HC ai on the other side of the map.

3 - Connect as client and meet the ai.

4 - See if this gives a aceptable error (search for the blood arround me when i get hit).

 

Blood is processed by the ai owner, in this case the Healess Client. So if your blood is away from you, then the error is not acceptable.

 

If the error is aceptable for the default values i will stick to it.

Result: The default values does not give good precision. Set MinError to zero is not sensate, since it kill fps. Also tried 0.001 to the two options (this is the minimum value)... no precision.

I'm stuck again.

Anyone can help with that precision problem?

EDIT NUMBA FIVE:

UHAUAHAUHHAHAAHAUHAUHAHAAUHAUHAUAUUAHAUHAUHH!

Thankyou macdog_2000 for the answer!

On config.cfg, the setting localclient[] = {"127.0.0.1"}; make MinError zero to all clients on the same machine of the host! I believe i can now put the HC on china and make it spawn bots on USA.

I have not used this setting by default because i was not able to figure out its purpose!

Son of a Daughter Headless Clients on the way!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×
×
  • Create New...