11.08.2026 04:33

Polowanie na opcje, które kłamią

⏱️ 7 min read
Share:

Przez ostatni czas robiłem w Moonlight Animate coś, co nie dokłada ani jednej nowej funkcji. Przeszedłem program od początku do końca i szukałem opcji, które istnieją, ale nic nie robią.

Brzmi jak sprzątanie. Nie jest. Brakująca funkcja to zwykły brak — widzisz, że czegoś nie ma, i szukasz obejścia. Opcja, która jest, wygląda normalnie, daje się kliknąć i nie robi nic — to coś znacznie gorszego. Nie tracisz przez nią funkcji. Tracisz przez nią zaufanie do wszystkiego pozostałego. Raz przyłapiesz suwak na tym, że nie ma wpływu na obraz, i od tej pory sprawdzasz każdy suwak. A wtedy program przestaje być narzędziem, a staje się czymś, czego trzeba pilnować.

Znalazłem trzydzieści kilka takich miejsc. Kilka opowiem, bo to dobre historie o tym, jak oprogramowanie potrafi kłamać w najlepszej wierze.

Tryby mieszania, które wszystkie znaczyły „normalny"

Klip w scenie może mieć tryb mieszania — mnożenie, ekran, nakładka, cała reszta. Lista była pełna, wybór się zapisywał, plik go pamiętał. Tylko że silnik rysujący scenę umiał wykonać kilka z nich, a pozostałe trzynaście rysował jak zwykłe krycie.

Nikt nie dostawał błędu. Wybierałeś „mnożenie", scena wyglądała inaczej niż zamierzałeś, i jedyne, co mogłeś zrobić, to uznać, że nie rozumiesz trybów mieszania. Teraz każdy z nich liczy się naprawdę, według tej samej matematyki, którą posługuje się reszta świata grafiki.

Dwadzieścia dwa polecenia menu działające na niewidzialnym dokumencie

To był mój ulubiony. Sporo pozycji w menu było podpiętych na sztywno pod dokument, który był otwarty w chwili budowania okna. Otwierałeś drugi obrazek, wybierałeś „scal w dół" — i operacja wykonywała się na poprzednim dokumencie. Cicho, poprawnie, nie na tym obrazku.

Presety narzędzi, które się nawzajem kasowały

Zapisane ustawienia narzędzia widać w dwóch miejscach: w panelu i w małym próbniku na pasku. To jedna lista pokazana dwa razy. Każde z tych miejsc trzymało jednak własną migawkę listy z chwili otwarcia i przy zapisie wpisywało ją w całości. Dodałeś preset w panelu, potem usunąłeś inny w próbniku — i ten pierwszy znikał, bo próbnik zapisał swoją, starszą wersję świata.

Ten sam wzorzec — kilku piszących, każdy z własną kopią jednego stanu — trafił mi się w tej fazie jeszcze dwa razy, w zupełnie niepowiązanych częściach programu. To chyba najczęstszy sposób, w jaki solidnie napisany kod traci dane.

Konwersja profilu koloru, która meldowała sukces

Zmiana profilu barwnego mogła się nie udać, ale komunikat i tak mówił, że się udała. Dostawałeś zielone światło i plik w starej przestrzeni barw. Teraz operacja najpierw sprawdza na jednym pikselu, czy w ogóle jest wykonalna, i kiedy nie jest — mówi to wprost, zanim cokolwiek ruszy.

Podgląd gry pokazujący kadr, którego gracz nie zobaczy

Edytor gier ma okno „Graj". Uruchamiało ono grę w rozmiarze swojego okienka, ignorując rozdzielczość, jaką ustawiłeś projektowi. Układałeś więc interfejs i kadrowałeś sceny pod obraz, do którego gotowa gra nigdy nie dojdzie. Teraz podgląd stosuje dokładnie te same reguły co gotowa gra — z czarnymi pasami włącznie, jeśli tak wypada.

Przy okazji wyszła rzecz, którą tamta poprawka dopiero obudziła: przeliczanie pozycji kursora skalowało piksel dwa razy. Dopóki podgląd chodził zawsze w jednym trybie, oba przeliczenia były neutralne i błąd spał sobie spokojnie. Włączenie prawdziwego kadru sprawiłoby, że każde kliknięcie lądowałoby obok celu. Naprawa i test poleciały w tej samej paczce co zmiana, która ten błąd odsłoniła.

I ten najgorszy: znikające rysunki

Scenę można wstawić do innej sceny jako gotowy element. Mechanizm, który ją wtedy składa, okazał się niepełną kopią tego głównego — brakowało w nim trzech przypadków. Efekty nałożone na klip nie były stosowane w ogóle, więc każde stopniowanie koloru i rozmycie znikało w chwili zagnieżdżenia. Nagrania timelapse nie renderowały się wcale. A najgorsze: klipy z rysunkiem klatka po klatce zwracały pusty obraz.

Czyli: animator rysuje sceny, wstawia je do sceny nadrzędnej — i jego rysunki po prostu nie ma. W kodzie stał nawet komentarz tłumaczący, że rysowanych klatek w tym miejscu być nie może. Mógł być prawdziwy kiedyś. Od dawna nie był.

„Off", które nie było wyłączone

Każdy tor dźwiękowy ma automatykę — zapisany przebieg głośności i panoramy w czasie — i przełącznik trybu, w tym pozycję „wyłączone". Przełącznik działał na odsłuchu. Ale przy eksportowaniu gotowego pliku automatyka wpalała się w nagranie mimo wyłączenia, bo część odpowiedzialna za renderowanie fizycznie nie miała jak zobaczyć tego ustawienia. Do tego wybór ginął po zamknięciu sceny: tor wyłączony wracał jako włączony.

Powód był ten sam co przy presetach: ten jeden przełącznik istniał w trzech niezależnych kopiach, z których żadna nie trafiała na dysk. Teraz jest jedną rzeczą, zapisaną w scenie, i widzą ją tak samo mikser, odsłuch i eksport.

Czego nie naprawiłem — i dlaczego to mówię

Dwie rzeczy zostały, i wolę je nazwać, niż przemilczeć.

Połączone warstwy — kiedy to pisałem, nadal się nie ruszały razem, mimo że program stawiał przy nich znaczek połączenia. Uznałem, że łatką się tego nie zrobi, bo cała ścieżka przekształcania obrazu jest z założenia jednowarstwowa, i odłożyłem to jako osobną przebudowę.

Dopisek tego samego dnia: zrobione. Wróciłem do tego jeszcze raz i okazało się, że rachunek policzyłem źle. Kluczowa trudność, której się bałem — żeby przesunięcie i przekształcenie kilku warstw naraz dało się cofnąć jednym ruchem, a nie kilkoma — nie istniała: zatwierdzenie i tak już zapisywało stan całego dokumentu. Dostałem ją za darmo i cała przebudowa zeszła do rozmiaru zwykłej fazy. Teraz połączony zestaw przesuwa się, wyrównuje i przekształca jak jedna bryła.

Ciekawsze jest to, że mój własny plan tej przebudowy zawierał błąd tej samej klasy, na którą polowałem. Napisałem w nim, że przy wyrównywaniu wystarczy dołożyć połączone warstwy do listy celów. Gdybym to zrobił, wyrównałyby się do siebie nawzajem i zlepiły na jednej krawędzi — czyli rozjechały rysunek dokładnie tak, jak połączenie ma temu zapobiegać. Zestaw musi liczyć się jako jeden cel, ze wspólnym prostokątem otaczającym. Zauważyłem to dopiero przy czytaniu, jak od lat robią to grupy warstw.

Morał ten sam co w całym tym wpisie, tylko wymierzony w siebie: plan, który brzmi rozsądnie, nie jest jeszcze planem, który działa.

Archiwum starych plików służące do sprawdzania, czy dzisiejszy program otworzy plik sprzed roku, ma na razie tylko wersję bieżącą — a pliku w starym formacie nie da się dziś wytworzyć, bo program umie zapisywać wyłącznie w aktualnym. Taki plik może wyłącznie powstać w czasie. Do tej pory sprawdzenie przechodziło na zielono i wyglądało jak dowód. Teraz wypisuje wprost, że niczego jeszcze nie dowodzi.


Nic z powyższego nie doda ci nowej możliwości. Ale kiedy następnym razem klikniesz coś w tym programie, jest o trzydzieści kilka powodów mniej, żeby zastanawiać się, czy to w ogóle działa. A to jest chyba warunek, żeby narzędziu dało się zaufać na tyle, by o nim zapomnieć i po prostu robić swoje.

📚 Related posts

27.08.2026 20:55

Data, której nie cofniemy nawet my

Każdy certyfikat autorstwa dostaje datę zapisaną w blockchainie Bitcoina — takiej nie podważy nikt, my też nie. Sprawdzisz ją bez konta i bez Moonligh...
Continue reading →
27.08.2026 19:35

Twój kolor, wszędzie

Trzy tryby i siedem akcentów, wspólnych dla strony i Moonlight Animate. Motyw jedzie z kontem, profil pokazuje gościom Twoje kolory, a harmonogram sam...
Continue reading →
27.08.2026 18:31

Kto moderuje i na jakiej podstawie

Moderator to teraz osobna rola z własnym zakresem, a nie administrator w przebraniu. Odrzucenie treści wymaga powodu, który trafia do autora razem z d...
Continue reading →

📧 Stay up to date!

Join the waitlist to get notified about new Dev Blog posts and Moonlight platform launch.