RE:NODE

Návody12 min čtení

Headless clienty v Arma 3 pro odlehčení AI

Jak fungují headless clienty v Arma 3: lokalita, nastavení server.cfg, slot v misi, přesun AI přes setGroupOwner nebo ACE, více HC a jak prokázat, že pomohly.

1 čtenář

Headless client (HC) je druhá kopie serverové binárky Arma 3 spuštěná s -client, která se připojí k tvému serveru jako neviditelný hráč a simuluje AI, kterou jí mise přidělí. Pomůže jen tehdy, když platí tři věci: AI je to, co žere čas snímku tvého serveru, mise nabízí v lobby slot pro headless client a něco - kód mise, headless komponenta ACE nebo jiný skript - na něj skutečně přenáší skupiny AI. Když to sedí, trvalá mise se stovkami AI drží hratelné FPS serveru hluboko do session; když nesedí ani jedna z těch věcí, utratil jsi paměť a podíl CPU za proces, který v slotu jen sedí a nic nedělá.

Přepínače na straně serveru (headlessClients[], localClient[]) jsou popsané v průvodci server.cfg pro Arma 3. Tento článek je o všem okolo: proč je lokalita celý příběh, jak dostat slot do mise, tři způsoby přesunu AI, provoz více HC a jak prokázat, že to fungovalo.

Lokalita: proč headless client vůbec může pomoci#

Každý objekt v multiplayerové session Arma 3 je lokální přesně na jednom stroji. Ten stroj spouští jeho simulaci - u AI to znamená hledání cesty, výběr cílů, aktualizaci znalostí, rozhodování o střelbě - a výsledky rozesílá všem ostatním. Každý další stroj drží vzdálenou kopii, kterou vykresluje a interpoluje, ale nepřemýšlí za ni.

Ve výchozím stavu je AI umístěná v editoru nebo vytvořená serverovými skripty lokální na serveru. Hlavní vlákno serveru tedy přemýšlí za každou jednotku AI v misi k tomu, co dělá jinak, a simulace Arma je převážně jednovláknová. Když stoupne počet AI, klesne FPS serveru, a když klesne FPS serveru, zhorší se všechno najednou: AI reaguje pozdě, vozidla sekají, hráči mají desync.

Headless client je prostě další stroj, na kterém může být AI lokální. Je to plnohodnotný klient Arma bez vykreslování a bez zvuku, takže celý jeho čas snímku jde na simulaci jednotek, které vlastní. Přesuň na něj sto AI a těch sto jednotek přestane serveru stát cokoli kromě síťových aktualizací.

state updatesowns its groupsowns its groupsHráčivlastní své jednotkyHC1skupiny AI, eastHC2skupiny AI, westDedikovaný servercíle, skripty
Kde se simuluje AI se dvěma headless clienty

Z tohoto modelu vyplývají tři důsledky, které vysvětlují většinu problémů s HC:

  • AI se sama nepřesouvá. Jednotka je lokální tam, kde vznikla, dokud na ní něco nezavolá setGroupOwner. Připojení HC nezmění nic na existující AI.
  • Lokalita je po skupinách. Přesouváš celé skupiny a s nimi jednotky, waypointy i vozidla, která řídí.
  • Skripty běží tam, kde běží. Kód na serveru, který velí jednotce přesunuté na HC, může přestat fungovat, protože mnoho příkazů se projeví jen tam, kde je jednotka lokální.

Vyplatí se to? Změř, než začneš stavět#

Headless client není zadarmo. Je to druhý proces Arma se stejným seznamem modů, takže potřebuje vlastní paměť - typicky 2 až 4 GB při střední sadě modů - a vlastní procesorový čas. Pokud problém tvého serveru není AI, nedá ti nic.

Nejdřív měř. Přihlas se jako admin a spusť #monitor 5, což každých pět sekund vypisuje do chatu FPS serveru a související čísla. Pak porovnej:

Co vidíšCo to znamenáPomůže HC?
FPS serveru klesá s rostoucím počtem AI a zotaví se, když AI umíráAI je ta cenaAno
FPS serveru pomalu klesá během hodin při stabilní AIÚnik ve skriptech nebo hromadění objektůNe, oprav misi
FPS serveru v pořádku, hráči si stěžují na lagSíť nebo výkon klientůNe
FPS serveru špatné od první minuty s málo AICena modů nebo skriptů při startuNe, profiluj misi
Paměť u limitu, FPS v pořádkuPaměť, ne AINe, a HC paměť zhorší

Obecnější verze je v co tick rate opravdu znamená a CPU vs RAM u herních serverů. V panelu s grafem CPU je typický obraz serverový proces přilepený na svém přídělu CPU, zatímco paměť je plochá a mise spawnuje AI.

Strana serveru ve zkratce#

Dvě pole v server.cfg způsobí, že server s HC zachází správně:

server.cfg
headlessClients[] = {"127.0.0.1"};localClient[] = {"127.0.0.1"};

headlessClients[] uvádí adresy, které smějí obsadit sloty headless clientu. localClient[] označí adresy jako lokální, čímž odstraní limity šířky pásma určené pro hráče na domácím připojení - bez toho je HC škrcený jako hráč a aktualizace AI se řadí do fronty. Pokud HC běží na jiném stroji, obě pole potřebují adresu toho stroje místo loopbacku.

HC se spouští stejnou binárkou:

bash
$ ./arma3server_x64 -client -connect=127.0.0.1 -port=2302 \    -password="joinpassword" -profiles=hc1 -name=hc1 \    -mod="@cba_a3;@ace" -world=empty -nosound

Co která část dělá:

  • -connect a -port míří na herní port serveru.
  • -password je heslo pro připojení, pokud ho server má. Ne heslo admina.
  • -mod musí přesně odpovídat seznamu klientských modů serveru. Položky -serverMod nejsou potřeba.
  • -profiles a -name dávají HC vlastní složku profilu a vlastní log, takže jeho soubor .rpt se nemíchá se serverovým.

HC se připojí, objeví se v lobby a obsadí slot headless clientu, pokud ho mise má. Pokud ne, zůstane na obrazovce výběru slotu.

Slot v misi#

Tohle je krok, na kterém ztroskotá většina hlášení „můj HC nic nedělá“. Mise musí obsahovat entitu headless clientu a ta musí být hratelná.

V editoru Eden je headless client logická entita s názvem Headless Client. Umísti jednu na každý HC, který chceš provozovat, a u každé:

  1. Dej jí název proměnné - HC1, HC2, HC3. Skripty najdou HC podle tohoto jména.
  2. Zaškrtni Playable. Nehratelná entita HC se jako slot nikdy nenabídne.
  3. Ulož a exportuj misi do multiplayeru, aby .pbo v mpmissions entitu obsahoval.

HC slot obsadí automaticky, když se připojí; nikdo ho nemusí přidělovat. Ve skriptech pak název proměnné odkazuje na objekt HC a owner HC1 (vyhodnocené na serveru) vrátí jeho ID klienta - číslo, které setGroupOwner potřebuje.

Velké komunitní mise jako Antistasi a Liberation se dodávají s již umístěnými sloty pro headless client. Mise z Workshopu, která v popisu o headless clientech nemluví, je skoro určitě nemá.

Tři způsoby, jak přesunout AI na headless client#

Jakmile slot existuje, něco musí AI přenést. Existují tři přístupy a lze je kombinovat.

1. Vytvořit AI rovnou na HC

Nejčistší přístup pro mise, které píšeš sám: spusť spawnovací kód na samotném HC, takže AI je tam lokální od narození a nikdy se nepřenáší.

init.sqf
// true only on a headless clientif (!hasInterface && !isServer) then {    [] execVM "scripts\spawnPatrols.sqf";};// fall back to the server if no HC is connectedif (isServer && {isNil "HC1" || {isNull HC1}}) then {    [] execVM "scripts\spawnPatrols.sqf";};

hasInterface je false na dedikovaných serverech a headless clientech; isServer je true jen na serveru. Tato kombinace identifikuje HC. Záložní větev je důležitá: mise, která spawnuje AI jen na HC, nemá žádné nepřátele v noci, kdy se HC nepřipojí.

2. Přenést skupiny ze serveru pomocí setGroupOwner

Pro AI umístěnou v editoru nebo vytvořenou existujícími serverovými skripty ji přenes. setGroupOwner běží jen na serveru, bere skupinu a ID klienta a přesune skupinu i její jednotky.

initServer.sqf
[] spawn {    // wait until the HC has connected and has a client ID    waitUntil { sleep 5; !isNil "HC1" && {!isNull HC1} && {owner HC1 > 2} };    sleep 30; // let mission init finish first    private _hc = owner HC1;    {        private _grp = _x;        if (local _grp            && {({isPlayer _x} count units _grp) == 0}            && {!(_grp getVariable ["keepOnServer", false])}) then {            _grp setGroupOwner _hc;        };    } forEach allGroups;};

Nejdůležitější jsou kontroly v té smyčce. Přenášej jen skupiny lokální na serveru, nikdy skupinu obsahující hráče a dej si způsob, jak vyloučit skupiny, které musí zůstat na místě - skriptované scény, jednotky s navázanou serverovou logikou. Prodleva nechá dokončit ostatní inicializace; přenos skupiny uprostřed nastavování je klasický zdroj napůl nakonfigurované AI.

3. Nechat to udělat mod

ACE3 obsahuje headless komponentu, která automaticky přenáší skupiny AI na připojené headless clienty a přebalancuje je, když se HC připojí nebo odpojí. Konfiguruje se v nastavení addonů CBA: zapni ji, nastav prodlevu přenosu a rozhodni, co se stane při odpojení HC. Má proměnnou pro vyloučení na úrovni skupiny i jednotky pro věci, které musí zůstat na serveru; přesný název ve své verzi najdeš v dokumentaci ACE. Pro modovanou skupinu, která už ACE používá, je to nejméně pracná cesta a funguje s AI umístěnou v editoru i vytvořenou přes Zeuse.

Starší mise používají Werthles' Headless Module, editorový modul, který dělá totéž. Na misi vyber jeden automatický mechanismus; dva systémy přesouvající stejné skupiny spolu bojují.

Co se rozbije, když AI změní vlastníka#

Přesun lokality není pro skripty neviditelný. Běžné problémy:

  • Příkazy s lokálním efektem. Některé příkazy fungují jen tam, kde je jednotka lokální. Serverová smyčka, která volá doMove, disableAI nebo setBehaviour na skupinu přesunutou na HC, může potichu nedělat nic. Spouštěj takový kód tam, kde skupina žije, například přes remoteExec zacílený na groupOwner, nebo nech celý skript chování běžet na HC.
  • Event handlery. Handlery přidané přes addEventHandler jsou lokální na stroji, který je přidal, a několik jich se spouští jen tam, kde je jednotka lokální. Serverový handler Killed nebo Hit na přenesené jednotce může přestat střílet. Použij multiplayerové varianty (addMPEventHandler s MPKilled, MPHit) nebo přidej handlery na vlastnícím stroji.
  • Nastavení aplikovaná před přenosem. Část stavu AI nastavená na serveru před přesunem přenos nepřežije. Skill, disableAI a chování aplikuj po přenosu, na novém vlastníkovi.
  • Mrtvá těla a úklid. Garbage collection pořád běží na serveru. To je v pořádku, ale úklidový skript, který před smazáním kontroluje local, přeskočí jednotky vlastněné HC.

Když se mise chová špatně jen s připojeným HC, tyhle čtyři body jsou kontrolní seznam.

Více headless clientů a dynamic simulation#

Jeden HC je druhé vlákno. Několik HC je několik vláken a mise s velmi vysokým počtem AI rozdělují skupiny mezi HC1, HC2 a HC3 - podle oblasti, strany nebo střídavě. Každý potřebuje vlastní hratelný slot, vlastní proces s vlastním -profiles a -name a vlastní díl paměti a CPU.

Víc HC pomůže jen tehdy, když jsou jádra, na kterých poběží. Na vlastním hardwaru je to otázka fyzických jader. Na hostovaném serveru je CPU obvykle pevný příděl - na RE:NODE je každý server jeden kontejner škrcený na podíl, který sis koupil - takže headless client běžící ve stejném přídělu s ním soupeří se serverem. Přesto pomáhá, když je server uvízlý na jednom vláknu a nevyužitý příděl zbývá, což je běžný případ, ale nemůže vytvořit CPU, které v plánu není. Druhý HC ve stejném přídělu málokdy předčí jeden.

Doplněk k headless clientům je dynamic simulation, zabudovaná do hry od verze 1.74. Zmrazí skupiny AI, které jsou daleko od jakéhokoli hráče, a probudí je, když se někdo přiblíží:

initServer.sqf
enableDynamicSimulationSystem true;"Group" setDynamicSimulationDistance 1500;{ _x enableDynamicSimulation true } forEach allGroups;

Zmrazená skupina stojí skoro nic, ať je lokální kdekoli. Na velkém terénu s posádkami AI všude odstraní dynamic simulation často víc zátěže než headless client a obojí dohromady je standardní nastavení pro velké trvalé mise. Povol ji pro každou skupinu po jakémkoli přenosu.

Jak prokázat, že to fungovalo#

Nespoléhej na to, že to funguje, jen proto, že je HC v lobby. Zkontroluj tři věci.

  1. Skupiny se skutečně přesunuly. V debug konzoli se spuštěním na serveru spočítej skupiny podle vlastníka: {groupOwner _x == owner HC1} count allGroups. Nula znamená, že se nic nepřeneslo.
  2. HC to zvládá. Nech HC logovat vlastní snímkovou frekvenci a počet skupin do jeho .rpt:
init.sqf
if (!hasInterface && !isServer) then {    [] spawn {        while {true} do {            diag_log format ["HC fps %1, local groups %2",                diag_fps, {local _x} count allGroups];            sleep 60;        };    };};
  1. Server se zlepšil. Spusť #monitor 5 ve stejném bodě mise s HC a bez něj. Pokud se FPS serveru nepohnulo, úzkým místem nebyla AI a HC může pryč.

HC, jehož vlastní FPS zkolabovalo, je teď úzkým místem místo serveru: AI, kterou vlastní, reaguje stejně špatně jako dřív. To je okamžik, kdy rozdělit práci na dva HC, snížit počet AI nebo se víc opřít o dynamic simulation. Logy .rpt z HC drž vedle těch serverových; logy, které stojí za uchování vysvětluje jak dlouho a proč.

Řešení potíží#

HC se v lobby nikdy neobjeví. Jeho adresa není v headlessClients[], seznam modů nesedí, nebo míří na špatný port. Přečti si vlastní .rpt HC - píše, proč se připojení nezdařilo.

HC sedí na výběru slotu. Mise nemá hratelnou entitu headless clientu, nebo jsou všechny sloty HC už obsazené.

HC se připojí, ale nic nevlastní. Nic AI nepřenáší. Přidej smyčku setGroupOwner, zapni headless komponentu ACE, nebo spawnuj na HC.

AI na HC stojí. Waypointy nebo skripty chování běží na serveru a už se neuplatní. Přesuň skript k vlastníkovi.

Serverové sledování zabití se rozbilo. Event handlery jsou lokální. Použij MPKilled nebo přidej handler na HC.

Všechno se zhoršilo. HC přitlačil server k limitu paměti, nebo sdílí příděl CPU, který byl už plný. Zkontroluj oba grafy a případně ho odeber.

HC se odpojí a nepřátelé zmizí. Když HC odejde, jeho AI se vrátí serveru. Pokud server pak zápasí, je to očekávané; pokud se AI smaže, nějaký skript uklízí skupiny HC při odpojení.

FAQ#

Potřebuju pro headless client samostatnou licenci Arma 3?

Ne. Headless client je bezplatná binárka dedikovaného serveru spuštěná v klientském režimu, stahuje se stejně jako server. Potřebuje stejné mody jako server a nic dalšího.

Kolik headless clientů mám provozovat?

Jeden, dokud nezměříš, že je přetížený. Druhý přidej, až když FPS prvního HC pod zátěží klesne a je k dispozici CPU pro další proces. Většina skupin nikdy nepotřebuje víc než jeden.

Opraví headless client desync?

Jen pokud je desync způsobený tím, že serveru kvůli AI dochází čas snímku. Síťový desync z připojení hráče nebo server s nedostatkem paměti to neovlivní.

Musí být mise napsaná pro headless client?

Potřebuje hratelný slot headless clientu. Přesun AI může obstarat mise, headless komponenta ACE nebo jiný skript, takže i mise bez kódu pro HC může profitovat, když přidáš slot a automatický balancer.

Může headless client běžet na jiném stroji?

Ano. Dej adresu toho stroje do headlessClients[] a localClient[], otevři cestu mezi nimi a počítej s trochou latence navíc u aktualizací AI. Na stejném stroji je to jednodušší a obvykle rychlejší.

Co se stane s AI, když headless client spadne?

Jeho skupiny se automaticky vrátí serveru. Mise pokračuje a server nese zátěž, kterou nesl předtím. Dobrá mise nebo balancer je přenese znovu, až se HC znovu připojí.


Komentáře

Zcela anonymně: žádný účet, žádný e-mail, žádné cookie. Ukládáme jen jméno, které napíšeš, text a čas - nic dalšího. Počet odkazů je omezený a značkování se nevykresluje.

0/2000