Monopoly app bouwen in Salesforce – deel 1: het speelbord

We gaan een Monopoly spel maken in Salesforce. Ik ga dit spel gedurende een aantal blogs stap voor stap opbouwen en zal je aan de hand van dit voorbeeld de nodige vaardigheden en best practices leren.

Hoe begin je je ontwerp?

Bij het ontwerpen van een app visualiseer ik eerst vanaf het begin tot eind het gebruiksproces om te ontdekken wat er technisch nodig is.

In dit geval moeten we er eigenlijk de doos van een echt Monopoly spel bij pakken, bekijken wat erin zit en de spelregels doorlezen.

Het eerste dat je in de doos vindt is het speelbord. Vanaf hier kunnen we al veel details uitwerken die we nodig hebben.

  • Er staan 40 vakjes op het bord waar spelers naartoe kunnen lopen
  • De volgorde van de vakjes op het bord is van belang
  • Alle vakjes hebben een naam
  • Sommige vakjes kunnen gekocht worden door spelers en hebben een aanschafprijs
  • Als je een straat, station of nutsbedrijf koopt, krijg je een kaartje in handen dat dit eigendom vertegenwoordigt
  • Straten, nutsbedrijven en stations behoren tot groepen
  • De groep heeft effect op de huur die je mag heffen en bepaalt of je huizen en hotels mag kopen.
  • Bij sommige vakjes moet betaald worden als je er op belandt.
  • Soms betaal je aan de bank, soms aan een andere speler.
  • Op sommige vakjes (kans, algemeen fonds, start, belastingen, vrij parkeren, ga naar de gevangenis) geldt een speciale spelregel als de speler er op belandt.

Eerste opzet voor het datamodel

Op basis van deze analyse van alleen het speelbord, kan ik al een groot deel van. Het datamodel uitwerken.

  • Het bord zelf is een object
  • Elk vakje op het bord is een child record van het bord
  • Aan een vakje kan een verhandelbaar object (straat, station, nutsbedrijf) verbonden zijn
  • Dat verhandelbaar object kan een speler als eigenaar hebben, heeft een aanschafprijs, een hypotheekwaarde en een prijslijst voor de huur.
  • Die prijslijst regels moeten de criteria bevatten om aan te geven wanneer welke prijslijst regel geldt en de prijs die gehanteerd moet worden.
  • Op het verhandelbaar object zelf moeten de eigenschappen bijgehouden worden die de huurprijs bepalen, zoals het aantal huizen.
  • Aan een vakje kan een regel (of verzameling regels, zoals de stapel kanskaarten) gekoppeld zijn
  • De spelers zelf hebben ook een record nodig zodat hun bezittingen en positie op het speelbord kunnen worden bijgehouden.

Om het datamodel flexibel en schaalbaar te maken, gebruik ik alleen master-detail relaties waar het echt niet anders kan en maak ik gebruik van many to many relaties via junction objecten.

Hoewel we ons er voorlopig nog niet mee bezig gaan houden, wil ik er in het datamodel nu al rekening mee houden dat er een mogelijkheid moet komen om meerdere ‘potjes’ parallel te kunnen hebben lopen en misschien zelfs andere spellen deels van dezelfde objecten gebruik te laten maken.

Met de bovenstaande ideeën bij de hand ga ik een datamodel uittekenen. Ik gebruik hiervoor graag Draw.io om de schets te maken van met name de relaties. Dat ziet er dan als volgt uit:

Aan de lijnen zie je welk object in de relatie het child record is en welke de parent.

De Position Rule is hierin het enige junction object. Zo maak je een many to many relatie.

Hierdoor kan dezelfde Rule aan verschillende Positions gekoppeld worden. Dat heeft zin omdat er meer dan 1 vakje met Kans en meer dan 1 vakje met Algemeen Fonds is en beide toch maar één stapel kaartjes hebben.

En dezelfde Position kan meerdere Rules onder zich hebben, wat we ook willen kunnen doen, omdat Algemeen Fonds en Kans stapels kaartjes zijn in plaats van steeds dezelfde regel als je op zo’n vakje komt.

Voor de object en veldnamen werk ik in het Engels. De gewoonte heeft twee voordelen: het is voor mijn niet Nederlands sprekende collega’s handiger en wat er gebouwd is, kan in de toekomst gemakkelijk ook bij andere klanten worden ingezet waar Nederlands misschien niet de voertaal is.

Het datamodel aanmaken in Salesforce

In Schema Builder kun je dit datamodel snel bouwen en goed visualiseren. Schema Builder vind je onder Setup > Objectbeheer > Schema Builder

Om een nieuw object te maken open je het Elements tabblad en sleep je een object op het canvas.

Vul het volgende scherm in.

Consonant of Vowel Sound?
De keuze Consonant of Vowel Sound heeft te maken met of voor de objectnaam in een Engelse zin het lidwoord a of an gebruikt wordt. Staat je hoofdttaal op Nederlands, dan wordt juist naar het geslacht van je objectnaam gevraagd. Is het een mannelijk of vrouwelijk woord, dan wordt het lidwoord de gebruikt, bij onzijdig het. Mijn voorkeur heeft het zogezegd dat Engels de basis is en je een Nederlandse vertaling voor alles toevoegt via de verschillende vertaalopties.

Velden op je object aanmaken, doe je ook door te slepen

Houd er wel rekening mee dat je object tabbladen, pagina layouts en field level security dan nog afzonderlijk moet regelen na het aanmaken van de objecten en velden. Gezien je dan de verschillende soorten taken bij elkaar bundelt, vind ik dit efficiënter dan al die stappen per veld te moeten doorlopen.

Pagina layouts wil ik later toch nog finetunen en rechten stop ik liever in een permission set dan een profiel. Ook het vertalen van object en veldlabels, help teksten en keuzelijst waarde is een op zichzelf staande stap.

Het datamodel dat we nu maken is de basis, maar gaandeweg het ontwerpproces kan het zijn dat we ontdekken dat er toch andere velden of relaties nodig zijn.

In de onderstaande tabel vind je de velden die ik nu op de 8 objecten aangemaakt heb

ObjectVeldnaamType veld
Board__cExternal_ID__cText, 40 characters, External Id, Unique
Position__cBoard__cLookup naar Board__c object, verplicht
Index__cNumber, 18 digits, 0 decimals
Asset__cLookup naar Asset__c object, niet verplicht
External_ID__cText, 40 characters, External Id, Unique
Asset_Group__cExternal_ID__cText, 40 characters, External Id, Unique
Asset__cExternal_ID__cText, 40 characters, External Id, Unique
Asset_Group__cLookup naar Asset_Group__c object, niet verplicht
Owned_by__cLookup naar Player__c object, niet verplicht
Purchase_Price__cCurrency, 6 digits, 0 decimals
Base_Rent_Price__cCurrency, 6 digits, 0 decimals
Asset_Rent_Rule__cExternal_ID__cText, 40 characters, External Id, Unique
Asset__cMaster-Detail naar Asset__c object, (altijd verplicht)
Number_of_Assets_in_Group_owned__cNumber, 1 digit, 0 decimals
Buildings__cPicklist, options: none/1 house/2 houses/3 houses/4 houses/hotel
Rent_Price__cCurrency, 6 digits, 0 decimals
Player__cExternal_ID__cText, 40 characters, External Id, Unique
Position__cLookup naar Position__c object, niet verplicht
Cash_Balance__cCurrency, 18 digits, 0 decimals
Rule__cExternal_ID__cText, 40 characters, External Id, Unique
Description__cText, 255 characters
Action__cPicklist, options: Receive Money/Pay Money/Move number of steps/Move to Position
Destination__cLookup naar Position__c object, niet verplicht
Allowed_to_travel_via_Start__cCheckbox
Amount__cCurrency, 6 digits, 0 decimals
Number_of_Positions_Forward__cNumber, 2 digits, 0 decimals
Financial_Transaction_Party__cLookup naar Player__c object, niet verplicht
Position_Rule__cPosition__cMaster-Detail naar Position__c object, (altijd verplicht)
Rule__cMaster-Detail naar Rule__c object, (altijd verplicht)
Index__cNumber, 3 digits, 0 decimals

Waarom die External ID’s?

External ID’s zijn een handige manier om bij het importeren van data relaties met bovenliggende records te leggen, zonder dat je de 18 karakters lange en niet heel gemakkelijk te onthouden Salesforce record Id’s van die Parent Records hoeft te gebruiken.

Hoe nu verder?

In een aantal volgende delen van deze serie werken we onze Monopoly app verder uit. Daarbij besteden we onder andere aandacht aan:

  • Hoe beweegt een speler zich over het bord?
  • Wat moet er gebeuren wanneer de speler op een nieuwe Position arriveert?
  • Hoe bepalen we welke huur er betaald moet worden?
  • Hoe kom je in de gevangenis en hoe kom je er weer uit?
  • Hoe geven we alle spelers real time inzicht in alles wat er gebeurt tijdens de beurten van de andere spelers?

Op donderdag 30 januari lees je deel 2 waarin we een custom app en Lightning Pages gaan inrichten.