lmue.net
Active projects
RotaskatA score tracker for private Skat rounds, built for the table rather than the browser.
Skat is scored by hand on paper, badly. Rotaskat is an Android app plus a small Ktor server that keeps the all-time ranking of a private club. Input happens at the table, between two rounds, often one-handed and with poor reception, so the app is offline-first and input speed is the quality metric that matters.
The part worth talking about is where the rules live. The domain model and the scoring logic exist exactly once, in a shared Kotlin module used by both the app and the server. The server can therefore recompute every round a client sends instead of trusting it. What gets stored are the raw facts of a game (who declared, what was played, how it ended), never the finished points. Change a house rule and the whole history is recalculated from the facts.
Honest status: the model, the scoring, the server and the app are built and tested, and the app runs end to end without a server at all. What is untested is operation. The server has never talked to a real Postgres, and nobody has ever used the interface on an actual device. A successful build proves it compiles, not that it works at the table.
Trait LadderA solver that finds the highest-scoring board for a TFT augment, running in the browser without a backend.
The Trait Ladder augment in Teamfight Tactics rewards you for fielding as many active non-unique traits as possible. Working that out by hand is tedious and usually wrong, because emblems, Kha’Zix evolutions, Lux forms, Elder Dragon and the Riftbeast team-size bonus all interact.
So it is not a lookup table, it is an actual optimisation problem: maximise active traits for a given team size, subject to the rules of the set. The solver is HiGHS compiled to WebAssembly and it runs entirely in your browser. No backend, no request to a server, nothing to keep running. The whole thing is a static site.
Game data is not hand-maintained either. A script pulls the current set from Community Dragon, verifies every image URL, and writes the result into the repo. The special cases that no data source encodes, such as Elder Dragon points, the Riftbeast bonus and the evolutions, live in a small and deliberately separate overrides file.
Ape SignalScheduled agent routines on a VPS that screen the market on measurable trend, then trade the result on paper and keep score.
Ape Signal scans the market twice a day and runs a simulated depot on what it finds. Candidates come from mechanical trend measures with published support: twelve-month momentum with the most recent month removed, distance to the 52-week extreme, relative strength against SPY. Market regime and volatility travel along as context, not as gates. Mentions and sentiment still get pulled in where they add something, but they now inform a chart-driven shortlist rather than produce one.
The division of labour is the point. Fills, stops and liquidations are checked deterministically against quotes on a fixed tick; the language model is woken only by real events, meaning a fill, a breached band or the close. Reasoning is expensive and non-deterministic, so it stays out of the loop that has to be exact. Every simulated execution pays a spread and a fee. The ledger is not in the business of flattering itself.
The scan runs twice a day, ahead of the European and the US open, and it goes wide rather than deep: the screener oversamples on raw columns and ranks locally, because sorting on the server cuts the winners off the list before they ever arrive. Candidates that do not become a trade are not discarded. They seed a watchlist, and every monitor tick checks it against close-based triggers: a 52-week breakout or breakdown, an EMA50 reclaim or loss, an EMA20 pullback, a volume spike, an RSI extreme flagged as a fade rather than an entry. The radar reports, it does not act. Behind a flag that is off by default, a fired trigger may wake a two-stage call that decides at most one limit order on that ticker, in its own budget, never on a position already held. An unreadable or declined answer means no trade, never a guess.
The strategy is not settled, and it is not meant to be. The first momentum screener turned out to be built backwards: it selected on the previous week’s strongest movers, which is precisely the side the short-term reversal effect shorts. It was replaced after checking it against published work rather than against a hunch. Everything since is measured the same way: each trade records whether it came from a screener or from the model’s own research, and the depot is charted against buy-and-hold SPY. Without that, a good month proves nothing.
To be explicit, because this touches money: it places no real orders. Ever.
About
Shaping real estate at SMARTBRIX.
The rest of the time I build small things and run them myself.
which is where the projects above come from