Stranger Than Usual

Give me the microplastics! They belong in the ocean!

Worst Premade Ever

Rollenspielszenen: Journal-Eintrag

Rollenspielszene. Wir sind eine Gruppe von Freigeistern die im Wald leben. Jüngstes Mitglied ist Siobhan, Nichte von Niamh, der schon länger bei uns lebt. Siobhan hat sich vorrübergehend aus ihrer politischen Arbeit zurückgezogen, weil es in der nächsten Stadt Leute gibt, die sie besser nicht sehen sollten.

Es ist später Vormittag. Siobhan wacht auf und bevor sie Niamhs Behausung verlässt, schreibt sie in ihr Journal:

Heute werde ich nicht das System stürzen, und das ist ok.

Klick- und tabbare barrierefreihe Tabellenzeilen in HTML

Ich bin kein großer Barrierefreiheitexperte, auch nicht, wenn es um Websites geht. Eines weiß ich aber: Einfach irgendwelche Elemente mit Javascript anklickbar zu machen, die üblicherweise nicht anklickbar sind, ist nicht barrierefrei, weil Screenreader oder andere Hilfstechnologie sie nicht als anklickbar erkennt. Das ist eine Barriere für z.B. sehbehinderte Personen, für die die Klickbarkeit einfach unsichtbar ist.

Vor diesem Problem stand ich gestern, als ich ein paar Tabellenzeilen (<tr>, „table row“ in HTML) nicht nur anklickbar, sondern auch mit der Tastatur auswählbar machen musste. Die Idee war: User sucht etwas, User kriegt eine Tabelle mit Ergebnissen, User klickt auf eine Zeile, irgendetwas passiert. In meinem Fall war es ein Button, der eine Änderung auslöste, es könnte aber auch genausogut ein Link sein, der irgendwohin führt.

Was tun? Man kann den <button> oder das <a> nicht um das <tr> wrappen, weil das in HTML nicht erlaubt ist. Man kann in jede einzelne Zelle einen Link oder Button stecken, aber das ist unschön und die Tabellenzellenpaddings sind dann auch nicht klickbar. Man könnte in eine Zelle einen Link stecken und dann zusätzlich mit Javascript die Zeile anklickbar machen. Das ist aber unschön und funktioniert nicht ohne Javascript (letzteres wäre in meinem Fall kein größeres Problem gewesen.

Ich habe ein bisschen recherchiert und einen Blogpost mit einer Lösung gefunden. Ich gehe hier nicht in die Details, lest euch dazu den Post durch, aber die Idee ist: Man packt nur in eine Zelle den Link und sorgt dann mit geschicktem CSS dazu, dass für typische Browsernutzer der Link auf die ganze Zeile ausgedehnt wird. Für Hilfstechnologie ist aber der ursprügliche Button oder der Link immer noch da (sollte aber einen passenden Text haben). Ich weiß nicht, ob das komplett barrierefrei ist, ist aber auf jeden Fall deutlich besser als die Variante, in der man die Zeile nur klickbar macht. Bonus: Man kann auch mit Tab durch die Zeilen wechseln und dann mit Enter eine auswählen (die Anleitung ist für einen <button>, mit leichten Änderungen funktioniert es aber auch für ein <a>).

Ich war also ganz zufrieden mit dem Ergebnis, bis mir ein Kollege sagte: Hey, das funktioniert bei mir überhaupt nicht und macht die ganze Seite unbrauchbar. Was ist passiert?

Wir sind kurz zusammen durchgegangen: In Firefox funktioniert es. In Chrome auch. In Safari nicht. Woran lag das? Nun, um den Klickbereich auf die ganze Zeile auszuweiten, habe ich einen Trick verwendet: Ich habe dem Button in CSS mit einem ::after selector ein Dummy-Kindelement hinzugefügt. Dieses habe ich dann mit position: absolute und inset: 0 positioniert und skaliert. Und zwar genau über das nächste Vorfahrelement, das ebenfalls explizit positioniert war (position: relative. In diesem Fall war es die Tabellenzeile <tr>.

Safari hat aber einen Bug, durch den ein position: relative an einer Tabellenzeile ignoriert wird. Dabei wollte ich die Tabellenzeile ja nicht einmal bewegen, ich brauchte sie nur als Referenzpunkt. Mangels weiterer positionierter Elemente hat sich dann das button::after auf die gesamte Seitengröße ausgedehnt. Man konnte also nichts mehr klicken. Egal, wo man klickte, es wurde immer derselbe Button gedrückt.

Glücklicherweise habe ich einen anderen Blogpost mit einem Workaround gefunden. Das ist ein bisschen hacky, funktioniert aber auf allen drei getesteten Browsern.

Rollenspielszenen: Das Glitzerding in der Wand

Rollenspielszene. Nini, Sprinkle und Cory sind vor der Scawnbande geflohen und zwar direkt in das Höhlensystem in der Rinde des Weltbaums, in der sie den gesuchten Schatz vermuten. Das Höhlensystem ist ein Irrgarten, durchsetzt von magischen Fallen, und Gedächtniszaubern, die das Verirren sehr leicht machen.

An einer Stelle tut sich ein Abgrund auf. Als Zi Ri kann Nini fliegen und erkundet deshalb den Boden des Abgrunds sowie den Gang, der gegenüber weiter geht. Im Gang gegenüber findet zie etwas Glitzerndes das in der Wand aus Borke eingelassen ist. Es glitzert! Nini ist klar, dass das der Weg ist, den die Gruppe nehmen muss.

Die anderen schaffen es mit einem heraufbeschworenen Seil, die andere Seite zu erreichen. Sie schauen sich das aus ihrer Sicht recht unbemerkenswerte Glitzerding an und wollen da weiter. Nini will aber das Glitzerding haben! Zie krallt sich an dem Glitzerding fest, während Sprinkle sie wortwörtlich von ihm wegzerren muss.

Neeeein! Mein Glitzerding!

Flutter Web: Schlechte Idee

In meinem vorherigen Projekt auf der Arbeit war das Frontend eine Flutter-Web-App. Der Grund dafür war, dass der Kunde für alle Frontends Flutter verwendet, also auch für unsere App. Das war übrigens derselbe Kunde, der überall C# verwendet (ugh).

Flutter fing an als ein Framework für Mobile-Apps. Und zwar eins, in dem man Apps nur ein Mal schreiben musste, um sie dann sowohl fürAndroid als auch für iOS verwenden zu können. Den Wunsch danach kann ich verstehen. Um das zu erreichen, verwendet Flutter auch nicht die nativen Bibliotheken der beiden Betriebssysteme, sondern re-implementiert die komplette UI-Bibliothek (passt sich aber vom Aussehen her an das jeweilige System an). Man kann hier geteilter Meinung zu Flutter sein (ich finde es grundsätzlich nicht so schlimm, aber vermutlich hätte man denselben Effekt auch mit einer PWA haben können), aber immerhin erfüllt es seine Aufgabe recht brauchbar.

Aber dann ist jemand auf die Idee gekommen, Flutter auch zur Entwicklung von Web-Anwendungen einzusetzen. Und hier beginnen für mich die Schmerzen. Flutter Web verfolgt nämlich denselben Ansatz wie auf Android und iOS: Alles wird neu gemacht, es werden keine nativen Elemente verwendet. Und im Web bedeutet das: Kein HTML (bzw. das HTML nur als Rahmen), alle UI-Inhalte werden in ein <canvas>-Element gezeichnet.

Mit anderen Worten: Man wirft alle native Browser-Funktionalität weg (mehr noch als bei anderen One-Page-Apps) und muss jede Kleinigkeit mit in den ausgelieferten Code packen. Und das ist nicht wenig. Eine einfache „Hello World“-App ist schon gut 9 MiB groß, wenn sie optimiert wurde. Im Developer-Modus sind es eher 100 MiB. Und damit sind einige Sachen noch nicht enthalten. Zum Beispiel:

  • SVG-Rendering: Dafür muss man eine gesonderte Abhängigkeit einziehen
  • relative Stylegrößen wie em in CSS
  • Hyperlinks. Ja, Hyperlinks. Das Rückrat des Webs. Geht nicht ohne halbwegs komplizierten Code.

Andere Funktionen, die sonst nativ mit dem Browser kommen, wurden auch re-implementiert (irgendwie muss man ja auf die neun Megabyte kommen):

  • Navigation
  • UI-Rendering (wie schon erwähnt im Canvas)
  • responsiveness
  • Layout
  • Barrierefreiheit (auf dem Canvas ein großes Problem, man muss eine Menge manuellen Aufwand betreiben, um nur grundlegende Barrierefreiheitsfunktionen zu bekommen)
  • Form handling
  • Textauswahl (zum Kopieren)
  • Scrolling (!)
  • je nach Betriebssystemeinstellungen ist sogar das Rendern von Schriftarten ein Problem

Alles in Allem erinnert das an die Flash-Apps der späten 2000er. Wo Leute aus irgendeinem Grund die ganze Website in Flash geschrieben haben, anstatt in HTML. Groß, langsam, Kernfunktionen des Browser werden ignoriert. Und alles, damit man eine App nur ein Mal schreiben muss. Wisst ihr was? Genau dafür gibt es Progressive Web Apps (PWAs). Aber nein, hier muss das Rad unbedingt neu erfunden werden, es erzeugt gewaltige Mengen an JS-Code um ein schlechteres Ergebnis zu bekommn.

Ich bin froh, dass ich damit nicht mehr arbeiten muss (das Projekt selber war allerdings ganz interessant, da wäre ich auch geblieben). Ich kann nur empfehlen: Nutzt Flutter nicht für Web-Apps. Und grundsätzlich: Wenn ihr eine App wollte, die auf verschiedensten (insbesondere Android und iOS) Systemen läuft, überlegt euch, ob eine PWA vielleicht eine Option wäre.

Bye, Windows

Im Jahr 2007 habe ich das erste Mal dauerhaft eine Linuxinstallation auf meinem Computer gehabt. Ich hatte schon vorher mit Linux experimentiert, bin aber immer gescheitert, üblicherweise an der Bootloaded Dual-Boot-Konfiguration mit Windows. Damals war das ein SuSE Linux. Nach einem Jahr hatte ich die Schnauze voll von SuSE und bin auf Gentoo umgestiegen. Ich habe in der ersten Woche mit Gentoo mehr gelernt als in einem Jahr mit SuSE, und habe einen Freund dermaßen zugetextet, dass er meinte, ich solle doch ein Blog anfangen. Also habe ich ein Blog angefangen.

Ich nutze Linux also seit gut 19 Jahren. Und obwohl ich auf meinen Laptops seitdem immer nur Linux hatte (meinen ersten Laptop habe ich erst nach meinem Abitur, vor Beginn meines Informatikstudiums bekommen), habe ich trotzdem immer noch eine Kiste gehabt, auf der im Dualboot Windows und Linux liefen.

Warum Windows? Ich komme mit Linux viel besser klar, und kam auch 2018 schon mit Linux viel besser klar. Für alles, was ich mit einem Computer machen wollte, gab es unter Linux ein Programm, mit dem ich genausogut oder besser klar kam. Browser? Der gleiche Browser (obwohl ich ein paar Probleme mit Flash und Java-Applets hatte, aber die gehören ja mittlerweile der Vergangenheit an). Abspielen von Audiodateien? Kein Problem. DVDs anschauen? libdvdcss. Programmieren? Fast alles davon läuft besser unter Linux. Es lief also alles. Außer Computerspielen.

Ich spiele immer wieder gerne. Und Spiele sind nicht wie Browser, oder Audioplayer, oder Videoplayer. Wenn dir ein Spiel gefällt, gibt es üblicherweise keine Open-Source-Alternative. Abgesehen davon war der Grafikkartensupport unter Linux immer scheußlich. Nun, letzteres hat sich geändert, nicht zuletzt, weil zunächst Cryptocurrency-Bros und „AI“-Rechenzentrum plötzlich genau diese Art von Rechenleistung brauchten. Die Kompatibilität der Spiele blieb ein Problem. Gut, es gab Wine, aber das lief nur so mäßig gut.

Darum also Windows. Und warum möchte ich jetzt so dringen davon weg? Nun, mein Spielerechner von 2019 läuft noch mit Windows 10. Und für ein Update zu Windows 11 fehlt ihm ein Trusted Platform Module-Chip der Version 2. Ansonsten würde die Hardware das ohne Probleme schaffen. Außerdem gibt es einige andere Unannehmlichkeiten mit Windows 11: Man braucht einen Microsoft-Account, um sich auf dem Rechner lokal einzuloggen, Microsoft stopft es voll mit „AI“-Tools, die ich nicht will (Stichwort MS Recall)… die Liste lässt sich fortsetzen.

Jetzt möchte ich meinen Spielerechner aber eigentlich behalten. Die Hardware ist noch völlig ausreichend für alle Spiele, die ich spiele. Neue Hardware ist teuer, insbesondere weil ein paar gehypete Konzerne allen RAM auf dem Markt gekauft haben (oder zumindest versprochen haben, sie würden das tun). Steam hat die „Steam Machine“ angekündigt, ein Standrechner auf Linuxbasis, mit dem man alle möglichen Steam-Spiele spielen kann. Aber das wird ja auch teuer…

Nur: Wenn Steam es schafft, Windows-Spiele auf der eigenen Linux-basierten Plattform zum laufen zu bringen, dann ja sicher auch auch meinem eigenen Linux-System. Ich bin ja kein großer Steam-Fan, aber dass Steam seit 2012 Linux unterstützt kann ich ihnen wirklich nur hoch anrechnen. Nicht nur haben sie einen Linux-Client, nein, sie haben auch viele eigene Spiele (z.B. Portal) nach Linu portiert und Spieleentwickler dazu ermutigt, das auch zu tun. Und sie haben Wine genommen und es zu Proton weiterentwickelt, so dass es eine Kompatibilitätsschicht zwischen Windows-Spielen und Linux-Betriebssystemen gibt.

Also habe ich mich am Montag daran gesetzt. Ich hatte das alte Linux von 2019 sträflich vernachlässigt und nicht geupdated, also habe ich es mir einfach gemacht und die Linux-Partition mit einem neuen Ubuntu 2026.04 überbügelt. Und Steam installiert. Erste Tests liefen erfolgreich. Aber ein etwas aufwändigeres Spiel (Sea of Thieves) konnte ich erst gestern ausprobieren, weil das 130 GiB zum Download sind und ich den Download tagsüber nicht laufen lassen kann, weil ich von zu Hause arbeite (deutsches Internet halt).

Ich musste zunächst ein bisshen herumfummeln (die Proton-Version auf die letzte stabile Version fixieren anstelle die Unstable-Version zu nehmen) aber danach lief Sea of Thieves ohne Probleme. Und Proton funktioniert ja nicht nur mit über Steam installierten Spielen. Ich kann also meine alten Spiele, oder Spiele, die ich über andere Anbieter bezogen habe, auch spielen. Vielleicht probiere ich auch den Heroic Games Launcher aus, ein Open Source-Projekt, dass das noch etwas einfacher machen soll (ist bastle zwar gerne, aber bei manchen Sachen möchte ich, dass sie einfach funktionieren).

Also Das ist es. Nach 19 Jahren Linux kann ich endlich Windows verlassen. Good riddance!

16 Byte

Die Demoszene betreibt eine Kunstform, mit möglichst geringen Resourcen möglichst beeindruckende Kunstwerke zu schaffen. Animiert, mit Ton, was auch immer. Es gibt viele verschiedene Kategorien von Demos. Aber eine Sache ist gleich: Selbstauferlegte Beschränkungen.

Und das ist teilweise wirklich beeindruckend. Neulich habe ich diese Matrix-artige Demo gefunden. Da flackern für eine ganze Zeit Buchstaben auf dem Bildschirm auf (und wenn die Bildschirmfarbe grün ist, dann auch in grün), so ähnlich die die fallenden Buchstaben im Film „Matrix“. Dazu ein gruseliger, metallisch klingender, aber auch rhythmischer Soundtrack.

Das Besondere: Es braucht nur 16 Byte (Sechzehn Byte! Nicht Kilobyte. Byte.) an Programmcode. Das Programm läuft unter MS-Dos und macht sich Eigenschaften von Speicherlayout, Grafikspeicher und Audiogeräten zu nutze. Der Autor hat in einem Blogpost beschrieben, wie das Ganze funktioniert.

Sechzehn. Byte.

Billige Zipbombe

Eine Zipbombe (oder Archivbombe) ist eine komprimierte Datei, die zu einer extrem großen Datei entpackt wird. Normalerweise erstellt man Zipbomben direkt durch genaue Kenntnis des Kompressionsverfahrens ohne tatsächlich Daten zu komprimieren. So kann man zum Beispiel eine 42 kiB große Datei auf 4,5 Petabyte aufblähen.

Die billigere Variante ist, einfach sehr gut zu komprimierende Daten zu nehmen und sie zu komprimieren. Deutlich weniger elegant und 4,5 Petabyte wird man damit nicht hinkriegen. Dennoch ganz lustig. Ein Nutzen für eine solche Datei ist zum Beispiel, Scraper, die sich nicht an Regeln halten (z.B. and die robots.txt) halten, abzustrafen.

Meine eigene billige Zipbombe

Cool, so etwas will ich auch haben. Ich habe aber nicht genug Kenntnis über Kompressionsverfahren um so etwas zu basteln, möchte keine vorgefertigte Zipbombe nehmen (deren Hash könnte ja auf einer ignore-list stehen) und hätte gerne eine Zipbombe, in der gültiges HTML steckt. Womit auch erklärt wäre, warum ich neulich eine große HTML-Datei möglichst schnell nach stdout schreiben wollte (dazu gibt es übrigens unten noch ein Update).

Ich habe drei verschiedene Kompressionsverfahren ausprobiert, die alle im HTTP-content-encoding header erlaubt sind: Brotli, gz und Zstandard. Ich habe jeweils die höchste Kompressionsrate gewählt (für gz allerdings nicht Zopfli, das wäre mir dann doch zu langsam gewesen, also nur herkömmliches gzip). Ich habe dann wie beschrieben eine etwa 42 GiB große Datei erzeugt und diese on-the-fly zur Kompression gegeben.

Die Messungen sind nur mit time gemacht, könnten also Ausreißer enthalten. genbig ist hier das Rust-Programm, das die HTML-Daten erzeugt. Das sind die Ergebnisse:

gzip

$ time  genbig | gzip --best --stdout > big.html.gz
real    1m15,029s
user    1m12,729s
sys 0m14,630s

Dauert eine Weile, und die Ergebnisdatei ist etwa 126 MiB groß. Eigentlich würde ich gz gerne mit reinnehmen, weil es am weitesten verbreitet ist (viele Bots unterstützen meiner Erfahrung nach überhaupt keine Transportkompression, ganz zu Schweigen von Brotli), aber 126 Megabyte sind mir zu groß, da werden auf meiner Seite zu viele Resourcen genutzt.

Brotli

$ genbig | brotli --force --best -o big.html.br
real    32m47,275s
user    32m36,105s
sys 0m16,348s

Das hat eine gute halbe Stunde gebraucht, also eine Größenordnung mehr als gzip. Autsch! Auf der positiven Seite: Die Datei ist angenehme 35 kiB groß. Damit kann ich arbeiten.

Zstandard

Und der Neueste im Bunde. Um hier die Performance vergleichen zu können, habe ich es einmal mit einem Kompressions-thread und einmal mit vier Kompressions-Threads laufen lassen. Es gab dabei jeweils immer noch einen separaten I/O-Thread. Zuerst die Version mit einem Thread:

$ time genbig | zstd -19 -T1 --no-content-size --size-hint=43009MiB -o big_single.html.zst
real    0m53,649s
user    1m4,932s
sys 0m19,570s

Dann die Version mit vier:

$ time genbig | zstd -19 -T4 --no-content-size --size-hint=43009MiB -o big.html.zst
real    0m20,540s
user    1m27,782s
sys 0m19,051s

Von der Zeit her also beides deutlich besser als gzip, ganz zu schweigen von Brotli. Das Ergebnis ist für beide Varianten gleich und etwa 3,7 MiB groß. Das kommt schon in eine brauchbare Richtung, ist aber Größenordnungen hinter der Brotli-Variante.

Fazit

Es war ganz lustig, das mal ausprobiert zu haben. Bisher habe ich diese Dateien noch nirgendwo im Einsatz, weil ich noch nicht genau weiß, wie ich sie einsetzen will. Ich möchte keine Suchmaschinencrawler abschrecken, und erst recht nicht, dass ein regulärer User aus Versehen auf diese Dateien stößt. Eher will ich LLM-Scraper bestrafen, die sich nicht an die robots.txt halten (die sie momentan aber noch nicht aus diesem Blog aussperrt) oder die ganzen Scanner, die bei mir nach Lücken suchen. Letztere können aber auch gutmütig sein, aber davon würde ich nicht unbedingt ausgehen.

Viele dieser Bots unterstützen wie gesagt sowieso keine Transportkompression, und die meisten, die es tun, kein Brotli. Und speziell die gzip-Datei ist mir zu groß für den Spaß. Trotzdem: War mal ganz lustig, das auszuprobieren.

Bonus: I/O-Optimierung

Zstandard ist wirklich schnell, besonders mit mehreren Threads. Tatsächlich war es so schnell, dass ich dafür ein Rust-Programm optimieren musste, so dass es schneller nach stdout schreibt. Dummerweise war das Rust-Programm danach zwar deutlich schneller als die Python-Variante, aber immer noch zu langsam. Mit vier Threads:

real    0m51,731s
user    2m8,343s
sys 0m22,070s

Wenn man sich den Prozess während der Laufzeit anschaut, stellt man fest, dass genbig 100 % eines Kerns auslastet, und zstd kommt gerade mal auf 190 % (von den mit 4 + 1 Threads möglichen 500 %). Das verfälscht natürlich die Messung. Außerdem: Verdammt soll ich sein wenn ich kein Programm schreiben kann, das nichts tut außer immer wieder das gleiche nach stdout zu schreiben und dabei schneller ist als ein Programm, dass dieselben Daten von stdin liest und komprimiert. Das wäre peinlich.

Aber ich kann ja sicher etwas verbessern. Zum Beispiel werden sehr viele kleine Schreiboperationen durchgeführt. Die gehen zwar in einen Buffer, trotzdem muss nach jeder Operation auf Fehler geprüft werden. Wenn man das eine Milliarde mal macht, kommt da richtig Rechenzeit zusammen. Also habe ich mir gedacht, ich schreibe einfach mehrere Einheiten von dem sich wiederholenden Teil in einem write-Aufruf:

fn gen_body_part() -> String {
    // 8 kiB is the default buffer size of BufWriter
    repeat(REPEATED).take((1024 * 8 ) / REPEATED.len() + 1).collect()
}

fn main() -> Result<()> {
    let body_part = gen_body_part();
    let body_bytes = body_part.as_bytes();

    let mut out = BufWriter::new(stdout().lock());

    writeln!(out, "{}", PREFIX)?;

    let repeats = APPROX_SIZE / body_bytes.len();
    for _ in 0..repeats {
        out.write_all(body_bytes)?;
    }

    writeln!(out, "{}", SUFFIX)
}

Das Ergebnis ist besser, aber nicht wesentlich besser:

real    0m48,688s
user    2m4,117s
sys 0m20,982s

genbig ist immer noch bei 100 % Auslastung, zstd bei etwa 200 %. Aber ich habe ja auch einen Fehler gemacht: Ich habe das, was ich auf einmal schreibe, ein sehr kleines bisschen größer gemacht als den Buffer. Wenn ich also die Funktion oben ändere in

fn gen_body_part() -> String {
    // 8 kiB is the default buffer size of BufWriter
    repeat_n(REPEATED, (1024 * 8) / REPEATED.len()).collect()
}

Dann hat genbig zwischendurch endlich Zeit Luft zu holen, zstd rechnet auf allen Threads am Limit und die Laufzeit verringert sich auf… Trommelwirbel

real    0m20,540s
user    1m27,782s
sys 0m19,051s

Etwa 20 Sekunden. Eine deutliche Verbesserung.

Ich hätte natürlich auf die Buffergröße anpassen können. Vermutlich gibt es noch einen Haufen Optimierungsmöglichkeiten hier. Und das hier ist ein sehr kurzes Programm. Ich frage mich, wie viel Software ich geschrieben habe, die langsam ist, weil sie an irgendeinem dummen Flaschenhals feststeckt. Ich frage mich auch, wie viel Software da draußen viel langsamer ist, als sie es sein müsste, weil irgendjemand einen dummen Flaschenhals übersehen hat. Naja, jedenfalls habe ich wieder etwas gelernt.

Digital Independence Towel Day

Frohen Towel Day an euch alle! Wisst ihr alle, wo euer Handtuch ist?

Heute Abend habe ich mich online mit ein paar Freunden zusammengesetzt, um zusammen auf Alternativen zu großen Techkonzernen umzusteigen. So à la Digital Independence Day, aber halt nicht am ersten Sonntag des Monats wo ich diesen Monat weder Zeit noch Ideen hatte, was ich tun sollte.

Heute haben wir aber ein paar Sachen geschafft:

  • Freundin A hat auf ihrem Smartphone eine googlefreie Android-Variante installiert und zum ersten Mal auch den Signal Messenger
  • einem linuxinteressierten Freund B haben wir Informationen zu einem möglichen Umstieg/Teilumstieg auf Linux gegeben. Das war eine gute Arbeitsteilung: Ich, erfahrener Linuxnutzer, was möglich ist und wie man bestimmte Sachen macht. A konnte ihm Erfahrungswerte auch nichttechnischer Sicht geben (sie ist mit Linux Mint sehr gut klar gekommen). Freundin C konnte Hilfe bei der Installation anbieten (was für mich schwierig wäre, weil alle anderen drei in Hamburg wohnen und ich nicht).
  • C hat mit dem Umstieg auf Posteo angefangen. Sie hatte schon einen Account, aber bisher noch keine Zeit gehabt, umzuziehen.
  • Ich habe das alte Linux 19.10 auf meinem Spielerechner (auf dem außerdem noch Windows 10 läuft) mit Linux 26.04 überbügelt und erste Erfahrungen gemacht, wie gut Valves Wine-Fork Proton funktioniert. Erste Erfahrungen waren positiv. Als nächstes probiere ich anspruchsvollere Spiele. Dann kann ich auch B erzählen, was er dort erwarten kann.

Alles in Allem: Ein erfolgreicher Abend in angenehmer Atmosphäre.

PS: Wir haben das Ganze ironischerweise über Discord organisiert und durchgeführt. Das zu ändern steht auch noch auf der Agenda.

Rollenspielszenen: Morgenlied

Rollenspielszene: Die Gruppe hat beschlossen, am nächsten Morgen früh aufzubrechen. Fredegar Stolzfuß, Barde, ist als erster wach. Um den anderen Gruppenmitgliedern ein schönes Aufwachen zu ermöglichen, weckt er sie mit einem fröhlichen Morgenlied.

Trotz seiner passablen Menschenkenntnis rechnete er nicht damit, dass das Thivuc überhaupt nicht gefallen könnte. Ein gezielter Wurf mit einem Stiefel, und Fredegar bricht das Lied ab. Banausen!