ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 168
Numărul 167 Numărul 166 Numărul 165 Numărul 164 Numărul 163 Numărul 162 Numărul 161 Numărul 160 Numărul 159 Numărul 158 Numărul 157 Numărul 156 Numărul 155 Numărul 154 Numărul 153 Numărul 152 Numărul 151 Numărul 150 Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 168
Abonamente

Dezvoltarea de jocuri și construirea de sisteme Enterprise

Bogdan Birseuan
Junior Full-Stack Developer @ msg systems Romania



PROGRAMARE

La 5 luni după ce am început primul meu joc, mi-am dat seama că va trebui să refac jumătate din el. Am învățat mai multe despre arhitectura software în acea perioadă decât în toți anii mei anteriori de facultate.

Mulți oameni din IT se joacă jocuri video ca hobby, și mulți dintre ei s-ar fi gândit chiar să folosească abilitățile lor de programare pentru a-și crea jocul visurilor lor, poate chiar să-l și lanseze public, dar puțini chiar fac asta. Chiar e atât de greu să faci un joc?

Să zicem că avem deja o idee pentru un joc video și am făcut deja un document de design al jocului. Ca să oferim câteva idei despre ce fel de joc vrem să facem, ne dorim ceva cu multe date, cu multiple sisteme care depind de date diferite și cu interacțiuni intensive între sisteme. În acest scop, jocurile din genurile roguelike/roguelite și Real-Time Strategy (RTS) sunt destul de bune, asta dacă nu vrem să gândim un joc și mecanici întregi de la zero. Dacă vrem mai multă "libertate", ar trebui să facem un Role-Playing Game (RPG). În final, putem crea orice vrem, în orice gen, în orice fel vrem, deoarece vom învăța din toate, dar acestea sunt cel mai probabil cele mai eficiente pentru scopul învățării.

SRSs & construirea fundației

Următorul pas este construirea de Software Requirements Specification (SRS). Prima întrebare la care ar trebui să răspundem este ce motor de joc vom folosi și de ce îl alegem. Deși acesta este un subiect foarte dezbătut, pentru scopul acestui articol, care este cel de învățare, sugerez Godot și GDScript. Unii ar putea să se gândească la Unity sau Unreal Engine 5 (UE5), pentru că sunt software-uri mai mature, dar exact asta le dezavantajează. Au atât de multe funcții încorporate încât sunt mai greu de navigat și, în loc să folosim timpul pentru dezvoltare și cercetare, îl petrecem căutând prin documentații scrise prost și învechite. Godot este mult mai modern, fiind un motor de jocuri gratuit și open-source (FOSS). Primește actualizări regulate și are o documentație bine scrisă, adusă la zi. Îmi place din prea multe motive ca să le listez aici, dar unul dintre principalele motive pentru care îl recomand este că are câteva funcționalități lipsă. Deoarece scopul principal al acestui articol este să învățăm, voi menționa că micile funcții lipsă ne dau ocazia să le creăm noi înșine, pentru proiect și nevoile lui, ca să înțelegem cu adevărat cum funcționează în culise. Pentru sisteme mai complexe, asta ne obligă să fim creativi cu soluțiile noastre.

Am putea crede că avem suficientă experiență pentru a nu fi deranjați să scriem un SRS sau să facem un document detaliat de dezvoltare a jocului și, în funcție de complexitatea și noutatea jocului pe care îl facem, această presupunere ar putea fi corectă. Chiar și așa, fără experiență anterioară în realizarea jocurilor, este foarte probabil să cădem în unele capcane comune. Cea mai comună capcană este să implementăm un joc ca pe un software normal. Spre deosebire de software-ul normal, la un moment dat, ne vom dori să schimbăm aproape fiecare lucru pe care l-am implementat, situațiile rare fiind cele în care vom spune "Acest lucru nu se va schimba niciodată pentru acest joc, va fi întotdeauna adevărat" sau "Voi folosi/voi avea nevoie întotdeauna de acest lucru așa / să se comporte astfel". Ca exemplu, am creat un sistem de hărți generate aleatoriu pentru genul roguelike menționat anterior. Multe roguelike-uri sunt construite pe matrice de dimensiune MxM, în loc de matrice de dimensiune MxN. Astfel de simplificări ne permit de obicei să generalizăm codul, dar dacă am decide mai târziu că vrem libertatea și caracterul aleatoriu al unui MxN, ar trebui să refactorizăm mult cod și să verificăm din nou multe dintre cazurile limită pe care un utilizator le-ar putea întâlni. Aceasta este natura generării aleatorii, ea încetinind procesul de dezvoltare. Și exact asta mi s-a întâmplat mie.

Când ne gândim la dezvoltarea de jocuri, majoritatea oamenilor se gândesc la gameplay și grafică, nu la meniuri, setări și framework-uri de testare, dar acestea sunt cu adevărat importante. Dacă vrem să creăm mai multe jocuri în viitor, este obligatoriu să stăpânim aceste sisteme. Fă-o o dată și fă-o bine! Crearea sistemului de setări mai întâi permite o personalizare ușoară pe termen lung, fără a pierde timp urmărind toate cazurile în care ar trebui să înlocuim codul ca să ne asigurăm că setările sunt citite corect. Aceasta este o capcană comună în care cad chiar și dezvoltatorii experimentați, deoarece există multe jocuri cu patch notes care includ setări care nu sunt citite corect. Pentru modelul de date al "setărilor", trebuie avut în vedere că acesta va trebui să ajungă într-un meniu, deci ne vom asigura că avem multiple modalități de a-l afișa, în funcție de tipul setării, de numărul de opțiuni etc. Deoarece am început să vorbim despre meniuri, stabilirea UI/UX-ului pentru joc va fi importantă și în etapele ulterioare, cum ar fi dezvoltarea unui Heads-Up Display (HUD) sau a altor sisteme de gameplay care au nevoie de un UI pentru interacțiune. Setarea timpurie a așteptărilor privind UI/UX asigură, de asemenea, o abordare consecventă pe parcursul dezvoltării. În cele din urmă, un framework de testare este o bună practică și, dacă nu vrem să petrecem timp căutând ceva creat de alții pe GitHub și să-l învățăm, trebuie să-l facem noi înșine. Indiferent dacă cineva vrea să creeze ceva nou fără să cerceteze subiectul înainte, sau să copieze framework-ul lor preferat de testare, toate abordările au avantajele lor.

Legarea și integrarea sistemelor între ele

Să definim ce presupun legarea și integrarea în contextul creării de sisteme:

Cineva ar putea crede că "singular" și "general" se contrazic, așa că haideți să discutăm un exemplu concret. Gândește-te la un generator de inamici. Are un scop foarte specific, dar dacă putem genera doar un singur tip de inamic, nu este un sistem grozav (sau general). Totuși, ar trebui să privim tot ce scriem prin acest tip de lentilă, fiind, totodată, conștienți că aproape fiecare regulă are excepțiile ei. Vor exista jocuri în care avem nevoie de ceva foarte specific, care probabil nu va mai fi folosit niciodată, iar identificare acestor excepții îți poate economisi mult timp. Trebuie să fim atenți să ne gândim la timpul și efortul necesare, respectiv dacă merită cu adevărat să creăm un sistem general, reutilizabil, în loc de unul specific proiectului. Modul în care a fost descris acest aspect, într-un videoclip intitulat "Best Code Architecture For Indie Games" în jurul minutului 3 (totuși, recomand să vizionați tot videoclipul, este grozav), creat de dezvoltatorul expert în jocuri Jonas Tyroller (@JonasTyroller pe YouTube), este că ar trebui ca 70% din cod să fie reutilizabil sub forma unui simplu folder de tip drop-in din jocuri anterioare, iar restul de 30% ar trebui să fie cod specific, de integrare. Iată o propunere ușor diferită: 60% ar trebui să fie sisteme reutilizabile, 10% ar trebui să fie sisteme noi și 30% integrare. Motivul pentru care este nevoie de 10% de sisteme noi este că, chiar și într-o fază mai târzie a dezvoltării jocului, ne va forța fie să examinăm codul și să găsim sisteme reutilizabile posibile, fie să venim cu idei noi pentru jocul la care lucrăm sau pentru unul nou.

Refactorizările majore sunt ceea ce sfaturile din acest articol încearcă să prevină, dar, chiar și așa, tot ne vom lovi de situații în care refactorizările sunt necesare. Aceasta este o oportunitate excelentă de a lua o pauză și de a analiza ce s-ar fi putut face pentru a evita o astfel de situație, și să vedem ce a funcționat și ce nu. Poate că exista o modalitate mai bună de a implementa ceva încă de la început.

Merită investigate următoarele concepte utile: delta time, interpolare, _physics_process versus _process in Godot (majoritatea motoarelor de jocuri au acest concept, doar cu nume diferite), shader-e. De asemenea, un alt video excelent pentru a face dezvoltarea de jocuri mai ușoară este "Gyms, Zoos, Museums: Your documentation should be in-game" de Robin-Yann Storm (@rystorm- pe YouTube).

Relevanța în era AI

În era LLM-urile și a AI-ului, tranziționăm de la a fi doar dezvoltatori de software care descifrează tichetele Jira, care înțeleg proiectul atât din punct de vedere business, cât și tehnic, care creează și refactorizează arhitecturi, care revizuiesc și scriu cod curat, la tot ce am discutat mai devreme, dar amplificat, scriind mai puțin cod manual. Momentan, LLM-urile nu sunt cele mai bune la arhitectura de proiect. Un motiv important pentru acest lucru este că, pentru multe proiecte, LLM-urile pur și simplu nu au suficient context și înțelegere a business-ului. Poate că lipsește documentația, poate că documentația este împrăștiată și/sau învechită. Să presupunem că reușim să actualizăm documentația în întregime și că o punem într-un singur loc la care AI-ul poate avea acces. Câteva întrebări de luat în considerare sunt: Cât de mult vrem cu adevărat să documentăm și cât vrem să dăm în final LLM-ului? Dacă i-am oferi doar date tehnice LLM-ului, acesta nu ar reuși să creeze arhitectură bună, deoarece nu ar ști nimic legat de companie sau de proiect, aspecte care să îi permit să ia decizii corecte. Dacă i-am oferi documentația create de noi, ne punem întrebarea dacă o corporație dorește ca întreaga sa documentație tehnică și de business să ajungă la o entitate terță. O alternativă este realizarea unui AI in-house, dar acest lucru este foarte scump, necesită întreținere permanentă și ar presupune să folosim modele open source. Sau am putea să ne cream modelele noastre, ceea ce este foarte scump și foarte riscant. Am putea considera că nu merită efortul, costurile și timpul investit.

Există 3 moduri principale de a folosi LLM-urile eficient, pentru a crea arhitectura unui proiect software:

  1. prompt simplu, de genul "Generează arhitectura proiectului pentru …(descrierea generală a proiectului și a business-ului)…" - potrivit ca punct de plecare pentru proiecte mai simple

  2. creează documentația de business și o descriere detaliată a proiectului, și apoi lasă agenții să parcurgă fișierele cu un prompt mai specific - potrivit și pentru proiecte de dimensiuni medii, dar există riscul de business menționat mai sus

  3. creează singur un SRS, complet cel puțin în proporție de 80-90%, dă-l unui LLM împreună cu o descriere generală a proiectului și a business-ului, iar apoi cere-i să ofere îmbunătățiri, să identifice descrierile vagi, inconsecvențele, dar și să pună întrebări despre orice informație neclară sau contradictorie - rezultate grozave indiferent de dimensiunea proiectului, dar demers mai lent ce trebuie gestionat de oameni cu experiență

Legat de punctul 3, dezvoltarea jocurilor ajută la acumularea de experiență și abilități. Când dezvoltăm jocuri, arhitectura este foarte importantă, pentru că gestionăm o mulțime de sisteme, obiecte, fișiere și resurse, iar performanța este o provocare permanentă. Prin urmare, dacă arhitectura e deficitară, acest lucru devine evident destul de repede. Va fi nevoie să refactorizăm, să reconsiderăm și să analizăm din nou ce nu a funcționat, dar și cum am fi putut să proiectăm soluția mai bine de la început, ceea ce oferă un antrenament grozav.

LANSAREA NUMĂRULUI 168

De la Vibe Coding la Production Engineering

Marți, 30 iunie, ora 18:00

Cognizant (Timișoara)

Facebook Meetup StreamEvent YouTube

NUMĂRUL 166 - AI for Programmers

Sponsori

  • Banca Transilvania
  • Betfair
  • MHP
  • .msg systems
  • P3 group
  • Cognizant Softvision
  • BMW TechWorks Romania

INTERVIURI