Gå til indhold
Journalen

Jeg genopbygger Habbo.dk for voksne, ti år for sent

skyskraber er min hobby: et 2D-chatunivers for dansktalende voksne i traditionen fra Habbo, Netstationen og 3Dbyen. 123 tabeller, 51 WebSocket-moduler, én udvikler.

6 min. læsetid#skyskraber#habbo#websockets#chat-platform

Jeg var elleve første gang jeg loggede ind på Habbo.dk. Min mor havde købt mig et Habbo coin-kort fra kiosken på hjørnet, med den forstilling at det var i stedet for en julegave. Jeg brugte mønterne på en sofa. En pixel-sofa, i et pixel-rum, i et hotel der eksisterede intet steds andet end i en Flash-applet der kørte på en beige iMac i mine forældres køkken.

Det var 2007. Habbo.dk lukkede i januar 2015. Jeg var dengang en teenager der var kommet videre til Facebook og IRC og de tidlige skud af hvad der til sidst ville blive resten af min karriere. Men jeg husker sofaen.

Jeg husker også, med et detaljniveau der overrasker mig, det specifikke feel ved et populeret chatrum klokken 20 på en tirsdag. Pixel-trængeselen af avatarer på en sofa der ikke var din. Måden private beskeder åbnede i et lille flydende vindue som du kunne træk rundt. Den lidt nervøse venten mellem at sende "hej" og se de tre prikker der betød at nogen, på den anden side af en skærm et sted i Danmark, skrev tilbage.

Habbo.dk er væk. Det er 3Dbyen også. Netstationen er stadig i live men det er en outlier - et stykke levende dansk internethistorie, næsten tre dekader gammelt, der meget bevidst ikke har moderniseret sig. Hele genren - 2D avatar-chat, real-time rum, spiller-økonomi, alt det - er blevet udhult og erstattet med TikTok og Discord og en svag kulturel antagelse om at voksne ikke gør den slags mere.

Jeg bygger skyskraber på vejen at antagelsen er forkert.

Hvad skyskraber er, og hvem det er til#

skyskraber - dansk for "skyskraber" - er en real-time 2D social chat-platform. Tematiske rum. Tilpassede avatarer. Lejligheder du kan dekorere. En spiller-drevet markedsplads med auktioner. Quests med multi-kapitel-historier og scriptede bot NPC'er. Minigames du husker fra en flash-arkade i 2009: loto, roulette, coinflip, sten-papir-saks. Loot-kister. Stripe-integrerede premium-abonnementer.

Det er, meget specifikt, til dansktalende voksne. 18+, ingen undtagelser. Aldersgrinden er en feature, ikke en papirarbejds-indrømmelse. Hele genrens omdømmeproblem fra 2000'erne - rovdyr på børne-chat-platforme, moderering der ikke kunne skalere, forældre der havde ret til at være misstrøiske - undgåes simpelt ved ikke at have børn på platformen. De fleste af de faktiske brugere af Habbo.dk i 2014, før det lukkede, var allerede voksne der loggede ind for nostalgia'en. 2026-versionen af det her produkt kan læne sig ind mod det publikum i stedet for at lade som om rundt omkring det.

Hvis du husker tidslinjen - Arto, Habbo.dk, Netstationen, Sol - ved du allerede præcis hvad skyskraber er. Hvis du ikke gør, er Habbo.dk-nekrologen på skyskraber-bloggen en bedre forklaring end jeg kan klare på tre afsnit her.

Hvorfor nu, og ikke for fem år siden#

Det ærlige svar er, at jeg for fem år siden ikke kunne have bygget dette. Ikke på egen hånd.

En 2D real-time multiplayer-platform med overfladearealet af en lille SaaS - økonomi, markedsplads, moderering, quests, achievements, betalinger, admin-værktøjer, alt det - er ikke et weekendprojekt. Det er to eller tre år af fuldtidsingeniørarbejde på et lille studie. Det er præcis den slags projekt der historisk ville en indie-udvikler starte på en bølge af entusiasme og opgive ved 30%-mærket når omfanget viser sig.

Hvad der ændrede sig er pair-programming-løkken. Jeg arbejder med Claude som en sand samarbejdspartner - ikke som et code-completion-værktøj, men som en anden ingeniør der vurderer, nægter og udforsker. skyskraber-kodebasen eksisterer i noget der ligner sin nuværende form fordi omkostningen ved "jeg er ikke sikker på hvordan jeg ville strukturere det, lad mig tænke højt med nogen der kender stacken" faldt til nærmest nul. Rækkevidde betyder mere end hovedtal, især når rækkevidde bliver ganget med et andet sind der ikke bliver træt klokken 23.

Det andet der ændrede sig er hoststack - min egen europæiske PaaS - der kommer sammen. En tung real-time WebSocket-workload på et hobby-budget ville historisk have betydet en bar Hetzner-boks, en masse sene-nat reverse-proxy-konfiguration og en sprød deploy-historie. At køre skyskraber på hoststack betyder git push, blue-green rollout, managed Postgres og Redis ved siden af tjenesten, og WebSocket-handover under deploys som tilsluttede brugere ikke bemærker. Platformens job er at gøre denne slags projekt til et håndterligt hobby-projekt. Det gør den.

Scale check#

At kalde skyskraber et hobby-projekt er teknisk korrekt og noget vildledende. På skrivningstidspunktet indeholder repo'et:

  • 123 database-tabeller

  • 42 backend-tjenester

  • 41 API route-filer

  • 51 WebSocket-moduler

  • 172 frontend route-filer (23 public, 149 inden i den autentificerede chat SPA)

  • 81 backend test-filer

Til sammenligning: det her website, micci.dk, har cirka en-tiendedel af det overfladearealet. skyskraber er i operationelle termer en lille SaaS der sker at være et hobby. Grunden til det er håndterligt som et hobby er at samme stack jeg bruger kommercielt - Bun, Hono, Drizzle, React 19, TanStack Router og Query, Tailwind - også kører hobbyen. Context-switching er den stille dræber af solo-arbejde. Samme stack overalt betyder jeg kan åbne apps/api/src/services i ethvert af mine repo'er og ved allerede konventionerne.

De to interessante dele, teknisk set#

Der er to engineering-beslutninger i skyskraber som jeg sandsynligvis aldrig ville have lavet til et kommercielt produkt, og som jeg tror er de mest interessante ting i kodebasen.

Det første er dual-app frontend. skyskraber sender to helt separate applikationer fra et repo: et offentligt marketing-site (index.html) og en autentificeret chat SPA (chat.html). De deler components, hooks, API-klienter og typer - men hver har sit eget route-træ, sit eget indgangspunkt og dets eget bundle. Marketing-sitet er lille, hurtigt og crawlable. Chat SPA'en er tung og aldrig indekseret. Marketing-sitet betaler ikke bundle-size-omkostningen af chat-appen, og chat-appen har ikke vægten af marketing-copy og SEO-stilladser. Sømmene mellem dem er to index.html filer og en Vite-konfiguration. Fem linjer beslutning, dages gevinst.

Det andet er WebSocket-arkitektur. 51 WS-moduler lyder som meget indtil du starter med at opregne: rum, tilstedeværelse, bevægelse, chat, typing indicators, message-moderering, room state, item trades, marketplace-listings, marketplace-bud, quest-progress, bot-dialog, minigame-state, admin-notifikationer, fængsel-håndhævelse. Hver har sin egen message-form, sit eget broadcast-område, sin egen reconnection-semantik. Halvdelen af kodbassens overfladeareal er blot at besvare spørgsmålet om hvem der skal vide om hvilken event, og hvornår, uden at smelte broadcast-laget.

Jeg skal skrive et dybere indlæg om hver af disse på et tidspunkt. For nu er version-one-observationen at real-time multiplayer er mest af alt en taksonomi problem, ikke et teknologi-problem. At vælge de rigtige kanaler og områder betyder mere end at vælge det rigtige WebSocket-bibliotek.

Hvor skal man kigge videre#

Hvis nostalgia-vinklen er det der fanger dig, skyskraber-bloggen er det rigtige sted at læse mere. Det er på dansk, fordi publikummet er det. Stykket om hvorfor avatar-chat vokser igen når folk bliver trætte af video-møder er det mest interessante kulturelle argument jeg har lavet til produktet hidtil.

Hvis du er en udvikler der læser det her og tænker på dit eget ucontrolleret hobby-projekt, er den del jeg opfordrer dig til at stjæle ikke genren. Det er same-stack-everywhere disciplin. Grunden til jeg har tid til at bygge et hobby-chat-univers er at intet i min kommercielle stack er ukendt når jeg sætter mig ned ved hobby-kodebasen. Bun er Bun. Hono er Hono. Drizzle er Drizzle. Den mentale afgift for context-switching, som plejede at spise en halv lørdag-eftermiddag hver gang, er væk.

Hvis du husker Habbo.dk, skyskraber.dk er åbent. Du ved hvad du skal gøre. Sofaen er lilla denne gang.

Var dette nyttigt?

Flere noter