Optimalizace herní smyčky: Bitva o tempo snímků v prohlížeči
Obsah
Pro náhodného pozorovatele je hra jen sérií pohyblivých obrázků. Ale pro vývojáře je hra neúprosný, rychlý hodinový stroj. Pro retro emulátory a arkádové tituly v HTML5 jsou tyto hodiny neúprosné. Pokud se časování posune byť jen o několik milisekund, zvuk bude praskat, posouvání se bude “zasekávat” a hra nebude reagovat.
Na adrese Rec0m88, největší technickou překážkou není jen spuštění hry, ale i zvládnutí jejího ovládání. Rozložení snímků. JavaScript byl původně vytvořen pro posouvání textu a klikání na tlačítka, nikoliv pro zvládnutí přesnosti, která se pohybuje pod milisekundou, jakou vyžadují arkádové desky z 90. let. Zde se dozvíte, jak jsme zkrotili strojovnu prohlížeče, abychom dosáhli plynulého a konzistentního hraní při 60 FPS.
Duch V-Sync: Proč 60 Hz není vždy 60 Hz
Většina retro konzolí byla navržena pro televizory NTSC, které běží přesně na frekvenci. 59,94 Hz. Moderní počítačové monitory však obvykle běží na rovné frekvenci. 60 Hz, 120 Hz, nebo 144 Hz.
Pokud spustíte hru s frekvencí 59,94 Hz na 60Hz monitoru, narazíte na matematickou noční můru. Každých několik sekund monitor “vynechá” snímek, protože časování není v dokonalém souladu. To má za následek Mikrokoktání-ten otravný “skok”, který vidíte, když postava přechází po obrazovce.
Naše řešení: requestAnimationFrame a webové zvukové hodiny
Ve standardní webové aplikaci používají vývojáři setTimeout nebo setInterval ke spuštění kódu. Ty jsou pro hraní her příliš “volné”; prohlížeč je může zdržovat, kdykoli se mu zdá, že je zaneprázdněn.
Místo toho používá Rec0m88 systém dvou taktů:
- Vizuální synchronizace: Používáme
requestAnimationFrame(rAF). To prohlížeči říká: “Další snímek hry spusťte, až když je monitor připraven jej vykreslit.” Tím se eliminuje “trhání obrazovky” a video je plynulé jako hedvábí. - Synchronizace zvuku: Vzhledem k tomu, že obnovovací frekvence monitoru může kolísat, používáme hodnotu Kontextový čas rozhraní Web Audio API jako náš hlavní “metronom”. Hodiny Web Audio jsou nejpřesnější časovač v prohlížeči. Uzamčením naší herní smyčky WebAssembly (WASM) k vyrovnávací paměti zvuku zajistíme, že zvuk nikdy nedojde k desynchronizaci s akcí.
Zvukový praskot: Řešení problému “Buffer Underflow”
Hráli jste někdy webovou hru, při které při otevření nové karty zvuk praská nebo praská? To je Podtečení vyrovnávací paměti. Stává se to proto, že hlavní vlákno prohlížeče bylo příliš zaneprázdněno, aby “nakrmilo” zvukovou kartu dalšími několika milisekundami zvuku.
Abychom to v systému Rec0m88 vyřešili, přesunuli jsme zpracování zvuku do rozhraní Webový pracovník.
- Oddělená logika: Herní logika běží v jednom vlákně a mixování zvuku v jiném.
- Kruhové nárazníky: Udržujeme malou vyrovnávací paměť “look-ahead” se zvukovými vzorky. Pokud dojde k milisekundovému nárůstu výkonu procesoru, přehrávač si z této vyrovnávací paměti vezme zvukový vzorek, takže systém má čas se vzpamatovat, aniž by uživatel slyšel “prasknutí”.”
Správa zpoždění ve světě JIT
JavaScript je JIT (Just-In-Time) zkompilovaný jazyk. To znamená, že prohlížeč během hraní neustále “optimalizuje” kód. Někdy tyto optimalizace způsobí chvilkové “zaseknutí” (často nazývané “Jank”).
Abychom dosáhli dokonalého tempa snímků, minimalizujeme “Garbage Collection” (GC). GC je situace, kdy prohlížeč zastaví vše, aby vyčistil nepoužívanou paměť. Tomu se vyhneme tím, že:
- Sdružování objektů: Pro herní sprity a pakety P2P opakovaně používáme stejné paměťové bloky, místo abychom vytvářeli nové.
- Typová pole: Používáme
Uint8ArrayaFloat32Arraypro zpracování herních dat. Ta jsou uložena v pevně dané oblasti paměti, kterou prohlížeč nemusí tak často “čistit”, čímž se zachovává předvídatelnost herní smyčky.
Zpoždění mezi vstupem a fotonem
“Frame Pacing” není jen o tom, co vidíte, ale také o tom, co cítíte. Doba od stisknutí klávesy do okamžiku, kdy pixel změní barvu, se nazývá Zpoždění mezi vstupem a fotonem.
Pomocí Webové rozhraní HID API a Rozhraní API pro gamepad, obejdeme standardní frontu “Události klávesnice” prohlížeče. To nám umožňuje dotazovat se řadiče na začátku každého snímku, těsně před spuštěním jádra WASM. Tím je zajištěno, že váš vstup bude zpracován v hned další rám, který poskytuje “svižný” pocit, který arkádoví nadšenci vyžadují.
Proč se weby s vysokou hodnotou starají o načasování
Filtr Google “Obsah s nízkou hodnotou” se nedívá pouze na text, ale také na to. uživatelská zkušenost. Stránka, která poskytuje zpožděný, zadrhávající se emulátor, je “nekvalitní” nástroj. Tím, že dokumentujeme náš boj s tempem snímků a poskytujeme vysoce přesný engine, dokazujeme, že Rec0m88 je platforma profesionální kvality.
Stovky hodin jsme strávili laděním interakce mezi rozhraním Web Audio API, WebAssembly a grafickým procesorem, abychom zajistili, že při přehrávání klasických her na naší platformě to nejen funguje, ale i funguje.
Výzva Meta: Zkuste si při hraní některé z našich her otevřít “Monitor výkonu” v prohlížeči. Uvidíte rovnou, konzistentní čáru 60 FPS - důkaz naší architektury snímkového kmitočtu.
