Moi kochani! Nieuchronnie zbliża się moment, który powinien się urzeczywistnić zdecydowanie dużo wcześniej (bo 2 lata temu, gdy zaczynałem prace nad tym). Mianowicie, już za chwileczkę, już za momencik...ukaże się kolejna produkcja, o której tak naprawdę nie napisałem ani słowa wcześniej, a to dlatego, że ona jest spoza tego "sznurka" gier, jakie dotychczas wypuszczałem. Zaraz wszystko wytłumaczę, a na razie ogłaszam uroczyście, że mój własny klon gry "Battle City" pt: "Rumble In The Factory", niedługo ujrzy światło dzienne 🤩!
KLON "BATTLE CITY" Z POWODU...I SENTYMENTU
Całą opowieść trzeba zacząć od początku, jako że niczego (dosłownie niczego) jeszcze o tym projekcie nie pisałem. W lipcu 2023 roku, zacząłem pracować nad "RITF" w celu posiadania argumentu do zatrudnienia. Po (kolejnym) brutalnym przekonaniu się, że ówczesne wysiłki nie przesuwają mnie mocno w kontekście konkurowania z resztą 😡, wziąłem się do pracy. Wpadłem na pomysł zrobienia projektu, który będzie nawiązywał do jednej z moich ukochanych gier z okresu dzieciństwa: "Battle City" 😎! Prace trwały do końca listopada...i wtedy je przerwałem 😞.
Tak naprawdę już nie pamiętam dlaczego właśnie wtedy prace zostały wstrzymane. Prawdopodobnie to kwestia studiów i konieczność myślenia o pisaniu magisterki. Potem weszła praca komercyjna, parę innych ważniejszych spraw i tak oto przechodzimy do grudnia, 2024 roku - tak, aż tyle mój klon "Battle City" czekał na kontynuacje 🙄. Przyszedł rok '25 i dopiero od niedawna jest szansa oszacować kiedy mniej więcej będę mógł wypuścić piękny produkt oczyszczony z wszelkich odnotowanych błędów z oznaczeniem 1.0 😁.
Za cyfrowymi kulisami
"Rumble In The Factory" nie jest skomplikowanym projektem, choć daję słowo, że mocno mnie umęczył jako osobę, która zbudowała cały ten projekt od momentu kliknięcia w "Unity" przycisku "Create New Project" 🙂. Sypnę troszkę danymi liczbowymi, bo wiem, że zawsze przyciągają uwagę 😄.
Liczba tzw. "commit'ów" na moim GitHub wynosi aktualnie 1,733 (w czasie pisania tego artykułu). Na początku posyłałem jeden na bardzo prostą rzecz np. zmiana tła kamery czy dodanie prefabrykatu. Z czasem zmieniłem nastawienie do tego i od grudnia zacząłem tworzyć taką "migawkę" co rozwiązanie jakiegoś problemu albo co jedną nową implementację.
Skrypty dot. funkcjonalności projektu, które napisałem: 183. Sporo jak na prosty klon "Battle City", prawda? Lecz są to skrypty po cholernie gruntownej refaktoryzacji. Praktyka w robocie komercyjnej przyniosła rezultat i po "przestawieniu się" na dobre praktyki (a już na pewno lepsze, niż poprzednie), uznałem za obowiązkowe przerobienie tego wszystkiego, co zrobiłem w 2023 roku. Potrwało to z jakieś 3 tygodnie, jednak wiedziałem, że to się opłaci i gdy przyszła pora na dokończenie implementacji, nie myliłem się ani trochę - późniejsze dokładanie nowych klocków było O WIELE prostsze.
Różnice względem oryginału
"RITF", poza własnoręcznie robioną oprawą graficzną i dźwiękową, oczywiście ma inne niektóre elementy różniące się od powszechnie znanej produkcji Namco z 1985 roku. Grę należało dopasować pod standardy współczesne + dodać jakieś kawałeczki oryginalności w swojej wersji. Przedstawię szybko czego nie znajdziesz w "Battle City" 🙂.
Menu główne
Zaczniemy od menu głównego. Wrzucam zrzuty ekranu z obu tytułów celem postawienia ich obok siebie:
![]() | ![]() |
Porównanie scen menu głównego (oryginał z 1985 roku vs. mój klon "Battle City").
Wyśrodkowane liczniki u góry
To pierwsza rzecz, która potrzebowała dostosowania pod obecne standardy. W tamtych czasach nie było takich udogodnień, jak automatyczne wyśrodkowywanie tekstów zależnie od zawartości (w pionie czy w poziomie). W silniku "Unity" to tylko kwestia dodania elementów UI do grupy i tyle 😂!
Numer wersji gry
W swoim klonie, umieściłem w prawym dolnym rogu numerek wersji, żeby też zrobić kroczek w stronę współczesności. On jest ledwo widoczny, jednak jak się wytęży wzrok, to można dostrzec napis "v.1.0" 😊.
Zamiana opcji "Construction" na "Wyjście"
W "Battle City" jest opcja "Construction" (pierwsza od dołu), która uruchamia edytor poziomu, co pozwala na zrobienie własnego poziomu i rozpoczęcie od niego gry. Natomiast nie można go ani zapisać, ani w żaden sposób zmodyfikować trwale wbudowanych etapów bez hakowania pliku ROM. Możliwość, choć jak na 1985 rok imponująca, to jednak wymagała zamiany na dzisiejsze standardy. W "RITF" zamieniłem tę opcję na "EXIT" (mój klon "Battle City" wyjdzie m.in. na systemy Windows, więc trzeba dać możliwość jakoś wyjść z gry 😝), a każdy chętny, który pobierze projekt z GitHuba, może dodać sobie własne etapy w formacie plików JSON 😇!
Wybór etapu
W scenie wyboru etapu także jest zawarta cegiełka własnej twórczości 😁. Dane etapów są odczytywane z katalogu "Resources" w projekcie jako pliki JSON. Natomiast uwzględniłem przypadek nieznalezienia żadnego pliku z danymi. Wtedy ma się pojawić informacja tekstowa dla gracza, że nie ma możliwości wybrania któregoś z etapów, ponieważ system odpowiedzialny za ich odczyt, nie znalazł ani jednego. Wtedy gracz może wrócić do sceny menu głównego, wyjść z gry, naprawić problem i wejść ponownie 👍.
![]() |
Komunikat dla gracza w scenie wyboru etapu w sytuacji braku znalezionych plików z danymi etapu.
Etap
Scena etapu, poza najbardziej rzucającą się w oczy różnicą, jaką jest własna grafika 🙂, też zawiera w sobie parę różnic jakich możesz nie wychwycić w pierwszym momencie. Oto co zostało zmienione względem oryginalnej wersji, na jakiej się wzorowałem.
Licznik zdobytych punktów
Ponieważ mogłem sobie na to pozwolić, odpicowałem liczniki zdobytych punktów pojawiających się w miejscu pokonanego przeciwnika bądź zdobytego bonusu. Nie tylko mogłem sobie po prostu wstawić tekst UI (w "Battle City" wyświetlane są sprite'y), lecz także dodałem efekt delikatnego przesuwania w osi Y oraz stopniowe przyciemnianie w czasie. To dało skromny, lecz przyjemny wygląd wizualny tego samego licznika.
![]() | ![]() |
Porównanie licznika zdobytych punktów (oryginał z 1985 roku vs. mój klon "Battle City").
Wiele bonusów w jednym czasie na mapie
W oryginalnej wersji, kiedy pojawi się jeden bonus w wyniku zniszczenia/uszkodzenia bonusowego przeciwnika (odcień fioletowy), to tamten jest usuwany i wtedy pojawia się nowy. U mnie tak nie ma. Może być ich tyle jednocześnie na mapie, ile pozwoli na to pusta przestrzeń (choć nadal znikają po pewnym czasie) 😁.
![]() |
Mój klon "Battle City" pozwala na dowolną liczbę bonusów w tym samym czasie a contrario do "Battle City", w którym każdy poprzedni bonus znika w momencie wylosowania kolejnego.
Zbieranie bonusów przez przeciwników 😁
Istnieją shakowane wersje "Battle City", w których przeciwnicy także mogą zbierać bonusy, tak jak gracze, co ma wówczas niekorzystny wpływ na graczy 😊. Na przykład bonus destrukcji natychmiast pozbawi życia graczy, a bonus fortecy (czyli "łopata", która obudowuje orzełka kawałkami metalu dookoła niego), wyczyści całą przestrzeń dookoła głowicy i to znowu gracze mają przechlapane 😁. Bardzo podobała mi się wizja implementacji "wyrównania szans" i tak oto po wejściu na najwyższy stopień trudności (szczegóły w dalszej części artykułu), możesz się spodziewać "zbierania" bonusów przez przeciwników dokładnie w taki sam sposób, jak Ty to robiłeś(-aś) 😎!
Brak "degradowania" gracza na czwartej randze po odniesieniu obrażeń
W "Battle City", jak gracz jest na najwyższej randze (nr 4, wtedy może niszczyć metal) i dostanie od któregokolwiek z przeciwników, to nie ginie, tylko "degraduje się" do niższej rangi, co ratuje mu to życie. Ja zrobiłem inaczej - gracz na każdej randze ma określoną liczbę punktów zdrowia i jak oberwie, to nie traci swojej rangi, tylko odbierany jest punkt zdrowia i gra dalej. Dopiero, gdy straci wszystkie punkty zdrowia, zostaje zniszczony - wtedy dopiero "wraca" do rangi nr 1 i musi ją zdobyć od początku.
Punktacja
W scenie punktacji też zawarłem ważną modyfikację. W "Battle City", zawsze wyświetla się czwórka typów przeciwników bez względu na to, czy zniszczyło się chociaż jeden "egzemplarz" tego typu, czy nie. Żeby nie zasypywać gracza niepotrzebną informacją, że utłukł 0 (zero) przeciwników danego typu 🤭, zaimplementowałem identyfikowanie typów przeciwników i wyświetla każdy z nich wtedy i tylko wtedy, gdy którykolwiek z graczy (bo dwóch graczy też uwzględnia 😉) zniszczył chociaż jednego z danego typu. I wtedy to ma sens 😁!
![]() | ![]() |
Porównanie scen punktacji (oryginał z 1985 roku vs. mój klon "Battle City").
Z mniejszych dostosowań, to zmniejszyłem u siebie odstępy pomiędzy licznikami, bo uważam że nie są potrzebne aż tak duże, jakie są w oryginalnej wersji. Oczywiście system "pakuje" wszystkie elementy UI do poszczególnych grup przez co nic się nie rozjeżdża, kolejność jest zachowana, a przeliczanie spójne i zgodne z rzeczywistością 😇!
Pozostałe
Zostawię jeszcze wzmiankę o innych rzeczach niezwiązanych z konkretną sceną.
Horyzontalna translacja tła pomiędzy scenami
Kojarzysz przesuwanie szarego tła, zanim pojawił się napis "STAGE" 😄? W oryginale jest pionowo, a w mojej wersji jest przesuwanie poziome. I to nie dlatego, że nie byłem w stanie zrobić tego pionowo 🤣, tylko że to jest jeden z elementów oryginalności. Bez obaw, UI wspiera różne rozdzielczości - nad tym też pracowałem 😀!
![]() | ![]() |
Porównanie translacji teł między scenami (oryginał z 1985 roku vs. mój klon "Battle City").
Stopnie trudności
W "Rumble In The Factory" zaimplementowałem od siebie system rosnącego poziomu trudności wpływającego głównie na statystyki przeciwników, lecz nie tylko 😉. Gdy gracz ukończy ostatni etap w kolejce, to załącza się pierwszy etap w kolejności (jak w oryginale) i tak rozgrywka się zapętla w nieskończoność, dopóki gracz (albo gracze) nie wyzioną ducha bądź głowicy nie trafi szlag (odpowiednik orzełka w "Battle City" 😉). Natomiast w "RITF", dodatkowo w tym samym momencie, stopień trudności wzrasta o jeden do góry wpływając na przebieg rozgrywki 😊. Zamieszczam tabelkę wyświetlającą na co dokładnie wpływa każdy ze stopni trudności i w jaki sposób:
Lp | Czas przywoływania przeciwnika [s] | Limit przeciwników na mapie w jednym czasie | Mnożnik prędkości ruchu przeciwników [%] | Częstotliwość strzelania przeciwników [s] | Przeciwnicy mogą zbierać bonusy |
1 | 2 | 3 | 100% | 1 | NIE |
2 | 110% | ||||
3 | 4 | 120% | 0,9 | ||
4 | 1,8 | 130% | 0,8 | ||
5 | 1,6 | 5 | 140% | ||
6 | 1,5 | 6 | 0,7 | TAK |
Ostatni stopień będzie naprawdę zaskakujący bowiem przeciwnicy również będą mogli zbierać bonusy 😏. Ten system działa dokładnie tak samo, jak niektóre przerobione wersje "Battle City" modyfikujące trudność gry - różnica będzie tylko taka, że to będzie wszystko w jednej produkcji. Tyle w temacie 😀.
![]() |
Ikony gwiazdek oznaczające aktualny stopień trudności (przyjmuje wartości 0-5).
Co sprawiło mi najwięcej trudności?
Tutaj zostawiłem sobie miejsce na wyciągnięte wnioski co z punktu widzenia programisty, było dla mnie twardym orzechem do zgryzienia. Nawet jeżeli klon "Battle City" nie jest dużym projektem, to jednak trochę było takich "orzechów" 🥜.
Połączenie pomijania translacji panelu w menu głównym ze sterowaniem
Implementacje w aplikacjach wszelakiej maści to "naczynia połączone" i ten przypadek dobitnie pokazuje prawdziwość tego pojęcia. W "Battle City" możesz pominąć łagodne przesuwanie się panelu menu głównego z elementami UI naciskając odpowiedni przycisk, zamiast czekać aż sam on "przyleci". To, co dobrze pamiętam od strony trudności, to reagowanie przez opcje na klawisze, nawet gdy chciało się tylko pominąć to przewijanie. W takiej sytuacji wpływanie na wybór i zaznaczenie którejś z dostępnych opcji musi być jeszcze nieaktywne, bo istniało ryzyko, że gracz wybierze opcję zanim ją nawet zobaczy 😅. Po odpowiednim podpięciu pod zdarzenie "panel dotarł do miejsca docelowego", udało się zaprogramować, żeby sterowanie się "odblokowywało" dokładnie w tym momencie (niezależnie od tego, czy translacja dotarła do końca, czy została pominięta) i potem działało na już widocznych opcjach 👍.
Kontrola dźwięków poruszania się robotów graczy
W grze występuje charakterystyczne przełączanie się dźwięków poruszania się robotów graczy zależnie od wciskanych przycisków. Gdy gracz stoi w miejscu, odpala się inny dźwięk, zaś gdy porusza się, to włącza się drugi. Weź do tego tę salwę przypadków:
- wyłączanie dźwięku stania w miejscu, gdy gra kończy się przegraną gracza (wyświetla się napis "GAME OVER", jak w oryginale),
- wyłączanie dźwięku stania w miejscu, gdy gracz pokonuje ostatniego przeciwnika (wygrywa),
- wyłączanie dźwięku stania w miejscu, gdy gracz pokonuje ostatniego przeciwnika (wygrywa) i nagle po chwili niszczy sobie głowicę (przegrywa),
- przełączenie dźwięku na stanie w miejscu, gdy gracz zostaje zniszczony w trakcie poruszania się,
- wsparcie dla dwóch graczy:
- obaj zaczynają się poruszać i nagle jeden z nich przestaje, a drugi dalej się porusza,
- obaj zaczynają się poruszać, jeden z nich przestaje, a po dłuższej chwili przestaje się poruszać drugi,
- obaj zaczynają się poruszać, jeden z nich przestaje, drugi dalej się porusza i po chwili znowu obaj poruszają się w tym samym czasie,
- jeden z nich zostaje zniszczony, drugi dalej się porusza.
i zrozumiesz dlaczego to całe zadanie może Cię na jakiś czas pozbawić zmysłów 🙂.
Uniwersalne działanie bonusów
W moim klonie "Battle City" położyłem duży nacisk na uniwersalność bonusów, tak aby każdy z nich działał prawidłowo dla obu "stron" toczącej się walki: dla "tych dobrych" (gracze) i "tych złych" (wrogowie). Poza obudowaniem całej struktury w klasie bazowej, trzeba było też zaprogramować efekt działania każdego z bonusów. O ile część była banalnie prosta, tak część wymagała dwóch różnych podejść z uwagi na sens albo ograniczenia (np. wrogowie nie przenoszą swoich danych pomiędzy mapami). Najlepiej będzie jak przedstawię to w formie tabelarycznej:
Rodzaj bonusu | Efekt po zebraniu przez gracza | Efekt po zebraniu przez przeciwnika |
tarcza | tymczasowo włącza tarczę, która zapewnia nietykalność | |
zamrożenie | tymczasowo wyłącza wszystkich przeciwników, zarówno tych na mapie, jak i przywołujących się | tymczasowo wyłącza wszystkich graczy na mapie |
forteca | tworzy kafelki metalu dookoła głowicy, które po krótkim czasie zmieniają się w cegły | usuwa wszystkie kafelki dookoła głowicy |
ranga | zwiększa rangę "awansując" gracza i podnosząc jego statystyki bojowe | zmienia przeciwnika w złoty rodzaj (najsilniejszy ze wszystkich) |
destrukcja | natychmiast niszczy wszystkich przeciwników na mapie | natychmiast niszczy wszystkich graczy na mapie |
życie | dodaje życie graczowi | dodaje punkt zdrowia przeciwnikowi |
W ten sposób, bonusy zapewniają użyteczność dla OBU stron i nie zachodzi sytuacja, w której część z nich okaże się bezużyteczna dla wrogów 😁.
Rekursywne wykrywanie dozwolonej pozycji dla bonusów
Kiedy pojawia się bonus, to jest losowana dla niego pozycja. Należało uwzględnić przypadek na mapie, w którym z jakiegoś powodu gracz nie będzie mógł się do niego dostać, bo na przykład znajduje się głowica, wszedł prosto na kafelki toksyn (odpowiednik kafelka wody, po którym nie można chodzić) czy mógłby "wbić się" w kafelki metalu i jak gracz nie posiada czwartej rangi, to też go nie zdobędzie 😑.
Poza uwzględnieniem wielu różnych przypadków:
- czy znajduje się dokładnie na głowicy?,
- czy znajduje się dokładnie na niedostępnym kafelku?,
- czy nachodzi bądź znajduje się dokładnie na innym bonusie?,
- czy nachodzi bądź znajduje się dokładnie na jakimkolwiek robocie (żeby nie było sytuacji zdobycia go w tej samej sekundzie 😉)?.
trzeba było też zadbać o "kafelkowe" ustawienie pozycji. Ten system usłyszał już niejedno moje westchnięcie, gdy przy tym siedziałem i chciałem to skończyć jak najprędzej 😜.
Ślizganie się po kafelkach przez gracza z wykrywaniem kolizji
Następna rzecz, która zostawiła wielkie "Ech". Samo "ślizganie się" po kafelkach z czarno-żółtymi pasami (odpowiednik lodu w oryginale 🍧) to prosta rzecz. "Kwiaty" zaczęły się robić, gdy system zapamiętywania w którą stronę poruszać robotem samoistnie, nie był przygotowany na szybkie zmienianie kierunku i strzelanie podczas jeżdżenia. Zdarzało się nawet, że po wystrzeleniu pocisku, on stał w miejscu (akurat to była sprawa innego błędu) 😝. Dodatkowo, animacja poruszającego się robota działała cały czas, nawet jak robot nie mógł jechać dalej, bo np. trafił na kafelek toksyn (zamiennik kafelka morza w oryginale 💧).
Ostatecznie trzeba było usunąć przełączanie flagi boolowskiej przez "OnTriggerEnter" oraz "OnTriggerExit" i zaimplementować cały system wykrywania obiektów przed sobą (pozycja robota z niewielkim przesunięciem do przodu w kierunku patrzenia). Gdy wykryto śliskie podłoże, uruchamiał się proces samoistnego poruszania się robota przed siebie, co symulowało ślizgawkę 🙂. Gdy poza śliskim podłożem wykryto przed sobą przeszkodę, automatyczne poruszanie się było dezaktywowane, co rewelacyjnie przekonuje widza, że zatrzymał się właśnie w tej chwili z powodu napotkanej przeszkody 💪. Możliwość dopasowania warstw takich, jakie się chce (przez LayerMask 😊), poszerzyło zakres elastycznej konfiguracji na jakie obiekty system ma reagować i które interpretować jak przeszkodę, a które nie. To zlikwidowało problem animacji poruszania się w miejscu ✅.
Nachodzenie na siebie przeciwników, gdy jeden z nich wejdzie w miejsce przywoływania w momencie pojawienia się przeciwnika
Kolejna masakra 💥! Przypadek, gdy przeciwnik znajdzie się w pobliżu miejsca, w którym tworzy się nowy przeciwnik i co wtedy? W takiej sytuacji, w oryginalnej wersji gry przenikają przez siebie jak duchy i "przestają", gdy już na siebie nie nachodzą. Samo wytłumaczenie tego abstrakcyjnie może wywołać efekt drapania się po głowie, a co dopiero zrozumienie problemu i poprawna implementacja 😯.
Tutaj pomogło wykrywanie czy w promieniu znajduje się jakiś przeciwnik i w przypadku wykrycia, przypisywało się niestandardową warstwę obu przeciwnikom: temu, który wówczas znajdował się blisko miejsca przywoływania przeciwników i temu, który właśnie się pojawił. Potem, poprzez metodę "OnTriggerExit", kontroler odpowiedzialny za przełączanie warstw, przechwytywał ten sygnał i przywracał obu przeciwnikom domyślne warstwy, co pozwoliło im "wykrywać się" na nowo (w sensie kolizji).
Uwzględnienie różnych przypadków skrajnych
Wzajemne zniszczenie się robotów, odstrzelenie sobie głowicy (odpowiednim orzełka w oryginale) po pokonaniu wszystkich przeciwników, liczba przeciwników przypisana do mapy mniejsza od liczby miejsc przywołujących ("spawner'ów") i wiele innych sytuacji mniej oczywistych. To wszystko trzeba było uwzględnić. To też nie należało do przyjemnych zadań. Raz, że trzeba dany przypadek zidentyfikować, a dwa, zapobiec jego powstawaniu poprzez dorzucenie implementacji. I nie skończyło się na palcach obu rąk 🙃.
Przeliczanie pokonanych przeciwników dla dwóch graczy jednocześnie
A to zostawiłem na deser 😜. Na ekranie wygląda prosto - system pobiera liczbę pokonanych przeciwników per typ, a następnie co krótki interwał czasowy, podlicza punkty za przeciwnika i zmienia liczniki (to w rzeczywistości jest tylko pokazanie graczowi albo graczom, kto ile pokonał) 🔄. Dodatkowo, w przypadku trybu dla dwóch graczy, sprawdzane są sumy pokonanych przeciwników i przyznanie bonusowych 1,000 punktów temu, który odstrzelił najwięcej przeciwników 💯.
Łapiesz? To teraz czytaj jak to wygląda pod maską 😈. Chcąc przeliczać dla N graczy równoległe, trzeba było pobrać słowniki od wszystkich graczy i wykonać sumę zbiorów (słownik to struktura danych przechowująca pary klucz-wartość). Jest to konieczne, aby uwzględnić przypadek nieregularnego aktualizowania obu liczników, bo np. gracz drugi ustrzeli 3 przeciwników danego typu więcej od pierwszego.
Druga rzecz, która wymagała starannego zaplanowania, to kolejność wysyłanych zdarzeń przez podsystemy. W scenie punktacji jest taka kolejność:
- pół sekundy "ciszy" przed rozpoczęciem podliczania punktów za pierwszy/kolejny typ przeciwnika,
- podliczanie liczby pokonanych przeciwników danego typu (1/8 sek. co iterację),
- jeżeli to nie był ostatni typ przeciwnika, powtórz krok 1,
- wypisanie sumy pokonanych przeciwników na każdego z graczy, razem z napisem "TOTAL",
- 2 sekundy "ciszy" przed przejściem do następnej sceny.
Zatem, trzeba było podzielić cały przebieg postępowania na 5 różnych systemów. Pierwszy, zarządzający całym przebiegiem i łączący się z innymi (taki "naczelny"). Drugi, odpowiedzialny za przełączanie się na kolejny typ przeciwnika, aż do wyczerpania. Trzeci, przeliczający każdorazowo dany typ przeciwnika. Czwarty, zarządzający odtwarzaniem dźwięków i w końcu piąty - odpowiedzialny za przyznawanie bonusowych punktów temu graczowi, który ma największą sumę pokonanych przeciwników (jeżeli jest remis albo przegrana, wtedy nie przyznaje, zgodnie z oryginałem).
Nawet nie będę próbował opisywać szczegółów, bo artykuł wyszedłby 3x większy 😅.
Kiedy premiera?
Teraz istotna informacja - to kiedy można spodziewać się publikacji wersji 1.0? Po wypuszczeniu paru kolejnych materiałów promocyjnych, czekają mnie drobne przeróbki w paru miejscach. Następnie chcę dodać więcej nowych etapów, żeby gracz miał co robić i nie przechodził tak szybko przez rosnące stopnie trudności i w sumie tyle - to będzie koniec pracy 🤩. W zależności od tego, jak szybko zamknę pozostałe zadania, przewiduję możliwość publikacji w dniach 10-16 lutego, przy czym nie piszę, że to pewne na 100%!
Tak oto kończy się opowieść o "zadymie w fabryce" 🙃. Klon "Battle City" traktuję tak, jakby pochodził spoza listy oficjalnych tytułów z dwóch powodów. Po pierwsze, nie planowałem jej wypuścić teraz. Po drugie, jest dostępny kod źródłowy, a z reguły go nie udostępniam, żeby mieć własne patenty, które podnoszą moje szanse na "bycie potrzebnym". Tu zrobiłem wyjątek, bo szukałem (i teraz też szukam) pracy w sektorze komercyjnym, a zerknięcie do kodu jest konieczne, żeby ludzie wiedzieli w jaki sposób do tego podchodzę ✔️.