Syncthing statt Dropbox
Friday, 13. February 2015
Dropbox steht schon länger auf meiner Liste auszuwechselnder Dienste. Da mein Heimserver wieder läuft und aufgeschreckt von der Ankündigung des baldigst wegfallenden Spacerace-Speicherplatzes habe ich Dropbox durch syncthing ersetzt.
Vorläufiges Fazit: Das funktioniert und ist in manchen Belangen besser als Dropbox, in anderen dagegen hinkt es hinterher.
Einrichtung
Die Installation ist einfach genug. Für Arch liegt es in den Quellen und ist ein pacman -S snycthing
entfernt. Für Ubuntu gibt es ein PPA (Danke an Gerald für den Hinweis):
curl -s https://syncthing.net/release-key.txt | sudo apt-key add - echo "deb http://apt.syncthing.net/ syncthing release" | sudo tee /etc/apt/sources.list.d/syncthing.list sudo apt-get update sudo apt-get install syncthing
Danach startet der Befehl syncthing
den Dienst und auch die Weboberfläche auf Port 8080. Dort können Ordner hinzugefügt werden, bei mir beispielweise der Dropbox-Ordner.
Besser ist es, syncthing-inotify ebenfalls zu installieren und den Rescan-Intervall des Sync-Ordners auf 0 zu setzen. Syncthing selbst fehlt das Feature, Änderungen direkt zu erkennen, stattdessen wird alle x Sekunden der Syncordner gescannt. Das ist Verschwendung und war hier schlicht inakzeptabel, weil so die Festplatte des Servers sich nie abschalten würde.
Zum Glück ist auch syncthing-inotify nicht zu kompliziert, man kann einfach das Release herunterladen, es nach /usr/local/bin/ verschieben und dann mit
syncthing-inotify -api=xxxxxxx
starten. Der API-Key findet sich in den Einstellungen.
Syncthing vs Dropbox
Im direkten Vergleich schlägt syncthing sich wacker.
ID statt Account ++/+
Syncthing nutzt ein ID-System. Statt einen Account zu haben, Dropbox zu installieren und sich dann im Client mit dem Account anzumelden, funktioniert bei syncthing alles über die Kontrolle des Rechners. Die ID des anderen Rechners eingeben, dies gegenseitig bestätigen, fertig. Es ist etwas ungewohnt, das spricht für Dropbox. Aber das ID-System ist letztendlich auch nicht komplizierter, und der Wegfall des Passworts ist praktisch.
Server statt Cloud ++/+-
Der große Unterschied ist natürlich, dass syncthing nicht mit einem zentralen Server funktioniert. Statt proprietärer Cloud-Lösung freie Software zum Selberhosten. Der Nachteil dabei ist, dass ich meinen Bürorechner nie mit meinem Heimrechner syncen könnte, hätte ich nicht zusätzlich den Pogo als Heimserver, der als Brücke dient. Denn die beiden sind nie gleichzeitig an. Der Vorteil ist der unbegrenzte Speicherplatz, soweit die Festplatten eben mitmachen - und ausschlaggebend ist die volle Kontrolle über die eigenen Daten.
Konfigurierbare Backups ++/+
Das Backupsystem gefällt mir sehr gut. Für jeden Ordner auf jedem Client kann eingestellt werden, wieviele Revisionen gesichert werden sollen, und der sehr hübsche Staggered File Versioning-Modus sichert dynamisch viele Backup, je nach Intervall der Änderungen. Dropbox hat auch Backups, und sie sind in der Cloud sicher vor Unbill daheim, aber zumindest ohne zu zahlen sind sie weniger mächtig.
Firewalls durchlöchern +/+
Wirklich wichtig und entsprechend positiv war auch, dass die Firewall des Routers kein Problem ist. Für Dropbox ja auch nicht, aber Dropbox ist nur ein Client, kein Server. Ich war nicht sicher, on der Pogo problemlos erreicht würde, oder ob Portweiterleitungen und dyn-dns-Einträge nötig sein würden. Nein, das lief direkt.
Edit-Push
Ohne syncthing-inotify wäre das fehlende Erkennen von Änderungen ein ernstes Problem gewesen, so nachgerüstet ist das ok.
Konflikte -/+
Andererseits hat syncthing kein Verständnis für Konflikte. Kommt eine Änderung verspätet an und die Datei wurde lokal schon verändert, werden diese lokalen Änderungen schlicht überschrieben. Gerade am Anfang, als ich den Syncordner zeitversetzt auf allen Rechnern freigeben musste, war das nicht vertrauenserweckend - funktioniert dort aber. Und immerhin ist das kein Problem, in das ich bei meiner üblichen Nutzung rennen sollte. Trotzdem, Dropbox macht das besser.
CPU und Ram -/++
Negativ ist die Ressourcennutzung. Nein, es hat meinen PC im Normalbetrieb nicht merklich ausgebremst. Aber am Anfang gab es Probleme: Der auf allen Clients schon vorhandene Sync-Ordner wurde nach dem Hinzufügen auf dem letzten Client, dem Laptop, daraufhin wohl als neu markiert und sowohl an meinen Desktop als auch an den Pogo zurückgeschickt. Auf dem Desktop nutzte dieser Sync 270% meiner Dreikern-CPU, also fast alles, und dauerte trotzdem über eine Stunde. Dropbox hat solche Kinderkrankheiten schon lange nicht mehr und arbeitet unbemerkt im Hintergrund.
Auch eine solche Kinderkrankheit: Im Normalbetrieb schießt die CPU-Nutzung auf 150%, wenn die Webadministration aufgerufen wird, ist sie zu sind es immerhin nur ~2%. 2,5GB Ram werden gerade belegt, plus 800MB für snycthing-inotify. Das ist zu viel, wenn es echte Nutzung wäre, aber die Zahlen könnten so hoch sein, weil 12GB im Rechner sind und syncthing sich ungenutzte Ressourcen anrechnen lässt. Immerhin funktioniert es auch auf dem Pogo, und der hat nur 256MB Ram.Verschlüsselung -/-
Schade auch, dass Dateien auf dem Server nicht von syncthing verschlüsselt werden. Denn das bedeutet, dass ich meine encfs-Verschlüsselung nicht einmotten kann, obwohl die Daten nicht mehr in die Cloud geschickt werden.
Fazit
In kurz: syncthing ist nett. Eine echte Alternative zu Dropbox ist es aber nur, wenn man irgendwo einen Server stehen hat. Und es hat noch nicht Dropboxs Feinschliff, massenmarktreif ist es also nicht. Aber solange der Pogo läuft ist syncthing für mich die bessere Lösung.
Wer es etwas einfacher oder Dropbox-ähnlicher haben will, der sollte sich Syncthing-GTK anschauen. Beispielweise beinhaltet das direkt inotify-Support. Die UI könnte für alles außer Server generell der richtige Weg sein, syncthing zu nutzen.
Grub failcheck deaktivieren
Wednesday, 11. February 2015
Eine weitere Entdeckung über Grub 2: Eines der Probleme mit ihm lässt sich einfach lösen, man muss nur wissen wie.
Mein Ubuntu folgt nicht dem Standard, ich benutze keine Desktopumgebung und keinen Displaymanager. Eines der Ergebnisse davon war, dass seit einiger Zeit der Timeout von Grub fehlt. Statt automatisch nach kurzer Zeit zu startete wartete er im Bootmenü auf das Drücken der Enter-Taste, und ich wusste nicht wieso. Nach einiger Zeit und etwas Testen kam ich dann darauf, dass es am failcheck liegt: Irgendetwas an meinem Setup führt dazu, dass Grub denkt, der letzte Start wäre gescheitert. Und auch das dauerte etwas, um es herauszufinden: Diesen Check kann man deaktivieren oder umgehen.
Um ihn zu umgehen, muss nur die Zeile
GRUB_RECORDFAIL_TIMEOUT=5
in die /etc/default/grub hinzugefügt und ein sudo update-grub
ausgeführt werden. Schon ist der Countdown wieder da, der failcheck entschärft. Nun läuft er bis zur Passworteingabe durch, was ich sehr angenehm finde.
Grub 2 verschönern
Tuesday, 10. February 2015
Mir war nicht klar, dass das inzwischen ohne größeren Aufwand möglich ist. Grub 2 unterstützt Themes, und inzwischen gibt es sogar welche. Das Bootmenü sieht so doch etwas hübscher aus.
Ich wählt fürs erste das Theme Grau:
Das Archiv herunterladen, entpacken, im Terminal mit
sudo ./install.sh
installieren, fertig.
Statistik in Ruby mit Statsample
Tuesday, 10. February 2015
Ich muss immer mal wieder Statistik anwenden, meist ohne dann wirklich Zeit dafür zu haben. R oder Julia ist mir fremd, daher griff ich meist auf handgeschriebene Bash-Skripts zurück und machte die schwierigeren Sachen, wie die Faktor- oder Signifikanzanalyse, mit externen Tools. Was eben gerade da ist.
Diesmal bin ich über statsample gestolpert. Das gem implementiert die relevanten Statistikfunktionen. Ich benutzte diesmal sowieso Ruby, da passte das gut in meine Datenverarbeitungsskripte. Und in meinen Augen hat es sich bewährt.
Zwei Beispiele: Ich habe in einer SQLite-Datenbank eine Sammlung von Kommentaren mit ihren Upvotes, und die Kommentare kann ich in zwei Gruppen unterteilen. Ich will wissen, ob die Verteilung der Upvotes zwischen den Gruppen sich signifikant unterscheidet, und wähle dafür einen t-Test. Das geht so:
require 'sqlite3' require 'statsample' include Statsample::Test db = SQLite3::Database.new "database.db" aUpvotes = db.execute("SELECT upvotes FROM comments WHERE group = 'a'";).flatten.to_scale bUpvotes = db.execute("SELECT upvotes FROM comments WHERE group = 'b'";).flatten.to_scale t_2=Statsample::Test::T::TwoSamplesIndependent.new(aUpvotes, bUpvotes) puts t_2.summary
Die Ausgabe enthält dann alle wichtigen Informationen und verrät mir, dass die zweite Stichprobe deutlich kleiner, die Varianz gleich ist und das benötigte Signifikanzniveau p = 0.5522
weit von statistischer Signifikanz weg ist.
= Two Sample T Test Mean and standard deviation +----------+--------+---------+------+ | Variable | mean | sd | n | +----------+--------+---------+------+ | Vector 1 | 9.1267 | 44.8019 | 3332 | | Vector 2 | 7.4539 | 59.6217 | 293 | +----------+--------+---------+------+ Levene test for equality of variances : F(1, 3623) = 0.4437 , p = 0.5054 T statistics +--------------------+--------+----------+----------------+ | Type | t | df | p (both tails) | +--------------------+--------+----------+----------------+ | Equal variance | 0.5945 | 3623 | 0.5522 | | Non equal variance | 0.4687 | 321.6479 | 0.6396 | +--------------------+--------+----------+----------------+ Effect size +-------+--------+ | x1-x2 | 1.6727 | | d | 0.2467 | +-------+--------+
Das zweite Beispiel ist ein chi²-Test um zwischen zwei Stichproben mit Kategorien zu unterscheiden. Ich habe bei der ersten Stichprobe 60 Leute in Kategorie A, 10 in B, 30 in C. Bei der zweiten sind es 60 in A, 25 in B und 15 in C. Signifikanter Unterschied?
m=Matrix[[60, 10, 30], [60, 25, 15]] x_2=Statsample::Test.chi_square(m) puts x_2.probability # => 0.003…
Hier gibt es keine schöne Ausgabe, sondern nur den p-Wert. Der ist mit 0.003 unterhalb einiger typischer Signifikanzniveaus, also ist der Unterschied zwischen den Beobachtungen für p < 0.01
beispielsweise signifikant.
Ich habe ein bisschen das Drumrum erklärt weil dort das Problem des Gems ist: Es fehlt Dokumentation. Klar, es ist nicht die direkte Aufgabe des Gems, dem Nutzer einen Statistikkurs zu geben. Es ist ein Werkzeug, mit dem Leute, die wissen was sie machen müssen, diese Aufgabe durchführen können. Aber selbst wenn man eine vage Ahnung hat findet man zu wenig darüber, wie man die Funktionen aufzurufen hat.
The Darkness 2
Sunday, 8. February 2015
The Darkness 2 ist ein Ego-Shooter mit Fokus auf der Story und mit ein paar Rollenspielelementen. Der Protagonist ist von einem Dämon (der Darkness) besessen, der ihm Tentakel und Schlangenköpfe aus dem Leib wachsen lässt, die zusätzlich zu den Pistolen und Gewehren als Waffen fungieren. Mit ihnen können Gegner attackiert und Gegenstände aufgenommen und geworfen werden.
Das Ganze ist wohl eine Comicumsetzung. Erklärt vielleicht, warum das Spiel ziemlich brutal ist. Und der Grafikstil ist etwas ungewöhnlich, wohl nicht ganz Cell-Shading, aber fast. Das sieht nicht schlecht aus.
Es gibt ein paar Parallelen zu Bioshock Infinite. Beide Spiele sind gut gemachte Shooter mit ein paar netten Zusatzelementen, aber spielerisch nicht weltbewegend. Über weite Teile des Spiels gibt es einen Begleiter, der hier in Schleichpassagen selbst gespielt wird. Zwar reicht seine Inszenierung längst nicht an Elizabeth heran, schlecht gemacht ist er aber auch nicht.
Der Anfang ist bombastisch, die Enden schwierig zu mögen aber bemerkenswert. Generell zieht das Spiel viel seines Reizes aus der düsteren Story und aus dem Spiel zwischen den zwei Realitätsebenen, das erinnert dann zwischendurch an Spec Ops: The Line. Obendrauf gibt es retrospektive Erzählungen in theatermonologähnlichen Zwischensequenzen. Mir hat das gut gefallen.
Performance-Tuning einer Webapp mit Index und Arbeitsvermeidung
Monday, 2. February 2015
Meinen Feedreader feedtragón nutze ich praktisch jeden Tag. Ich bin soweit zufrieden, aber nach der Eingewöhnungsphase fiel mir auf, dass er etwas langsam war. Gemessen und uff: Die längste Wartezeit kam durchs Warten auf eine Antwort vom Server. Kein gutes Zeichen. In diesem Artikel werde ich beschreiben, wie ich das Problem anging und dabei diese Verbesserung produzierte:
Die Wartezeit wurde reduziert auf ein 84stel, von 2,8 Sekunden am Anfang auf ~33ms.
Schritt 1: Index setzen
Jedes mal, wenn eine Seite geladen wird, holt feedtragón eine Liste aller abonnierten Feeds vom Server, und prüft dann jeden Feed auf ungelesene Einträge. Dafür muss er die Einträge aus der Datenbank holen, das macht er mit diesem Query:
SELECT url, title, content, id FROM entries WHERE feed = ? AND read = 0 AND id > ? LIMIT 10;
Er beschränkt sich also auf 10 Einträge mit einer höheren ID als die Start-ID, so funktioniert das Endless-Scrolling, aber das ist hier nicht weiter wichtig. Wichtig ist der Rest des WHERE-Statemends: feed = ? AND read = 0
. Da werden also zwei Spalten abgefragt. Und insgesamt dauerte das alles 2,8 Sekunden - also nicht nur dieser Query, sondern alle zusammen.
Ich bin kein Datenbankexperte, aber ich vermutete, dass diese Abfrage schneller funktionieren könnte. Das ist eine SQLite-Datenbank, dort kann man das mit EXPLAIN QUERY PLAN
prüfen:
sqlite> EXPLAIN QUERY PLAN SELECT url, title, content, id FROM entries WHERE feed = ? AND read = 0 AND id > ? LIMIT 10; 0|0|0|SEARCH TABLE entries USING INTEGER PRIMARY KEY (rowid>?)
Was heißt das jetzt? Ich musste es nachgucken. Dass er hier nur mit dem Primary Key sucht heißt, dass er für read und feed keine andere Möglichkeit hat als manuell zu suchen. Also muss dafür je ein Index her:
sqlite> CREATE INDEX entries_read_idx ON entries(read); sqlite> CREATE INDEX entries_feed_idx ON entries(feed); sqlite> EXPLAIN QUERY PLAN SELECT url, title, content, id FROM entries WHERE feed = ? AND read = 0 AND id > ? LIMIT 10; 0|0|0|SEARCH TABLE entries USING INDEX entries_feed_idx (feed=? AND rowid>?)
feedtragón gestartet, den Browser aufgemacht, in die Netzwerkanalyse geschaut und mich gefreut: Die Wartezeit auf den Server schrumpfte von 2,8s auf 0,5s. Damit war die Sache für mich erstmal abgehakt und feedtragón ausreichend optimiert.
Schritt 2: Join (Arbeitsvermeidung)
Später kam mir dann der Gedanke, dass es besser gehen müsste. Denn das Vorgehen, das ich oben beschrieb - alle Feeds holen, ans Template schicken, dort deren Einträge holen, dann nur die Feeds mit ungelesenen Einträgen anzeigen - ist keineswegs effizient. Es folgt aus einer strikten Einhaltung der für dsnblog skizzierten Architekturprinzipen: Objekte ohne Controller, die für ihre Daten zuständig sind. Das ist toll zu schreiben, besonders das Datenbanklayer bleibt einfach beherrschbar, aber Dee erwähnte damals das möglicherweise kostspielige Befüllen der Daten. Und die Einträge des Feeds aus der Datenbank zu holen ist kostspielig.
Vorher holte er also alle Feeds aus der Datenbank:
SELECT url, id, name FROM feeds;
und filterte dann im Template die Feeds aus, die keine neuen Einträge haben:
feeds.each do |feed| erb :feedlink, :locals => {:feed => feed, :current_feed_id => current_feed_id} if ! feed.entries.nil? && feed.entries.size > 0 end
wobei feed.entries() wieder die Datenbank aufruft, mit dem im ersten Schritt optimierten Query.
Stattdessen könnte man auch direkt nur die Feeds übergeben, die ungelesen Einträge haben. Dafür muss nur die Feed- und die Eintragstabelle gejoint werden:
SELECT DISTINCT feeds.url, feeds.id, feeds.name FROM feeds JOIN entries ON (entries.feed = feeds.id) WHERE entries.read = 0;
Das Filtern kann dann entfallen. Und so schrumpften die 0,5s noch einmal, auf diesmal 0,033s.
Das ist vielleicht etwas spezifisch. Der Kern hier ist: Unnötige Datenbankabfragen durch einen geschickten Join zu vermeiden ist eine gute Idee, und es auch wert wenn es etwas gegen die vorhandene Struktur geht.
Schlusswort
Natürlich sind das keine konstanten Werte. Wären mehr Feeds und mehr Einträge in der Datenbank bräuchte alles länger. Der Server hat wahrscheinlich eine langsamere Platte als mein Rechner mit seiner SSD. Außerdem ist nun nur die Wartezeit auf den Server minimiert, er muss immer noch danach etwaige Bilder herunterladen, außerdem kommt die Transportzeit zum Server dazu.
Trotzdem: Der Unterschied ist auch auf dem Server da. Statt "Klick, Warten, Rendern, da" ist es nun "Klick, Rendern, da" - den Schritt auf realistisch gesehen etwa unter eine Sekunde Ladezeit, von vorher über 3, spürt man deutlich.
pc-kombo empfiehlt Arbeitsspeicher
Sunday, 1. February 2015
In den Hardwareempfehler pc-kombo habe ich beim monatlichen Update nun Empfehlungen für Arbeitsspeicher eingebaut.
Er empfiehlt DDR3-1600, für Billig-PCs ein 2GB-Modul, für PCs bis 500€ ein 4GB-Kit und für alles darüber ein 8GB-Kit. Man sieht an den harten Grenzen vielleicht: Völlig ausgereift ist das noch nicht, und die Empfehlung basiert auf Tests, subjektive Einschätzung und momentanen Preis, nicht auf Benchmarks. Aber es sind in meinen Augen dennoch sinnvolle Empfehlungen.
Mit der neuen Hardwarekategorie funktionierte das alte Design nicht mehr gut. Zusammen mit den Mainboardempfehlungen geht es jetzt mehr in Richtung vollständigen PC-Empfehler, daher gibt es jetzt eine Listensicht mit integriertem Link zu Amazon, statt wie vorher für die Links eine separate Sektion unten zu haben und den Prozessor neben die GPU zu setzen. Ich finds gut, so geht es langsam wieder zu der Ursprungsidee eines vollständigen PC-Konfigurators zurück. Nur fehlen mir immer noch gute Ideen für den Rest des Interface.
Edit Und der im Screenshot sichtbare kleine Dreher mit der Geforce GTX 690 ist nun auch behoben
Bioshock Infinite
Wednesday, 28. January 2015
Bioshock Infinite ist das erste Spiel, welches das KI-Begleiterproblem löst. Dadurch ist es etwas wirklich besonderes. Gleichzeitig ist es spielerisch gar nicht so interessant und die Story ermüdend.
Das KI-Begleiterproblem besteht darin, dass Spiele mit KI-Begleitern meist nervig sind. Oftmals stehen die Begleiter im Weg, laufen in Gegnerhorden, sind zu stark oder nutzlos; immer aber sind sie klar ziemlich dämliche KI, die entweder stumpf dem Spieler folgt und ansonsten herumsteht, oder die einer festgelegten Skriptsequenz folgt.
Elizabeth hat kein einziges dieser Probleme. Sie folgt dem Spieler nicht nur, sie läuft gerne mal voraus. Sie steht nicht herum, sie guckt aus dem Fenster oder schaut sich an, was auf dem Tisch liegt. Sie reagiert angeekelt auf die Leiche am Boden, sie muss vom Rauch Husten, sie zeigt Emotionen.
Und sie kann nicht sterben, beteiligt sich nicht direkt am Kampf, dadurch kann sie das eigentliche Spiel nicht behindern. Sie nervt nie. Im Gegenteil, sie hilft mit Munition und Heilung. Wenn Bioshock Infinite ansonsten auch nichts besonderes sein mag, wie sie Elizabeth umgesetzt haben sollte eine Blaupause für jedes zukünftige Spiel mit KI-Begleitern sein.
Elizabeth ist das wichtigste Spielelement, und sie ist zentral für die Story. Gleichzeitig entwickelt sie sich im Laufe der zehn Stunden Spielzeit. Ob ihre nun eine coming-of-age-Story oder nur ein Fall oder sonst eine Story ist, das vermag ich gar nicht zu sagen. Das ist positiv. Alleine dass eine KI-Figur eine Geschichte hat, die dann auch noch im Spiel erzählt wird, und die dann nichtmal ganz uninteressant ist - das ist für einen Shooter herausragend. Das ist wie ein Begleiter aus Baldurs's Gate 2, nur tausendmal besser, weil eben nicht den Großteil der Geschichte nur eine vom Spieler herumbewegte Figur.
Es hilft natürlich, dass Elizabeth hübsch ist, ohne in das übliche Modell einer Computerspiel-Frau gesteckt zu werden.
Spielerisch ist dieses Bioshock gar nicht so interessant, weil es eben nur ein Shooter ist. Es hat allerdings ein paar unübliche Elemente. Durch die Levels laufen in der Höhe Schienen, an die der Protagonist wie die Gegner sich hängen können und dadurch ziemlich schnell werden. Auf Knopfdruck können durch Elizabeth vorher inaktive Elemente herbeiteleportiert werden, freundliche Geschütztürme oder Kletterhaken zum Beispiel. Später ist das Spiel auch gar nicht so einfach, da hilft das.
Teilweise hängt der Schwierigkeitsgrad an den gewählten Waffen. Von ihnen gibt es zwei Rangstufen, beispielweise erst eine Schrotflinte, dann später eine stärkere Variante mit kürzerer Reichweite. Ich fand das unglücklich, denn spannend sind die neuen Varianten nicht, und ist dann am Ende doch nur Munition für eine der Anfangswaffen da wird das vorher zu einfache Spiel eher schwierig.
Es ist ansonsten wie das erste Bioshock, nur mit anderen Waffen und anderen Zaubern und vielleicht etwas anderer KI. Die Levels sind etwas offener, ohne wirklich groß zu sein. Statt einer Unterwasserwelt ist es eine fliegende Stadt. Und statt einer Ayn Rand Philosophiegeschichte mit Moralentscheidung mit den Little Sisters und Überraschungseffekt hat es eine Art Zeitreisegeschichte, die Moralentscheidung fehlt. Deren Wegfall wäre ok. Aber wenn ich irgendwas nicht mehr abkann, dann sind es Zeitreisegeschichten mit all ihren Inkonsistenzen, die Autoren dann für ihre Absurditäten nutzen.
Das Spiel spielt - wieder - mit dem Spieler, versucht einen Punkt daraus zu machen, dass er nicht entscheiden kann. Aber das hat schon vor Jahren Bioshock besser gemacht, das hat (bei mir) gerade erst Spec Ops nochmal aufgegriffen, und es ist hier bewusst in einer Form inszeniert, die den Spieler nerven soll. Wenn der Protagonist in einem Raum steht und Elizabeth sagt "Du kommst hier nicht raus, bis du das und das machst", dann führt das nicht dazu, dass ich mich mit der Unausweichbarkeit des Schicksals auseinandersetze. Nach einer solchen Szene bin ich nur genervt. Und die große Überraschung war diesmal vorhersehbar.
Also: Gutes, spielenswertes Spiel, bemerkenswert besonders durch Elizabeth. Ansonsten ein gut gemachter Shooter. Aber durch Geschichte samt Ende und Inszenierung derselben trotzdem kein Spiel, das ich in meine Liste wirklich guter Spiele aufnehmen kann - obwohl ich es gerne durchspielte.
Serendipity 2.0 ist veröffentlicht
Saturday, 24. January 2015
Endlich! Es hat ein paar Jahre gedauert, aber nun ist Serendipity 2.0 fertig. Die offizielle Ankündigung steht im Blog.
Heute kann ich mich kurz fassen, denn ich habe mich bereits bei meinen Mitstreitern bedankt und die wichtigsten Änderungen vorgestellt.
Einen Nachtrag habe ich: Auf Openhub ist s9y als Projekt eingetragen und dort wird auch der Quellcode analysiert. Und wir sind geschrumpft. Sicher im Core nur unwesentlich - die Smartifizierung kostet eher etwas mehr Code, aber sie strukturiert ihn besser - und ich kann den Zeitpunkt nicht ganz einem bestimmten Commit zuordnen, trotzdem ist das eine sehr gute Sache. Weniger Code heißt normalweise weniger Bugs.
Ich wünsche frohes Updaten und viel Spaß mit dem neuen Backend!
Schaut im Zweifel auch, was die anderen schreiben:
systemds binary journal ist eine bescheuerte Idee
Sunday, 18. January 2015
Meine jüngsten Erfahrungen mit Arch bestärken mich darin, auf meinem Hauptcomputer einen großen Bogen um alles mit systemd zu machen. Es ist nervenaufreibend bescheuert.
Das Arch auf meinem Pogo startet nicht mehr, ich habe keine Idee warum. Also starte ich ihn ohne Arch, mounte die Platte und will in die Logs schauen. Und das geht nicht, denn das systemd Log ist binary. Auf dem alten Linux vom pogo ist da natürlich kein Viewer dazu, aber hey, selbst für mein Ubuntu finde ich keinen Viewer dafür (denn: Ich finde dafür überhaupt keinen viewer, außer systemctl, was mir nicht hilft).
Natürlich ist das konfigurierbar. Wahrscheinlich, irgendwie. Aber es würde mich gar nicht wundern, wenn ich dafür irgendein Paket installieren oder einen Voodoo-Befehl ausführen müsste. Was nicht geht, denn in das ARM-System kann ich von hier aus nicht chrooten. Aber es ist sowieso nicht so dokumentiert, dass ich es bisher fand. Außerdem bekomm ich Kopfschmerzen von dem Blödsinn, statt jetzt das Bootproblem zu lösen mich erstmal um lesbare logs kümmern zu müssen.
Systemd stinkt. Ich such jetzt eine Alternative.
Bundler scheitert an Nokogiri auf Arch Linux ARM
Friday, 16. January 2015
Auf meinem pogo läuft (jetzt wieder) Arch, und es soll mein music-streamer drauf laufen. Für die Lyricanzeige benutzt der nokogiri, und das mit bundler zu installieren scheitert.
Nokogiri ist ein komisches ruby-gem. Es versucht sich selbst komplett zu kompilieren, was unter Arch-ARM scheitert. Die kritische Abhängigkeit libxml2 ist aber auch in den Quellen. Unter Ubuntu würde man libxml2-dev installieren und danach bundle config nokogiri.build --use-system-libraries
ausführen, woraufhin ein bundle install
durchlaufen würde.
Nicht so unter Arch. Dort lautet der nötige Befehl, um nokogiri mit gem zu installieren, so:
gem install nokogiri -- --use-system-libraries --with-xml2-include=/usr/include/libxml2 --with-xml2-lib=/usr/lib/
Also einfach den bundle config
-Befehl von oben anpassen, zu
bundle config nokogiri.build --use-system-libraries --with-xml2-include=/usr/include/libxml2 --with-xml2-lib=/usr/lib/
?
Das funktioniert nicht. In keiner Konfiguration, Kombination, ob mit oder ohne --use-system-libraries, keiner Quelle aus dem Internet folgend lässt bundler sich dazu bewegen, nokogiri mit dem Äquivalent das Gem-Befehls zu installieren. Entweder versucht er, alles selbst zu kompilieren, oder er findet die libxml2 nicht.
Ich durfte mich jetzt also entscheiden, nokogiri oder bundler rauszuschmeißen. Auf nokogiri zu verzichten erschien mir hier als das kleinere Übel.
Ruby ist toll. Aber das Verpacken von Rubycode zur späteren Verteilung stinkt.
Spec Ops: The Line
Thursday, 15. January 2015
Über Spec Ops dürfte man schonmal etwas gehört haben, das vage so klang: Es ist dieser relativ kurze Anti-Kriegs-Shooter mit hübscher Grafik. Das stimmt auch.
Von der Spielmechanik ist es ein Shooter mit Deckungssystem und KI-Kollegen. Ohne die neueren Versionen von Call of Duty - oder was auch immer im spunkgargleweewee-Genre gerade läuft - selbst gespielt zu haben, es hieß in den Tests damals, die Grundmechanik ähnele denen sehr, und das glaub ich gern: Es spielt sich schnell, kurzweilig und ist unheimlich brutal, ohne irgendwas neues zu bieten.
Warum dann Anti? Weil die Story es so will.
Statt den befehlsverweigernden Soldaten zum Helden zu stilisieren, zeigt Spec Ops ihn als traumatisierten Mörder. Wenn anfangs er und seine zwei Kollegen noch motiviert die Ursache für die wahnwitzige Situation und den Status der amerikanischen Soldaten herausfinden wollen und sich gegenseitig anfeuern, feinden sie sich später immer mehr an. Weil sie eben nicht einer normalen Mission folgen, sondern Videospiellogik, die hier aber eben nicht einfach funktioniert. Weil die Videohelden hier doch nur die Psyche von normalen Menschen haben, müssen sie am erlebten Wahnsinn kaputtgehen.
Klar, es gibt dann später natürlich einen speziellen Dreh in der Geschichte, der überraschend dann aber auch nicht mehr ist, da schon eine ganze Weile angedeutet. Und ja, das Spiel zeigt furchtbare Szenen, es vermittelt den Anti-Kriegsgedanken so deutlich, dass das Schießen durch die Feindeshorden am Ende keinen Spaß mehr macht. Das ist hier ausnahmsweise mal eine Leistung.
Und doch, es versagt. Um seine Geschichte zu erzählen, in der - Videospielkritik mal ausgeklammert - ein Soldat die falsche Wahl trifft, fasst es diese Geschichte in einen linearen Ablauf, in dem der Spieler keine Wahl hat. Wenn am Ende der Protagonist für seine Entscheidung angefeindet wird, distanziert das die Geschichte völlig vom Spieler, denn ich habe nie eine Entscheidung getroffen. Es gibt eine besonders brutale Szene, bei der Zivilisten sterben, und während dies für den Fall des Protagonisten ein Schlüsselpunkt ist, hat der Spieler wieder keinen Einfluss. Also auch keinerlei Verantwortung.
Witcher macht das besser. Auch dort gibt es Krieg, und auch dort wird er wohl kaum glorifiziert. Aber in den Witcher-Spielen trifft der Spieler Entscheidungen und hat dadurch Verantwortung für das, was geschieht. Gerade weil selten vorherzusehen ist, was geschehen wird (was Witchers System von Biowares Gut-Böse-Simplistik unterscheidet). In Spec Ops ist auch nicht alles vorhersehbar, so will ich gar nicht tun. Aber es fehlt durch die völlige Linearität die Tiefe, um daraus mehr zu machen als einen interaktiven Film.
Ohne Entscheidungen gibt es keine Moral.
Charlie
Saturday, 10. January 2015
Das erste mal so nah zu solchen Anschlägen zu sein fühlte sich sehr seltsam an. Es waren unangenehme Tage, den Vorgängen im Livestream zu folgen, zu sehen wie die Kollegen mit Verwandten und teils selbst in Paris wohnend zutiefst verunsichert sind. Jede neue Nachricht ein Schock, doch auch immer die Hoffnung dass die Terroristen endlich alle gefasst sind. Jetzt sind drei tot, aber zwei Personen werden immer noch gesucht und generell bleibt die Frage, wie tief diese Zelle noch geht.
Was mich unheimlich wütend machte sind die Leute, die eine solche Tragödie für ihre eigenen politischen Ziele nutzen wollen. Das sieht zum Glück auch hier nicht nur ich so. Marine Le Pen, die Führerin der französischen Faschisten, forderte direkt nach dem Anschlag die Wiedereinführung der hier erst in den 80ern abgeschafften Todesstrafe. Billiger geht es nicht.
Sollte man meinen, aber die CDU kann noch dümmer. Zusammen mit den Polizeigewerkschaften fordern sie die Vorratsdatenspeicherung. Obwohl Frankreich die Vorratsdatenspeicherung hat und es eben nicht half. Obwohl die Terroristen auf Beobachtungslisten standen und ihre Kommunikation sowieso hätte überwacht werden können, völlig ohne Massenüberwachung. Die Forderung der CDU ist das dümmste Verhalten absoluter Arschlöcher, mit dem man auf eine solche Terrortat reagieren kann. Sie zeigt, dass es diesen Feinden der Demokratie nur um die Abschaffung der Freiheit in Deutschland, um die eigene Machterweiterung geht. Sie sind ebenfalls Terroristen.
Wenn mein Eindruck der Stimmung der Franzosen stimmt, wird am Sonntag die ganze Nation in Paris sein. Ich hoffe, es wird ein würdiges Gedenken an die Opfer.
Hitman: Blood Money
Saturday, 3. January 2015
Vor vielen Jahren spielte ich den ersten Teil, ohne ihn je zu beenden, denn ich blieb in einem Dschungellevel hängen. Blood Money spielte ich jetzt über Weihnachten und beendete es problemlos.
Es ist ein gutes Spiel, und das liegt am Leveldesign. Es gibt immer mehrere Möglichkeiten, kreativ den Auftrag zu erledigen. Einige sind direkt in die Levels gebaut, manipulierbare Objekte wie fallende Kronleuchter. Andere sind Schleichwege und Verkleidungen. Hier ein Beispiel:
Ein vom Barkeeper erhaltenes Aphrodisiakum im Martini führt dazu, dass die Zielperson der Frau folgt, also aus der Menschenmenge verschwindet. Er läuft sogar zu einem Balkon, auf dem er ein einfaches Ziel ist. Eine Alternative wäre gewesen, auf das Dach zu klettern und ihn so versteckt zu erschießen.
Das Spiel besteht also darin, die Levels nach solchen Möglichkeiten zu durchsuchen. Das schöne dabei ist, dass es zur Not immer auch anders ginge - mehr Wachen ausschalten, eine Bombe legen, sonstwie improvisieren. In späteren Levels war meine erste Lösung die Nutzung der zwei Silberpistolen mit Schalldämpfer, erst beim zweiten Durchspielen wurden auch diese schleichend gelöst.
Die Grafik ist natürlich alt, die Bedienung empfand ich als hakelig, besonders das Anschleichen. Und auch in der Geschichte klaffen Lücken, was da im Hintergrund angeblich alles vorgeht spiegelt sich kaum in den Missionen selbst. Trotzdem hält die Geschichte das Spiel etwas zusammen, und sie motiviert ein tolles Ende.
Dankeschön, Rückblick und Ausblick für s9y
Wednesday, 24. December 2014
Es mag verfrüht sein, denn es kann ja noch alles um die Ohren fliegen. Aber weil wir ja doch ausgiebige Alpha- und Betaphasen hatten und weil ich wirklich glaube, dass mit dem RC die 2.0 fertig ist, ist hier auch der Punkt, an dem ich mich bedanke. Matthias dafür, dass er als Frontend-Designer massgeblich das Backend und damit 2.0 gebaut hat. Ian für die wahnsinnig wertvolle Hilfe vor allem in der Anfangszeit mit der Smartifizierung - ohne dich hätten wir gar nicht angefangen. Garvin gleich für zwei Dinge: 1. den Freiraum, 2.0 überhaupt anzugehen und 2. die fortwährende Hilfe beim Entscheiden und beim Ausbügeln von Bugs.
Gedankt sei auch allen, die s9y 2.0 getestet haben, also Bernd, Dirk, Thomas, Robert, Ben, … und wen ich gerade vergesse.
Wir haben damit schon angefangen, aber es wird jetzt weiterhin darum gehen, 2.x zu bauen und dabei den Entwicklungsmodus zu normalisieren. 2.0 war lange Zeit ein Alleingang von Matthias und mir. Das hat Vorteile: Es entfällt die Notwendigkeit, alles direkt abzustimmen und auszudiskutieren. Es hat schon so zu lange gedauert, das war notwendig. Aber als wir 2.0 öffneten gab es dann direkt Zusammenstöße. Das gleiche passierte, als ich Falk einbringen wollte. Beide Male ging es meines Erachtens vor allem um Entscheidungskompetenz - und um das klar zu sagen, der Streit führte zu Ecken in 2.0, die ich immer noch für falsch halte, die kein Nutzer verstehen kann, so wie der Streit mit Falk dazu führte, das wichtige Modernisierungen nicht angegangen wurden. Gleichzeitig dauerte nach der Öffnung alles - für mich frustrierend - lange. Das müssen wir in Zukunft besser machen: Nicht, dass ich alles entscheide, sondern dass wir da zu einem Modus finden, der ohne Streit zu besseren Egebnissen führt.
Ich glaube, dafür brauchen wir vor allem gemeinsame Vorstellungen, was wir erreichen wollen - denn genau die sind etwas, die ich bei 2.0 etwas forciert habe; was nur dank der Anpassung derselben, der Kompatibilität mit Matthias Vorstellungen und Garvins Duldung funktionierte.
Ich hoffe, dass das s9y-Treffen im März in Essen da helfen wird. Dort können wir wir neben dem Kennenlernen klären, wie wir weitermachen: Wie wir s9y entwickeln, wohin wir wollen, ob es das mit den Großprojekten erstmal war oder ob wir ein s9y 3 anstreben.
Für mich war 2.0 eine wertvolle Erfahrung, ein wichtiger Teil meiner Entwicklerlaufbahn. Denn eigentlich sind die Grundlagen einer Blogsoftware nicht kompliziert. Aber eine 10 Jahre alte PHP-Blogsoftware mit den Ausmaßen und den Fähigkeiten von s9y ohne zu große Brüche zu erweitern, und das noch in einem Projekt mit anderen Menschen, das ist durchaus kompliziert genug - und das musste ich erst lernen. Und das mit meinem inneren Konflikt zusammenbekommen, ob die Entwicklung an s9y überhaupt eine sinnvolle Nutzung meiner Zeit ist, was zu der Frage führt, was ich mir überhaupt wovon verspreche. Darüber nachzudenken war wichtig.
Darüber nachzudenken passt wohl jetzt auch gut in die Weihnachtszeit. Ich wünsche euch allen eine schöne.