Dlaczego MVC i TDD nie są częściej wykorzystywane w architekturze gier? [Zamknięte]

155

Przedmówię to, mówiąc, że nie szukałem dużej ilości źródeł gier ani nie budowałem zbyt wiele na sposób gier.

Ale przychodząc od próby zastosowania praktyk kodowania „korporacyjnego” w aplikacjach internetowych, poważne spojrzenie na kod źródłowy gry boli mnie: „Co to za logika widoku robi z logiką biznesową? To wymaga refaktoryzacji ... więc to, refaktor, refactorrr „

Martwi mnie to, gdy zaczynam projekt gry i nie jestem pewien, czy próba mvc / tdd procesu tworzenia będzie nam przeszkadzać czy nam pomagać, ponieważ nie widzę wielu przykładów gier, które używają tego lub duży nacisk na lepsze praktyki architektoniczne w społeczności.

Poniżej znajduje się fragment świetnego artykułu na temat prototypowania gier , chociaż wydawało mi się, że postawa, którą wielu twórców gier wydaje się stosować podczas pisania kodu produkcji:

Błąd nr 4: Budowanie systemu, a nie gry

... jeśli kiedykolwiek zdarzy ci się pracować nad czymś, co nie prowadzi bezpośrednio do przodu, zatrzymaj się właśnie tam. Jako programiści staramy się uogólniać nasz kod, nadawać mu elegancji i być w stanie poradzić sobie w każdej sytuacji. Stwierdzamy, że swędzenie jest wyjątkowo trudne, a nie zadrapanie, ale musimy się nauczyć. Wiele lat zajęło mi uświadomienie sobie, że nie chodzi o kod, ale o grę, którą ostatecznie dostarczasz.

Nie pisz eleganckiego systemu elementów gry, całkowicie pomiń edytor i podłącz kod w stan, unikaj opartego na danych, parsowania, szaleństwa XML i po prostu koduj to cholerstwo.

... Po prostu wyświetlaj rzeczy na ekranie tak szybko, jak to możliwe.

I nigdy, nigdy, nigdy nie używaj argumentu „jeśli poświęcimy trochę więcej czasu i zrobimy to we właściwy sposób, możemy ponownie wykorzystać go w grze”. ZAWSZE.

to dlatego, że gry są (głównie) zorientowane wizualnie, więc sensowne jest, aby kod był mocno ważony w widoku, więc wszelkie korzyści z przeniesienia rzeczy do modeli / kontrolerów są dość minimalne, więc po co się tym przejmować?

Słyszałem argument, że MVC wprowadza narzut wydajności, ale wydaje mi się, że jest to przedwczesna optymalizacja, i że należy zająć się ważniejszymi problemami z wydajnością, zanim będziesz się martwić o narzuty MVC (np. Renderowanie potoku, algorytmy AI, struktura danych przechodzenie itp.).

To samo dotyczy TDD. Nie często widzę gry wykorzystujące przypadki testowe, ale być może wynika to z powyższych problemów projektowych (widok mieszany / biznesowy) oraz z faktu, że trudno jest testować komponenty wizualne lub komponenty, które opierają się na wynikach probablistycznych (np. Działają w ramach symulacji fizycznych ).

Być może po prostu patrzę na zły kod źródłowy, ale dlaczego nie widzimy więcej takich „korporacyjnych” praktyk stosowanych w projektowaniu gier? Czy gry naprawdę różnią się tak bardzo pod względem wymagań, czy też jest to kwestia ludzi / kultury (tj. Twórcy gier pochodzą z innego pochodzenia, a tym samym mają inne nawyki kodowania)?

timoxley
źródło

Odpowiedzi:

137

Jak mówi cytat, wielu programistów popełnia błąd (próbuje) zbudować system, a nie grę. Zazwyczaj ten system wymyka się spod kontroli, dopóki nie stanie się tak skomplikowany, że teoretycznie może poradzić sobie ze wszystkim, ale w praktyce wszystko, co masz, to duży pakiet kodu. Lub częściej, zanim dojdziesz do etapu roboczego, jesteś tak zaplątany w kod, że nie działa, że ​​tracisz koncentrację (jeśli miałeś na początku) i motywację (ponieważ nic tak naprawdę nie działa).

Prototypy i iteracje zwykle działają znacznie lepiej. W końcu może wyjść z tego świetny projekt, ale częściej wychodzi z niego coś prostszego i bardziej wyrafinowanego. KISS i YAGNI przychodzą mi na myśl.

Osobiście uważam, że trzeba zachować równowagę. Jeśli istnieje podstawowa mechanika twojej gry, popracuj nad nią. Nadal musisz iterować, ale musisz to udoskonalić. Wskazówka: organizacja twojego kodu nie jest podstawową mechaniką twojej gry.

Przykład : Peggle , autor: PopCap Games. Podstawową mechaniką gry jest fizyka piłki. Udoskonalili to! Jestem pewien, że spędzili sporo czasu, upewniając się, że jest on absolutnie idealny, ponieważ to właśnie sprawia, że ​​gra. Ale jednocześnie mogę całkowicie wyobrazić sobie wczesny prototyp ich gry, który może po prostu przyciąga duszki do ekranu i wykonuje bardziej prymitywne wykrywanie kolizji i odbijanie się, aby sprawdzić, czy pomysł na grę jest fajny. Potem, gdy dowiedzieli się, że strzelanie do piłki i oglądanie jej odbicia może być naprawdę zabawne, udoskonalili odbijanie piłki. (to oczywiście tylko spekulacje)

Zależy to również od twoich wymagań technicznych, które powinieneś wcześnie sprecyzować (nie projekt gry, tylko wymagania techniczne). Platforma, na której działa twoja gra, nie powinna się zmienić, a jeśli powinno się to zmienić, musisz dokładnie wiedzieć, w jakim stopniu zamierzasz to zmienić, nie więcej i nie mniej. Zaprojektuj to. Jeśli tworzysz grę dla OpenGL i nie obchodzi Cię DirectX, to naprawdę nie przejmuj się nią. Oznacza to, że jeśli wygodniej jest, aby każda jednostka rysowała się sama i nie martwiła się o Fabryki i inne podobne wzorce projektowe, zrób to. Jest w porządku, ponieważ spełnia wymagania. Nie powinieneś go później zmieniać, niezależnie od tego, co sobie powiedziałeś. I naprawdę najgorszy scenariusz? Refaktoryzuj później., uzyskanie działającej gry na jednej platformie, nawet jeśli oznacza to, że nie może ona jednocześnie i automatycznie uruchamiać się na tosterze.

Jednak projektowanie oparte na testach jest bardziej opiniotwórczym tematem. Uważam, że twórcy gier powinni zrobić więcej. Myślę też, że twórcy gier mają jedne z najbardziej rygorystycznych, napiętych harmonogramów i myślą, że nie mogą sobie pozwolić na spędzanie czasu na TDD, kiedy chcą po prostu rozpocząć grę. Ponadto, ponownie z motywacją, TDD jest znacznie wolniejsze i możesz zobaczyć dużo mniej działającej gry (przynajmniej na początku). Może to mieć poważny negatywny wpływ na motywację programisty.

Myślę, że to także ogólny brak wiedzy i praktyki. Nie sądzę, że TDD jest również rozpowszechniony w innych obszarach, ale podobnie jak zwinny rozwój, myślę, że się rozprzestrzenia. Można powiedzieć, że minęło wiele czasu (a może nie, jak może być za lata). Ważniejsze niż TDD jest „RDD” - rozwój oparty na wymaganiach. Właśnie to wymyśliłem.Jaki jest twój cel Aby stworzyć grę. Wszystko inne zajmuje drugie miejsce. Jeśli możesz udowodnić, że TDD zwiększa produktywność i pomaga zespołom dotrzymywać terminów, to czy nie sądzisz, że wszyscy będą z niego korzystać? I może tak jest. Ale teraz nasza branża jest bardziej konkurencyjna niż kiedykolwiek wcześniej, są trudniejsze i wcześniejsze terminy, a rzeczy po prostu muszą działać. Pracownicy budowlani nie budują najpierw rusztowań; kładą fundament, następnie podnoszą ściany i podłogi, i dopiero wtedy budują selektywne fragmenty rusztowania, aby wykonać określone zadania, które rusztowanie jest wygodniejsze. Myślę, że to samo dotyczy rozwoju oprogramowania.

Przepraszam za tak długi post. Mam nadzieję, że zyskałeś z tego trochę mądrości. Jestem tylko studentem, mówiąc o moich spostrzeżeniach, z bardzo ograniczonym doświadczeniem w branży, ale z dużą ilością lektur od ekspertów branżowych. Więc weź moje słowa z odrobiną soli.

I hej, rób, co według ciebie zadziała. Zawsze możesz go zmienić lub zeskrobać i zacząć od nowa. To jest fajne w każdej formie inżynierii; jeśli początkowo ci się nie uda, spróbuj czegoś innego. (lub coś takiego :-P) Nie wylewasz betonu; oprogramowanie jest plastyczne.


Nawiasem mówiąc, od pewnego czasu zadaję to samo pytanie i badam tego rodzaju zasady projektowania. Oto kilka pytań, zarówno tutaj, jak i w przepełnieniu stosu, które mogą okazać się istotne:

Ricket
źródło
32

Oto moja pierwotna odpowiedź na podobne pytanie dotyczące SO od jakiegoś czasu, przynajmniej dotyczące części twojego pytania dotyczącej MVC:

Jest rzadko używany w grach. Długo zastanawiałem się, dlaczego, ale oto moje przemyślenia:

Istnieje MVC, aby rozróżnić dwie reprezentacje. Model jest abstrakcyjną reprezentacją twoich danych. W ten sposób maszyna wyświetla stan twojej aplikacji. Widok (i kontrolery) reprezentują bardziej konkretną widoczną instancję tego systemu w sposób znaczący dla ludzi.

W większości aplikacji biznesowych te dwa światy są zupełnie inne. Na przykład model arkusza kalkulacyjnego jest po prostu siatką wartości 2D. Nie musi myśleć o tym, jak szerokie są komórki w pikselach, gdzie są paski przewijania itp. Jednocześnie widok arkusza kalkulacyjnego nie wie, w jaki sposób wartości komórek są obliczane lub przechowywane.

W grze te dwa światy są znacznie bliżej siebie. Świat gry (model) jest zazwyczaj zbiorem bytów umieszczonych w jakiejś wirtualnej przestrzeni. Widok gry to także zestaw bytów umieszczonych w jakiejś wirtualnej przestrzeni. Ograniczające się objętości, animacje, położenie itp., Wszystkie rzeczy, które można by uznać za część „widoku”, są również bezpośrednio używane przez „model”: animacja może wpływać na fizykę i sztuczną inteligencję itp.

Rezultat końcowy jest taki, że linia między modelem a widokiem w grze byłaby dowolna i nie byłaby pomocna: w rezultacie powielalibyśmy wiele stanów między nimi.

Zamiast tego gry mają tendencję do rozdzielania rzeczy wzdłuż granic domen: sztuczna inteligencja, fizyka, dźwięk, rendering itp. Będą trzymane tak osobno, jak to możliwe.

hojny
źródło
20

Ponieważ MVC nie pasuje do architektury gry. Przepływ danych w grze jest zupełnie inny niż w przypadku aplikacji typu enterprice, ponieważ nie jest oparty na zdarzeniach i często ma (bardzo) napięty budżet milisekundowy na wykonanie tych operacji. Jest wiele rzeczy, które muszą się wydarzyć w 16,6 milisekund, więc korzystniej jest mieć „stały” i sztywny potok danych, który przetwarza dane potrzebne na ekranie dokładnie w tym samym czasie.

Ponadto istnieje separacja; przez większość czasu po prostu nie jest podłączony w taki sam sposób jak wzór MVC. Istnieje silnik renderujący (widok), obsługa danych wejściowych użytkownika (kontroler) i pozostałe, takie jak logika rozgrywki, ai i fizyka (model). Pomyśl o tym; jeśli pobierasz dane wejściowe od użytkownika, uruchamiasz AI i renderujesz obraz 60 razy na sekundę, to dlaczego potrzebujesz obserwatora między modelem a widokiem, aby powiedzieć ci, co się zmieniło? Nie interpretuj tego tak, jak mówię, że nie potrzebujesz wzorca Observer w grach, tak, ale w tym przypadku tak naprawdę nie jest. W każdym razie wykonujesz całą tę pracę, każdą klatkę.

Chociaż TDD prawie nigdy nie jest używane w studiach programistycznych, stosujemy zwinne metody tworzenia oprogramowania, a SCRUM wydaje się być popularnym wyborem, przynajmniej tutaj w Europie. Powód jest prosty, zmiany pochodzą zewsząd. Artyści mogą chcieć większego budżetu na teksturę, większych światów, więcej drzew, podczas gdy projektanci chcą bogatszej historii (więcej treści na dysku), świata transmisji strumieniowej, a wydawcy chcą, abyś skończył na czas i budżet, podobnie jak dział marketingu. Poza tym „stan techniki” szybko się zmienia.

Nie oznacza to, że my też nie przeprowadzamy testów, większość studiów ma duże działy pytań i odpowiedzi, przeprowadzamy mnóstwo testów regresji i regularnie przeprowadzają testy jednostkowe. Jednak nie ma sensu przeprowadzanie testów jednostkowych z góry, ponieważ duża część błędów jest związana ze sztuką / grafiką (dziury w siatkach kolizyjnych, niewłaściwe tekstury, usterka w cieniowaniu pola), których testy jednostkowe nie są w stanie pokryć. Poza działającym kodem najważniejszym czynnikiem każdej gry jest to, że jest fajna i nie ma w niej testów jednostkowych.

Pamiętaj też, że w świecie konsol jest jeszcze inaczej, ponieważ programujesz więcej dla sprzętu niż dla czegokolwiek innego. Ogólnie rzecz biorąc (PS2 / PS3) oznacza, że ​​przepływ danych jest o wiele ważniejszy niż przepływ kodu w prawie każdym przypadku; ze względów wydajnościowych. Co w większości przypadków unieważnia użycie TDD jako narzędzia architektonicznego. Dobry kod OOP ma ogólnie zły przepływ danych, co utrudnia wektoryzację i równoległość.

Jasper Bekkers
źródło
13

Dlaczego MVC i TDD nie są częściej wykorzystywane w architekturze gier?

Ostrzeżenie: opinia z wyprzedzeniem.

MVC nie jest używane (dużo), ponieważ:

  1. MVC jest stosunkowo nowym podejściem, a gry są zwykle oparte na starym kodzie. Większość osób tworzących aplikacje MVC za każdym razem buduje je z niczego. (Wiem, że sam MVC ma tak naprawdę dziesięciolecia; nowością jest powszechne zainteresowanie nim, które zasadniczo pochodzi z aplikacji internetowych takich jak RoR). W oprogramowaniu biznesowym, na którym pracowałem, opartym na starszym kodzie, MVC również nie miało sensu. To kwestia kultury, ale nie jest specyficzna dla gry.
  2. MVC jest zasadniczo wzorcem GUI dla programów sterowanych zdarzeniami. Gry nie są zdominowane przez GUI ani sterowane zdarzeniami, dlatego ich zastosowanie nie jest tak wspaniałe, jak w przypadku aplikacji internetowych lub innych aplikacji opartych na formularzach. MVC jest zazwyczaj wzorem Observera z pewnymi dobrze znanymi rolami, a gry często nie mają luksusu czekania na coś interesującego - muszą aktualizować wszystko co klatkę (lub jakąś odmianę), niezależnie od tego, czy ktoś kliknął coś .

Nie oznacza to, że gry nie mogą się wiele nauczyć od MVC. W grach, które tworzę, zawsze staram się oddzielić model od widoku. Tradycyjna koncepcja widoku i kontrolera będącego 2 częściami tego samego obiektu (widgetu) tak naprawdę nie działa, więc musisz być trochę bardziej abstrakcyjny. Zgadzam się z tobą, że wydajność prawdopodobnie nie będzie tutaj prawdziwym problemem. Jeśli wydajność może być korzystna z oddzielenia elementów wizualnych i logicznych, ponieważ jest to bardziej podatne na spójność pamięci podręcznej, równoległość itp.

TDD nie jest używane (dużo), ponieważ:

  1. Korzystanie z gier jest naprawdę niewygodne. Ponownie, jest to w porządku dla oprogramowania sterowanego zdarzeniami, w którym wejścia i wyjścia wychodzą, możesz porównać to, co zobaczyłeś, z oczekiwaniami i zaznaczyć to poprawnie. W przypadku symulacji z dużą ilością współdzielonego stanu jest to znacznie bardziej niezręczne.
  2. Nie ma niepodważalnych dowodów, że to w ogóle pomaga. Po prostu wiele roszczeń, a niektóre dane często oparte na sprawozdaniach własnych i apelacjach do władz. Być może pomaga biednym programistom stać się miernym, ale powstrzymuje dobrych programistów. Być może czas poświęcony na pisanie testów może być lepiej poświęcony na naukę zasad SOLID lub na zaprojektowanie właściwego interfejsu. Być może fałszywe poczucie bezpieczeństwa daje testy, które przechodzą bez żadnego rzeczywistego dowodu, że masz wystarczającą liczbę testów, aby upewnić się, że Twój obiekt działa prawidłowo.

Ponownie, jako zastrzeżenie, uważam, że testy jednostkowe są świetne, ale nie sądzę, aby „testowanie najpierw” było korzystne lub sensowne. Nie sądzę też, aby testowanie głównej symulacji było praktyczne, gdy tak wiele stanów wspólnych zmienia się wiele razy na sekundę. Ogólnie ograniczam swoje testy do mojego niskiego poziomu i kodu biblioteki.

Jednak, jak zapewne możecie się domyślić, jestem w dużej mierze stronniczy w stosunku do „kodowania korporacyjnego”, ponieważ przedsiębiorstwa są dobrze znane z przekraczania terminów i budżetów. „Podobnie jak twórcy gier!” Słyszę jak mówisz - cóż, tak. Nie sądzę, aby ktokolwiek naprawdę wiedział teraz najlepszy sposób na tworzenie oprogramowania i nie jestem przekonany, że stosowanie regimentowanych praktyk w oprogramowaniu mainstream jest w ogóle krokiem naprzód w porównaniu z bardziej swobodnymi praktykami w oprogramowaniu rozrywkowym. Podejrzewam, że jest to przede wszystkim korzystne dla tych, którzy polegają na towarowych programistach Java, gdzie podejścia te nie są drabiną do wspinania się na wyższe wysokości, ale siatką bezpieczeństwa, aby zapobiec spadaniu zbyt nisko.

Kylotan
źródło
9

Jak zauważa Kylotan: „W grach nie można traktować aspektu prezentacji jako odłączalnej i wymiennej koncepcji, takiej jak HTML i CSS dla aplikacji internetowych”. Po zbudowaniu kilku gier przy użyciu prostego wzorca MVC (nie dużego szkieletu) odkryłem, że głównym problemem jest to, że Twój model musi wiedzieć o twoim widoku. Jest bardzo prawdopodobne, że będziesz musiał użyć danych bitmapowych sprite, danych hitbox lub danych geometrii 3D z zasobów graficznych, aby pomóc w wykrywaniu kolizji (lub innym podobnym zadaniu). Oznacza to, że każdy model potrzebuje odniesienia do swojego widoku, co łamie klasyczny wzorzec MVC - na przykład nie można już utworzyć nowego widoku dla istniejącego modelu itp.

Model komponentów, który widzisz np. W Unity3D, jest najlepszym sposobem na uporządkowanie kodu gry.

Iain
źródło
4

MVC, na niektórych poziomach, jest już używany w tworzeniu gier. Jest to wymuszone przez system operacyjny, który ma różne interfejsy do wprowadzania i grafiki. Większość gier ma także kilka innych wystąpień MVC, np. Oddzielając fizykę od renderowania i wątków wejściowych. To działa dobrze. Współczesna idea MVC wydaje się polegać na tym, że należy ją powtarzać fraktalnie, dopóki nikt nie będzie w stanie zrozumieć kodu. Na szczęście gry tego nie robią.

TDD nie jest używane, ponieważ rzadko wiadomo, że gra powinna „zrobić”, zanim powtórzy się wiele razy na prototypie. Praktyki z TDD, takie jak ciągłe testowanie lub testy integracyjne, są często stosowane w tworzeniu gier.


źródło
3

Systemy gier powoli przechodzą na lepsze praktyki. Frameworki takie jak XNA zapewniają wgląd w to, jak uczynić kod bardziej uogólnionym / czystym, bez zwiększania nadmiernego czasu projektowania i wykonywania. Ogólnie rzecz biorąc, powiedziałbym, że w systemach gier chodzi o optymalizację złożoności w stosunku do szybkości wykonania, a jednocześnie utrzymanie napiętego harmonogramu rozwoju i motywację. Zastosowanie koncepcji inżynierii oprogramowania i projektowania systemu po prostu nie jest priorytetem nr 1 w takim środowisku.

W moich osobistych projektach gier staram się komentować kod, a przynajmniej czynić go czytelnym, i łączę ze sobą systemy, które pozwolą nieco bardziej elastycznie później (tj. Ogólność) w jak największym stopniu, ale na koniec dnia, jeśli nie posunąłeś swojej gry do przodu, po prostu nie czuje się dobrze.

Zwykle także przed ukończeniem gry masz co najmniej 1000 pomysłów na ulepszenie podstawowej mechaniki, podstawowych systemów itp. W taki sposób, że bardzo niewiele z tego „nadającego się do ponownego wykorzystania” kodu będzie naprawdę być użyteczne. Za dnia pracuję na normalnym rynku pracy i chociaż systemy, nad którymi pracujemy, mogą być ogromne, szczerze mówiąc, myślę, że bledną w porównaniu ze złożonością gier.

Deleter
źródło
2

Nie mam szczególnej opinii na temat MVC poza tym, że widok jest często oddzielony od logiki przez prosty fakt, że pętla renderująca pakuje mnóstwo rzeczy do przetworzenia przez jakiś sprzęt i to nie jest miejsce, w którym chcesz "gry" logika dzieje się jednocześnie. „Kontroler” jest również oddzielony sprzętem, ale niestety wielu, jeśli nie większość twórców gier, „interesuje” pracę w module obsługi kontrolera. (IMO, kontroler kontrolera powinien czytać przyciski i drążki i budować „prezentację” do gry, ale moje mydło nie jest tak silne.)

Z drugiej strony TDD jest czymś, o czym mam bardzo mocne opinie. Po prostu zmienia rozwój w taki sposób, aby stworzyć oprogramowanie, na którym łatwiej jest zbudować. Jest to trudniejsze, bez wątpienia. Oczywiście, ponieważ trudniej to zrobić, nie zostało to zrobione. Niektórzy narzekają na to, że TDD (lub bardziej ogólnie testowanie jednostkowe) nie ma wartości, ponieważ „gra jest testem”, ale faktem jest, że w TDD testowanie jest prawie nieistotne. Istotą TDD jest projektowanie i architektura oprogramowania, które powstaje w wyniku tego procesu.

Objęcie TDD naprawdę zmienia podejście do programowania. Miałem pewne przeczucia, co było dobre, a co złe, zanim zacząłem ścieżkę TDD, ale kiedy wskoczyłem obiema stopami, naprawdę zrozumiałem znacznie więcej na temat tego, jak rzeczy, które robiłem, albo pomagały, albo utrudniały przyszły rozwój . Rzeczywiście, jest to swego rodzaju punkt za stanowiskiem kodera, TDD bez t .

Wracając do tego, dlaczego nie jest częściej używany w grach, poza tym, że jest trudny, uświadamia ludziom, że sposób, w jaki zawsze to robili w przeszłości, niepotrzebnie utrudniał własną pracę, a dla programistów, szczególnie jest to gorzka pigułka, na którą nawet można spojrzeć, znacznie mniej połykać.

Jestem przekonany, że ludzie, którzy odmawiają przyjęcia TDD, po prostu nie chcą być lepszymi programistami. Myślą już, że są „doskonali” w programowaniu, projektowaniu lub architekturze, podczas gdy w rzeczywistości ich kod mówi coś zupełnie innego.

dash-tom-bang
źródło