Hvordan statisk kodeanalyse hjelper i GameDev-industrien

( 4. des 2020)

Spillindustrien utvikler seg kontinuerlig og utvikler seg raskere enn en fartkule. Sammen med veksten i bransjen øker kompleksiteten i utviklingen også: kodebasen blir større og antall feil vokser også. Derfor må moderne spillprosjekter være spesielt oppmerksomme på kodekvaliteten. I dag vil vi dekke en av måtene å gjøre koden din mer anstendig, som er statisk analyse, samt hvordan PVS-Studio i praksis hjelper til med å utvikle spillprosjektet i forskjellige størrelser.

“Det viktigste jeg har gjort som programmerer de siste årene er å aggressivt forfølge statisk kodeanalyse. Enda mer verdifullt enn de hundrevis av alvorlige feilene jeg har forhindret med det, er tankegangsendringen om måten jeg ser på programvarens pålitelighet og kodekvalitet.

Vi har jobbet med store spillutviklere i mange år, og i løpet av denne tiden klarte vi å gjøre mange interessante og nyttige ting for spillindustrien. Det er ikke mye av en overraskelse, gitt listen over våre kunder fra spillindustrien. Vi støtter aktivt våre kunder: å integrere PVS-Studio i sin egen utviklingsprosess, fikse feil funnet av analysatoren, og vi lager til og med spesielle tilpassede funksjoner.

I tillegg gjør vi mye uavhengig utvikling av analysatoren i GameDev-retningen, samt fremme PVS-Studio, og fortelle folk om interessante feil som den har funnet i forskjellige videospill.

Visst, vi har noen interessante historier å fortelle. Denne artikkelen vil dekke flere slike tilfeller.

PVS-Studio and Unity

En av måtene vi markedsfører produktet på er å skrive artikler om å sjekke åpne prosjekter. Alle drar nytte av disse artiklene: en leser får sjansen til å sjekke ut noen uvanlige feil i et kjent prosjekt og lære noe nytt. Når det gjelder PVS-Studio-teamet, får vi muligheten til å vise arbeidet som er gjort med ekte kode, slik at prosjektutviklere kan lære om feil og fikse dem på forhånd.

Vår første store bekjentskap med Unity fant sted i 2016, da utviklerne av denne spillmotoren åpnet kildekoden til flere komponenter, biblioteker og demoer i deres offisielle lager. Ikke rart, vi kunne ikke passere en slik forlokkende sak og ønsket å skrive en artikkel om å sjekke den posterte koden.

Så fant vi ut at Unity3D-koden (på den tiden ble motoren kalt slik) var av veldig høy kvalitet. Men fortsatt klarte vi å finne ganske mange alvorlige feil i den. Det var nok av dem til å skrive en artikkel .

To år senere skjedde en annen ting – Enhetsutviklere åpnet koden til motoren og redaktøren selv. Og akkurat som forrige gang, kunne vi ikke legge merke til det og sjekket kildekoden til motoren. Og det var ikke for ingenting – vi fant også en gjeng med fengende mangler.

Samtidig går intensjonene våre langt utover bare å skrive artikler. Vi fortsetter å jobbe med PVS-Studio, og GameDev er et av de viktigste områdene for vår utvikling. Derfor vil vi at Unity-spillutviklere skal kunne få en best mulig analyse av prosjektene sine.

Et av trinnene for å forbedre kvaliteten på Unity-prosjektanalysen var å skrive kommentarer for metoder definert i Unity Scripting API .

Metodekommentarer er en spesiell mekanisme som brukes i PVS-Studio. Det tillater en bruker å gi analysatoren all nødvendig informasjon om en bestemt metode. Den er skrevet i spesialkode av analysatorutviklerne selv (dvs. av oss).

Denne informasjonen kan være av helt forskjellige slag. For eksempel: hvordan metoden kan påvirke parametrene som sendes til den, om den kan tildele minne, og om den returnerer en verdi som må håndteres. Dermed tillater annotering analysatoren å forstå metodikkenes logikk bedre, slik at den kan oppdage nye og mer komplekse feil.

Vi har allerede skrevet et stort antall forskjellige merknader (for eksempel for metoder fra systemet namespace), og vi var glade for å legge til metodekommentarer fra Unity Scripting API til dem.

Vi begynte å utvide listen over merknader med en vurdering. Hvor mange metoder er det totalt? Hvilke skal merkes først? Det var mange metoder totalt, så vi bestemte oss for å starte med å kommentere de mest brukte.

Slik lette vi etter populære metoder: først samlet vi en gruppe prosjekter fra GitHub som bruker Unity-funksjoner, og deretter brukte vi et selvskrevet verktøy (basert på Roslyn) for å beregne samtaler til metodene vi var interessert i. Som et resultat fikk vi en liste over klasser hvis metoder oftest ble brukt:

  • UnityEngine.Vector3
  • UnityEngine.Mathf
  • UnityEngine.Debug
  • UnityEngine.GameObject
  • UnityEngine.Material
  • UnityEditor.EditorGUILayout
  • UnityEngine.Component
  • UnityEngine.Object
  • UnityEngine.GUILayout
  • UnityEngine.Quaternion

Deretter forble det å kommentere metodene til disse klassene. Vi opprettet et testprosjekt og gravde oss i dokumentasjonen for å få så mye informasjon om disse metodene som mulig. For eksempel prøvde vi å sende null som forskjellige argumenter for å se hvordan programmet ville oppføre seg.

Under slike kontroller oppdaget vi noen interessante, udokumenterte opplysninger fra tid til annen. Vi fant til og med et par bemerkelsesverdige feil i motoren. For eksempel når vi kjører følgende kode:

MeshRenderer renderer = cube.GetComponent();
Material m = renderer.material;
List<int> outNames = null;
m.GetTexturePropertyNameIDs(outNames);

selve Unity-editoren krasjer (i det minste i versjon 2019.3.10f1). Selvfølgelig er det lite sannsynlig at noen vil skrive en slik kode. Det er fortsatt nysgjerrig at Unity-redaktøren kan krasje ved å kjøre et slikt skript.

Så vi hadde skrevet kommentarene. Etter å ha kjørt analysen, fant vi umiddelbart nye utløsere. For eksempel oppdaget analysatoren en merkelig samtale til GetComponent -metoden:

void OnEnable()
{
GameObject uiManager = GameObject.Find("UIRoot"); if (uiManager)
{
uiManager.GetComponent();
}
}

Analysator advarsel: V3010 Returverdien for funksjonen GetComponent kreves for å bli brukt. – ADDISIONAL IN CURRENT UIEditorWindow.cs 22

Metoden GetComponent innebærer retur av en spesifikk verdi selv på grunn til navnet sitt. Det er logisk å anta at denne verdien skal brukes på en eller annen måte. Nå takket være den nye kommentaren, vet analysatoren at et slikt «uten tilsyn» til denne metoden kan indikere en logisk feil og advarer om det.

Dette er ikke den eneste advarselen som dukket opp i settet til vår test prosjekter etter å ha lagt til nye kommentarer. Jeg vil ikke sitere resten, for ikke å gjøre denne artikkelen for stor. Det viktigste er at nå kan utviklingen av Unity-prosjekter ved hjelp av PVS-Studio tillate deg å skrive mye tryggere og renere kode uten feil.

Hvis du ønsker å lese mer om vårt arbeid med kommentarer for Unity-metoder, her er artikkelen: Hvordan PVS-Studio-analysatoren begynte å finne enda flere feil i Unity-prosjekter .

Unreal Engine 4

Når, tilbake i 2014, utviklerne av Unreal Motor 4 åpnet kildekoden til motoren, vi klarte rett og slett ikke å komme forbi det prosjektet og skrev også en artikkel om det. Motorutviklerne likte artikkelen og fikset feilene vi fant. Men dette var ikke nok for oss, og vi bestemte oss for å prøve å selge lisensen for analysatoren vår til Epic Games.

Epic Games var interessert i å forbedre motoren sin med PVS-Studio, så vi ble enige om følgende : vi fikser Unreal Engine-koden på egenhånd slik at analysatoren ikke gir noen advarsler, og gutta fra Epic Games kjøper lisensen vår og belønner oss i tillegg for utført arbeid.

Hvorfor alle advarsler måtte være fikset? Faktum er at man kan få maksimalt utbytte av statisk analyse ved å rette feil rett når de dukker opp . Når du sjekker prosjektet ditt for første gang, får du vanligvis flere hundre (og noen ganger tusenvis) advarsler. Blant alle disse analysatorutløserne er det lett å miste advarsler som er utstedt for nyskrevet kode.

Ved første øyekast kan dette problemet løses ganske enkelt: du trenger bare å sette deg ned og gå gjennom hele rapporten , gradvis korrigere feil. Men selv om denne metoden er mer intuitiv, kan det ta tid. Det er mye mer praktisk og raskere å bruke undertrykkelsesfiler.

Undertrykk filer er en spesialfunksjon i PVS-Studio som lar deg skjule analysatoradvarsler i en spesiell fil. Skjulte advarsler vil imidlertid ikke vises i påfølgende logger: du kan se dem separat.

Etter å ha hatt mange utløsere etter den første kontrollen, kan du legge til alle oppdagede advarsler i undertrykkingsfilen med et par klikk, og du vil få en ren logg uten en eneste oppføring etter neste kontroll.

Nå som de gamle advarslene ikke lenger er inkludert i loggen, kan du enkelt oppdage en ny advarsel umiddelbart når den vises. Her er rekkefølgen av handlinger: skriv koden -> sjekk den med analysatoren -> se en ny advarsel -> fikse feilen. Slik får du mest mulig ut av å bruke analysatoren.

På samme tid, ikke glem advarslene i undertrykkingsfilen: de kan fortsatt inneholde advarsler om store feil og sårbarheter, akkurat som før. Derfor bør man gå tilbake til disse advarslene og redusere antallet deres med jevne mellomrom.

Ingen tvil, dette scenariet er praktisk, men utviklere fra Epic Games ønsket at koden deres skulle løses med en gang, så de passerte oppgave for oss.

Og vi fikk jobbe. Etter å ha sjekket prosjektkoden, fant vi 1821 advarsler om Level_1 og Level_2. Å analysere et så stort volum advarsler krever seriøst arbeid, og for å lette hele prosessen har vi satt opp kontinuerlig kodeanalyse på CI-serveren vår.

Det så slik ut: hver natt på serveren vår, den nåværende versjonen av Unreal Engine 4 ble bygget, og umiddelbart etter byggingen ble analysen automatisk startet. Når gutta våre kom på jobb om morgenen, hadde de alltid en fersk rapport fra analysatoren, som hjalp dem med å spore fremdriften med å eliminere advarsler. I tillegg tillot dette systemet oss å kontrollere byggestabiliteten når som helst ved å kjøre den manuelt på serveren.

Hele prosessen tok oss 17 virkedager. Tidsplanen for å fikse feil var som følger:

Faktisk gjenspeiler denne tidsplanen ikke vårt arbeid. Etter at vi hadde løst alle advarslene, ventet vi ytterligere to dager på at de skulle godta de siste trekkforespørslene våre. All denne tiden ble den siste versjonen av Unreal Engine sjekket automatisk, som igjen fortsatte å bli oppdatert med ny kode. Så, hva tror du skjedde? I løpet av de to dagene fant PVS-Studio fire flere feil i koden! En av dem var avgjørende og kunne potensielt føre til udefinert oppførsel.

Selvfølgelig løste vi også disse feilene. På det tidspunktet hadde utviklere av Unreal Engine bare én ting igjen: å sette opp automatisk analyse på sitt eget sted, akkurat som vi har gjort. Fra det øyeblikket begynte de å se advarsler hver dag som ble utstedt for koden de nettopp hadde skrevet. Dette tillot dem å fikse feil i koden akkurat da de dukket opp – i de tidligste stadiene av utviklingen .

Du kan lese mer om hvordan vi jobbet med Unreal Engine-koden i offisiell Unreal Engine-blogg eller på nettstedet vårt .

Analyse av forskjellige spill

Nevnte jeg at vi sjekke forskjellige åpne prosjekter og skrive artikler om dem? Så nå har vi mange lignende artikler om spillprosjekter! Vi skrev om spill som VVVVVV , Space Engineers , Kommando & Conque r, osu! og til og med (en veldig tidlig artikkel) Doom 3 . Vi har også samlet topp 10 av mest interessante programvarefeil fra videospillindustrien.

Så vi sjekket sannsynligvis det meste av kjente open source-motorer. I tillegg til Unity og Unreal Engine 4, prosjekter som Godot , Bullet , Amazon Lumberyard , Cry Engine V og mange andre har kommet under synet.

Den beste delen av alt dette er at mange av feilene vi beskrev senere ble løst av prosjektutviklerne selv. Det er hyggelig å føle at verktøyet du utvikler gir reelle, synlige og håndgripelige fordeler for verden.

Du kan se en liste over alle artiklene våre relatert til utvikling av videospill på en eller annen måte på spesiell side av bloggen vår.

Konklusjon

På dette punktet kommer artikkelen min til en slutt. Jeg ønsker deg ren og korrekt fungerende kode uten feil og feil!

Interessert i emnet statisk analyse? Vil du sjekke prosjektet ditt for feil? Prøv PVS-Studio .

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *