Alt-F4 #44 - Ein neuer Blickwinkel  30.07.2021

Geschrieben von arrow in my gluteus maximus, editiert von stringweasel, Nanogamer7, Conor_, Therenas, Firerazer,
übersetzt von EDLEXUS, lektoriert von marceljoint, Nanogamer7

Inhaltsverzeichnis

Erinnert ihr euch an den ersten April dieses Jahr? Es ist schon etwas her, aber wenn ihr an dem Tag den Subreddit besucht habt, habt ihr mit Sicherheit das verwirrende Video von arrow in my gluteus maximus gesehen. Wenn nicht, wird Ausgabe #44 diese Woche euch auf den neuesten Stand bringen, und erklären, wie diese Darstellung schwarzer Magie vollbracht wurde.

Ein neuer Blickwinkel auf “Ein neuer Blickwinkel auf Züge in Factorio” arrow in my gluteus maximus

Vor zwei Wochen habe ich ein Video namens “A new perspective on trains in Factorio” (de: “Ein neuen Blickwinkel auf Züge in Factorio”) veröffentlicht. Wenn du es noch nicht gesehen hast, schaue es dir an bevor du diesen Artikel ließt, er wird sonst wenig Sinn ergeben.

Manche berichteten von Kopfschmerzen, nachdem sie dieses Video gesehen haben, ich habe dich hiermit gewarnt.

Die Leute, die die in der Beschreibung verlinkte Mod heruntergeladen haben wissen, dass das ganze ein Aprilscherz war. Für alle die es nicht mitbekommen haben: Entschuldigung. Einige haben gefragt, wie ich dieses Video gemacht habe, also habe ich mich dazu entschlossen, einen Artikel darüber zu verfassen. Nicht zuhause nachmachen!

Ich habe einige Spekulationen darüber gehört, das ich irgendwie die 3D-Modelle aus dem Spiel extrahiert habe, aber das ist gar nicht nötig. Es handelt sich nur um eine simple Rotation des Bildes. Obwohl diese Idee erst mal simpel klingt, ist die Umsetzung etwas komplizierter. Das erste Problem ist, das Bildschirme keine Kreise sind, so dass beim Drehen Teile des Bildes abgeschnitten werden, und andere Teile, wie die GUI fehlen.

Am Ende verwendete ich meine übliche Lösung für Aufnahmeprobleme in Factorio: Bildschirmfotos. Bildschirmfotos im Spiel haben nicht die selben Limitierungen wie eine normale Bildschirmaufnahme. Um ein Video aufzunehmen habe ich also jeden Tick ein Bildschirmfoto von einem Bereicht gemacht, der größer ist als das, was normalerweise zu sehen ist, so das beim rotieren keine Ecken fehlen.

Das nächste Problem ist, das die UI mitrotiert, was nicht gewünscht ist. Auch hier können uns Bildschirmfotos helfen. Der take_screenshot() Command hat eine Option namens show_gui. Der Trick ist, jeden Tick zwei Bildschirmfotos zu machen, eins mit der UI und eins ohne. Wenn wir nur die Stellen herausnehmen, die sich unterscheiden, erhalten wir nur das UI, welches wir dann nachher über das rotierte Bildschirmfoto legen können. Das war zumindest der Plan, welcher von einigen Problemen in der Videobearbeitung durchkreuzt wurde. Beispielsweise unterstütz mein Videoeditor keine verlustfreien Formate (zumindest habe ich keine gefunden), deshalb sind kleine Encodingunterschiede in der UI sichtbar.

Ich habe allerdings herausgefunden, das in neueren Factorioversionen die UI in Bildschirfotos nicht mehr an die Position des Spielers gebunden ist. Es ist immer sichtbar, egal von welchem Teil der Karte man einen Screenshot macht. Ich habe mir dann eine Farbe ausgesucht, die so oder so ähnlich nicht wirklich im Spiel vorkommt. Angeboten hat sich da Pink. Ich habe dann die Farbe von Beton auf pures Pink geändert und die Wolken ausgestellt. Die Position der UI habe ich dann so verändert, das rundherum nur pink zu sehen ist, so das ich das UI über eine Art Greenscreen, beziehungsweise eher Pinkscreen, ausschneiden kann.

Pinkscreened UI

Es gab aber auch damit einige kleine Probleme. Es stellt sich heraus, es gibt transparente Teile in der UI, hauptsächlich die Detailanzeigen wenn man über Dinge drüberhovert. Sie sahen jetzt alle pink aus. Ich habe sie am Ende per Hand aus der UI herausgeschnitten, und es scheint niemanden aufgefallen zu sein.

Als nächstes habe ich eine kleine Mod geschrieben, die einen Ton abgespielt hat, wenn ich einen Bildschirmfoto aufgenommen habe, so das ich am Ende den Ingameton mit den Bildschirmfotos synchronisieren konnte, ähnlich zu Filmklappen in Filmen. Die Mod schrieb auch den game.players[1].vehicle.orientation -Wert in eine Textdatei. Ich habe dann diese Werte verwendet, um heruaszufinden, wie weit ich die Bilder drehen muss, geglättet mittels Splines

Ich hatte Angst, das diese Schritte nicht genug waren, um es glaubhaft zu machen. So viele Bildschirmfotos zu machen verlangsamt das Spiel ungemein. Ich hatte Angst, das es offensichtlich war, dass das Video beschleunigt war. Ich habe nach einem Weg gesucht, die Aufnahme zu beschleunigen. Nach Aufnahme der Bildschirmfotos habe ich sie mit FFmpeg in ein mp4 konvertiert, also warum nicht den Zwischenschritt rausschneiden und direkt FFmpeg mit Factorio verbinden. Sowohl pngs encoden, als auch sie auf die Platte zu schreiben sind sehr aufwendige Operationen. Wenn ich also diese Schritte überspringen könnte, wäre es viel schneller.

Schritt eins wäre es, Bildrohdaten direkt aus Factorio zu extrahieren (nicht zu verwechseln mit dem .raw-Format), anstatt sie als png zu speichern. Ich habe keinen einfachen Weg gefunden, das zu tun, aber eine .bmp ist verdammt nah dran. Das sind die Bilddaten in anderer Reihenfolge, mir einem Header am Anfang. Es sollte also vier schneller zu encoden sein als ein png.

Der nächste Schritt ist es, die Bilder in FFmpeg zu bekommen, ohne sie vorher zwischenzuspeichern. Es stellt sich heraus, das FFmpeg eingebaute Features für soetwas hat, so das eine benannte Pipe mit .bmp-Endung das Problem löste. (Beispielcommand: ffmpeg -f image2pipe -framerate 60 -i - -r 60 -c:v libx264 -vf format=yuv420p -crf 1 example.mp4 -y < pipe.bmp)

Man darf nicht vergessen, die Pipeline mit dem sleep-command: sleep 10000000 > pipe.bmp zwischen den Bildschirmfotos offenzuhalten. Am Ende dann den Command killen damit FFmpeg die Aufnahme beendet. Ich habe einen Test mit wenigen FPS gemacht und… irgendwas ist falsch! Was geht hier vor sich?

Das Problem ist, das Bilder untereinander vermischt werden. Factoriorendering ist Multithreaded. Während ein Frame noch in die Pipe geschrieben wird, kann es sein, das der nächste bereits beginnt und die Pixel beider Frames vermischt. Der Fix dafür ist, Factorio dazu zu zwingen, mit dem Beginn den Renderns eines Frames darauf zu warten, das der vorherige beendet wurde. Das kann damit erreicht werden, in jedem Frame game.set_wait_for_screenshots_to_finish() zu rufen. Das verlangsamt Factorio so weit, das wir nicht mehr von Echtzeit reden können. Obwohl ich noch einige Ideen hatte, das ganze zu beschleunigen, hatte ich zu diesem Zeitpunk bereits viel zu viel Zeit aufgewendet und mich entschieden, die alte und bekannte Variante über Replays zu verwenden.

Factorio hat dieses wunderbare Feature, wo nicht überprüft wird, ob der Code der Mods zwischen Aufnahme und Abspielen eines Recordings verändert wurde. Ich habe so zuerst ein Replay mit normaler Geschwindigkeit aufgenommen und dann einen meiner Mods verändert, so das er jeden Tick Bildschirmfotos macht. Beim Abspielen des Replays wird Factorio anfangen, Bildschirmfotos zu machen, wenn die Veränderungen in der Mod nicht den Gamestate verändern.

Traurigerweise musste ich wegen der Verwendung von Replays einige Szenen auslassen. Ich wollte zeigen wie komisch es ist, aus gedrehter Perspektive zu bauen, aber Factorio speichert die Position des Mauszeigers nicht im Replay. Im Replay folgt die UI der Position der Maus beim abspielen, nicht der Mausposition bei der Aufnahme.

Vergleich zwischen normalen Bauen (linkss) und Bauen im Replay (rechts)

Insgesamt war es eine spaßige Herausforderung und ich hatte viel Spaß dabei, die Factoriospieler zu verwirren.

Beitragen

Wie immer suchen wir nach Leuten, die zu Alt-F4 beitragen wollen, sei es mit einem Artikel oder durch Hilfe bei Übersetzungen. Wenn du etwas Interessantes im Kopf hast, das du mit der Community in einer eleganten Art teilen möchtest, hier kannst du das tun. Falls du dir unsicher bist, beantworten wir gerne Fragen zu Inhalt und Struktur. Falls das nach etwas klingt, woran du interessiert bist, tritt unserem Discord bei, um es nicht zu verpassen!