hyhy.gg

Case study

LLB Dojo

A trainer for defensive positioning in Lethal League Blaze. It runs on a 2D physics engine I wrote from scratch, and its daily puzzle was scored against a consensus of expert players.

Live at dojo.hyhy.gg

A new puzzle every day for more than 90 days in a row, generated and rotated with no manual work.

The problem

Defence in Lethal League Blaze is a geometry problem that players solve by instinct. Given every angle an attacker could hit from, where do you stand to cover them all? There was no way to practise that on purpose, only the reps a match happens to give you. Dojo is a sandbox where you place characters and simulate ball trajectories. It also ran a daily puzzle where the whole community attempted the same scenario.

My role

Just me, on concept, design, engineering and operations. Puzzles were generated automatically, and I worked with community experts to source the answers that decided what was correct.

What's technically interesting

A 2D physics engine written from scratch

The ball reflects off stage boundaries and character hitboxes. The bounce triggers on the ball's leading edge instead of its centre, which is what makes the simulated paths match what players see in the game. Paths render as SVG, with arrow markers set back from each bounce point. On top of that, each character has special moves that launch or curve the ball, move the character, or create hazards.

The sandbox mid-simulation, with characters placed, attack angles on, and trajectories drawn in SVG with arrows.
The sandbox mid-simulation, with characters placed, attack angles on, and trajectories drawn in SVG with arrows.

Expert answers instead of an algorithm

A positioning puzzle has no single correct answer you can calculate, so the scoring didn't try. Up to five hand-picked expert players submitted answers ahead of time. Outliers were dropped and the rest were averaged into the official answer. Player submissions were scored by their distance from it in pixels and grouped into tiers. The decision record for this is below.

Capture pending

A daily puzzle with a scored result. The tiers make the scoring decision visible to players.

A puzzle pipeline that ran itself

Puzzles were generated automatically, with random defender start positions and parry-guard logic so every scenario was solvable without anyone checking it. Weekly Vercel cron jobs worked out the expert consensus, moved the queue along, and pinged the next week's experts through Discord webhooks, all behind a shared cron secret. That kept a new puzzle going out every day for more than 90 days without me touching it.

Capture pending

Owner admin, with expert management and the puzzle queue.

Tests and documentation

47 Vitest test files cover business logic, API routes and components, across about 40K lines of source. There's a 30KB domain model with a glossary of the game's terms, and 11 ADRs record decisions like SVG over canvas, Vercel with Neon, and expert consensus. Migrations run before every build, and Husky and lint-staged check every commit.

Stack

  • Next.js 16.2 (App Router)
  • React 19.2
  • TypeScript 5 strict
  • Bun
  • PostgreSQL on Neon serverless
  • Prisma 7.8
  • BetterAuth 1.6 (Discord OAuth)
  • shadcn/ui + Radix
  • Tailwind v4
  • PostHog + Vercel Analytics
  • Vercel cron

Proof

  • A small group of regulars. The most active worked through 20 to 25 puzzles a month.
  • 9 pages · 11 API route handlers · 9 Prisma models
  • 47 test files · 11 ADRs · ~40K lines across 181 files