21 feb. 2018
Snake '97 Updaten
Over de uitdagingen van het ontwikkelen van een razend populaire game
Een paar jaar geleden gooide mijn broer in een Amsterdamse kroeg een biertje over mijn iPhone. Het arme ding kon het Nederlandse gerstenat minder waarderen dan ik: het gaf de geest. Terwijl ik wachtte op een nieuwe telefoon, gebruikte ik een oude die niets anders kon dan sms'en, bellen en... Snake! Het idee voor Snake '97 was geboren en deze maand was het tijd om de razend populaire game te updaten.

Snake '97
Oorspronkelijk programmeerde ik Snake in 2011 voor iOS. Het kostte me ongeveer twee weken om een werkend prototype te maken dat eruit zag en aanvoelde als de echte klassieker uit de jaren 90. Mijn broer hielp me met de graphics door scherpe macro's van mijn oude telefoon te maken (het is nog steeds een raar idee dat zovelen van jullie een kopie van mijn telefoon in hun zak hebben).

Het werd opgepikt door een paar grote blogs waardoor Snake '97 wereldwijd de toplijsten bestormde. Vandaag de dag wordt het over de hele wereld gespeeld, vertaald in 53 talen en beschikbaar voor iOS, Android, Windows, ChromeOS en MacOS.

Noodzaak tot update
In 2011 was er maar één iPhone, de iPhone 4. Als ontwikkelaar kon je Android veilig negeren en Windows Phone was nog niet eens uitgevonden. Het leven was zo mooi als een (luie) ontwikkelaar zich kon wensen: slechts één schermformaat.

Spoel door naar vandaag, Apple verkoopt momenteel 8 iPhones en er zijn miljoenen en miljoenen Android-apparaten, allemaal met verschillende schermformaten, processors, geheugen en softwareversies. Het is een understatement om dit een uitdaging te noemen...
Om de fun in Snake '97 te behouden, moest ik de game-engine in de kern updaten. Op de een of andere manier moest ik de graphics op elk scherm ter wereld passend maken en rekening houden met de verschillen in verwerkingskracht en geheugen....

Eén game-engine om ze allemaal te regeren
De originele versies van het spel hadden allemaal hun eigen engine. Eén voor iOS, één voor Android, één voor Windows enz. Toen ik Snake 2k (de Snake II-spelvariant) lanceerde, voegde ik gewoon nog een set game-engines toe. In totaal heb ik 6 verschillende Snake game-engines geprogrammeerd in Objective-C (iOS), Java (Android) en C# (Windows). Het draaiende houden van deze engines op nieuwe apparaten met verschillende schermformaten, processors en geheugenconfiguraties werd steeds moeilijker.
Maar deze maand heb ik de knoop doorgehakt, en hoe. Ik heb een andere Snake game-engine ontworpen en gebouwd. Maar deze was bedoeld om alle vorige te vervangen. Hij moet draaien op iOS, Android en Windows. Ik wilde een engine die klaar was voor de toekomst, voor elk scherm en elk soort invoer (toetsenbord, touch, pencil, gamepad, joystick, noem maar op).

HTML5 Rocks
Het web heeft de native app-technologie ingehaald. Er zijn veel nieuwe API's geïntroduceerd die rijke interactieve ervaringen mogelijk maken op veel verschillende apparaten. Ik vroeg me af hoe moeilijk het zou zijn om Snake '97 te laten werken op webtechnologie. Er is maar één manier om daar achter te komen, dus ik ben begonnen.
Responsieve graphics
Eerst begon ik met het bouwen van de graphics-engine op basis van HTML5 canvas en een responsief schaalsysteem dat ik had ontworpen voor de Android-versie van Snake '97. In wezen meet de engine de beschikbare schermgrootte, oriëntatie en pixeldichtheid. Het vertaalt automatisch fotomateriaal met hoge resolutie naar jouw specifieke scherm.

De nieuwe graphics-engine houdt zelfs rekening met rare dingen zoals de notch van de iPhone X. Dit alles gebeurt in een fractie van een seconde. Ik heb de nieuwe graphics-engine ook zo ontworpen dat hij reageert op veranderingen in schermgrootte. Nu is het mogelijk om het spel te spelen in portret- of landschapsmodus, in een venster of op volledig scherm (of gesplitst scherm als je op een iPad zit).


Verschillen in verwerkingskracht
Denk je dat een simpel spel zich geen zorgen hoeft te maken over rekenkracht? Fout! In een spel als Snake is timing essentieel. Mensen spelen het spel met "spiergeheugen", waarbij ze hun tikken op het touchscreen herhalen zonder na te denken over individuele bewegingen.
De game-engine moet voorspelbaar zijn, hij moet constant draaien. Maar bovendien moet de ervaring hetzelfde zijn, of je nu op een oud Android-apparaat zit of een 6-core krachtpatser zoals de iPhone X.

Ik heb de hogesnelheidsvideocamera van de iPad Pro gebruikt om Snake-gameplay in slow motion vast te leggen. Met behulp van de video kon ik frame voor frame verschillen in snelheid ontdekken. Dit leidde tot een intern benchmarksysteem (met behulp van timers, die milliseconden tellen) dat automatisch de snelheid van het spel aanpast, precies afgestemd op jouw specifieke apparaat.
Besturing: Touch, Toetsenbord, Pencil, Gamepad
Spelers besturen de Snake met behulp van de retro-bediening (het oude telefoontoetsenbord). De originele iOS-versie van het spel gebruikte vaste transparante UIButtons die ik over de foto's van de oude telefoon plaatste. Een simpele en effectieve start.
Helaas hadden de knoppen van iOS wat lag (wat onvoorspelbare vertragingen in de invoer veroorzaakte) en schaalden ze duidelijk niet naar verschillende schermformaten. Ik heb letterlijk nieuwe coördinaten hardcoded voor elke nieuwe iPhone die Apple de afgelopen jaren heeft geleverd.... geen leuke klus.
De nieuwe game-engine gebruikt een truc die ik heb ontwikkeld voor de Android-versie: dynamisch gepositioneerde virtuele knoppen. Met behulp van de schaalinformatie die de graphics-engine berekent, onderhoud ik dynamisch een matrix van X- en Y-coördinaten die overeenkomen met de virtuele knoppen. Wanneer een speler het scherm aanraakt, berekent de engine de dichtstbijzijnde knop met behulp van wiskunde, de stelling van Pythagoras.

Dit werkt perfect en maakt effectief het hele scherm een knop. Het spel is veel leuker om op deze manier te spelen. Naast touch heb ik ook ondersteuning voor het toetsenbord toegevoegd, zodat mensen zonder touchscreen ook Snake kunnen spelen.
Terwijl ik aan de bediening werkte, ontdekte ik nog meer HTML5-goedheid, de GamePad API. Het stelt programmeurs zoals ik in staat om gamepads, joysticks en andere invoerapparaten te ondersteunen die zijn aangesloten via USB of Bluetooth.

Het ondersteunen van verschillende gamepads is een uitdaging, maar desalniettemin leuk. Ik heb zeker een hele dag verloren tijdens het "testen" ... het perfectioneren van mijn vaardigheden met behulp van de formidabele SNES-gamepad en de heerlijke analoge stick van de DualShock-controller. ("Sorry schat, ik ben hier aan het werk...")

Internationalisering
Als je dit leest, begrijp je waarschijnlijk Engels. Maar een groot deel van het Snake '97-publiek is niet-Engelstalig. Sterker nog, er zijn spelers met meer dan 30 verschillende talen. Van Spaans tot Russisch, van Arabisch tot Hebreeuws, van Duits tot Japans. Noem maar op, Snake heeft het.
Het ontwerpen van een interface die afhankelijk is van tekst is een uitdaging als je de wereld wilt bedienen. Pictogrammen zijn ook niet feilloos (verschillende betekenissen voor een afbeelding). Als UX-designer moet je nadenken over concepten die wereldwijd breed worden gebruikt. Voor Snake heb ik pictogrammen gebruikt van een klok, snelheidsmeter, luidspreker en een trofee. Deze pictogrammen zijn overal ter wereld gebruikelijk en zijn precies om deze reden gekozen.

De app-beschrijving bestaat uit tekst die ik heb laten vertalen door een professionele vertaaldienst. Sommige andere uitgevers vertrouwen op Google Translate - maar ik weet dat dat tot sombere resultaten leidt.
Wereldwijde ranglijst
In de jaren 90 kreeg je wat straatcrediet als je een mooie score in Snake had behaald. In de originele versies van Snake '97 had je alleen je eigen topscore om te verslaan en op iOS kon je je score uploaden naar GameCenter.
Voor de nieuwe versie wilde ik een meer wereldwijd bereik, met de introductie van een "wereldwijde ranglijst". Het is het nieuwe geïntegreerde klassement dat je spel direct rangschikt, waarbij scores van mensen over de hele wereld worden vergeleken. Er zijn drie ranglijsten: aller tijden, 24 uur en laatste uur.

De topscores worden verwerkt door een ongelooflijke 48-core Intel XEON-server met een enorme hoeveelheid geheugen. Hij draait Debian GNU/Linux, MariaDB, NGINX en NodeJS. Tijdens piekuren verwerkt hij meer dan 10 spelscores per seconde. De serverconfiguratie is een aparte blogpost waard die ik later zal schrijven - dus houd deze blog in de gaten als big data jouw ding is.

Download nu
Er is maar één manier om erachter te komen of mijn werk goed is: probeer het zelf.
Laat het me weten als je bugs tegenkomt, je vindt mijn contactgegevens hier.
