Od lat robię filmy o tym, jak używać AI do pracy. W pewnym momencie zorientowałem się, że mówię ludziom, co da się zbudować, ale sam nie zbudowałem niczego, co byłoby naprawdę trudne. Więc postanowiłem zrobić grę. Nie prototyp na weekend, tylko coś, w co dałoby się grać.
Nie programuję w Rust. Nie robiłem wcześniej gry 3D. Miałem pomysł, który towarzyszy mi od dawna: osada, którą budujesz w dzień, i noc, która przychodzi po ciebie. Coś w klimacie Kingdoms and Castles, tylko ciemniejsze i słowiańskie.
To jest pierwsze, co zobaczyłem na ekranie.

Pamiętam, że siedziałem przed tym dłuższą chwilę i miałem dwie sprzeczne myśli naraz. Pierwsza: to wygląda żałośnie. Druga: to się rusza i to ja to zrobiłem. Druga wygrała i dlatego jest ten wpis.
Zanim cokolwiek, jedna decyzja, która mogła zabić projekt
Trzeba było wybrać silnik. Naturalny wybór dla kogoś, kto robi rzeczy w przeglądarce, to three.js: JavaScript, natychmiastowy podgląd, ogromna społeczność, wszystko znajome. Alternatywą było Bevy, czyli silnik w języku Rust, którego nie znałem, przed wersją 1.0, z API zmieniającym się między wydaniami.
Mogłem o tym poczytać na Reddicie i wybrać to, co pisze większość. Zamiast tego zrobiłem test. Ta sama scena w obu silnikach, pomiar bez synchronizacji pionowej, czyli realna liczba klatek, a nie zaokrąglone sześćdziesiąt.
| Scena | Obiekty | Klatki na sekundę |
|---|---|---|
| Pusta mapa 48×48 + 11 budynków | ~2 300 | ~480 |
| Miasteczko z tłumem | 15 000 | ~130 |
| Skrajny stress test | 75 000 | ~38 |
To przypadek, który w prawdziwej grze nigdy nie wystąpi.

Wybrałem Bevy. Nie dlatego, że jest modny, tylko dlatego, że city-builder z ambicją rośnięcia to dokładnie ten przypadek, w którym architektura ECS w natywnym Rust bije jednowątkowy JavaScript. Doszedł drugi argument, o którym wtedy myślałem jako o odległej mrzonce: jeśli gra kiedykolwiek trafi na Steama, Bevy daje natywny plik .exe, a three.js wymaga opakowania w Electron ważące ponad sto megabajtów.
Zapłaciłem za to cenę, której wtedy nie widziałem. Bevy jest przed wersją 1.0 i część czasu poszła na walkę z API, które zmienia się między wydaniami. Ale to temat na osobny wpis, bo ma swoje własne, całkiem zabawne dno.
Pierwsza rzecz, która mnie ośmieszyła
Modele 3D generowałem sztuczną inteligencją, bo nie umiem modelować. Poprosiłem generator o osiem tysięcy trójkątów, czyli o coś lekkiego, co gra uniesie w setkach kopii.
Dostałem sześćset dziewięćdziesiąt trzy tysiące.
Jeden dom ważył dwadzieścia siedem megabajtów i nie zdążał się załadować w cztery sekundy, więc gra pokazywała puste miejsce tam, gdzie miał stać budynek. Przez dobre pół godziny byłem przekonany, że mam błąd w kodzie stawiania budynków. Czytałem tę samą funkcję czwarty raz.
Nie miałem błędu w kodzie. Miałem błąd w założeniu, że generator zrobi to, o co go poproszę. AI robi coś, co wygląda dokładnie tak, jak prosiłeś, i jest kompletnie bezużyteczne z powodu, o którym nie pomyślałeś.
| Liczba | Co znaczy |
|---|---|
| 693k | trójkątów zamiast zamówionych 8 tysięcy |
| 27 MB | waga jednego domu przed obróbką |
| 4,8 MB | po uproszczeniu siatki |

Trzy dni później: 9429 linii w jednym pliku
Tempo było wysokie. Za wysokie. Kod pisał się tak szybko, że wszystko lądowało w jednym pliku: kamera, gospodarka, fale wrogów, walka, budowanie, teren i interfejs. Po trzech dniach ten plik miał 9429 linii.
Wyglądało to na sukces. Przecież działa. Problem w tym, że każda kolejna zmiana kosztowała więcej niż poprzednia, bo żeby cokolwiek znaleźć, trzeba było przewinąć przez wszystko inne.
To jest moment, w którym po cichu umiera większość hobbystycznych projektów. Nie dlatego, że coś przestaje działać. Dlatego, że przestaje się chcieć.
Rozbicie głównego pliku, 7 lipca: 9429 linii w jednym pliku, podejście pierwsze: 8 modułów, podejście drugie: 15 modułów tematycznych. Dwa przebiegi tego samego dnia. Dla gracza nie zmieniło się nic. Dla tempa pracy zmieniło się wszystko.
Zrobiłem to w dniu, w którym pierwszy raz pomyślałem „nie chce mi się tego szukać”. Ten próg okazał się zaskakująco dobrym sygnałem i korzystam z niego do dziś. Kiedy szukanie zaczyna męczyć bardziej niż pisanie, to nie jest zmęczenie. To jest informacja o strukturze.
Gdzie jestem po trzech tygodniach
Historia projektu ma 286 zapisów. Trzy pierwsze dni lipca to praca przed startem: wybór silnika i testy. Reszta miesiąca to dni, w których realnie coś powstawało.
Co bym powiedział sobie sprzed trzech tygodni. Nie wybieraj narzędzia na podstawie opinii w internecie, tylko na podstawie pomiaru na własnym przypadku. Ten test zajął mi jeden dzień i zdjął wątpliwość, która inaczej wracałaby przez cały projekt.
W następnym wpisie: sześć podejść do jednego efektu, test, który za każdym razem pokazywał zielone światło, i dlaczego to było gorsze niż brak testu.