KI auf Flughöhen

Kürzlich hatte ich eine gute Diskussion zum Einsatz von LLMs in der Software-Entwicklung, die eine gewisse Differenzierung erlaubte. Derzeit werden Diskussionen rund um den Einsatz sehr schwarz-weiß geführt – ich komme von der AI-kritischen Seite und Argumente rund um Ressourcen-Verbrauch, Finanz-Bubble, Ausbeutung, Sicherheit, Psychosen, Slop sind hiermit acknowledged, werden in der folgenden Betrachtung, aber nicht noch einmal aufgegriffen.

Im Einsatz von LLMs unterscheide ich zwischen zwei Arten: Ist das LLM eine Funktion innerhalb eines größeren Prozesses oder steuert das LLM diesen Prozess. Macht du Bildbearbeitung und nutzt in deiner Software ein Feature zum sauberen Markieren eines Object, ist es Ersteres. Du könntest es ohne AI machen, ist aber mehr administrativer Aufwand, der kreative Prozess liegt bei mir. Du hast eine Automatisierung, die deterministische Schritte geht und ein Schritt ist ein Prompt zu einem LLM, ist ebenfalls Ersteres, solange das LLM eine einzelne klare Funktion, zB eine Qualifizierung erfüllt.
Zweiterem entspricht der Ansatz “mach mir alles”, wenn der kreative Prozess an sich an das LLM abgegeben wird. The Oatmeal hat das schön zusammengefasst.

Ähnlich sehe ich es auch bei Software-Entwicklung. Du kannst einen sehr gezielten LLM Einsatz haben, der an den richtigen Stellen sehr hilfreich ist und eine gute Ergänzung ist. Für mich ist dass, wenn ich komplexen Code debuggen (stell dir 5x verschachtelte SQL vor und frag nicht woher die kommen) und das LLM erstaunlich oft ihr beschriebene Fehler auflösen kann. Meine Erfolge mit Coding Agents sind dagegen gering, was hauptsächlich daran liegt, dass ich sie mit lokalen Open-Source LLMs und zu schwacher Hardware betrieben habe.

Ich war letztes Jahr zu einem n8n-Meetup. N8n nutze ich öfters, wenn es darum geht schnell Automatisierungen zu prototypen. Umgeben war ich von Marketing-Personen und Product-Manager*Innen, die stolz ihre selbst gebauten Systeme zeigten. Automatisierungen wild zusammen geklickt aus 5 Services ohne Rücksicht auf Performance, Datenschutz, Skalierbarkeit und Stabilität. Aber sie waren stolz drauf und es erfüllte für sie eine Aufgabe, die vorher nicht erfüllt werden konnte. Was in der Luft schwang, war eine Abwertung der eigenen IT-Abteilung. Du hörtest den Frust von Menschen, die zu oft “nein, machen wir nicht”, “nein, keine Ressourcen” oder “wir setzen es aufs Backlog, du hast es in 4 Monaten” zu hören bekommen haben. Ihnen ist egal, dass ihre AI-Lösungen alle paar Wochen zusammenbrechen und ein Datenschutz-Albtraum sind.

Im Product Management gibt es eine Organisationsmethode von Flughöhen (Flight levels). Du kannst Initiativen in verschiedenen Flughöhen haben, die alle hohe Prioritäten genießen, aber unterschiedliche Zeithorizonte haben.
Die Quickwins auf niedriger Flughöhe sind schnell eingeführt, lassen sich schnell ändern und können schnell wieder ersetzt werden.
In der mittleren Flughöhe sind Themen mit Blick auf das nächste Projekt, die über die nächsten Wochen/Monate relevant werden.
Die strategischen Themen sind oberste Flughöhe und die dicken Bretter. Diese ändern sich selten und haben einen langen Zeithorizont.

Software kann ebenfalls in diese Flughöhen eingeteilt werden und je nach Höhe kommen unterschiedliche Anforderungen.
Dein Einmal-Script von der AI geschrieben, dass du nicht wieder verwenden willst ist ein Quickwin vorausgesetzt es ist bei unkritischen Dingen im Einsatz.
Die vibe-gecodete Anwendung ist eine nächste Flughöhe mit überschaubarer Lebensdauer aber praktischem Nutzen. Es wird oft kaputtgehen, aber das macht nichts. Es hilft dir, niemand anderen und du kannst die Verantwortung für dich tragen.
Die nächste Höhe ist Software, die mit Zugriff auf das Lethal Trifectar – Private Daten (Kreditkarte), Zugriff ins Internet(kann Daten zu Webseiten schicken) und Zugriff durch Unbefugte (LLM führt Inhalt einer E-Mail aus) – hat. Hier erreichen wir den Punkt an dem Vibe-Coding nicht mehr empfehlenswert ist und wo LLM-Einsatz nur noch in isolierten einzelnen Funktionen sinnvoll sein könnte.
In der höchsten Flughöhe ist die Software das Zentrum deines Businessmodells. Soll sie für Jahre stabil und skalierbar sein, so halte LLMs davon fern. Hier spielen Architektur, Software-Design, Performance und langfristiges Komplexitäts-Management eine große Rolle und können hier nicht LLMs nicht mithalten.

Nach diesen Flightleveln bewerte ich für mich, wann welcher AI-Einsatz tolerabel ist.
Kenne deine Werkzeuge, deine Risiken und wann du einen Bogen drum herum machst.

Pro Bending – Game mechanics

Last time I wrote about how I started building my first game Pro Bending.
This time I want to look into the game mechanics and some thoughts behind it.

First, checkout the game available on Itch.io for free. It’s generally working as intended, although a bit rough around the edges – call it character. 😀

The game ended up being quite similar to hat I had in mind. It is inspired by The Legend Of Korra by having an arena with multiple zones and two teams who have to push the opponent team back in their zones and gain territory. Pushing them off the edge leads to a Knockout and instant win.
So the players goal is to balance their strategy between offensively trying to push the enemy back, and defensely avoiding to get hit and thus increasing risk of being pushed back yourself. The whole gamplay is implemented on this balance – with a lot of room fore refinement.

Two teams face-off in an elevated arena. Players of both teams have an elemental skill – fire, water, earth. Their goal is to push their opponents back on their field, thereby gaining territory. Match winner is who wins 3 rounds by gaining the most territory in each. You have to attack to proceed, while defend against the attacks of your opponents. All players on the field have 3 critical properties: Accuracy, Balance and Power. Accuracy determines how precise attacks are, while power determines how far your range attack goes. Balance is a defensive property describing how “steady” you are when receiving attacks – loose your balance, you get pushed back more easy. Each elemental attack addresses one poverty. Fire attacks reduce power. Water attacks reduce accuracy. Earth attacks reduce Balance. This creates a game dynamic where you have to quickly strategize, see and take opportunities and switch between offense and defense.

The steering is based on WADS movement with auto-aiming to a selected enemy. I was and I am still trying different input sets. I was considering something League-Of-Legends or Heroes Of The Storm, but the characters require a different mobility. The target is still inspired by it. I am still trying how to add game controller support. Two actions I have yet to implement and try how they affect game play is blocking (defensive position to absorb projectile with minimal damage) and dashing (fast avoiding movement).

Speaking of LoL. Right now for each elemental bender only one simple attack is implemented. This is where I have plenty of ideas also inspired by LoL and HotS, I may try in the future. I would like to make the elements more different. Right now the only difference is in health effects. Water reduces accuracy which increases the margin of error when firing projectiles. This reduces their offensive capability. Earth has the biggest wooms and reduces balances, being hid by earth makes the opponent slide more, thus increasing risk of being pushed over the line. Lastly hitting with fire reduces the Power of the hit character. Power being the ability to throw an attack and the strength of the attack.
What I switched around a few times is weather this is rather a bullet hell (dozents of projectiles, each hit doing minimal damage) or more strategic (few projectiles, strong damage). Between those extremes, I’m more on the bullet hell end at the moment. With blocking and dashing, and different steering, I could imaging leaning more into the strategic aspects again.

The AI is already doing it’s thing, but here is also a lot of room for improvement, for better play, strategy, coordination and personalities.
Lastly, right now you only have the quickmatch. I could imagine having a campaign where you team has to work through the full tournament in multiple rounds to win, with a small embedded story. This is where we are in let’s-dream territory. I may add some new things over time, but for now I’m happy with the state I have now. For a 3 months project in my free time I’m proud of the result. I hope you enjoy it as much as me. 🙂

Solving Tailscale DNS issues

As I mentioned the other day, I fell in love using Tailscale for making my local private network accessible remotely. I’m also using this in my company, but with one colleague, had an issue, I didn’t find any documented solution online. So here is mine.

I have a Tailscale network with multiple self-hosted services running in Docker and made available with Tailscale. If you have an account and your account is invited to the network, you can access them. This worked for 2 of 3 colleagues. The third had the Tailscale client running on their Windows, it showed up as active in the Tailscale admin console and the list of machines. It looks like it runs perfectly, but when you try access the the service within the network, it fails in Firefox with the error PR_END_OF_FILE_ERROR or SSL_ERROR_INTERNAL_ERROR_ALERT. In other browsers the error would just show as a connection error.

If you put the service in a public Tailscale tunnel, access is possible.
if you go on their machine, open Powershell and call tailscale status it would show all status just fine. Calling tailscale ping <service-name> shows success ping to the service.

I tested Windows defender and firewall settings, but could not find anything that could explain the issues.

Calling tailscale dns status provides on the machine provides an overview of the dns options Tailscale is using. Here it showed this:

=== 'Use Tailscale DNS' status ===

Tailscale DNS: disabled.

Tailscale is configured to handle DNS queries on this device.
Run 'tailscale set --accept-dns=false' to revert to your system default DNS resolver.

So I switched this on:

tailscale set --accept-dns=true

Et voila, calling the service work again!

So now I’m in this half-satisfactory space of having a solution, but not knowing the root cause. My guess is that this colleague hasn’t updated Tailscale since them installed it initially in October and when they installed the latest version, it did not install the latest default configurations properly.

My expectation would be that turn Tailscale DNS off again, would lead to the same issue, but it didn’t.

tailscale set --accept-dns=false

So something is weird, is resetted when activated DNS and stays good when deactivating it again.
Well it works, for now and I hope it’s a permanent solution.

Everchords is sunsetted

Back in 2018 I had a problem. I was writing song lyrics in Evernote, but displaying them for playing was annoying. I started work on Everchords a tiny platform allowing you to connect your Evernote account and display SongPro lyrics beautifully. Over time I added more convenience features for songwriting that helped me a lot to streamline my song writing process. This was a big help when producing Bettlektüre.

All this ended a year ago, when I stopped using Evernote. So it wasn’t part of my workflow anymore. I kept doing security updates, but these took more effort lately. I thought for a long time how to continue it, but ultimately, I don’t know. I’m using Obsidian.md now, which does not have similar APIs. While all data is fully accessible being “just markdown files”, there is no default pipeline to process and there are so many ways to build this pipeline, that it makes little sense to build and maintain a full platform around this. So I decided to take #Everchords offline.

The itch it scratched is still there, as I write my notes in #Obsidian, I may want to have a better songwriting experience again. We will see in time how I will change my process, adopt a different tool set or build something again to cover this.