Problem Dreamlinera

Banner image

Lata temu Boeing zapowiadał Dreamlinera jako samolot przyszłości, który miał wyznaczać nowe standardy. Okazało się, że głównym standardem, jaki wyznaczał, była ilość usterek spowodowana wprowadzeniem nieużywanych i nieprzetestowanych wcześniej rozwiązań.

Zamiast latać, samolot stał w hangarach i dostawał kolejne poprawki oraz aktualizacje, a Boeing tracił na każdej jednostce nawet kilkadziesiąt milionów dolarów.

Boeing miał z tymi samolotami problem nawet w 2022, lata po premierze.

Eksperci podają wiele czynników, które wpłynęły na taką sytuację, ale jeden z nich jest też wyjątkowo często widoczny w branży IT:

Poprzednie samoloty Boeinga były w większym lub mniejszym stopniu kolejnymi iteracjami sprawdzonych rozwiązań. Jednak Dreamliner został zaprojektowany od początku i jego najważniejsze systemy były czymś zupełnie nowym. Czymś, z czym Boeing wcześniej nie miał doświadczenia.

Przeprojektowali i zaczęli wymieniać wszystkie najważniejsze systemy jednocześnie. Przy łączeniu ich ze sobą okazało się, że wiele podsystemów nie działa tak, ja powinno.

Osoby, które uczyły mnie programować, nazwały to kiedyś Problemem Dreamlinera i pokazali mi, jak przekłada się to na tworzenie oprogramowania.

Cyberpunk 2077

Jako przykład wykorzystam Cyberpunka, który po premierze okazał się jednym z największych przypałów w historii gier i wg mnie doskonale obrazuje Problem Dreamlinera.

Mogłoby się wydawać, że dla ludzi, którzy stworzyli takie arcydzieło jak Wiedźmin 3 i przy okazji jeden z najlepszych otwartych światów, jest to po prostu kolejny RPG z otwartym światem.

Jednak tak naprawdę jest to zupełnie inna gra, w której przeprojektowali i wymienili wszystkie najważniejsze systemy jednocześnie.

Świat fantasy na świat SF, małą liczbę NPC na olbrzymią liczbę NPC, zamiast koni wrzucili ruch drogowy i samochody (których też jest znacznie więcej niż koni), miecze zastąpili strzelaniem, hakowaniem i walką wręcz, tryb trzecioosobowy zastąpili pierwszoosobowym, miasta można eksplorować wertykalnie... Lista zmian w porównaniu do poprzednich gier jest olbrzymia.

Do tego postanowili jeszcze, że zrobią turbo zaawansowaną graficznie grę, która w dniu premiery będzie działać na 7 różnych konsolach i niezliczonej konfiguracji pecetów.

Przy tak wielkiej skali zmian, ponad miliard złotych budżetu i nadgodziny programistów tym razem nie wystarczyły, żeby dopracować wszystkie mechaniki w grze.

Gra zabiła konsole poprzedniej generacji. "Płynność animacji" schodziła do zawrotnych 15 klatek na sekundę przy rozdzielczości 720p w stresowych sytuacjach - 3 klatki mniej i osiągnąłby poziom dwuwymiarowych animacji Disneya z lat 50. W takim stanie gra była niegrywalna i na jakiś czas Sony wycofało ją nawet ze swojego sklepu.

Do tego: beznadziejne AI, bezduszność NPCów, setki problemów z odpalaniem skryptów, niezliczona ilość małych glitchy typu latające w powietrzu i teleportujące się postacie oraz przedmioty, mnóstwo wyciętych ficzerów.

To wszystko skutecznie zniszczyło obraz otwartego, żyjącego świata, który przez długi czas był po prostu pustą wydmuszką.

Naprawienie większości problemów związanych z wydajnością oraz grafiką zajęło ponad rok, a i tak nie można mówić o pełnym sukcesie.

Inne problemy są stopniowo naprawiane z mniejszym lub większym powodzeniem.

Obecnie gra jest w takim stanie, że sam kupiłem swoją kopię i bardzo dobrze się bawię. Jednak to wyłącznie dlatego, że skupiam się wyłącznie na wątkach fabularnych, które są genialne. Cała reszta, związana z otwartym światem, jest po prostu bezsensowna, niedopracowana i wg mnie zupełnie niepotrzebna. Cały czas muszę przymykać oko na dziesiątki bugów i od czasu do czasu wczytywać stan gry, bo coś się zawiesiło (stan na styczeń 2023).

Nawet nie zahaczając o rzeczy, które były przez lata zapowiadane i nigdy nie wylądowały w finalnej grze widać, że ludzie z CDP wprowadzili zbyt dużo nowych rzeczy naraz i przy łączeniu wszystkiego ze sobą, praktycznie nic nie zadziałało tak, jak powinno.

Cyberpunk, podobnie jak Dreamliner, był przez długi czas uziemiony i teraz, mimo że lata, jest ciągle naprawiany.

Wiele problemów, ze względu na skalę i rozmiar zmian w porównaniu do Wiedźmina 3, nie będzie rozwiązanych nigdy, albo będziemy bardzo długo czekać na poprawki.

Jak robią to inni?

Dobrym kontrastem są gry Rockstara.

Każda kolejna odsłona GTA, to kolejna iteracja dokładnie tego samego - gry o gangsterach w mieście.

Nawet gry z cyklu Red Dead Redemption, są tak naprawdę grami o gangsterach, tylko tym razem na dzikim zachodzie. Mimo zmiany samochodów i miast na konie i pola widać, że te same mechaniki działają pod spodem, w każdej z tych gier.

Rockstar nie wymienia wszystkiego naraz, Rockstar poprawia, szlifuje oraz iteruje.

Każde GTA to lepsza wersja poprzedniej gry.

Pierwsze Red Dead Redemption, było próbą generalną, grą na mniejszą skalę. RDR2 to niewiarygodnie dopracowany wirtualny świat i najprawdopodobniej najlepszy symulator życia w takim świecie, jaki kiedykolwiek powstał.

Cykl wydawniczy też jest zupełnie inny: w 2013 GTA 5 wydali na PS3 i x360, w 2014 na PS4 i Xbox One, w 2015 na PC i w 2022 na PS5 i Series X/S.

Rockstar dał sobie rok (!) na wypuszczenie gry na kolejną generację konsol i jeszcze trochę więcej na wypuszczenie wersji na PC.

To samo było z RDR 2. Nie próbowali robić rewolucji na wszystkie platformy jednocześnie.

GTA 5 miało problemy i bugi, jak każda gra, ale z tego, co pamiętam, obyło się bez dramatów obecnych przy Cyberpunku. Gra została okrzykniętą jedną z najlepszych gier na każdej generacji konsol i jest to najlepiej sprzedająca się gra wszech czasów (poza Minecraftem).

Grafika i mechaniki z RDR2 są porównywane do wszystkich kolejnych gier z otwartym światem i jak na razie ciężko jakiejkolwiek grze je przebić.

Co mi to wszystko daje?

Po pierwsze: gdy widzę, że firma pakuje się w Problem Dreamlinera, to wiem, żeby nie kupować preorderów :).

Poza drugie: nie robię i nie wymieniam wszystkiego naraz:

  • nie wprowadzam zbyt wielu zmian w kodzie naraz
  • nie pracuję nad zbyt wieloma ficzerami naraz
  • nie refactoruję wszystkiego naraz
  • nie komituje wszystkiego naraz
  • nie releasuje wszystkiego naraz
  • nie robię wielkich rewolucji w kodzie
  • nie próbuję nauczyć się wszystkiego naraz
  • nie próbuję robić w pracy wszystkiego naraz
  • nie wprowadzam wielu nawyków naraz
  • nie czytam zbyt wielu książek naraz

Zamiast tego stosuję zasadę skauta, inkrementalny refactoring, buduję próbne rozwiązania i proof of concept, stawiam na ewolucję zamiast rewolucji, rozbijam zadania na mniejsze, robię mniejsze releasy i wprowadzam zmiany w mniejszych iteracjach.

Staram się zidentyfikować jedną najważniejszą rzecz, która sprawi, że wszystkie inne będą prostsze lub niepotrzebne zgodnie z tym, co opisał Gary Keller w książce The One Thing.

What's the ONE Thing you can do, such that by doing it, everything else will be easier or unnecessary?

Większość klientów, z którymi współpracuję, ciągle wpada w Problem Dreamlinera i w końcu wchodzi w tryb ciągłego gaszenia pożarów. Żeby szybciej łatać bugi i dowieźć aplikację na produkcję, dorzucają do zespołu kolejne osoby, które potykają się o siebie nawzajem.

Jeden z najczęstszych argumentów dla takiego postępowania: "ale przecież to jest w innej, odrębnej części systemu, więc można to robić równolegle".

Na początku kupowałem ten argument, bo brzmi sensownie. Jednak koniec końców zawsze trzeba te odrębne części połączyć ze sobą. I niestety dzieje się to najczęściej na ostatnią chwilę, przed samym releasem i w momencie, gdy każdy programista jest zajęty problemami z własnymi zadaniami.

Wtedy każde oderwanie się od swojego zadania, żeby zintegrować swój kod z kodem, który człowiek widzi pierwszy raz na oczy, to olbrzymi wysiłek mentalny, który bardzo często prowadzi do kolejnych bugów, opóźnień i niedopatrzeń.

Najbardziej bezproblemowe projekty, w których brałem udział to te, w których klienci nie próbowali zarzucać problemu kolejnymi programistami, tylko ustalali priorytety i mieli jasno zdefiniowany zakres MVP, który potem stopniowo ulepszaliśmy.

Niestety programiści również z własnej winy pakują się w te same problemy.

Przykładowo: zamiast wprowadzać małe zmiany inkrementalnie, robić mniejsze pull requesty, które da się przeczytać w 10 minut i mergować zmiany w małych porcjach, robią jeden wielki PR, którego code review zajmuje kilka godzin, poprawki trwają nawet kilka dni, a zmergowanie do głównego brancha w efekcie rozciąga się czasem nawet na kilka tygodni, stopniowo zabijając zapał nawet najbardziej zapalonych programistów.

Smutno się wtedy patrzy na autora tych wielkich zmian, bo dostaje kilkadziesiąt komentarzy na CR, które potem naprawia przez kilka godzin (lub dni).

Czasem okazuje się, że musi większość kodu przepisać, bo nie o to chodziło i w efekcie pozbawia sam siebie przyjemności płynącej z dowożenia zadania.

Traci całą motywację, jeden z najważniejszych elementów produktywności, który pozwala oszczędzać punkty szaleństwa i WTFy, tak bardzo potrzebne w naszej pracy.

Zdaję sobie sprawę, że w niektórych projektach, zwłaszcza legacy, wprowadzanie małych zmian jest ekstremalnie trudne, ale można próbować i widzę, że zbyt rzadko to robimy.

Podsumowując

Problem Dreamlinera występuje wtedy, gdy próbujemy wprowadzić zbyt wiele zmian w tym samym czasie. Prowadzi to do opóźnień, nieprzewidzianych bugów oraz utraty znacznej ilości naszych punktów szaleństwa, bo musimy ogarnąć bardzo szeroki kontekst zmian.

Żeby obejść ten problem, staram się nie wprowadzać zbyt wielu zmian naraz, zmniejszyć ilość rzeczy, które w tym samym czasie biorę sobie na głowę. Dotyczy to programowania, pracy, nauki nowych rzeczy i ogólnie życia.

Dobrze działa u mnie rozbijanie zadań na mniejsze części, tworzenie MVP, ustalanie priorytetów i wprowadzanie zmian stopniowo. Ciągłe dowożenie nowych, dopracowanych funkcjonalności w małych partiach to chyba najlepszy sposób na podbicie motywacji i produktywności.