Case

Hero-filmen i C++. Noll rader för hand.

Filmen på vår startsida är ingen stockvideo och ingen WebGL-demo, utan en drönarflygning över ett landskap byggt av riktig aperiodisk matematik. Ljuset är fysikaliskt simulerat stråle för stråle med path tracing, i en renderare som skrevs från grunden i C++ med tre utbytbara backends: CPU, CUDA och Metal.

Matematiken, 3D-världen, renderaren, kamerafysiken och pipelinen designades, skrevs, granskades och renderades under ett enda dygn. Varenda rad kod kommer från Anthropic Fable 5 i Claude Code. Vi skrev inte en enda rad själva. Så här gick det till.

Validerade aperiodiska plattor
54 289
Simulerade ljusvägar
663 mdr
Rader C++, noll beroenden
1 305
Bildrutor i 1080²
2 220
Renderingstid på en laptop
4 h
Rader skrivna för hand
0

01

Uppdraget

TokenTeks symbol är en hatt. Inte vilken hatt som helst, utan einstein-plattan: den trettonsidiga form som upptäcktes 2023 och som kan täcka ett oändligt plan utan att mönstret någonsin upprepar sig. För ett bolag som bygger skräddarsytt i stället för att återanvända mallar kunde symbolen knappast vara mer träffande: en enda form som räcker till oändlig variation.

Den nya webbplatsen behövde en bakgrundsfilm till startsidan, och kraven som sattes på morgonen den 10 juli var korta och tydliga:

  • Filmen ska bygga på den riktiga matematiken. Inte på en textur eller på någon annans demo, utan på substitutionssystemet från forskningsartikeln, validerat till maskinprecision.
  • Det ska vara en förrenderad film, inte realtidsgrafik. Ljuset ska simuleras fysikaliskt och skärpedjupet ska komma från en simulerad lins, så att filmen får samma lugn som ett makrofoto i studio i stället för den plastiga ytan hos realtidsgrafik på webben.
  • Inga färdiga komponenter någonstans i kedjan. Ingen spelmotor, ingen färdig renderare, inget köpt material. Allt som syns i bild ska komma från kod i projektets eget repo.

En sak till: det var fredag, och sajten skulle ha sin film.

02

Matematik som aldrig upprepar sig

Arbetet började där varumärket börjar, med själva hatten. Plattan byggs upp av åtta drakfyrhörningar ur rutnätet som uppstår när varje hexagon i ett hexagonnät delas i sex delar, och alla dess tretton hörn ligger på punkter i rutnätet. Formen kan bara täcka planet aperiodiskt, och den behöver hjälp av sin egen spegelbild för att klara det: i varje täckning är en liten andel av plattorna spegelvända. Det lilla faktumet fick bli hela den visuella idén, för i ett fält av identiska mörka plattor är de spegelvända plattorna matematiskt speciella. Därför är det just de, och bara de, som får vara orangea.

Einstein-plattan, dess spegelbild och en liten del av mönstret. De spegelvända hattarna utgör 12,7 procent av varje täckning.
Einstein-plattan, dess spegelbild och en liten del av mönstret. De spegelvända hattarna utgör 12,7 procent av varje täckning.

Mönstret skapas av en generator på 373 rader Python som porterar substitutionssystemet från Craig Kaplans verktyg hatviz. Det enda externa biblioteket är shapely, och det används bara för validering. Fyra metaplattor expanderas rekursivt nivå för nivå, och efter fem nivåer består mönstret av 54 289 hattar. 6 912 av dem är spegelvända, 12,7 procent, exakt den andel som teorin förutsäger.

Substitutionsnivå 1 till 4: varje metaplatta ersätts rekursivt av ett kluster av mindre plattor.
Substitutionsnivå 1 till 4: varje metaplatta ersätts rekursivt av ett kluster av mindre plattor.

Ett mönster är bara värt att använda om det bevisligen är det riktiga, så generatorn kontrollerar sitt eget resultat vid varje körning:

  • alla plattor har exakt samma area, med en spridning under 10⁻⁹,
  • inga två plattor överlappar varandra, det största uppmätta överlappet ligger kring 10⁻¹¹,
  • ytan hänger ihop i ett stycke, utan ett enda inre hål,
  • andelen spegelvända plattor landar på teorins 12,7 procent.

Kontrollerna bevisar inte aperiodiciteten en gång till, det har forskarna redan gjort. De visar att just vår ändliga bit av mönstret är en korrekt realisering av deras konstruktion.

En detalj var nära att slinka igenom: hela mönstret behövde speglas över den lodräta axeln, eftersom TokenTeks logotyp har motsatt orientering mot hatten så som den ritas i forskningsartikeln. Efter speglingen matchar de flesta plattorna logotypen, medan de sällsynta spegelvända fortfarande är de som kan bli orangea accenter.

03

En värld byggd av ett bevis

Nästa steg förvandlar den validerade matematiken till en tredimensionell värld. Varje plattas kontur krymps 0,03 enheter inåt, så att det bildas smala spår mellan plattorna där ljuset senare fastnar. Konturen trianguleras med en metod som klarar hattens inåtbuktande form och dras sedan ut till ett prisma.

Geometrin runt en accentplatta i den skarpa scenfilen: spår, prismor och en svagt självlysande orange hatt.
Geometrin runt en accentplatta i den skarpa scenfilen: spår, prismor och en svagt självlysande orange hatt.

Plattornas höjder blev dygnets tydligaste lektion i att enkelt slår avancerat. Terrängen bygger på fraktalt brus i fyra oktaver med en våglängd på 42 enheter. Höjderna avrundas till 50 fasta terrassnivåer, och då ser landskapet ut som skulpterade sedimentlager i stället för formlösa kullar. De första versionerna formade bruset med golvnivåer, havsnivåer och cosinusfunktioner, och varenda en av dem plattade till något band av höjder. Varje förslag upptäcktes i förhandsvisningen och ströks inom några minuter. Den slutliga lösningen blev en enda rad:

# ren linjär mappning utan formkurva. Golvnivåer, havsnivåer och cosinus
# plattar alla till något höjdband. Linjärt håller varje punkt i lutning.
h = TERRAIN_AMP * n          # n = fraktalbrus utsträckt till 1..99-percentilen
if TERRAIN_STEP > 0:
    h = round(h / TERRAIN_STEP) * TERRAIN_STEP

Ovanpå det får varje platta en egen liten höjdjustering, högst 0,03 enheter, så att grannplattor aldrig ligger exakt jäms med varandra.

Terrängen som trådmodell med flygrutten ovanför: 50 terrassnivåer och inga tillplattade band.
Terrängen som trådmodell med flygrutten ovanför: 50 terrassnivåer och inga tillplattade band.

Scenen innehåller bara det som kameran hinner se under flygningen: en remsa på 131 gånger 261 enheter, framräknad genom att kamerans synfält sveps längs rutten bildruta för bildruta. Den första beräkningen följde bara ruttens mittlinje. Det räckte inte, för i de lutande svängarna svänger synfältet ut upp till tolv enheter åt sidan, och då kom mönstrets kant in i bild som svarta kilar. Det var exakt den buggen GPT 5.6 Sol hittade vid en av sina externa kodgranskningar under kvällen, och lösningen blev att utöka mönstret från fyra till fem substitutionsnivåer.

Efter beskärningen återstår 10 127 plattor, och varje platta får ett eget material där ljushet och ytjämnhet varieras lite slumpmässigt. Det är därför fältet glittrar diskret i stället för att se ut som en enda gjuten skiva.

De orangea accenterna väljs utifrån den rutt kameran faktiskt flyger. Scenbyggaren har en egen kopia av flygmodellen, porterad rad för rad från C++-koden och verifierad mot originalet med en tolerans under en hundradels enhet. Med den flugna rutten som facit väljer den spegelvända hattar inom sju enheter från markspåret, närmast rutten först och med minst åtta enheter mellan varje accent. 19 stycken kom med i den slutliga scenen, och kameran flyger rakt över dem i stället för att lämna dem ute vid bildkanten. Varje accent är dessutom svagt självlysande och renderas till en egen ljusbuffert, som i efterbearbetningen blir det mjuka, lavaliknande skenet.

Koreografin uppifrån: flygrutten, kamerans synfält mot marken och de 19 orangea accenterna längs spåret.
Koreografin uppifrån: flygrutten, kamerans synfält mot marken och de 19 orangea accenterna längs spåret.

Till slut packas allt i en binärfil på 15,3 MB som renderaren läser i ett svep: 10 128 material och 374 701 trianglar, ingenting annat.

04

En renderare från en tom fil

Kravet på noll beroenden utesluter alla färdiga motorer, så renderaren skrevs från grunden i C++17. Hela filmens optik ryms i en enda headerfil på 425 rader som kompilerar oförändrad som vanlig C++, som CUDA och som Metal Shading Language.

Det är en klassisk path tracer utan genvägar, anpassad för exakt en scen:

  • En simulerad lins. Varje ljusstråle utgår från en slumpad punkt på en bländaröppning med radie 0,42, så skärpedjupet uppstår ur geometrin i stället för ur ett filter i efterhand. Oskärpan växer fysikaliskt korrekt med avståndet från fokalplanet.
  • En materialmodell med GGX och Lambert. Resultatet är en matt, mörk plast där spårens kanter glimmar till i ljuset.
  • Direktsampling av ljuskällan. Varje studs skickar också en stråle rakt mot lampan, och därför blir de mjuka högdagrarna rena redan vid 256 ljusvägar per pixel i stället för runt 2 000.
  • Ett sökträd för geometrin (BVH) som gör att varje stråle bara behöver testas mot en bråkdel av scenens 374 701 trianglar. Därför går det snabbt på vilken hårdvara som helst.
  • Högst fem studsar per ljusväg, med sannolikhetsbaserad avslutning efter två. Extrema ljusvärden dämpas för att undvika brus, men medvetet inte i första studsen: de ljusa bokehskivorna är själva poängen med bilden och ska inte tonas ned.
Uppbyggnaden av en ljusväg: linssampel, studsar, skuggstrålar mot ljuskällan och dämpning av extremvärden.
Uppbyggnaden av en ljusväg: linssampel, studsar, skuggstrålar mot ljuskällan och dämpning av extremvärden.

Renderaren är dessutom deterministisk rakt igenom, inte av en slump utan som princip. Slumptalsgeneratorn får sitt frö från bildrutans nummer, pixelns position och beräkningsblockets index, så samma bildruta och samma pixel ger samma resultat varje gång. Varje bildruta kan därmed renderas om helt fristående, och det är den egenskapen som senare gör att renderingen kan delas upp, avbrytas och återupptas utan risk.

En kamera som flyger över höga berg med en extremt ljusstark lins har ett problem: ett fast fokusavstånd blir fel nästan överallt. Lösningen är tio rader kod och ett enkelt medianfilter:

// autofokus: lägg fokalplanet på medianen av avstånden i en liten
// ruta kring bildens mitt. Fast strålmönster utan slump: deterministiskt
// per bildruta, och medianen hoppar inte när en kant passerar mitten.
for (int j = 0; j < 5; ++j)
    for (int i = 0; i < 5; ++i)
        if (intersectBVH(S, cam.pos, rayThroughGrid(i, j), &hit))
            depths.push_back(hit.t * dot(d, cam.fwd));
std::nth_element(depths.begin(), depths.begin() + n/2, depths.end());
cam.focusP = cam.pos + cam.fwd * depths[n/2];

Tjugofem mätstrålar skickas ut i ett fast rutnät, och fokus läggs på medianen av deras avstånd. Ett medelvärde skulle dras iväg så fort halva rutnätet hamnar över en dalgång, och ett slumpat mönster skulle få skärpan att pumpa mellan bildrutorna. Medianen över ett fast rutnät gör ingetdera: bildens mitt är helt enkelt alltid skarp, och bergen glider genom fokalplanet som i ett miniatyrlandskap.

Linsmodellen och autofokusen: bländaröppning, fokalplan och medianen av 25 avståndsmätningar i bildens mitt.
Linsmodellen och autofokusen: bländaröppning, fokalplan och medianen av 25 avståndsmätningar i bildens mitt.

Bildrutorna lämnar renderaren som råa linjära ljusvärden. Efter renderingen läggs glöden från accenterna på, bilden tonmappas, och ett knappt synligt brus adderas så att de nästan svarta tonerna klarar videokomprimeringen utan ränder. Bildströmmen skickas sedan direkt in i ffmpeg: 7,8 GB som aldrig skrivs till disk.

05

Kameran som fick lära sig flyga

Den svåraste delen av dygnet var inte ljusberäkningarna utan kameran, och det är också den del som skrevs om flest gånger. Plandokumentet visar hela utvecklingen. Först en rak kameraåkning, sedan en perfekt loopande cirkelbana, sedan en kamera som följde en utstakad kurva. Alla godkändes, och alla förkastades inom några timmar av samma skäl: en kamera på räls känns som en kamera på räls, hur mjuk rälsen än är.

Den slutliga kameran, revision åtta, följer ingen bana alls. Den är en simulerad FPV-drönare med en actionkamera fast monterad i 45 graders vinkel nedåt, och den flygs av en styrkedja där varje led påverkar nästa:

// FPV-modell. Styrningen föreslår den acceleration som skulle följa
// rutten. Drönaren måste först vrida nosen mot den riktningen, och
// först därefter kan motorkraften ändra hastigheten. Rörelsemängden
// bär genom svängen: vrid först, tryck sedan.
V3 requiredThrust = guideAccel + vel * (1.0f / dragTau);
float targetYaw   = atan2(requiredThrust.x, requiredThrust.y);
yawV += (wrapPi(targetYaw - yawS) * wY * wY - 2*zY*wY*yawV) * dt;
V3 bodyF{sin(yawS), cos(yawS), 0};        // nosen, inte rutten
V3 desiredAccel = clampLen(bodyF * thrust - vel * (1/dragTau), accelMax);
accel += clampLen(desiredAccel - accel, jerkMax * dt);   // rycktak

Styrningen siktar på en punkt femton enheter längre fram längs en kurva genom tretton ruttpunkter, men den får bara föreslå. Drönaren måste först vrida nosen mot den riktning där kraften behövs, och bara motorkraft i nosens faktiska riktning kan ändra hastigheten. Resten sköter rörelsemängden.

FPV-modellens uppbyggnad: styrning, girdynamik, fysik och en fast monterad kamera. Kurvan följer drönaren, inte klockan.
FPV-modellens uppbyggnad: styrning, girdynamik, fysik och en fast monterad kamera. Kurvan följer drönaren, inte klockan.

Filmen beter sig som riktig drönarfilm eftersom den formas av samma fysik. I den hårdaste svängen pekar drönarens kropp 30,4 grader vid sidan av färdriktningen, samtidigt som farten ligger stabilt kring två enheter per sekund. Kameran tittar in i svängen upp till 19,9 grader innan banan hinner dit, och det är precis det som skiljer FPV-film från en kamera på räls. Horisonten lutar som mest 10,6 grader, och det beror på sidoaccelerationen i svängen, inte på någon justering av bilden i efterhand.

74 sekunder flygdata: sidglidning, blickens försprång, lutning och fart. Kurvorna liknar data från en riktig drönare eftersom fysiken är densamma.
74 sekunder flygdata: sidglidning, blickens försprång, lutning och fart. Kurvorna liknar data från en riktig drönare eftersom fysiken är densamma.

En detalj är avgörande för resten av kedjan: hela flygsimuleringen körs om från start för varje bildruta. Det låter slösaktigt men kostar mikrosekunder, att jämföra med flera sekunder för själva ljusberäkningen. Vinsten är att varje bildruta får exakt samma kameraposition oavsett vilken dator den renderas på. Kameran har inga sparade tillstånd, ingen förberäknad bana och inget sätt att glida ur synk.

06

En studio som reser med

Ljussättningen består av en enda varmvit rektangulär ljuskälla på 60 gånger 54 enheter och ett svagt himmelsljus. Tricket är att ljuskällan följer kamerans riktning: alltid 24 enheter till höger, 36 framför och 39 ovanför. Varje bildruta i den 72 sekunder långa flygningen är därmed ljussatt som ett och samma fotografi. Det är det som gör loopens skarv osynlig och som ger filmen dess stilla studiokänsla, samtidigt som en hel bergskedja glider förbi under kameran.

Scenens uppställning: kamera, medföljande ljuskälla och fokalplan. Hela filmen är ljussatt som ett enda fotografi.
Scenens uppställning: kamera, medföljande ljuskälla och fokalplan. Hela filmen är ljussatt som ett enda fotografi.

07

En kärna, tre sorters kisel

Klockan 17:59 stod det klart att CPU-renderaren skulle behöva ungefär ett dygn, ett dygn som inte fanns. Lösningen blev projektets mest tillfredsställande ingenjörsarbete. Renderarens kärna kompilerar oförändrad som C++17, som CUDA och som Metal Shading Language, så filmens hela utseende, från materialmodell och lins till slumptal och ljusberäkning, finns på exakt ett ställe.

#if defined(__METAL_VERSION__)
  #define HD inline          // funktionskvalificerare
  #define DEV device         // adressrymd för GPU-minne
  #define THR thread         // trådlokal adressrymd för referenser
  typedef uint u32; typedef ulong u64;
  HD float xsqrt(float v) { return metal::sqrt(v); }
#else                        // vanlig C++ / CUDA
  #define HD __host__ __device__ inline
  #define DEV
  #define THR
  HD float xsqrt(float v) { return sqrtf(v); }
#endif

Hela priset för portabiliteten är några få rader anpassningar: en funktionskvalificerare, två nyckelord för minnesåtkomst och ett par matematikfunktioner. Koden som återstår per backend är nästan generande liten:

Backend Fil Rader Finessen
CPU main.cpp 44 en arbetskö som fördelar bildens rader över 16 kärnor
CUDA cuda_main.cu 90 renderingen delas upp i korta pass, annars tror Windows att grafikkortet har hängt sig och startar om drivrutinen
Metal metal_main.mm 136 GPU-koden kompileras först när programmet startar, direkt från den gemensamma kärnfilen plus 23 rader Metal-kod
En kärna, tre backends: samma ljusberäkning på CPU-trådar, CUDA-kärnor och en Metal-kärna som kompileras vid start.
En kärna, tre backends: samma ljusberäkning på CPU-trådar, CUDA-kärnor och en Metal-kärna som kompileras vid start.

De tre backendarna jämfördes mot varandra och gav visuellt identiska bildrutor. Metal-versionen renderade en bildruta i full kvalitet på cirka 6,5 sekunder, mot CPU-versionens 38,6. Därmed gick planen att starta renderingen före läggdags från nödvändighet till lyx.

08

En pipeline som tål Ctrl-C

Ett enda skript sköter hela leveransen: rendering, segment om 60 bildrutor, en förlustfri mellanversion, loopklippningen och till sist de färdiga videofilerna och startbilden. Två designbeslut bär upp alltihop.

Segmenten fungerar som en cache, inte bara som lägesrapport. Varje segment sparas som en färdig fil. Avbryts körningen fortsätter nästa körning efter det senast färdiga segmentet. Som mest går 60 bildrutor förlorade, ungefär sex minuter GPU-tid.

Cachenyckeln bygger på innehållet i allt som kan påverka en pixel. Inte på tidsstämplar eller filnamn. Scenfilen, konfigurationen, upplösningen och den exakta binärkoden i själva renderaren vägs samman till ett fingeravtryck:

# Fingeravtrycket tas på innehållet i allt som kan påverka en pixel:
# scenen, konfigurationen och renderarbinärens exakta bytes.
FP=$({ cat scene.bin config.txt
       print -r -- "$S $SPP $FRAMES $SEG ${TRACER:t}"
       cat -- "$TRACER" } | cksum | tr ' ' '_')

Ändras scenen, utseendet eller renderaren så ändras fingeravtrycket, och pipelinen kan då inte blanda in gamla bildrutor i en ny film. Det är den oglamorösa anledningen till att kamerafysiken kunde skrivas om klockan 20:36 och renderingen ändå kunde startas tryggt 23:32.

Datatratten: 663 miljarder ljusvägar blir 7,8 GB råa bildrutor, som aldrig skrivs till disk, och till sist en webbfilm på 24 MB.
Datatratten: 663 miljarder ljusvägar blir 7,8 GB råa bildrutor, som aldrig skrivs till disk, och till sist en webbfilm på 24 MB.

Filmen loopar var 72:a sekund, och klippet är medvetet enkelt. Cirkelbanan hade gett en perfekt skarv på köpet, men den ströks ju för att den kändes livlös. I stället renderas två extra sekunder efter looppunkten, mitt i en sväng, och de tonas över i filmens början under två sekunder av aktiv rörelse. Rörelsen döljer skarven, och ögat hittar aldrig något fruset ögonblick att haka fast vid. När sidan laddas börjar filmen dessutom alltid på en ren och skarp startbild.

Loopklippet: två extra sekunder mitt i en sväng tonas över i filmens början. Rörelsen döljer skarven.
Loopklippet: två extra sekunder mitt i en sväng tonas över i filmens början. Rörelsen döljer skarven.

09

Rendernatten

Den sista commiten landade 23:32. Renderskriptet valde Metal-versionen, och laptopen fick tillbringa natten med att beräkna 663 miljarder ljusvägar: 2 220 bildrutor, 1080 gånger 1080 pixlar per bildruta och 256 ljusvägar per pixel, var och en med upp till fem studsar.

Renderingstid per bildruta under natten, samt jämförelsen mellan de tre backendarna.
Renderingstid per bildruta under natten, samt jämförelsen mellan de tre backendarna.

Kurvan över renderingstider berättar sin egen historia. De snabba bildrutorna visar terräng på avstånd. Den dyra sträckan är den långa svängen där närliggande berg fyller bilden med kraftig oskärpa: varje stråle kräver då mer geometriarbete, och fler strålar överlever till full längd. Snittet blev 6,49 sekunder per bildruta och fyra timmar totalt. Startbilden skrevs till disk klockan 03:41.

Alla utseendebeslut under dagen togs däremot i 500 gånger den hastigheten. Renderarens förhandsläge byter till en enklare kamera, en ljusväg per pixel och förenklad skuggning, och det var i det läget hela flygningen koreograferades.

Förhandsläget där dagens alla beslut togs, jämfört med samma bildruta i slutlig kvalitet.
Förhandsläget där dagens alla beslut togs, jämfört med samma bildruta i slutlig kvalitet.
Konvergensstegen: samma utsnitt renderat med 4, 16, 64 och 256 ljusvägar per pixel.
Konvergensstegen: samma utsnitt renderat med 4, 16, 64 och 256 ljusvägar per pixel.

Direkt ur renderaren i hög upplösning, framtagna för den här artikeln med samma program och samma scen som filmen:

Loopens början, samma bildruta som filmens startbild.
Loopens början, samma bildruta som filmens startbild.
S-svängen vid 17 sekunder, där oskärpan gör grovjobbet.
S-svängen vid 17 sekunder, där oskärpan gör grovjobbet.
Planflykt över terrasserna vid 48 sekunder.
Planflykt över terrasserna vid 48 sekunder.
Den hårdaste svängen vid 63 sekunder: 30 graders sidglidning och 10 graders lutning.
Den hårdaste svängen vid 63 sekunder: 30 graders sidglidning och 10 graders lutning.

10

Dygnet i gitloggen

Alla tider gäller den 10 juli 2026 och är hämtade ur gitloggen:

Tid Händelse
11:42 Första versionen: mönstergenerator, scenbyggare, CPU-renderare och de första bildrutorna
12:01 Cirkelbanan införs, och avvecklas i tysthet
12:01 till 16:21 Utseendearbete: grafit och orange låses fast, bländare 0,42 väljs, rak åkning och cirkelbana provas och stryks
16:21 Flygkamera längs kurva, förhandsläge och en bakgrundsbildsgenerator
17:34 Klart att rendera: första flygningen godkänns utifrån förhandsfilmer
17:59 CUDA-version, så att ett grafikkort på andra sidan kontoret kan hjälpa till
18:33 Gemensam renderkärna och Metal-version: en ljusberäkning, tre maskiner
18:49 Renderskriptet: löpande status, avbryt och återuppta, automatiskt val av backend
19:24 Granskningen från GPT 5.6 Sol åtgärdad: större mönster och scen byggd utifrån den faktiskt flugna rutten
19:43 Autofokus: fokalplanet följer medianavståndet i bildens mitt
20:36 Blicken leder in i svängarna: FPV-modellen i sin slutliga form
23:32 Slutversion för webben. Renderingen startar
03:41 Startbilden skrivs till disk efter fyra timmar GPU-tid och 663 miljarder ljusvägar

Här är resultatet, filmen som i dag ligger bakom rubriken på startsidan:

72 sekunder och 24 MB. Filmen loopar utan synlig skarv.

11

Därför räckte ett dygn

Vi förstår om det låter osannolikt: en AI-modell som under ett dygn designar, skriver och dokumenterar validerad forskningsmatematik, en path tracer i C++ med tre backends och en flygmodell som lurar ögat. Ändå var det ingen magi, utan tre saker som samverkade.

En beslutsam art director. Varje utseendebeslut togs på några minuter, alltid utifrån underlag i form av förhandsfilmer och stillbilder, och revs aldrig upp igen. Terrängarbetet är mönstret i miniatyr: sex formkurvor föreslogs, sex tillplattade höjdband upptäcktes, och den enkla linjära lösningen vann. Snabba veton slår långsam konsensus.

Ett agentiskt arbetssätt. Bygget var en enda lång arbetssession där människa och AI jobbade i par. Människan stod för art direction, smak och vetorätt. Anthropic Fable 5 i Claude Code stod för design, implementation, svar på granskningar och dokumentation. Plandokumentet fungerade som gemensamt kontrakt, och varje version av designen finns kvar där. Det är skälet till att den här artikeln kunde skrivas i efterhand med repot som enda källa. Koden granskades dessutom externt två gånger under dagen, av GPT 5.6 Sol. Att låta AI granska AI är en fast del av vårt arbetssätt, alltid med en annan modell än den som skrev koden. När kvällens granskning hittade två riktiga buggar var båda rättade och verifierade inom en timme, eftersom pipelinens fingeravtryck gjorde det billigt att validera om allt.

Determinism som princip. Styrd slump överallt, konfiguration som text, cachar med innehållsbaserade nycklar och en kamera som räknas om från start för varje bildruta. Ingenting i kedjan beror på vad som hände i går, och det är exakt därför kedjan kunde byggas om fyra gånger under en och samma dag.

Hela projektet består av 373 rader mönstermatematik, 551 rader scenbygge och 1 305 rader renderare. Det ersätter vad som normalt hade varit ett Blender-projekt, en renderfarm och en byrå för rörlig grafik. Webbplatsen fick sin film, och filmen råkar vara ett matematiskt bevis.

Arbetssättet är detsamma som i våra kunduppdrag: tydlig riktning, snabba beslut på underlag och AI-agenter som skriver varenda rad. Så bygger vi produktionssystem, och så byggde vi vår egen startsida.

Substitutionsreglerna är porterade från Craig S. Kaplans hatviz (BSD-3-Clause). Plattan kommer ur artikeln "An aperiodic monotile" av Smith, Myers, Kaplan och Goodman-Strauss, 2023. Allt annat i projektet, generatorn, renderaren, kameran och pipelinen, skrevs från grunden den 10 juli 2026.

Vill ni se vad ett dygn räcker till?

Samma arbetssätt som byggde filmen bygger produktionssystem hos våra kunder: tydliga mål, snabba beslut och AI-agenter som skriver koden. Hör av er så visar vi hur det ser ut hos er.