Prestanda är en nyckelkomponent för att upprätthålla VALORANTs konkurrensmässiga integritet, och vårt team är det som ansvarar för att övervaka, underhålla och förbättra både server- och klientprestanda.

Vi är glada över att kunna ge en uppdatering om en funktion som har varit under utveckling i flera månader: Global Invalidation. Vi kommer snart att gå in på detaljerna om funktionen, men låt oss först ägna lite tid åt att titta på hur den här funktionen har påverkat klientprestanda sedan patch 4.03.

Spoiler alert: det är ganska häftigt.Aaron Cheney, en mjukvaruingenjör i VALORANTs Performance-team


Global Invalidation har gett betydande förbättringar för en stor del av vår spelarbas. Faktum är att det är den enskilt största prestandavinsten för spelare sedan lanseringen.

Även om dessa diagram är spännande – och vi är nöjda med resultaten – är det viktigt att förstå exakt vad du tittar på. Vi arbetar med stora, komplexa datamängder; Att organisera, filtrera och kontrollera data hjälper oss att förstå spelarupplevelsen. Här är vad du behöver tänka på för att förstå hela bilden:

Diagrammet plottar “patch” vs. “genomsnittlig FPS”; högre siffror är bättre.
Varje rad representerar en gemensam hårdvarukonfiguration (CPU+GPU-parning) från vår spelarbas. När vi analyserar prestationsdata anser vi denna sammankoppling vara den viktigaste prediktorn för förväntad prestanda. Maskiner med samma CPU+GPU-parning är aggregerade i dessa diagram.
Datasamplen är tagna från två köer: Unrated och Competitive. Eftersom dessa är de mest populära spellägena i VALORANT lägger vi ner mycket ansträngning på att förstå och förbättra prestanda inom dessa områden.
Vi har uteslutit spel som inte har exakt 10 spelare. Detta säkerställer att outliers inte snedvrider data (spel med färre spelare presterar bättre).


SAMMANFATTNING AV GLOBAL INVALIDATION

Global Invalidation ger upp till 15 % vinster för CPU-bundna klienter (vanligtvis medelstora till höga specifikationer). Att inse dessa vinster var en insats som sträckte sig över flera team och som tog många månader att slutföra. Vår process för att identifiera områden i spelet som är mogna för optimering gav resultat, och att hantera risker längs vägen bidrog till att säkerställa en stabil upplevelse för spelarna.


Vem får nytta av detta

Baserat på våra livemätningar har Global Invalidation levererat upp till 15 % förbättring för klientkonfigurationer som är CPU-bundna (vanligtvis medelstora till höga specifikationer).

Även om den uppåtgående trenden är märkbar totalt sett, representerar den inte spelandet från ögonblick till ögonblick. Dessutom garanterar det inte att varje maskin med matchande hårdvara kommer att se identiska resultat.

Detta innebär att baslinjeprestandan för VALORANT på CPU-bundna maskiner i allmänhet har ökat, men exakt hur din specifika maskin kommer att prestera beror på ett antal andra faktorer som är unika för dig.


FÖRSTÅ GLOBAL INVALIDATION

Innan vi kan ge en ordentlig översikt över Global Invalidation måste vi först förklara lite om UI-element i Unreal Engine.

WIDGETS OCH TRÄDSTRUKTURER

UI-element (även kända som widgets) skapas från mindre byggblock med hjälp av en trädstruktur. Trädstrukturen är analog med filsystemet på din dator. En widget kan ha hur många barn som helst (precis som en mapp kan ha hur många filer som helst).

Dessa byggstenar kan kombineras för att skapa komplexa widgets. Vår ammunitionsdisk består till exempel av många delar och trädet ser ut ungefär som följande:

Om man sätter ihop allt ser ammunitionsräknarens byggstenar ut så här:

(De röda konturerna ovan är överdrivna för tydlighetens skull. I praktiken skulle många av konturerna överlappa varandra.)

Närhelst en eller flera widgetar ändras inom trädstrukturen kan det påverka flera andra widgetar. Till exempel, om en widget flyttar till en ny position på skärmen, måste alla widgetar nedanför också räkna om sin position. Dessa ändringar hanteras av ett system som heter “Invalidering”, som vi kommer att prata om i nästa avsnitt.

INVALIDATION

Ogiltigförklaring är den mekanism som Unreal Engine använder för att indikera när en viss widget har ändrats och behöver uppdateras.

En widget måste ogiltigförklaras av en mängd olika anledningar: animering, färg, opacitet, storlek, ordning, text, bilder och många andra egenskaper kan ändras som svar på något som händer i spelet. När dessa ändringar händer med en widget är den “Ogiltig”, vilket signalerar att den behöver uppdateras.

För att komplicera den här processen lite mer kan en widget ha flera typer av ogiltigförklaring. Några typer inkluderar:

  • Layout – När storleken på en widget ändras (mycket dyrt).
  • Paint – När utseendet på widgeten har ändrats men inte har ändrat storlek.
  • Child Order – När ordningen på widgets har ändrats i trädet (antyder också layout, och är därför dyrt).
  • Visibility – När synligheten för en widget har ändrats, antingen blir den osynlig eller synlig (antyder också layout, och är därför dyr).

Dessa typer av ogiltigförklaring används för att indikera vilken typ av operationer som måste utföras för att rita den korrekt.

Det blir ännu mer komplicerat när en widget är beroende av en annan widget. Widgetar är organiserade i hierarkier och deras layout är beroende av ett antal faktorer. Att ogiltigförklara en enstaka widget kan kräva att ett antal relaterade widgetar ogiltigförklaras för att kunna ritas korrekt. Till exempel, om flera widgetar är organiserade i en vertikal layout (t.ex. den sociala panelen med din vänlista) och ordningen på widgets ändras (t.ex. en vän kommer online), måste alla widgetar i den vertikala layouten uppdateras.

Det finns flera mål med ett system som detta:

  • Ogiltigförklara så få widgetar som möjligt. Detta minskar antalet widgetar som måste uppdateras för att kunna rita ordentligt.
  • Ogiltigförklara endast en widget när det behövs. Att felaktigt ogiltigförklara en widget slösar bort värdefulla CPU-cykler.
  • När en widget inte är ogiltig, cacha resultatet för att snabbt rita det varje bildruta. Om inget ändras kan CPU-cykler sparas.

Det räcker med en titt under huven för att förstå hur widgets uppdateras och vilka typer av saker som kan orsaka ogiltigförklaring. Därefter ska vi titta på hur utvecklare omsätter detta i praktiken.

INVALIDATION BOXES

Unreal Engine tillhandahåller en komponent – en så kallad Invalidation Box – för att gruppera flera widgets tillsammans. Alla widgetar som finns i en enda ogiltigförklaringsruta förhindras från att bli förbevisade, förkryssade eller målade. Istället cachelagras resultatet i en vertexbuffert.

Närhelst en av widgetarna i invalideringsrutan ogiltigförklaras, kasseras cachad data och widgeten uppdateras och målas igen. Även om det kan vara dyrt att uppdatera cachen för en enskild bildruta, är det amorterade resultatet mycket bättre i det långa loppet.

Invalidation Boxes är en viktig del av att göra VALORANTs UI prestanda, särskilt när vi arbetade mot lansering. Men de är inte helt gratis:

  • Utvecklare måste förstå vilka widgetar som är bra kandidater för att gruppera tillsammans med en Invalidation Box. Alla widgetar som uppdateras regelbundet är inte lämpade för detta.
  • Att placera widgets i en invalideringsbox kräver manuellt arbete från utvecklarens sida. Det är inte möjligt att göra för varje widget i spelet, och därför måste utvecklare också förstå vilka widgetar som är värda att lägga i en invalideringsbox.

För att läsa mer om Invalidation Boxes, kolla in Epics dokumentation.

Nu har vi tillräckligt med sammanhang för att prata om Global Invalidation!


ENTER GLOBAL INVALIDATION

Vid det här laget kanske du tänker för dig själv, “Varför inte bara lägga in varje UI-element i en global invalidation Box?” Tja, det är precis vad Global Invalidation gör (mer eller mindre).

Global Invalidation syftar till att avsevärt förbättra användargränssnittets prestanda över hela spelet samtidigt som det minskar manuellt arbete som krävs av utvecklare för att placera widgets i individuella Invalidation Boxes. Det är den bästa av alla världar.

Men från och med UE4.25 (versionen av Unreal Engine som VALORANT använder), stöds inte Global Invalidation universellt för alla widgettyper. Senare versioner av Unreal Engine har gjort förbättringar, men VALORANT kunde inte dra fördel av det direkt. Dessutom hade vi ingen stor förståelse för hur mycket snabbare global invalidering skulle göra VALORANT.

Här började vårt arbete.


VARFÖR GÖRA DET HÄR ARBETE?

I slutet av juli 2021 beslutade teamet att ta Global Invalidation för en testkörning under ett internt speltest. Mindre ändringar gjordes för att fixa några buggar så att speltestet kunde slutföras. Men vi visste att buggar skulle dyka upp under speltestet… och vi hittade verkligen buggar.

I slutet av speltestet hade vi samlat in cirka 20 buggar – och det var bara de uppenbara. Det var troligen mer subtilt, lömska buggar väntade på att hittas, för att inte tala om flera kantfall som inte hade testats specifikt.

Men… gav Global Invalidation prestandavinster? Det gjorde det absolut.

Genom att analysera data som genererades från det enda speltestet fastställdes det att användargränssnittet var ~35 % snabbare. (Obs: UI är bara en del av kostnaden för en enskild bildruta.)

Men vi hade fortfarande många öppna frågor:

  • Hur mycket tid behövs för att fixa alla buggar?
  • Vilket/vilka team ska ansvara för arbetet?
  • Har detta prioritet framför annat planerat arbete? För att möta regelbundna innehållssläpp är våra scheman ofta fastställda månader i förväg och nya arbeten – även något så spännande som detta – är svårt att passa in i schemat.
  • Skulle åtgärda felen ta bort prestandavinsterna? Att fixa alla buggar skulle kräva många kodändringar, som var och en har potential att göra att användargränssnittet blir dyrare.
  • När ska vi göra detta arbete? Att veta att Global Invalidation aktivt utvecklades i senare Unreal Engine-versioner innebar att vi behövde överväga vår tidslinje för att integrera ändringar från Epic.

Till slut bestämde vi oss för att arbetet var värt besväret av ett par anledningar.


UNREAL ENGINE INTEGRATIONER OCH TIMINGÖVERVÄGANDEN

Även om Unreal Engine 4.26 och 4.27 har gjort betydande framsteg med global invalidering, arbetar VALORANT med ett försenat integrationsschema. Anledningen till att vi inte jobbar på “bleeding edge” är för att hantera risker och säkerställa stabilitet för våra spelare.

Eftersom vårt schema innebar att vi skulle stanna på Unreal Engine 4.25 i många månader till, innebar det att spelare inte skulle kunna dra nytta av dessa prestandavinster på över ett år. Det passade inte bra hos oss.

För mer information om hur VALORANT tänker på Unreal Engine-uppgraderingar, kolla in den här Twitter-tråden från VALORANTs tekniska ledare, Marcus Reid.

KÄNDA PRESTANDA VINSTER

Global Invalidation representerade något alldeles unikt när det gäller prestationsarbete: uppmätt värde. Vi mätte de potentiella vinsterna under ett internt speltest, och vägen till att leverera det värdet var (för det mesta) tydlig.

Prestationsarbete är svårt. Det är ett spel om tum, inte miles; inkrementella förändringar bidrar generellt till att förbättra prestandan över tid, och det är sällsynt att hitta en enda förändring som kan ge tvåsiffriga vinster. Detta var en för saftig optimering för att lämna på bordet.

Även efter att ha tagit hänsyn till minskade vinster på grund av buggfixar, var Global Invalidation den bästa chansen för oss att leverera betydande vinster för spelare inom en rimlig tid.


HUR VI UTFÖRDE DETTA ARBETE?

Även om de första experimenten kring Global Invalidation började i slutet av juli 2021, började allvarliga ansträngningar för att stabilisera funktionen inte förrän i slutet av september 2021.

SELECTIVT INTEGRERA EPISKA FÖRÄNDRINGAR

Att fullständigt integrera Unreal Engine 4.26 och 4.27 var borta från bordet, men eftersom vi visste att Epic aktivt hade arbetat med Global Invalidation, bestämde vi oss för att gräva igenom tusentals ändringar och identifiera vilka förändringar som sannolikt skulle komma oss närmare en stabil, fullt fungerande Global Annullering.

Att delvis integrera förändringar var en utmanande uppgift. Det var viktigt att modifiera så få kärnmotorfunktioner som möjligt för att bibehålla stabiliteten och samtidigt dra in de rätta ändringarna från Epic. Allt detta arbete gjordes i en separat gren från den huvudsakliga VALORANT-grenen för att förhindra att andra utvecklare påverkades.

Efter att selektivt integrera Epics ändringar i vår motor, tillbringade vi flera veckor till att fixa så många buggar som möjligt samtidigt som vi förberedde oss för att introducera Global Invalidation i VALORANTs huvudgren. Längs vägen skapades en växel för att låta oss snabbt aktivera och inaktivera funktionen (om något katastrofalt skulle inträffa).

Med många buggar fixade, och med många av Epics ändringar från 4.26 och 4.27, slog vi ihop från vår isolerade gren tillbaka till huvudgrenen.

HITTA GEMENSAMMA BUGGAR

Även om många av buggarna med Global Invalidation manifesterade sig på olika sätt, kunde grundorsaken ofta spåras tillbaka till ett enda problem. Dessa var de mest värdefulla buggarna att fixa, eftersom det kunde eliminera flera problem med en enda ändring. En förändring, till exempel, fixade 10+ buggar som var utspridda över hela spelet. Noggrann analys av rotproblemet ledde till robusta lösningar som förbättrade tillförlitligheten och stabiliteten för Global Invalidation.

IDENTIFIERA BUGGAR, FIXA BUGGAR, PLAYTEST, SPOLA OCH REPETA

De följande veckorna och månaderna innebar en regelbunden cykel för att aktivera Global Invalidation före ett speltest, identifiera en serie buggar, inaktivera Global Invalidation efter speltestet och fixa dessa buggar.

Färre buggar rapporterades med varje iteration av loopen. Vi fortsatte att göra detta tills den stadiga strömmen av insekter förvandlades till ett långsamt dropp och till slut slutade.

I slutet av november 2021 var alla stora problem lösta och Global Invalidation var i stort sett stabil.

ANMÄRKNINGSVÄRDA BUGGAR

  • Astra kraschar spelet – Vid ett tillfälle möttes alla Astra-spelare med en krasch när de laddades in i spelet. Denna bugg åtgärdades efter att ha integrerat ändringar från Epic.
  • Multipelt arv kraschar – Multipelt arv i C++ är ett knepigt ämne. Utan att komma för långt in i ogräset, utfördes inte ordningen på förstörare i en viss klass i rätt ordning, vilket orsakade en krasch. Att helt enkelt byta 2 rader kod för att ändra arvsordningen löste problemet. För att läsa mer om multipelt arv, kolla in den här sidan.
  • Oändligt chattljud – I menyerna spelar chattfältet ett ljud när du håller muspekaren över det. Till allas förtret fick en bugg att ljudet spelades upp flera gånger i sekunden. Att fixa det här felet innebar att man förstår tidpunkten för hur widgetar tar emot mushändelser flera gånger per bildruta.

TESTMETODER

En del av Global Invalidation som gjorde oss särskilt försiktiga (och därför noggranna med våra tester) är att det påverkar alla aspekter av spelet. Bokstavligen.

Din vänlista? Absolut. Knappen du trycker på för att köa? Det också. Inställningsmenyn? Det kan du ge dig på. Min headshot-procent? Väl…

Poängen är att UI-element finns i hela spelet, och de förmedlar ofta viktig information till spelarna. Att bryta ens ett av dessa UI-element var oacceptabelt.

För det ändamålet skapade vår QA-avdelning en testplan med flera strategier för att bygga upp förtroendet för att Global Invalidation fungerade som det var tänkt.

VERTICAL SLICE TESTNING

En “vertical slice” av VALORANT representerar den huvudsakliga vägen spelarna i allmänhet tar, från att starta klienten, till att stå i kö för en match, till att spela ett helt spel, till att interagera med skärmen i slutet av spelet. Genom att fokusera på de kritiska delarna av spelet kunde QA snabbt testa de mest använda delarna av spelet och identifiera problem tidigt.

DESTRUKTIV TEST

Där testning av vertical slice slutar tar destruktiv testning vid. Denna typ av testning är avsedd att identifiera icke-nominella problem, ofta genom att modifiera externa faktorer (som nätverksping, bildhastighet, alt-tabbning, etc.). Beväpnad med en uppsättning interna verktyg tillbringade QA flera veckor med att göra destruktiva tester.

EDGE CASE TEST

Många delar av VALORANT upplevs bara av en liten andel av spelarbasen. Vissa delar av spelet upplevs bara en gång (t.ex. New Player Experience). Bara för att de delarna av spelet är mindre genomkorsade gör det dem inte mindre viktiga. Att identifiera och testa alla våra edge-fall hjälpte till att fånga dolda fel.

PBE (PUBLIC BETA ENVIRONMENT) TESTNING

PBE var en viktig milstolpe för Global Invalidation.

  • Det var första gången utomstående spelare kunde testa funktionen. Detta innebar att Global Invalidation kunde testas under “verkliga förhållanden”.
  • PBE representerar en mängd olika hårdvaruspecifikationer. PBE täcker avsiktligt intervallet från låga till höga specifikationer, och testning med ett så stort utbud av spelarenheter hjälpte oss att bygga upp förtroende för hur väl Global Invalidation skulle prestera över den bredare spelarbasen.

Efter att ha testat på PBE under helgen 22 januari 2022 – 23 januari 2022, hade vi förtroende för att Global Invalidation inte stör integriteten och att prestandavinster var i linje med våra förutsägelser.


LANSERA GLOBAL INVALIDERING

Efter att ha lanserat Global Invalidation med Patch 4.03 övervakade vi noga spelarrapporter för buggar. Vi höll också ett öga på resultatdata för att bekräfta att våra uppskattningar stämmer överens med resultaten. I slutändan blev Global Invalidation en stor framgång för spelare, och vi hoppas att du njuter av den förbättrade bildtiden.

Nu när Global Invalidation är ute i världen, går Performance-teamet tillbaka till arbetet med att leverera ännu fler optimeringar.

Hela artikeln om Global Invalidation inklusive resultaten finns på PlayVALORANT

Taggar:

Kommentera

Denna webbplats använder Akismet för att minska skräppost. Lär dig hur din kommentardata bearbetas.

Spel Hubben
error:
%d bloggare gillar detta: