Ik bouwde een scorebord voor toepen, omdat het bierviltje altijd kwijtraakte
Wie weleens toept, kent het. Iemand houdt de stand bij op een bierviltje of de achterkant van een bonnetje, halverwege valt er bier overheen, en na een uur weet niemand meer of Kevin nou op 7 of op 8 stond. De discussie daarover duurt vaak langer dan het potje zelf.
In het weekend toep ik met mijn vrienden. Er bestond al een toepen-app, maar daar kwamen advertenties in. Toen dacht ik: dit kan ik ook zelf maken. Ik begon met een scorebord op de website, en dat werkt nog steeds op toepapp.nl.
Dus heb ik ToepApp gemaakt: een simpel scorebord voor toepen op de iPhone. Spelers toevoegen, plus en min tikken, klaar. In dit stuk vertel ik kort hoe ik het heb gebouwd en welke keuzes ik maakte.
Wat het moest doen (en vooral wat niet)
- Werkt zonder internet. Toepen gebeurt in kroegen, op campings en in kelders van studentenhuizen. Daar heb je niet altijd bereik.
- Geen account, geen advertenties, geen tracking. Je wilt de score bijhouden, niet eerst inloggen.
- Snel. Eén tik per punt. Ook na een paar biertjes.
- Bitchpunten. Wie de toepregels kent, weet dat die erbij horen. Ze krijgen hun eigen teller per speler.
Alles wat daar niet aan bijdroeg, heb ik weggelaten.
Waarom Flutter
Ik volg op school nu mobile app development, dus het was het perfecte moment om het scorebord opnieuw te bouwen als echte app. Flutter leek me een goede keuze omdat ik met één codebase straks ook een Android-versie kan maken. Dat blijkt nu handig: meer dan de helft van de bezoekers van toepapp.nl gebruikt Android, dus daar wordt aan gewerkt.
De hele app is ongeveer 1.500 regels Dart. Er zitten maar drie packages in: shared_preferences om het spel op te slaan, audioplayers voor geluid en in_app_review voor de beoordelingsvraag.
Het spel mag nooit kwijtraken
De eerste versie hield de score alleen in het geheugen bij. Prima, totdat iemand de app per ongeluk wegveegt, of iOS hem op de achtergrond afsluit omdat iemand tussendoor foto's maakt. Dan ben je alles kwijt, en dat is precies het probleem dat de app moest oplossen.
Nu wordt na elke wijziging de hele stand als JSON opgeslagen:
Future<void> save(List<Player> players) async {
await _prefs.setString(
'players_v1',
jsonEncode([for (final p in players) p.toJson()]),
);
}
Bij het opstarten wordt dat weer ingeladen. Eén regel die ik belangrijk vond: een beschadigd bestand mag de app nooit laten crashen. Lukt het inlezen niet, dan start de app gewoon met een leeg scorebord in plaats van met een foutmelding.
Een klein bugje dat ik daarbij tegenkwam: elke speler heeft een intern id. Na het herstellen van een spel begonnen nieuwe spelers weer bij id 0, waardoor er twee spelers met hetzelfde id konden zijn. Nu telt de app verder vanaf het hoogste bestaande id.
Om een beoordeling vragen, maar niet irritant
Beoordelingen zijn belangrijk in de App Store, maar niemand wil midden in een potje een pop-up. Daarom vraagt de app het pas als iemand hem echt gebruikt:
- minstens 3 keer geopend,
- verspreid over minstens 2 dagen,
- in totaal zo'n 20 minuten gebruikt,
- en daarna minstens 120 dagen niet opnieuw.
Het moment is ook bewust gekozen: bij het opstarten, of direct nadat je een nieuw spel start met dezelfde spelers. Dan is er net een potje afgelopen en is iedereen in een goede bui. Nooit tijdens het spel.
Een leuk detail: als je de app open op tafel laat liggen, telt dat maar voor maximaal twee uur mee. Anders zou één lange avond meteen alle drempels halen.
De metalen pijp
Elke app heeft een geheimpje nodig. Tik op de titel TOEPEN bovenin en je hoort het bekende geluid van een vallende metalen pijp. Het heeft geen enkel nut. Het is gewoon een grappig geluid waar mijn vrienden en ik om moeten lachen, en daarom zit het erin.
Nederlands, ook voor de App Store
Een verrassing bij de eerste release: de App Store liet "Engels" zien als taal, terwijl de app helemaal Nederlands is. Dat kwam doordat het Xcode-project nog op Engels stond als ontwikkeltaal. Nu staat alles op Nederlands, ook de systeemteksten van Flutter zelf, zoals het kopieer- en plakmenu en de VoiceOver-hints.
Wat ik ervan leerde
- Klein houden werkt. De app doet één ding, en dat maakt hem makkelijk uit te leggen.
- Opslaan is geen extraatje. Bij een scorebord is "ik ben alles kwijt" de ergste bug die er is.
- De App Store is een vak apart. Naam, ondertitel, trefwoorden en taalinstellingen maken veel verschil in of mensen je kunnen vinden.
Probeer het
ToepApp is gratis voor iPhone. Geen iPhone? Op toepapp.nl staat een scorebord dat in elke browser werkt, en de spelregels van toepen voor wie het nog moet leren.
Download ToepApp in de App StoreIk hoor graag wat je mist of wat beter kan. Mail naar support@toepapp.nl.