Gry video są programami i podlegają tym wszystkim, uniwersalnym zasadom tworzenia oprogramowania. Czytając literaturę o projektowaniu dobrego kodu, można ulec złudzeniu, że opisywane tam systemy komputerowe nijak się mają do gamedevu, ponieważ pojawiają się tam takie pojęcia jak: domeny, encje, modele i reguły biznesowe. Tak naprawdę, większość z tych bytów jest obecna w kodzie gry. Wiedza odnośnie tego, gdzie one się znajdują, pozwoli na zaprojektowanie dużo czystszej architektury.

Fundamenty czystej architektury

Prawdopodobnie, większość programistów jest zaznajomionych z koncepcją architektury warstwowej. Na przykład, w architekturze trójwarstwowej, aplikacja dzieli się na warstwy: prezentacji, logiki oraz danych. Każda z warstw składa się z właściwych sobie komponentów, czyli zbiorów klas lub funkcji, spełniających to samo zadanie (w uproszczeniu).

Powszechną zasadą, w projektowaniu architektury warstwowej, jest to, aby komponenty wyższego poziomu nie zależały od komponentów poziomów niższych.

Oznacza to, na przykład, że komponent odpowiedzialny za wyświetlanie danych, nie powinien zależeć od sposobu w jaki te dane pobieramy z serwera. Ale czym tak dokładnie jest zależność komponentów?

Zależności komponentów

Komponent zależy od innego komponentu, gdy używa jego elementów składowych (np. klas). Wtedy też, jest zależny od wprowadzonych w nim zmian i musi na nie reagować w swoim kodzie.

Klasa A używa klasy B. Komponent K1 zależy od K2.

Gdyby w powyższym przykładzie w klasie B zmieniła się nazwa metody którą używa klasa A - klasa ta musiałaby wówczas tę zmianę wprowadzić również u siebie.

Poziomy komponentów

Czym w takim razie są poziomy komponentów? Albo raczej powinniśmy zapytać - jak rozkładać komponenty na poziomy? Najlepszą odpowiedzią jest: tak aby reguły biznesowe znajdowały się na poziomie najwyższym, a infrastruktura - na najniższym.

Czym niżej - tym bliżej sprzętu. W kontekście silnika gry, do infrastruktury należy cały ten niskopoziomowy kod OpenGL'a odpowiedzialny za renderowanie obiektu trójwymiarowego. Na najwyższym poziomie, mógłby on zostać wywołany przez prostą funkcję renderGreenOrc() - stosując nazewnictwo w przyjętej domenie ;)

Czym wyżej - tym bliżej... no właśnie czego? Na pewno nie usera, bo przecież najbliżej gracza jest obraz wyrenderowany przez infrastrukurę. Czym wyżej, tym bliżej implementacji reguł biznesowych.

Czym są reguły biznesowe?

W ramach tego wpisu, pozwólmy sobie na pewne uproszczenie i analogię:

Jeżeli infrastrukturą byłaby kuchnia, razem ze wszystkimi narzędziami potrzebnymi do wykonania pysznego dania, to regułami biznesowymi byłby przepis jak to danie przygotować.

Taki przepis mógłby wyglądać następująco:
Schłodzone ciasto pieczemy ok. 15 minut w piekarniku rozgrzanym do temperatury 200°C. Po tym czasie wyjmujemy je z piekarnika i odstawiamy na 10 minut, by lekko przestygło.

Reguły biznesowe, są zatem regułami służącymi do realizacji odpowiedniego scenariusza pracy aplikacji (systemu). Gdy aplikacja mobilna, powinna po 10 dniach użytkowania nagrodzić użytkownika rabatem 30% na usługi z wewnętrznego sklepu - to te reguły wymyśliła osoba związana z biznesem, a nie programista. Programista umożliwił jedynie realizacje tych reguł.

Kod implementujący reguły biznesowe jest najczęściej zmienianym kodem w całej aplikacji. Reguły biznesowe w najlepszym przypadku nie powinny mieć żadnych zależności, dlatego też kod za nie odpowiedzialny znajduje się na szczycie hierarchii zależności komponentów (albo w centrum, gdy mówimy o architekturach warstwowych).

Reguły biznesowe w kodzie gry

Jeżeli mówimy o kodzie gry, to najczęściej modyfikowanym elementem jest sam skrypt gry. To skrypty implementują odpowiednik reguł biznesowych. Aby jeszcze bardziej zwiększyć jego podatność na zmiany, najczęściej jest on kompilowany niezależnie. Silniki gier takie jak Unity koncentrują się głównie na skryptach...

... a tak naprawdę na danych. Gra jest oprogramowaniem, generowanym przez dane wejściowe. Są to różnego rodzaju assety jak właśnie skrypty, ale również grafiki, pliki muzyczne itd. Podejście takie nosi nazwę Data-Driven Programming i wrócę do tego zagadnienia w innych wpisach.

Podsumowując:

W gamedevie, regułami biznesowymi są skrypty gry. To właśnie tam, tworzymy nasze zasady gry.

Podsumowanie

Być może dla większości osób czytającej ten wpis, to nic odkrywczego. Prosta sprawa, skrypty na górze, kod niskopoziomowy... nisko. Jednak mając już takie podwaliny możemy zacząć przenosić wiedzę z innego typu oprogramowania na nasze gamedevowe podwórko.

Kwestie, jak łączyć klasy i komponenty aby otrzymać czystą architekturę, spróbuję poruszyć w następnych wpisach. Dajcie znać, co o tym myślicie!