Sommaren 2013 lanserade Google ett spel där motståndaren visades på en videoskärm placerad mitt på spelplanen. Cube Slam var en variant av Pong i 3D som spelades ansikte mot ansikte i webbläsaren utan insticksprogram. Byrån North Kingdom skapade spelet åt Google Creative Lab i samarbete med Public Class och Dinahmoe. Den svenske utvecklaren Einar Öberg ansvarade för 3D-grafiken hos North Kingdom.
- Original
- North Kingdom tillsammans med Public Class och Dinahmoe
- Uppdragsgivare
- Google Creative Lab
- Lansering
- 12 juni 2013 som Chrome Experiment
- Teknik
- WebGL och three.js, Web Audio, CSS 3D, WebRTC och Go på App Engine
- Källkod
- Öppen källkod under MIT-licensen
- Status i dag
- Arkiverat, eftersom originalsidan inte längre finns online
Den här artikeln beskriver spelet och tekniken bakom det, men redaktionen har inte byggt originalet. Det tekniska innehållet baseras på Googles egna blogginlägg från lanseringen, den publicerade källkoden och Einar Öbergs ursprungliga genomgång av 3D-scenen som tidigare fanns på den här adressen.
Vad var Cube Slam?
Cube Slam var inspirerat av Pong. Spelaren styrde en paddel längs sin kortsida och försökte slå en kub förbi motståndaren. Målet var att träffa motståndarens skärm tre gånger så att den exploderade. Mellan nivåerna ändrades sköldar, hinder och gravitationsfält så att ingen match blev lik den föregående.
Under spelets gång kunde extrafunktioner låsas upp. Googles lista omfattade eldklot, lasrar, flera bollar samtidigt, spegelvända kontroller, skottsäkra sköldar, dimma, spökbollar, tidsinställda bomber, paddlar i ny storlek och extra liv. Där fanns även dödsbollar, som Google själv rådde spelarna att undvika.
Cube Slam skilde sig från andra Pongkloner genom hur motståndaren hanterades. Man bjöd in en vän med en länk, varefter vännens ansikte syntes i realtid på en skärm i spelvärlden medan ni pratade med varandra. Ingen av er behövde installera något. Om ingen vän var tillgänglig fanns björnen Bob, en datorstyrd motståndare som blev svårare ju längre du kom.
Projektet ingick i Googles samling Chrome Experiments och finns nu arkiverat på Experiments with Google. Syftet var att visa vad WebRTC klarar i en vanlig webbläsare. Vid lanseringen gick det att spela två mot varandra i Chrome på datorer och i Chrome OS. På mobiler och surfplattor kunde man bara utmana Bob eftersom WebRTC saknades i Android-versionen av Chrome. En app i Chrome Web Store gjorde det möjligt att spela mot Bob även utan internetanslutning.
Så fungerade det
Internt bestod Cube Slam av flera lager som var oberoende av varandra. Spelmekaniken med fysik, banor och kollisioner separerades helt från den grafiska renderingen. Denna uppdelning gjorde att samma motor kunde driva en WebGL-version med rikare grafik på datorer och en enklare CSS 3D-lösning för enheter utan WebGL-stöd. Källkoden innehåller tre renderingsmetoder: en för 3D, en för CSS och en enkel 2D-vy som användes för att felsöka synkroniseringen.
WebRTC: video och spel direkt mellan spelarna
WebRTC är en uppsättning gränssnitt i webbläsaren för realtidskommunikation. Cube Slam använde tre av dem. getUserMedia bad om tillstånd att använda kamera och mikrofon. RTCPeerConnection skötte överföringen av video och ljud mellan deltagarna. RTCDataChannel skickade den data som höll spelet synkroniserat.
Det centrala är peer to peer. Om brandväggar inte hindrade trafiken flödade datan direkt mellan de två datorerna utan mellanhänder. Enligt Justin Uberti i Googles WebRTC-team gav detta lägre latens för spelarna och lägre serverkostnader för utvecklarna. När en brandvägg blockerade den direkta anslutningen tog en reläserver av typen TURN över. Den servern låg på Google Compute Engine.
Innan webbläsarna kan kommunicera direkt krävs ett utbyte av adresser och konfigurationer. Det kallas signalering och sköttes av en server skriven i Go på Google App Engine. När kopplingen väl var upprättad behövdes servern knappt under själva matchen.
Att hålla två spel i takt
Grafiken var inte den svåraste utmaningen. Einar Öbergs projektsida förklarar att Pong verkar enkelt men att latens, svarstid, extrapolering och omspelning blev stora hinder när spelarna befann sig på olika platser. Varje deltagare upplever matchen med en viss tidsskillnad och båda måste ändå se samma kub på exakt samma position.
Lösningen i källkoden bygger på att skicka indata i stället för positioner. Båda webbläsarna kör samma fysiksimulering, bildruta för bildruta. Över nätverket går information om vad spelarna gör med sina paddlar och i vilken bildruta det sker. Om motståndarens indata kommer fram för sent återställs spelet till den senaste bekräftade bildrutan och händelserna spelas upp igen med korrekt indata.
Därför kördes RTCDataChannel i opålitligt läge. Ett paket som kommer fram för sent har ofta ingen nytta i ett snabbt spel. Uberti påpekade att ett enskilt borttappat paket inte bromsar hela programmet när kanalen slipper vänta på omsändningar. Källkoden innehåller även verktyg för att mäta latens och jämföra kontrollsummor för spelets tillstånd mellan spelarna, vilket gör synkroniseringsfel omedelbart synliga.
| Data | Väg | Varför |
|---|---|---|
| Video och ljud | Direkt RTCPeerConnection mellan spelarna | Vännens ansikte visas på skärmen i spelvärlden |
| Indata från spelarna för varje bildruta | RTCDataChannel används i opålitligt läge | Liten fördröjning där båda beräknar samma match |
| Anslutningsdata och adresser | Signalering via en server på App Engine | Behövs bara när kontakten upprättas |
| Trafik bakom brandväggen | TURN-server på Compute Engine | Reservlösning när direktvägen är blockerad |
Världen byggd i three.js
WebGL och biblioteket three.js användes för att skapa grafiken. North Kingdom hade använt en lågpolygonstil med enkla former och platta färger i flera tidigare projekt. Spelaren befann sig i ett landskap med berg, skog och djur. Kameran rörde sig långsamt runt arenan under spelets gång.
Koden visar att motståndarens skärm var en verklig yta i 3D-världen. Videon från vännens kamera lades som textur på ytan, vilket gjorde ansiktet till en del av världen i stället för att placera det som en separat ruta ovanpå. Vid spel mot Bob visades björnen på samma position.
Terräng och skog från Perlin-brus
De avlägsna bergen bildades av platta rutnät formade med Perlin-brus, som ger mjuka och naturliga slumpvärden. Källkoden använder implementationen ImprovedNoise för både terrängen och skogen. Bergen fick ny form vid varje besök. Hörnen flyttades först lite slumpmässigt i sidled så att de inte skulle se ut som ett rutnät, närliggande hörn slogs ihop och lyftes därefter i höjdled. Tre lager med olika inställningar skapade förgrund, mellangrund och bakgrund.
Marken intill arenan modellerades för hand. Djuren vandrade där och en statisk modell förenklade beräkningen av deras position på ytan.
Även skogen utgick från Perlin-brus. Att räkna ut trädens placering vid spelstart tog för lång tid, så positionerna togs fram i förväg och lagrades i koden som en lång lista med siffror. Träden byggdes av enkla grundformer: en kloss som stam och en fyrsidig kon som krona. Alla träd slogs ihop till en enda geometri så att hela skogen ritades med ett enda anrop till grafikkortet och skuggorna med ett till. En genomgång av ridged Perlin noise finns för dig som vill förstå brusfunktionerna bättre.
Björnen Bob och spegeleffekten
Bob, spelets datorstyrda motståndare, var en egen liten 3D-scen. Han ritades till ett separat renderingsmål som sedan användes som textur på skärmen i spelvärlden på samma sätt som vännens video. Upplösningen på den osynliga ytan anges i källkoden till 512 gånger 360 pixlar. Måtten halverades i mobilläget för att spara kraft. En blandning av morfanimationer för blinkningar och miner samt vanliga förflyttningar styrde Bob när han skakade, gick ut eller följde kuben med blicken.
Nivåerna mot Bob var skriptade. Enligt projektets dokumentation fanns upp till elva förprogrammerade nivåer, varefter nya slumpades fram. Nivåerna låg i separata uppsättningar för enspelarläget, mobilversionen och spel mellan två personer.
Spegeleffekten ingick bland extrafunktionerna. Hela scenen ritades då till ett renderingsmål som placerades på ett plan i skärmens storlek. Planet vändes i en animation. När övergången var klar spegelvändes hela sidan med CSS, vilket gjorde att även texten i gränssnittet hamnade bakvänd medan spelet återgick till vanlig rendering.
Prestanda i varje bildruta
Videokodning, avkodning och fysik delade datorns kraft med spelet. Kantutjämningen stängdes därför av som standard trots att de raka kanterna på de fyrkantiga formerna blev taggiga. Som ersättning fick enkla plan en textur med lite tom marginal runt motivet så att texturfiltreringen själv skapade en mjuk kant.
Effekter som brukar läggas på efter renderingen, till exempel en dammig yta och svepande linjer, visade sig vara för dyra. I stället placerades ett plan som barn till kameran på ett avstånd och i en skala som täckte skärmen exakt. Knepet är billigt men begränsat: planet kan inte läsa den färdiga bilden, så skärpedjup och färgkorrigering går inte att göra på det sättet.
Det var också viktigt att hålla JavaScripts skräpsamlare lugn, eftersom en plötslig städning orsakar ett ryck i bilden. Ett grundläggande råd från arbetet är att återanvända befintliga vektorer med metoden set i stället för att skapa nya objekt varje bildruta. Vanliga objekt hölls i förallokerade pooler som återanvändes. Nya objekt skapades helst mellan omgångarna när ett kort ryck inte märks.
Prototyperna med rörelsestyrning
Ursprungligen planerade teamet att kroppsrörelser skulle styra spelet. Teamet byggde prototyper där webbkameran följde ett färgat objekt som spelaren flyttade i luften, med mus eller tangentbord som alternativ. Spårningen fungerade hyggligt men räckte inte när tempot ökade och precision krävdes. Styrningen blev opålitlig för många användare på grund av ljusförhållanden, bildbrus och svårigheten att välja en specifik färg att följa.
Det fanns även ett nätverksproblem. Synkroniseringen byggde på förändringar, ungefär som att paddeln rör sig åt vänster med en viss fart. Med kamerastyrning hade spelet behövt skicka exakta positioner varje bildruta, vilket ger mer trafik och gör det svårare att dölja fördröjning. Rörelsestyrningen ströks och spelet fick tangentbord, mus och pekskärm.
Mottagandet
Samma dag som spelet lanserades kom inlägg på flera av Googles bloggar. Justin Uberti beskrev tekniken på Chromium-bloggen och Googles utvecklarblogg medan Clem Wright från Google Creative Lab presenterade spelet på den officiella bloggen. Engadget nämnde att Chrome krävdes för tvåspelarsläget medan Safari och Firefox fungerade för enspelarläget. Sajten beskrev Cube Slam som ett tennisinspirerat Pong-spel med integrerad videochatt.
Einar Öbergs projektsida uppger att spelet hade två miljoner unika besökare och upp till 10 000 samtidiga användare under den första månaden. Sidan listar även utmärkelser som Site of the Day hos Awwwards och FWA samt Adobes Cutting Edge Project of the Week. Adobe utsåg projektet till tvåa bland årets Cutting Edge-projekt. Cannes Lions placerade Cube Slam på kortlistan för varumärkesspel 2014.
Utvecklare har fortsatt att intressera sig för spelet länge efteråt. Källkoden var öppen från början och länken till den ursprungliga genomgången av 3D-scenen på denna adress delas fortfarande av webbplatser om webbgrafik.
Går det att göra likadant i 2026?
I dag är det enklare än när Cube Slam släpptes. Det opålitliga läget för datakanaler fungerade bara i Chrome på dator år 2013 och Google planerade då att införa ett pålitligt läge. WebRTC och datakanaler är nu en etablerad webbstandard med utförlig dokumentation och stöd för båda lägena.
Originalet finns dock inte kvar. Adressen cubeslam.com svarar inte och Googles experimentsida anger att projektet är arkiverat. Koden bygger på three.js-versionen från 2013 och använder borttagna klasser som den gamla Geometry. Utan ändringar går det inte att köra koden i en modern miljö.
Om källkoden. MIT-licensen gällde när Cube Slam publicerades som öppen källkod på Google Code. Projektet kan fortfarande laddas ned från Google Code, som i dag är ett arkiv. Enligt MIT måste licenstexten och upphovsrättsnoteringen följa med om koden används eller ändras i egna projekt. Det finns inofficiella speglar, men inget officiellt GitHub-arkiv. Informationen verifierades den 20 oktober 2026.
Bygg något liknande
Ett eget 3D-Pong mot en vän online är ett bra övningsprojekt. Börja med själva spelet och lägg till nätverket sist så att du kan felsöka stegvis. three.js-manualens första kapitel är en bra start om biblioteket är nytt för dig, liksom vår korta introduktion till 3D. Stegen nedan räcker för att skapa en första spelbar version.
1. Scenen
Bygg paddlarna och kuben av enkla lådor med BoxGeometry och spelplanen av ett platt plan. Du behöver också skapa en perspektivkamera, en scen och en renderare.
2. Spelloopen
Flytta kuben med en viss hastighet i varje bildruta. Byt tecken på hastigheten när kuben träffar en kant eller en paddel och registrera poäng när den passerar.
3. Fast tidssteg
Kör fysiken i fasta steg, exempelvis 60 gånger per sekund, oavsett skärmens bildfrekvens. På så sätt beter sig spelet likadant på båda datorerna.
4. Miljön
Skapa berg med en brusfunktion och slå ihop alla träd till en enda geometri, likt lösningen i Cube Slam.
Nätverket bygger du med WebRTC. Stegen nedan visar flödet för en datakanal mellan två webbläsare.
- AnslutningenBåda parter skapar en RTCPeerConnection. Den som bjuder in skapar en datakanal med createDataChannel.
- SignaleringenErbjudanden, svar och nätverkskandidater skickas via en egen server, till exempel med WebSocket.
- Kanalen öppnasDen mottagande sidan tar emot händelsen datachannel. När händelsen open har kommit kan båda sidor skicka meddelanden.
- SpeletSpelet skickar bara indata och bildrutans nummer. Båda klienterna kör samma simulering och stämmer av mot varandra.
En datakanal påminner om WebSocket men går direkt mellan webbläsarna och är krypterad hela vägen. Vid skapandet av kanalen väljer du om meddelanden ska levereras i ordning samt hur många gånger de skickas om. För snabba spel fungerar det bra med en kanal som inte väntar på inaktuella paket, vilket var det läge Cube Slam använde. MDN beskriver dessa alternativ i guiden för datakanaler i WebRTC.
Webbläsarna hittar inte varandra utan hjälp av en server för signalering. För ett inledande test kan du kopiera erbjudandet och svaret manuellt mellan två flikar. En TURN-server behövs bakom vissa mobilnät och brandväggar precis som hos Cube Slam. En sådan server kan du hyra eller driva själv med fri programvara.
Vad du kan lära dig av Cube Slam
Cube Slam visar att nätverksspel står och faller med tidshanteringen. Grafiken får gärna vara enkel, men spelet upplevs som trasigt om kuben studsar eller syns olika hos spelarna. Metoden att bara sända indata och låta båda sidor beräkna samma händelseförlopp används fortfarande i snabba spel.
Projektet visar också fördelen med att hålla isär logik och grafik. Samma spelmotor renderades med WebGL, CSS och en enkel 2D-vy för felsökning. Det gav stöd för fler enheter och gjorde det lättare att hitta synkroniseringsfel utan att titta på 3D-scenen. En sådan uppdelning gör det lättare att byta renderare i egna projekt.
Avslutningsvis visar spelet att prototyper får misslyckas. Nästan en månad lades på rörelsestyrning som inte hamnade i slutprodukten, men strykningen förbättrade upplevelsen. Andra projekt av samma utvecklare finns beskrivna i artiklarna om Urban Jungle Street View och Lathe. Båda utgår från idén att avancerad 3D ska fungera direkt i webbläsaren.
Vanliga frågor om Cube Slam
Vilka skapade Cube Slam?
Byrån North Kingdom producerade spelet tillsammans med Public Class och Dinahmoe på uppdrag av Google Creative Lab. Einar Öberg ansvarade för 3D-grafiken i three.js.
Vilket år kom Cube Slam ut?
Google släppte spelet den 12 juni 2013 som ett Chrome Experiment. Matcher mellan två spelare fungerade då i Chrome på dator och i Chrome OS.
Hur fungerade spel mellan två användare?
WebRTC hanterade överföringen av video och ljud direkt mellan webbläsarna. Spelinformationen skickades via en separat datakanal medan båda datorerna räknade fram samma match utifrån spelarnas indata.
Går det att spela Cube Slam i dag?
Nej, originalet finns inte längre. Den gamla webbplatsen svarar inte och Googles sida för experiment listar projektet som arkiverat.
Är källkoden fri att använda?
Ja. Koden publicerades under MIT-licensen, som tillåter att den används och ändras om licenstexten och upphovsrättsnoteringen följer med.
Vem var Bob?
Bob var en datorstyrd björn som var motståndare när ingen vän fanns online. Svårighetsgraden ökade med varje nivå och vid lanseringen var Bob den enda tillgängliga motståndaren på mobila enheter.
Källor
- Google: Play Cube Slam face-to-face against your friends, 12 juni 2013
- Google Developers Blog: Play Cube Slam, a real-time WebRTC video game, 12 juni 2013
- Chromium Blog: Play Cube Slam, a real-time WebRTC video game
- Experiments with Google: Cube Slam
- Einar Öberg: Cube Slam (projektsida)
- Engadget: Google’s latest Chrome Experiment, 12 juni 2013
- Cannes Lions: Cube Slam, kortlista 2014
- Google Code Archive: cubeslam (källkod, MIT-licens)
- MDN: Using WebRTC data channels
- MDN: RTCDataChannel
- three.js manual: Creating a scene
Uppgifterna kontrollerades 20 oktober 2026.

