Kategorien
Computerspiele Kritik

Spielkritik: Shadow of the Tomb Raider (2018)

Shadow of the Tomb Raider, der zwölfte Teil der Reihe, der dritte des Reboots. Die Vorgänger, Tomb Raider und Rise of the Tomb Raider, hatten mit ja gut gefallen, mit der Kritik, dass das Raiden von Tombs etwas umfangreicher sein könnte, insbesondere im zweiten Teil war da schon eine deutliche Verbesserung zu spüren.

Im dritten Teil (und hoffentlich letzten, in dem wir die strunzlangweilige Originstory um die verlorene Familie und Laras Vaterkomplex durchspielen müssen), verursachen wir in der Anfangssequenz den Weltuntergang, den wir im Lauf des Spiels verhindern müssen. Aufhänger ist mayanische Mystik um die Stadt Paititi, wir lernen viel über den religiösen Hintergrund, während wir Trinity bekämpfen und den Weltuntergang abwenden wollen.

Das Spiel ist visuell und akustisch extrem beeindruckend. Was da aufgefahren wird, erstmals hab ich wirklich angehalten und die Welt angesehen. Gerade in hektischen Sequenzen geht unter, wie viele Details und wie viel Tiefe die Spielwelt hat. Das ist teilweise einfach wunderschön anzusehen.

Die Jaguare: wenn die angreifen, das grollt und brüllt und sieht sooo gut aus…

Überhaupt: die Töne. Es raschelt, grunzt, schreit, grummelt, zischt an allen Ecken und Enden, genau im Raum lokalisierbar – beeindruckend.

Sehr gut gelungen ist (wieder einmal) die Vertonung von Lara, hier gilt Camilla Luddington großer Dank, aber auch die Mimik und Laras Bewegungen sind sehr, sehr gut gelungen. Wenn sie mitten im Spiel mal kurz zur Kampfmaschine wird, dann sieht man das bereits am Gesichtsausdruck. Und weiß, da will man jetzt nicht der Gegner sein.

Auch der Humor zieht, wenn er denn mal eingesetzt wird. Leider viel zu wenig.

Gut gelungen ist auch, dass man sich grundlegende Waffen nicht erst spät im Spiel erspielen muss, man kann ziemlich gleich mit Pfeil und Bogen losziehen, das Maschinengewehr hab ich nur in unübersichtlichen Massenkämpfen eingesetzt, Pistole und Pumpgun sind für mich nicht nötig gewesen.

Die Geschichte ist in Ordnung, für mich hätte die ganzen Anspielungen auf ihre Eltern nicht sein müssen, aber sie nehmen genügend wenig Raum im Spiel ein.

Die Kontrolle über Lara ist noch mal besser geworden, lediglich bei Sprüngen und „direkt vor etwas stellen“ ist das manchmal ungenau. Außer in den Actionsequenzen, wenn die Kamera vom Spiel übernommen wird und damit die Steuerung anders ist als im Rest des Spiels. Da bin ich doch sehr häufig neben das Ziel gesprungen. Das ist sehr ärgerlich.

Apropos ärgerlich: hat sich irgendjemand tatsächlich ausgedehnte Unterwasserpassagen mit Luftmangel und nichtsterblichen Gegnern gewünscht? War das nicht schön, dass es das in den Vorgängerspielen nicht gab?

Und die elendiglichen Cut-Scenes. Es gibt sie noch und sie bringen nicht so viel, wie die Entwickler gerne hätten.

Und die Verlangsamung der Bewegung. Das bleibt mir bei 45 Stunden Spielzeit in Erinnerung, obwohl es wahrscheinlich nur 3 Minuten ausgemacht hat. Es ist soooooo nervig.

Die Übersichtskarte finde ich nicht mehr übersichtlich, da war die von Teil 1 am besten bisher.

Ach ja, das Raiden von Tombs ist etwas ausgebaut worden, aber nicht wirklich schwierig. Hier hätte durchaus mehr sein können, dafür muss ich nicht unbedingt als One-Woman-Desaster-Area Horden von Leuten umbringen.

Obwohl: die Szene in der Raffinerie – die ist schon sehr, sehr cool.

Und ein letzter Kritikpunkt: das ganze Aufleveln war im ersten Teil noch ok, im zweiten schon etwas kompliziert und ist in diesem Teil sowas von übertrieben. Mit verschiedenen Pfaden und Kosten und was weiß ich. Ich will mit Lara spielen und mir nicht Gedanken drüber machen, ob ich zwei oder drei Pfeile gleichzeitig abfeuern kann und welche Kräuter ich sammeln muss und, und, und…

Denn dazu bin ich sowieso nicht gekommen. War es im zweiten Teil noch einfach, sich an Leute anzuschleichen und sie ruhig zu ermorden, sind die hier sofort auf der Hut, da brauche ich dann die meisten Fähigkeiten nicht mehr. Dazu ist das Kaufen und Verkaufen ausgebaut worden – wem macht denn so etwas Spaß?

Dennoch: das Spiel ist toll. Ich fürchte zwar, dass in einem Nachfolger die Kritikpunkte noch mehr ausgearbeitet werden, weil Spieleredakteure und -rezensenten (ja, Männer) sowas mögen und keine Casual Gamer sind, aber ich werd es mir trotzdem holen.

Fazit: sehr, sehr gutes, wunderschönes Spiel mit kleinen Unannehmlichkeiten.

Kategorien
Computerspiele Kritik

Spielkritik: Duke Nukem Forever (2011)

Nach dem großen Erfolg von Duke Nukem 3D war klar, dass schnell ein Nachfolger kommt, der das Spiel aufgreift, leicht verbessert und viel Geld einbringt.

Leider hat das nicht geklappt. Keine Ahnung, was genau schiefgegangen ist, mit hoher Wahrscheinlichkeit schlechtes Projektmanagement, überzogene Ansprüche und so. Fast jedes Jahr kam neue Hoffnung auf, dass der Duke wiederkommt, ab 2001 wurde „when it’s done“ zum geflügelten Spruch für die Development Hell. 2009 ging dann 3D Realms pleite und ich dachte, das wird gar nichts mehr.

Dann plötzlich war das Spiel 2011 fertig, ein extrem sexistischer Ausschnitt kündigte das Spiel an, von dem ich noch dachte, dass er ironisch mit den Erwartungen der Spieler:innen spielt (ja, das war Naivität oder Blödheit, wahrscheinlich eine Mischung aus beidem).

Da lag ich weit weg. Das Spiel ist sexistische Kackscheiße und ein richtig, richtig schlechtes Spiel. Ladezeiten aus der Hölle, Gameplay aus der Hölle, Steuerung aus der Hölle, Level, die einfach unterirdisch schlecht sind. Wenn man sehen will, wie ein Computerspiel nicht sein sollte, dann Duke Nukem Forever spielen.

Höhepunkt die Wände mit Brüsten, auf die man schlagen soll. Im gleichen Level soll man alle Frauen, die dort schwanger an Pfähle gebunden sind, erschießen.

Ich denke mir das nicht aus, das ist im Spiel drin und das ist ernst gemeint.

Damit war der Duke dann auch tot, davon erholt sich nicht einmal eine ironische Spielfigur, es zeigt auch gut das Problem in der Spieleszene, dass die Entwickler und das Gamestudio dachten, dass so ein Spiel ok ist.

Während ich sonst froh bin, wenn ich daran beteiligt sein kann, wenn Spielgeschichte geschrieben wird (Doom, Duke Nukem 3D, Half Life) ist das hier eindeutig der Tiefpunkt meiner Spielerkarriere.

Wenn die Spieleindustrie wenigstens draus gelernt hätte…

Kategorien
Computerspiele Kritik

Spielkritik: Duke Nukem 3D (1996)

Nach dem Riesenerfolg von Doom und Doom II schossen natürlich Nachfolger wie die Pilze aus dem Boden. Unter ihnen Duke Nukem 3D, der Nachfolger zweier 2D-Plattformer, der den nächsten Standard für FPS setzte. Entwickler firma: 3D Realms.

Im Gegensatz zu Doom kann die Spielerin mit dem Jetpack fliegen und die Umgebung deutlich mehr zerstören als das Doom zuließ. Dazu kamen interessante Gegner und ein schnodderiger Duke, der klar an den Ash aus Army of Darkness angelegt ist und seine Zitate fast vollständig aus diesem Film schöpft. Dazu kommt ein leichter Sexismus, der damals zum guten Ton gehörte, jedoch noch halbwegs in den Sphären von Big Trouble in Little China und ähnlichen Filmen schwebte.

Das Spiel ist ein Klassiker und das zu recht. Das Leveldesign ist phantastisch und abwechslungsreich, die Gegner sind gut, der Schwierigkeitsgrad ist anspruchsvoll aber nicht unfair.

Eine interessante Waffe z.B. ist die Verkleinerungskanone, mit der die Gegner soweit verkleinert werden, dass man sie mit dem Fuß zerstampfen kann.

Das war’s eigentlich schon, Genrefans können einen Blick riskieren, im Gegensatz zu Doom finde ich das Spiel schlechter gealtert, das Leveldesign ist zwar gut, aber die Gags und Art des Duke sind doch sehr aus der Zeit gefallen.

Einziger Wermutstropfen: die Entwicklungshölle für einen Nachfolger und dessen unterirdische Qualität.

Fazit: Klassiker des FPS-Genres.

Hail To the King, Baby.

Kategorien
Computerspiele Kritik

Spielkritik: Doom 3 (2004)

Wie gestern schon geschrieben, sorgte der Erfolg von Quake dafür, dass Doom acht Jahre nicht fortgesetzt wurde. Pläne, Doom weiterzuführen, gab es jedoch schon die ganze Zeit und id sah die Möglichkeit, eine neue Engine mit einem neuen Doom zu promoten.

Dazu muss gesagt werden, dass id damals (heute weiß ich nicht) deutlich mehr Geld an Engines verdiente, insbesondere an der Quake-Engine, als an den Spielen selbst. U.a. um die Möglichkeiten zu zeigen und diese zu promoten wurden dann Referenzspiele wie Doom 3 erzeugt.

Außerdem muss man löblich erwähnen, dass id sehr lange auf plattformübergreifende Engines gesetzt hatte, insbesondere um Linux-Gaming hat sich id sehr verdient gemacht.

Vor diesem sehr positiven Hintergrund: Doom 3 ist ein Griff ins Klo.

Doom und Doom 2: Spiele ohne Geschichte, bei denen es darum geht, Horden von Dämonen zu metzeln und das in einer unglaublichen Geschwindigkeit mit einer vorgegebenen Anzahl von unveränderlichen Waffen, die einfach nur schießen.

Doom 3: ein sehr, sehr langsames Spiel mit viel Geschichte und ab und an gesetzten Spitzen von Dämonen mit Waffen, die man verbessern kann und die äußerst kompliziert einzusetezn sind, teilweise mit Aufladen durch Kills.

Man drückt auf eine Taste und mehrere Sekunden später setzt sich die Spielfigur in Gang und schleicht vor sich hin, dass man Tränen in den Augen bekommt. Keine Freudentränen.

Ja, das Spiel sieht grandios aus. Ja, die Atmosphäre ist gruslig. Ja, gegen Ende hin wird das Spiel besser. Ja, der Zeitgeist verlangt nach Spielen mit Story, Atmosphäre und Aufleveln. Ja, Half Life hat mit diesen Zutaten ein geiles Spiel gemacht (obwohl Gordon Freeman nie so langsam wird wie der Doom Guy hier). Ja, die Kritiker fanden das gut und kritisierten maximal die Reminiszenzen an die Original-Dooms(!)

Aber nein: das ist kein Doom. Das ist ein guter Horrorshooter mit Atmosphäre aber kein Doom.

Ich bau doch keine Ducati, die aussieht und sich fährt wie eine Goldwing und sag dann: tolle Ducati.

Und ja, alle anderen liegen hier falsch und ich hab Recht.

Ich hab da Spiel durchgespielt, teils aber nur aus Pflichtbewusstsein. Und das ist es doch nicht.

Was hab ich mich drauf gefreut…

Und wenn dann das Doom rauskommt, das ich haben will – hab ich eine PS 3! Argh. Wird besser, hab aufgerüstet aber noch nicht durchgespielt.

Ich könnte jetzt Detailkritik üben an den luftleeren Phasen, den unnötigen Schockeffekten, dem Leveldesign, der allgemein vorherrschenden Dunkelheit aber das würde am Thema vorbeigehen, denn für ein anderes Spiel sind das passable Elemente.

Aber Doom.

Fazit: nix für mich.

Kategorien
Computerspiele Kritik

Spielkritik: Doom II (1994)

Klar gab es nach dem Erfolg von Doom einen zweiten Teil. Glücklicherweise nur ein Jahr nach dem ersten. Glücklicherweise wurde nichts neu erfunden, sondern der erste Teil verbessert.

Doom II.

Größer. Viel größer. Mehr Dämonen, darunter fiese Zeitgenossen wie der Arch-Vile, der Mancubus oder der Revenant. Eine neue Waffe: die Super-Shotgun (aus der Nähe ein Schuss für einen Demon).

Die Geschichte: die Dämonen sind auf die Erde gelangt, müssen getötet werden und dann geht es in die Hölle zum Endkampf.

Es gibt 30+2 Bonuslevel, die hintereinander durchgespielt werden, als Verbesserung zu Doom sind die Level gigantisch groß und extrem gut gebaut. Jeder Level hat seinen eigenen Charakter, überall bewegt sich was, und mit einer guten Strategie kann man viel erreichen.

Zwei neue Monster, Heavy Weapon Dude und Pain Elemental finde ich nicht so gut gelungen, aber das ist Beschweren auf hohem Niveau.

Die Freude, die Level zu erkunden, zu sehen, was sich Sandy Petersen und American McGee ausgedacht haben und die Freude, wenn man einen Level endlich geschafft hat…

Apropos Level geschafft, ich kann das Spiel nicht durchspielen, für den letzten Level, Icon of Sin, fehlt mir die spielerische Qualität. Selbst im God Mode ist das Ding nicht schaffbar. Ich hab mir ein paar Videos angesehen, wie es geht: es bleibt unschaffbar.

Macht aber nix, der Rest macht einfach nur Spaß. Keine Story, die man durchleiden muss, kein Waffenaufleveln, keine Ablenkung vom Ziel des Spiels: Spaß.

In Deutschland gab es wieder Indizierungsunfug, das war nicht anders zu erwarten.

„Leider“ erfand id software danach Quake, das mit einer neuen Engine und Quake Arena das Netzwerkspielen revolutionierte. Das bedeutete für Doom leider eine Pause von acht langen Jahren bis zum nächsten Spiel, lang insbesondere, weil ich mit Quake nie warm wurde.

Fazit: ein weiterer Meilenstein der Spielgeschichte, noch einen Tick besser als Doom.

Kategorien
Computerspiele Kritik

Spielkritik: Doom (1993)

Doom.

Der Beginn der Ära der Computerspiele.

Das Computerspiel.

Genredefinierend. Unendliche 3D-Freiheit. Unglaublich schnell. Präzise Steuerung. Ausgefeilte Grafik.

Sowas hatte die Welt davor noch nicht gesehen. Ein 3D First Person Shooter, bei dem man sich in drei Dimensionen bewegen kann! Wände, die nicht in 90-Grad-Winkeln zueinander standen! Vorher gab es Wolfenstein 3D, dann kam Doom und blies die restlichen Spiele einfach weg. Unmengen von Spieler:innen saßen gebannt an Rechnern und lieferten sich Kämpfe mit Dämonen aus der Hölle.

id Software, John Carmack, John Romero, Sandy Petersen.

Die erste Episode wurde über Uninetzwerke als Shareware verteilt, die zwei weiteren Episoden mussten dann bezahlt werden. (Obwohl das Spiel in Raubkopien ohne Ende verteilt wurde (hab ich gehört), bekam id Software Unmengen von Geld für das Spiel. Unmengen.) Die Level-Dateien wurden mit der Dateiendung .wad (Where’s All The Data) abgespeichert, daher der Begriff des wad-Files, in dem ein Level mitsamt Grafiken gespeichert wurde. Ein weiterer Durchbruch kam mit dem Port auf Windows 95, der von Microsoft bezahlt wurde, um Windows 95 als Spieleplattform zu etablieren.

Doom machte bereits im ersten Wurf so gut wie alles richtig. Die Engine war unglaublich schnell und fast fehlerfrei programmiert. Die Level waren anspruchsvoll aber sehr spielbar. Die Steuerung war und ist extrem einfach und eingängig, nicht überfrachtet, nicht zu simpel. Die Grafik war bahnbrechend, die Musik angeblich auch gut (ich hatte für Doom noch keine Soundkarte). Das Spiel konnte langsam oder schnell gespielt werden, Speedruns sind auch heute noch problemlos möglich. Und es war möglich, eigene Level als wad-Files zu erstellen und mit anderen zu teilen.

Damit etablierte sich Doom nicht nur als gutes Spiel, es definierte auch 3D-FPS sehr früh in Punkto Spielmechanik, Waffen, Waffenauswahl, Interaktion etc. Die Automap-Funktion z.B. wurde bereits hier etabliert. Das Speichern und Laden war eine Frage von Sekundenbruchteilen auf der Hardware von 1993! Die Levelgestaltung enthielt geheime Räume und Easter-Eggs.

Natürlich war der Titel in Deutschland von 1994 bis 2011 indiziert, es ist so lächerlich, noch lächerlicher als die Farce um Evil Dead. Auch international wurde das Spiel zum Synonym für die Verrohung der Jugend durch Computerspiele und man weiß nicht, was man dazu sagen soll, wenn es nicht heute noch nachwirken würde, insbesondere in Person von CDU-Politikern und Innenministern.

BPjS damals: „Vom Wahnsinn erfaßt gehen Forscher und Testpersonen zum blutigen Angriff aufeinander über.“

Hatte ich schon lächerlich erwähnt?

Die Geschichte im Spiel ist schnell erzählt: auf Phobos und Deimos sind Tore zur Hölle entstanden, durch die Dämonen und anderes Zeug gekrochen kommt, das umgebracht gehört. Das wird uns auf drei Schriftseiten mitgeteilt, der Rest ist pures Geballer.

Erstaunlicherweise ist der Mangel an ausgefeilter Geschichte nicht schlimm, denn welche Zusatzmotivation würde mir eine weitere Geschichte bieten? Nicht viel, wie Doom 3 beweist (das auch noch andere Mängel aufweist). Carmack selbst (zu Recht):

Story in a game is like story in a porn movie; it’s expected to be there, but it’s not that important.

Die Figuren des Spiels sind ikonisch: Baron of Hell, Cyberdemon, Cacodemon, Imp, Lost Soul, Spectre, Spider, … Jede:r, der/die das Spiel gespielt hat, kennt die Typen und weiß exakt, wie man sie besiegt. Demon, zwei Schüsse mit der Shotgun aus der Nähe. Lost Soul einer, aber die Nerven behalten beim Ranfliegen.

Die Waffen des Spiels sind ikonisch: die Kettensäge. Die Shotgun. Der Raketenwerfer. Und natürlich die BFG 9000.

Was ist noch ikonisch? Cheat Codes. IDCLIP: durch Wände gehen. IDDQD: God Mode. IDKFA: Full Keys, Weapons And Ammo.

1997 wurde der Quellcode der Doom-Engine veröffentlicht, 1999 wurde er unter GPL gestellt. Das brachte Doom natürlich noch eine weitere, riesige Verbreitung, so dass es heutzutage kein Computersystem gibt, auf dem Doom nicht läuft. Inclusive Displays von Druckern. Der Quellcode soll übrigens sehr gut geschrieben sein, ich hab ihn mir noch nicht angesehen, ich kenne mich mit C nicht so gut aus, dass ich das einschätzen könnte.

Was gibt es noch zu erzählen? Die Entwickler haben einen seltsamen Sinn für „Humor“, in den ersten Versionen von E1M4 war ein Hakenkreuz versteckt, angeblich ganz unschuldig, immerhin wurde es in späteren Versionen entfernt.

Ach ja: ich war dabei. Während ich die erste Welle der Computerspiele auf Heimcomputern wie C64, Amiga, Atari etc. verpasst hatte bzw. spät dazugestoßen bin, war ich bei Doom von Anfang an dabei und konnte so die Entwicklung der FPS und der weiteren Computerspiele selbst miterleben. Das ist schon cool, bis man irgendwann abgehängt wird durch andere Sachen, aber das ist ok.

Damals waren Computer extrem teuer und ich war jung und brauchte das Geld. Daher hatte ich für Doom keine Soundkarte zur Verfügung und konnte das Sounddesign erst bei Doom 2 erleben. So habe ich erst im zweiten Teil gelernt, dass man die Gegner früher hört als sieht und dass Geheimtüren akustisch unterschiedlich reagieren. Hab es trotzdem durchgespielt. Bei mir lief als Hintergrund Metallica oder Motörhead.

Ich kann das Spiel heute noch durchspielen und bis auf wenige Ausnahmen kenne ich das Leveldesign, Geheimverstecke, Easter Eggs. Das geht aber jede:r Spieler:in mit dem ersten Spiel so.

Wenn man das Spiel heute ansieht, ist es potthässlich, geblieben sind aber Schnelligkeit und Spielbarkeit. Von daher lohnt sich ein Blick des Spielprinzips wegen, grundsätzlich hat id aber mit dem Doom-Reboot einen schöneren Nachfolger geschaffen, der die gleiche Schnelligkeit aufweist, sich leider aber in der Auflevelung der Waffen und sonstigem Nebengeraffel vertut. Aber das ist der Zeitgeist, gefällt genügend Leuten.

Fazit: Meilenstein der Spielegeschichte, bester FPS ever (bis Doom 2 kam), immer noch ein sehr, sehr gutes Spiel.

Kategorien
Computerspiele Kritik

Spielkritik: Rise of the Tomb Raider (2015)

Da der Reboot durchaus erfolgreich war, kam die fällige Fortsetzung zwei Jahre später auf den Markt: Rise of the Tomb Raider. Leider nur ab PS 4, mangels einer solchen und eines fähigen Spielerechners konnte ich den Teil erst dieses Jahr nachholen.

Technisch wird wieder die Underworld-Engine verwendet – das garantiert schon mal wirklich gute Grafik und gute Steuerung (mit Einschränkungen beim Springen).

Wir begleiten Lara (wieder einmal) in ihrer Weiterentwicklung zur Lara, die wir eigentlich spielen wollen, ok, das ist grad das Ding der Entwickler – muss ich nicht gut finden als Idee. Ist aber, wie beim Reboot, ordentlich umgesetzt.

Lara selbst wurde im Gesicht verändert, sie sieht jetzt irgendwie puppenartiger aus. Wieder so eine Sache, auf die ich schwer den Finger legen kann, aber da musste ich mich eigentlich am längsten dran gewöhnen, irgendwas stimmt da für mich nicht.

Wir steigen ein mit dramatischen Szenen in Sibirien, wo wir uns durch eine Cut-Scene-Hölle spielen müssen. Ja, ich stehe spielbaren Cut-Scenes eher skeptisch gegenüber, insbesondere im Reboot war das viel zu viel und viel zu simpel. Das wird hier besser gelöst. Der Anfang lässt zwar Schlimmes vermuten, das war es aber schon fast, der Rest des Spiels verzichtet größtenteils auf diesen „Kniff“ – sehr angenehm.

Dann Rückblende, wir spielen uns nach Sibirien – ach nee, das ist schon in Filmen nicht meins, in Spielen erst recht nicht. Zwei Filme kenne ich, die das gut machen: Pulp Fiction und Memento, Spiele kenn ich gar nicht. Es ist ok, von vorn nach hinten zu spielen. Aber wie auch der Anfang: es wird einmal gemacht, dann wieder gelassen, ok.

Zurück in Sibirien sind wir erst einmal sehr langsam unterwegs, können uns nicht bewegen, Waffen kannste vergessen und ich dachte schon: uiuiui. Was auch immer Entwickler da treibt: nein. Macht das nicht. Realismus hin und her: ich bringe hier problemlos Bären um, erledige alleine mit Pfeil und Bogen eine russische Armee, kann stundenlang mit Kletterhaken kopfüber klettern, aber durch Schnee kann ich nur langsam stapfen?

Aber auch hier wieder: dauert zum Glück nur kurz und dann nimmt das Spiel endlich Fahrt auf. Also am Anfang drei Todsünden raushauen und dann besser werden – lasst das bitte nicht die Standardstrategie werden.

Wobei im Endkampf die letzte begangen wird, aber dazu später.

Jetzt arbeiten wir uns durch die Welt durch und die ist wunderschön. Wirklich. Manchmal einfach stehenbleiben und umsehen. Oder mit Dingen interagieren. Wir sind von freier Bewegung oder Untersuchung der Welt zwar noch weit entfernt aber schon deutlich freier als im Reboot. Es macht Spaß, einfach mal auf Bäume zu klettern und zu gucken.

Storytechnisch suchen wir ein Artefakt, das unsterblich macht, weil Laras Vater das auch gesucht hat. Ja, die Fixierung auf den Vater ist wie im Reboot vorhanden und bringt mir nix. Lara tut in diesem Teil alles nur, um ihrem (toten) Vater nachzueifern und das wird gerade hinten heraus sehr obsessiv und ist nicht gesund. Im Abspann lösen wir uns davon, aber bis dahin ist es ein langer Weg durch diverse Nachrichten, Dokumente und Gedanken. Und ja: beim ersten Spielen guck ich mir das alles an.

Für das Artefakt reisen wir durch Sibirien, dann ein Tal und später ein Kloster, die Orte sind alle sehr gut umgesetzt und oft positiv sehr offen gestaltet. Leider wird unsere Bewegung oft künstlich eingeschränkt, oft sehr fadenscheinig: so können wir bis zur Mitte des Spiels unser Messer zwar zum Ausweiden von Tieren benutzen, nicht aber zum Zerschneiden von Stricken.

Die Welt wird gerade ab dem Tal von Menschen bevölkert, mit denen wir nicht nur durch Pfeil und Bogen interagieren, sondern mit denen wir uns unterhalten und denen wir helfen können. Das ist eine angenehme Abwechslung und hier wurde eine sehr gute Mischung aus Text und Action gefunden.

Ebenfalls ist es sehr schön, dass der Abenteueraspekt etwas mehr hervorgehoben wurde, es ist mehr zu sehen, auszuprobieren, zu erforschen. Insbesondere die Anzahl und Qualität der Tombs ist erhöht worden. Dennoch: das ist noch weit entfernt von dem Tomb Raider, das ich spielen will, bei dem man nur Tombs raided und gut ist. Aber man muss sich halt auch an das aktuelle Spiel anpassen: der Schwerpunkt liegt hier anders und im Rahmen dessen wurde das gut umgesetzt.

Neben dem Tombs gibt es noch Herausforderungen und Missionen, die den linearen Spielablauf unterbrechen. Hat mir sehr gut gefallen, das Konzept.

Was mich stört ist, dass man die einzelnen Areale nicht komplett durchspielen kann, bevor ein neues in Angriff genommen wird, da uns dafür bestimmte Fähigkeiten noch fehlen, die wir erst später erspielen (das Messer zum Beispiel). Wir müssen dann später zurückkommen. Auch, dass wir uns bestimmte Fähigkeiten bzw. Gegenstände kaufen müssen (in Spielwährung) ist nicht so meins, das holt mich stark aus dem Spiel heraus. Auch das Aufleveln von Waffen und Fähigkeiten am Camps. Ist ok, halt nicht so meins.

Nach 47 Stunden stehen wir dann dem Endgegner gegenüber und zum einen ähnelt der Kampf sehr stark dem Endkampf des Reboots. Zum anderen: ich levele alle meine Waffen auf, bin top ausgerüstet aber zum Endkampf wird mir das alles weggenommen? Ernsthaft? Außerdem musste ich eine Fähigkeit nutzen, die ich bisher nicht eingesetzt hatte: Bomben basteln und auf Gegner werfen. Krieg ich hin, aber macht nicht wirklich Spaß. Aber das ist nur eine kurze Sequenz und durch sind wir: Welt gerettet, von Vater emanzipiert (hoffentlich), Happy End.

Der Schwierigkeitsgrad des Spiels ist angenehm spielbar (ich spiele auf „normal“), ich bin größtenteils ohne Hilfe durchgekommen. Dreimal musste ich das Netz bemühen, zweimal wegen Nichtigkeiten, einmal, weil ich partout ein Artefakt nicht gefunden habe. Ich hab alle Missionen, Herausforderungen und Tombs gelöst, alle Dokumente und Artefakte gefunden, bis auf ein Dokument, das in der Zusatzmission „Baba Jaga“ an einer Stelle liegt, für die ich eine Sequenz auf die Zehntelsekunde timen muss und für jeden neuen Versuch ca. eine Minute Vorbereitungszeit brauche (oder ich sterbe, dann zwei Minuten). Nach einer Stunde probieren bin ich jetzt soweit, dass ich auf das Dokument verzichte. Vielleicht versuche ich es später noch einmal.

Insgesamt ist das Spiel sehr gut gelungen, viele Kritikpunkte des Reboots wurden angenommen und verbessert, die Spielbarkeit erhöht (Springen ist noch zu ungenau, sonst alles gut) und die Balance zwischen Abenteuer und töten deutlich verbessert. Was nicht heißt, dass Schwarzenegger nicht neidisch wäre, mit welcher Wucht und Gradlinigkeit ich hier Massen von Gegnern töte. Möglichst mit dem Bogen, das ist eleganter. Aber ich kann auch mit Explosionen, Gift oder Feuer arbeiten.

Apropos Waffen: mit dem Bogen kommt man gut durch, bei manchen Massenszenen ist das Maschinengewehr besser geeignet. Erstaunlicherweise habe ich auch virtuell ein Problem damit, Bomben auf Menschen zu werfen oder Sprengfallen aus Menschen zu bauen (ernsthaft, das geht deutlich zu weit), aber ich hab einen Heidenspaß dran, Zusatzpunkte zu bekommen, wenn ich Kopfschüsse am Stück verteile (acht in Folge mein Rekord). Schon seltsam.

Wie schon gesagt, die Welt ist wunderschön, es lohnt sich tatsächlich, sie sich anzusehen. Nicht nur die Berge und Landschaft, auch die Tiere, Häuser etc.

Und es sind schöne Spielideen dabei: Hühnerwerfen zum Beispiel. Das ist angenehm albern, insbesondere im Kontext der Bedrohung.

Und in der Baba-Jaga-Mission schafft es das Spiel, eine richtig gruslige Atmosphäre zu erschaffen – das ist schon was.

Was auch angenehm ist, dass die Hilfe halbwegs vernünftig auf das eigene Spielen eingestellt werden kann. Leider muss man für alle Geheimnisse zu oft „den Blick“ anwenden und hier wird Lara schwatzhaft, was unsere derzeitige Aufgabe angeht. Hier wäre mehr Einstellbarkeit besser.

So viel dazu, das Spiel hat Spaß gemacht, selten gelangweilt und wartet mit schönen Szenen und Herausforderungen auf.

Ein wirklicher Faux-Pas war die exklusive Veröffentlichung auf Xbox 360 und Xbox One zum Start – das war wirklich ein Mittelfinger gegenüber den PS-Spieler:innen, die das Spiel großgemacht haben. Außer Geldgier gibt es da auch keine Entschuldigung.

Fazit: sehr, sehr gutes Spiel mit der neuen Lara Croft.

Kategorien
Computer Programmierung

Java-Stream-API

Weil ich gestern das Script hatte: die Stream-API von Java ist schon geil für einige Anwendungsfälle. Kurz, prägnant und lesbar.

Ausschnitt vom Code gestern: einmal Pfad bis in die Unterverzeichnisse traversieren und die Dateien bearbeiten:

try (Stream<Path> paths = Files.walk(pathSource)) {
  paths
    .filter(Files::isRegularFile)
    .filter(path -> path.toString().endsWith(EXTENSION))
    .forEach(path -> processFile(path, args[1], Integer.parseInt(args[2])));
}

Gerade das Filter-Map-Reduce-Pattern macht was her (Map ist im Beispiel nicht dabei).

Aber ich finde es nicht einfach zu lernen und da ist viel try-error und Nachlesen (ich hab mir ein Buch gekauft!) dabei, gerade bei Syntax, Variablen-Zugriff und sonstigen Nebeneffekten.

Die Funktion processFile z.B. darf keine Exception werfen, sondern nur RuntimeException, weil das sonst nicht compiliert. Hat bestimmt seinen Grund, ist aber programmtechnisch blöd, weil nicht mehr so sauber.

Aber irgendwas ist immer…

Kategorien
Computer Programmierung

Java als Scriptsprache

Mal etwas anderes als Filme: Seit Java 11 kann man Java als Scriptsprache einsetzen, das heißt, direkt eine Java-Datei aufrufen.

Im Endeffekt schreibt man eine Klasse mit main-Methode, die die Arbeit erledigt (man kann wohl mehrere Klassen in eine Datei packen, aber wer macht sowas).

Was rauskommt, ist typisches Scripting der ersten Stunde: Spaghetticode, der eine Aufgabe erledigt und nicht wiederverwendet werden kann. Wenn man sich dessen bewusst ist, ist das tatsächlich hilfreich.

Vorteil: das Script ist plattformübergreifend nutzbar
Nachteil: Java ist nicht für Scripting entworfen, der Code ist grauenhaft, es ist nur eine Datei erlaubt, also keine Wiederverwendung

Ich habe das jetzt mal ausprobiert, da ich schnell eine Lösung brauchte und mich in Python etc. immer erst einarbeiten muss und auf meinen Rechnern überall Java installiert ist.

Ob ich das dauerhaft Bash-Scripts (die echt nicht schön aussehen) und Ant-Scripts vorziehe – mal so, mal so, vermute ich. Alles mit Aufruf von Programmen auf dem Rechner wird wohl bash oder Ant bleiben, bei dem Rest muss ich gucken.

Mein aktuelles Beispiel: neuen Dateinamen für eine Datei finden mit Informationen, die aus dem XML (kml) geholt werden. Dafür sieht es ganz ok aus…

Aufruf: java RenameKML.java <path> <color> <width>

import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.Writer;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

public class RenameKML {

  private final static String EXTENSION = ".kml";

  /**
   * Main method.
   */
  public static void main(String[] args) {

    System.out.println("Rename KML");

    try {

      if (args.length < 3) {
        throw new Exception("Missing parameters.");
      }

      Path pathSource = Path.of(args[0]);
      if (Files.exists(pathSource)) {
        try (Stream<Path> paths = Files.walk(pathSource)) {
          paths
              .filter(Files::isRegularFile)
              .filter(path -> path.toString().endsWith(EXTENSION))
              .forEach(path -> processFile(path, args[1], Integer.parseInt(args[2])));
        }
      } else {
        throw new FileNotFoundException(pathSource.toString());
      }

    } catch (Exception e) {

      System.err.println();
      e.printStackTrace();
      System.err.println();
      printUsage();

      System.exit(1);

    }

  }

  /**
   * Usage information.
   */
  private static void printUsage() {

    System.out.println("Usage:\tjava RenameKML.java <path> <color> <width>");
    System.out.println("\tcolor: RRGGBBAA");
    System.out.println("");

  }

  /**
   * Process single file.
   *
   * A normal Exception cannot be declared, because this method is called from
   * withni Stream.forEach, only RuntimeException is allowed there.
   */
  private static void processFile(
      final Path theXMLFile,
      final String theColor,
      final int theWidth
  ) {

    System.out.println(String.format("Processing %s with color %s and width %d", theXMLFile.toString(), theColor, theWidth));

    try {

      String sXMLContent = Files.readString(theXMLFile);
      sXMLContent = cleanKML(sXMLContent, theColor, theWidth);


      Path pathOutFile = Path.of(theXMLFile.getParent().toAbsolutePath().toString(), String.format("%s%s", getNewFilename(sXMLContent), EXTENSION));

      writeKMLFile(pathOutFile, sXMLContent);

      if (!theXMLFile.toAbsolutePath().equals(pathOutFile.toAbsolutePath())) {
        System.out.println(String.format("\tDeleting: %s", theXMLFile.toString()));
        Files.delete(theXMLFile);
      }

    } catch (Exception e) {
      throw new RuntimeException(e);
    }

  }

  /**
   * Clean KML from unused or strange tags/content.
   */
  private static String cleanKML(
      final String theKML,
      final String theColor,
      final int theWidth
  ) throws Exception {

    String sKMLColor = theColor.replaceAll("(..)(..)(..)(..)", "$4$3$2$1");

    String sKMLCleaned = theKML;
    // IconStyles
    sKMLCleaned = sKMLCleaned.replaceAll(
      "<Style id=\".*\"><IconStyle>.*?</IconStyle></Style>",
      ""
    );
    // Folder
    sKMLCleaned = sKMLCleaned.replaceAll(
      "<Folder>(.*)</Folder>",
      "$1"
    );
    // Recording Placemarks
    sKMLCleaned = sKMLCleaned.replaceAll(
      "<Placemark>.*?Recording.*?</Placemark>",
      ""
    );
    // Fill name, remove other
    sKMLCleaned = sKMLCleaned.replaceAll(
      "<name>.*<description>(.*)</description>(<Placemark>)",
      "$2<name>$1</name>"
    );
    // Remove double names
    sKMLCleaned = sKMLCleaned.replaceAll(
      "<name>(.*)</name><name>.*?</name>",
      "<name>$1</name>"
    );
    // Remove last name/description
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(</Placemark>)<name>.*</description>",
      "$1"
    );
    // Remove strange underlines
    sKMLCleaned = sKMLCleaned.replaceAll(
      "<u>(.*?)</u>",
      "$1"
    );

    // reformatting description

    // time conversion (strangely complicated)
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(\\d{2}\\:\\d{2}\\:\\d{2}) vorm\\. ",
      "$1 "
    );
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(\\d{1}\\:\\d{2}\\:\\d{2}) vorm\\. ",
      "0$1 "
    );
    Matcher matchTime = Pattern.compile("(\\d{1,2})(\\:\\d{2}\\:\\d{2}) nachm\\. ").matcher(sKMLCleaned);
    while (matchTime.find()) {
      sKMLCleaned = sKMLCleaned.replaceAll(
        String.format("%s%s nachm\\. ", matchTime.group(1), matchTime.group(2)),
        String.format("%d%s ", Integer.parseInt(matchTime.group(1)) + 12, matchTime.group(2))
      );
    }

    // Duration
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(Duration\\: )(\\d{1}h\\d{2}'\\d{2}\")",
      "$10$2"
    );
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(Duration\\: )(\\d{2})h(\\d{2})'(\\d{2})\"",
      "$1$2:$3:$4"
    );
    // Description itself
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(<description><!\\[CDATA\\[)Start\\: (\\d{2}\\.\\d{2}\\.\\d{4}).*?(\\d{2}\\:\\d{2})\\:\\d{2} .*?End\\: \\d{2}\\.\\d{2}\\.\\d{4}.*?(\\d{2}\\:\\d{2})\\:\\d{2} .*?Duration\\: (\\d{2}\\:\\d{2})\\:\\d{2}.*?Length\\: (.*?)km.*?Avg Speed\\: (.*?)km h.*?Max Speed\\: (.*?)km h.*?Low\\: (.*?)m.*?High\\: (.*?)m.*?Gain\\: (.*?)m.*(\\]\\]></description>)",
      "$1Am $2 von $3 bis $4 Uhr, Dauer: $5 h, Strecke: $6 km, Ø: $7 km/h, v_max: $8 km/h, Höhenmeter: $11 m von $9 m bis $10 m$12"
    );

    // /reformatting description

    // Single TimeStamp
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(</styleUrl>)(<gx:Track>)(<altitudeMode>.*</altitudeMode>)(<when>.*?</when>)",
      "$1<TimeStamp>$4</TimeStamp>$2$3"
    );
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(<altitudeMode>.*</altitudeMode>)<when>.*</when>",
      "$1"
    );

    // Change color
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(<color>).{8}(</color>)",
      String.format("$1%s$2", sKMLColor)
    );

    // Change width
    sKMLCleaned = sKMLCleaned.replaceAll(
      "(<width>).(</width>)",
      String.format("$1%d$2", theWidth)
    );

    return sKMLCleaned;

  }

  /**
   * Write KML file, tidy up first.
   */
  private static void writeKMLFile(
      final Path theOutFile,
      final String theXMLContent
  ) throws Exception {

    System.out.println(String.format("\tWriting: %s", theOutFile.toString()));
    Files.writeString(theOutFile, tidyXML(theXMLContent), StandardOpenOption.CREATE, StandardOpenOption.WRITE);

  }

  /**
   * Tidy up XML.
   */
  private static String tidyXML(
      final String theXMLContent
  ) throws Exception {

    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(theXMLContent.getBytes()));
    doc.getDocumentElement().normalize();

    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    DOMSource source = new DOMSource(doc);

    String sResult = null;

    try (Writer swXML = new StringWriter()) {

      transformer.transform(source, new StreamResult(swXML));
      sResult = swXML.toString();

    }

    return sResult;

  }

  /**
   * Get new filename from name and date within KML file.
   */
  private static String getNewFilename(final String theXML) throws Exception {

    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(theXML.getBytes()));
    doc.getDocumentElement().normalize();


    NodeList nList = doc.getElementsByTagName("name");

    if (nList.getLength() != 1) {
      throw new Exception("more than one or no name tag");
    }

    String sName = nList.item(0).getTextContent();


    nList = doc.getElementsByTagName("when");

    if (nList.getLength() != 1) {
      throw new Exception("more than one or no when tag");
    }

    LocalDateTime dteWhen = LocalDateTime.parse(nList.item(0).getTextContent(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);

    return String.format("%s_%s",
      dteWhen.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
      cleanFilename(sName, true)
    );

  }

  /**
   * Clean filename from special characters.
   */
  private static String cleanFilename(
      final String theFilename,
      final boolean convertUmlauts
  ) {

    String sConverted = theFilename;

    sConverted = sConverted
        .replace(" ", "_")
        .replace("?", "_")
        .replace(":", "_")
        .replace(";", "_")
        .replace(",", "_")
        .replace("/", "_")
        .replace("\\", "_")
        .replace("*", "_")
        .replace("(", "_")
        .replace(")", "_")
        .replace("[", "_")
        .replace("]", "_")
        .replace("{", "_")
        .replace("}", "_")
        ;

    if (convertUmlauts) {
      sConverted = sConverted
          .replace("ä", "ae")
          .replace("Ä", "Ae")
          .replace("ö", "oe")
          .replace("Ö", "Oe")
          .replace("ü", "ue")
          .replace("Ü", "Ue")
          .replace("ß", "ss")
          ;
    }

    return sConverted;

  }

}

/* EOF */

Als Vergleich hier das Ant-Script, dass die XML-Umwandlung vornimmt, könnt Ihr ja selbst sehen, was Ihr lesbarer findet…

<?xml version="1.0" encoding="UTF-8" ?>

<project name="kml" default="help" basedir=".">

	<import file="/home/ekleinod/working/git/edgeutils/ant/ant-commons.xml"/>

	<target name="kml" depends="clearLog" description="Clean all KML files in directory.">

		<fail message="Pfad für die KML-Dateien nicht gesetzt (Farbe: RRGGBBTT): ant kml -Dkml:path=&quot;.&quot; -Dkml:color=&quot;14C8F0CE&quot; -Dkml:width=&quot;5&quot;" unless="kml:path" />
		<fail message="Farbe für die KML-Dateien nicht gesetzt (Farbe: RRGGBBTT): ant kml -Dkml:path=&quot;.&quot; -Dkml:color=&quot;14C8F0CE&quot; -Dkml:width=&quot;5&quot;" unless="kml:color" />
		<fail message="Breite für die KML-Dateien nicht gesetzt (Farbe: RRGGBBTT): ant kml -Dkml:path=&quot;.&quot; -Dkml:color=&quot;14C8F0CE&quot; -Dkml:width=&quot;5&quot;" unless="kml:width" />

		<echo message="Bearbeite KML-Dateien in '${kml:path}', Farbe '${kml:color}', Breite '${kml:width}'" />

		<echo message="Remove IconStyles" />
		<replaceregexp
				encoding="utf-8"
				match="&lt;Style id=&quot;.*&quot;&gt;&lt;IconStyle&gt;.*&lt;/IconStyle&gt;&lt;/Style&gt;"
				replace=""
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Remove Folder" />
		<replaceregexp
				encoding="utf-8"
				match="&lt;Folder&gt;(.*)&lt;/Folder&gt;"
				replace="\1"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Remove Recording Placemarks" />
		<replaceregexp
				encoding="utf-8"
				match="&lt;Placemark&gt;&lt;TimeStamp&gt;.*&lt;/TimeStamp&gt;&lt;/Placemark&gt;"
				replace=""
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Fill name, remove other" />
		<replaceregexp
				encoding="utf-8"
				match="&lt;name&gt;.*&lt;description&gt;(.*)&lt;/description&gt;(&lt;Placemark&gt;)"
				replace="\2&lt;name&gt;\1&lt;/name&gt;"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Remove last name/description" />
		<replaceregexp
				encoding="utf-8"
				match="(&lt;/Placemark&gt;)&lt;name&gt;.*&lt;/description&gt;"
				replace="\1"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Remove double names" />
		<replaceregexp
				encoding="utf-8"
				match="&lt;name&gt;(.*)&lt;/name&gt;&lt;name&gt;.*&lt;/name&gt;"
				replace="&lt;name&gt;\1&lt;/name&gt;"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Remove strange underlines" />
		<replaceregexp
				encoding="utf-8"
				match="&lt;u&gt;(.*)&lt;/u&gt;"
				replace="\1"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<antcall target="timeconversion" />

		<echo message="Reformat description" />
		<replaceregexp
				encoding="utf-8"
				match="(Duration\: )(\d{1}h\d{2}'\d{2}&quot;)"
				replace="\10\2"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="(Duration\: )(\d{2})h(\d{2})'(\d{2})&quot;"
				replace="\1\2:\3:\4"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="(&lt;description&gt;&lt;!\[CDATA\[)Start\: (\d{2}\.\d{2}\.\d{4}).*?(\d{2}\:\d{2})\:\d{2} .*?End\: \d{2}\.\d{2}\.\d{4}.*?(\d{2}\:\d{2})\:\d{2} .*?Duration\: (\d{2}\:\d{2})\:\d{2}.*?Length\: (.*?)km.*?Avg Speed\: (.*?)km h.*?Max Speed\: (.*?)km h.*?Low\: (.*?)m.*?High\: (.*?)m.*?Gain\: (.*?)m.*(\]\]&gt;&lt;/description&gt;)"
				replace="\1Am \2 von \3 bis \4 Uhr, Dauer: \5 h, Strecke: \6 km, Ø: \7 km/h, v_max: \8 km/h, Höhenmeter: \11 m von \9 m bis \10 m\12"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Insert TimeStamp" />
		<replaceregexp
				encoding="utf-8"
				match="(&lt;/styleUrl&gt;)(&lt;gx:Track&gt;)(&lt;altitudeMode&gt;.*&lt;/altitudeMode&gt;)(&lt;when&gt;.*?&lt;/when&gt;)"
				replace="\1&lt;TimeStamp&gt;\4&lt;/TimeStamp&gt;\2\3"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Remove other TimeStamps" />
		<replaceregexp
				encoding="utf-8"
				match="(&lt;altitudeMode&gt;.*&lt;/altitudeMode&gt;)&lt;when&gt;.*&lt;/when&gt;"
				replace="\1"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Fill color (RGBT)" />
		<replaceregexp
				encoding="utf-8"
				match="(&lt;color&gt;).{8}(&lt;/color&gt;)"
				replace="\1${kml:color}\2"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<echo message="Reformat color (RGBT -> TBGR)" />
		<replaceregexp
				encoding="utf-8"
				match="(&lt;color&gt;)(..)(..)(..)(..)(&lt;/color&gt;)"
				replace="\1\5\4\3\2\6"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Fill width" />
		<replaceregexp
				encoding="utf-8"
				match="(&lt;width&gt;).(&lt;/width&gt;)"
				replace="\1${kml:width}\2"
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

		<echo message="Tidy XML" />
		<apply executable="xmllint" parallel="false" force="true" dir="${kml:path}" relative="true">
			<arg value="--format" />
			<arg value="--output" />
			<targetfile />
			<srcfile />
			<fileset dir="${kml:path}" includes="*.kml" />
			<mapper type="identity" />
		</apply>

	</target>

	<target name="timeconversion" depends="clearLog">

		<echo message="Reformat time" />

		<replaceregexp
				encoding="utf-8"
				match="(\d{1}\:\d{2}\:\d{2}) vorm\. "
				replace="0\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="(\d{2}\:\d{2}\:\d{2}) vorm\. "
				replace="\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="1(\:\d{2}\:\d{2}) nachm\. "
				replace="13\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="2(\:\d{2}\:\d{2}) nachm\. "
				replace="14\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="3(\:\d{2}\:\d{2}) nachm\. "
				replace="15\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="4(\:\d{2}\:\d{2}) nachm\. "
				replace="16\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="5(\:\d{2}\:\d{2}) nachm\. "
				replace="17\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="6(\:\d{2}\:\d{2}) nachm\. "
				replace="18\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="7(\:\d{2}\:\d{2}) nachm\. "
				replace="19\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="8(\:\d{2}\:\d{2}) nachm\. "
				replace="20\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="9(\:\d{2}\:\d{2}) nachm\. "
				replace="21\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="10(\:\d{2}\:\d{2}) nachm\. "
				replace="22\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="11(\:\d{2}\:\d{2}) nachm\. "
				replace="23\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>
		<replaceregexp
				encoding="utf-8"
				match="12(\:\d{2}\:\d{2}) nachm\. "
				replace="00\1 "
				flags="g">

			<fileset dir="${kml:path}" includes="*.kml" />

		</replaceregexp>

	</target>

</project>

<!-- EOF -->
Kategorien
Computerspiele Kritik

Spielkritik: Tomb Raider: Underworld (2008)

Tomb Raider: Underworld, der neunte Teil der Reihe und der letzte „richtige“, „altmodische“, „originale“ Teil der Serie, wie auch immer man das nennen will.

Kurz erklärt: bis hierher war das Spielprinzip: Lara geht durch eine Welt, die sie erkundet, Fallen ausweicht, Rätsel löst, ab und an jemanden umbringt und insgesamt ein großes Rätsel um ein Artefakt löst und so die Welt rettet.

Dieser Teil ist der letzte, der das in dieser Art tut, das Reboot von 2013 geht da andere Wege, hier kämpfen wir uns mit Lara durch eine Originstory und nur am Rande lösen wir sehr simple Rätsel. Das ist jetzt nicht verbittert gemeint, neun Spiele lang dasselbe Prinzip: wahrscheinlich war es gut, hier mal kräftig aufzuräumen, ob man allerdings den Kern der Spiele so verändern musste – kann man so oder so sehen. Das Reboot gefällt mir, ist halt nur ein anderes Spiel. Wie dem auch sei:

Auf in den letzten Kampf auf der PS 3 mit der neuen Underworld-Engine, die auch heute noch die Spiele nutzen.

Wir spielen die übliche Levelstruktur, zusammengehalten durch eine dünne Geschichte, wir besuchen das Mittelmeer, Thailand, Mexiko, die Arktis und Croft Manor.

An sich ist das Spiel nicht schlecht. Es sieht fantastisch aus, Lara wurde wieder verbessert, die Bewegungen sind klasse, an sich stimmt alles. Bis auf das Leveldesign und den Schwierigkeitsgrad.

Es gibt Gegenden, da schlunzt man durch und es gibt Gegenden, da ist es unglaublich zäh und man muss eine Sequenz auf die Sekunde genau durchführen, um weiterzukommen. Meist trifft das Boni, so dass der Spielfluss bewahrt bleibt, aber es ist nervig, wenn man nach einer Stunde immer noch an einer 10-Sekunden-Sequenz hängt. Das Ganze mit langen Ladezeiten zwischen den Versuchen.

Die Rätsel sind sehr, sehr einfach konzipiert, da ist kein Nachdenken, sondern nur Ausführen nötig. Schade.

Dazu kommt, dass Croft Manor explodiert. WTF? Warum?

Außerdem, und das ist nicht gut, konnte ich das Spiel nicht beenden, weil es eine Sequenz gab, die ich nicht geschafft habe, in einem Turm hochzuspringen auf versenkbaren Plattformen, dabei ein Monster abschießen und auf Flammen achten. Das Ganze vielleicht eine halbe Minute pixelgenau ohne Zwischenspeichern oder Umsehen. Pixelgenau meint pixelgenau. Lange Ladezeiten zwischen den Versuchen.

Ich hab es versucht. Zwei Stunden lang. Dann hab ich aufgegeben und das Spiel nicht mehr angefasst und ich werde es auch nicht mehr anfassen. Immerhin ist der Controller heilgeblieben – die halten halt viel aus.

Bis dahin wurde ich angenehm unterhalten mit eingestreuten Frustmomenten, diese Sequenz hat das zunichte gemacht.

Bis dahin hatte ich nur ein Spiel nicht beenden können: DOOM 2 und das ist für Normalsterbliche auch nicht machbar aber nicht schlimm, weil DOOM.

Hier setzte die Sequenz einfach den Ton: ein ordentliches Spiel durch die Spielmechanik unspielbar gemacht. Sehr, sehr schade.

Dabei hatte insbesondere Uncharted parallel gezeigt, wie ein Tomb-Raider aussehen kann.

Das Spiel kam auch insgesamt nicht so gut an, so dass erst 2013 ein Nachfolger kam, das angesprochene Reboot ohne Altlasten.

Fazit: leider mit dem Arsch die gute Atmosphäre eingerissen.