Upubliczniono kod Soldata

13

Kojarzycie Soldata? Tę starą 2-wymiarową polską strzelankę, popularną jakieś 10 lat temu? No to właśnie opublikowano jej kod źródłowy w Pascalu: https://github.com/Soldat/soldat

title

Gra miała ponoć raczej burzliwy cykl deweloperski po tym jak jej twórca Michał Marcinkowski dał sobie spokój. Wersja na Steama była zapowiadana od lat i stała się wręcz memem, ale w końcu doczekaliśmy się i niej, zapowiedzieli Soldat 2, a teraz otworzyli kod - w sumie jestem wręcz zdumiony, że ludzie wciąż w tym dłubią. Popularność już nie ta co kiedyś, ale ciągle można spotkać grających w to ludzi (głównie chyba Polaków i Turków), sam raz za czas instalowałem i grałem. Stabilność gry jest, jak na dzisiejsze czasy, raczej siermiężna - lagi regularnie denerwują ludzi tym, że regularnie strzały granatnika i rzuty granatem są niezaliczane (ale już samemu zabić się nimi łatwo).

Zostawiam tu dla z znających Pascala, niech rzucą okiem i ocenią kod, jestem ciekaw opinii.

0

Grę znam i grałem całkiem sporo. Fajnie że teraz mogę zobaczyć ją od środka. Z lagami o których piszesz się nie spotkałem. Jedyne lagi jakie doświadczyłem w tej grze były spowodowane moim internetem.

Strasznie urzekające jest, że w kodzie postać nazwana jest "Gostek" (i te funkcje typu "RenderGostek()").

3

Spędziłem masę godzin na tej grze lata temu. Nawet udało się trochę powygrywać w jakichś ligach. W sumie do teraz zdarza mi się pykać, ale sporadycznie i po serwerach też widać, że jest garstka ludzi, która w to gra.
Mimo wszystko i tak najnowsza wersja jest całkiem niedawno wydaną wersją i ludzie cały czas w tym dłubią.

Nawet znowu wystartowała najpopularniejsza (i pewnie teraz jedyna) liga tej gry:
https://www.sctfl.net/forums/
Statystyki meczy: https://stats.sctfl.net/index.php
Playoffy: https://stats.sctfl.net/
Ludzie pewnie wskrzesili ligę nudząc się na kwarantannie. :D

9

Jak już wyżej wspomniałem, w ogóle nie znam tej gry, ale w kod zaglądnąłem i muszę powiedzieć, że jest całkiem nieźle jak na kod Pascalowy. Ale to nie znaczy, że mi ten kod odpowiada, bo jest sporo do poprawy.



Pierwsze to mieszanie paradygmatów. Oryginalny kod (Michała) pisany był w całości proceduralnie, co akurat w przypadku gier było powszechne. W późniejszych latach kod został rozszerzony, ale już obiektowo. Można to zauważyć np. w module Gfx – lata później, inny autor, kod obiektowy. Albo robi się wszystko proceduralnie, z wykorzystaniem prymitywów, albo obiektowo, opakowując prymitywy w klasy. Szkoda, że przez te kilkanaście lat nie przerobiono tego kodu na całkowicie obiektowy. Albo modułu Gfx na proceduralny. ;)

Kod wygląda ładnie i jest dobrze nazwany – ale tylko dobrze, bo zauważam sporą niekonsekwencję. Wiele identyfikatorów nie trzyma konwencji PascalCase i wykorzystany jest minimalizm znany z języka C, nazwy parametrów nie posiadają prefiksów (nie da się ich odróżnić od zmiennych). Większość kodu jest po angielsku, ale też da się znaleźć identyfikatory polskie, np. GFX_GOSTEK_ZLOTYLANCUCH, w dodatku niektóre zgimbusowane, jak GFX_GOSTEK_MORDA.

Mało tego, niektóre są całkiem bez sensu, np.:

GameMenu: array of TGameMenu; // menu jest macierzą menu? :|

Poza tym zmienne oznaczone jako ”C-var” niepotrzebnie trzymają konwencję nazewnictwa znaną z C. Wszystkie te zmienne mogłyby być nazwane po pascalowemu – w niczym to nie przeszkodzi.



Formatowanie jest dobre, ale znów – tylko dobre. Autor wykorzystuje puste nawiasy przy bezparametrowych subrutynach (co jest godne pochwały), ale niestety nie wszędzie. Złożone instrukcje warunkowe nie trzymają poprawnego formatowania i są wyrównywane jak instrukcje wyboru, z else if w tej samej linii (to jest zło). Poza tym sporo nadmiarowych begin end, czego też nie lubię i co mi przeszkadza. Takich przypadków jest więcej, ale to akurat malutka niedogodność.

To co też nie jest fajne to bardzo długie ciała podprogramów. Ja wiem że w przypadku gier (szczególnie starych) było to normalne, ale gra jest tak mała, że podział kodu na większą liczbę małych funkcji nie wpłynęłoby na framerate, a nawet jeśli, to w razie czego przecież jest inline i wychodzi na to samo.

Niektóre funkcje mają pod setkę linii, a w środku inicjalizacja masy zmiennych i kupa drabinek ifów oraz miliony zmiennych lokalnych – np. funkcja LoadMapGraphics z modułu MapGraphics ma ich aż 51 i jest długa na ponad 600 linii!!! To samo procedura Update_Frame z modułu UpdateFrame (niezłe nazewnictwo…) – jedna procedura w module, na niemal 400 linii.

Do tego bardzo dużo podprogramów ma hardkodowane wartości łańcuchowe (małe zło) oraz literały liczbowe (duże zło), których znaczenia nie ma się skąd dowiedzieć, ani też nie ma się jak domyśleć o co w nich chodzi.



Trudno mi się wypowiedzieć na temat samej technicznej jakości kodu, bo nie znam go w całości. Nie wiem jak dokładnie działa, bo nie analizowałem dokładnie każdego modułu i każdej jego linijki. To co mi się rzuciło w oczy to np. brak inline'owania funkcji stricte matematycznych, których jest dużo i które jak podejrzewam są wykorzystywane mnóstwo razy w każdej klatce gry. Ale nie mam na tyle czasu, aby pobrać źródła i przeanalizować je dokładnie.



Podsumowując – kod jest napisany całkiem nieźle i na tyle czytelnie, że praca z nim nie byłaby trudna. Sporo rzeczy wymaga poprawy, ale przede wszystkim unowocześnienia – skusiłbym się na wprowadzenie pełnej obiektowości. To mała gra, ma niewiele kodu, więc spokojnie można wszystko przerobić na klasy. Narzut obliczeniowy czy pamięciowy będzie znikomy (absolutnie niezauważalny i nie mający żadnego znaczenia), ale za to pozwoli w znacznym stopniu skrócić kod i ułatwić jego zrozumienie.

Problem jest tylko taki, że z tego co widzę, dokumentacji nie ma – ani w postaci zewnętrznych dokumentów, ani nawet w postaci komentarzy wewnątrz źródeł. Komuś z zewnątrz, kto będzie chciał poprawić ten kod i go uwspółcześnić, trudno będzie się w nim połapać, bez wnikliwej i czasochłonnej analizy.

Mimo wszystko i tak prezentuje się lepiej niż wiele współczesnych kodów pascalowych, które widuję w sieci. ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1