Building a Monopoly app in Salesforce - part 5: What happens when a Player arrives at a new Position?

In the previous episode in our Monopoly serieswe began working on the screen flow that allows you to take your turn as a player.

We developed the functionality for rolling the dice, moving the player to a new position, and applying the rules for double rolls within the flow.

Now it's time to look at the next steps. What needs to happen when the player lands on a new squares?

The following scenarios are possible:

  1. The Player lands on a Tax square and must pay money to the bank
  2. he player passes or lands on Go and receives money from the bank
  3. The player lands on Chance or Community Chest and the rule on the top card of the deck applies to them
  4. The player lands on a street, station, or utility that is still available for purchase and can decide whether to buy the asset
  5. The player lands on a street, station, or utility owned by another player and must pay rent

For the first two, the solution is straightforward. Each of these spaces has a single Position Rule. The rule linked to the Position can be used to perform the action associated with that rule.

To keep things organized, I want to isolate subprocesses wherever possible and design standalone subflows for them.

When a web of subflows emerges, it is helpful to document it, allowing you to quickly see which flow is used and when.

Let’s start building our subflows for executing a Position Rule.

Screenflow for executing a Position Rule.

Since we also want to display information to the player on the screen within this subprocess, we design this flow as a Screenflow.

This flow will only be used as a Subflow, so we can define clear names for our input variables.

To execute a Rule, we need:

  • The Rule record variable
    • Name: inputRule
    • Type: record
    • Object: Rule__c
    • Available for input: checked
  • The Player record variable
    • Name: inputPlayer
    • Type: record
    • Object: Player__c
    • Available for input: checked

There are 4 types of rules:

  • Move Number of Steps
  • Move to Position
  • Pay Money
  • Receive Money

Although I mentioned in the previous edition that I always want to avoid decisions with multiple outcomes, in this case, I still want to include a branch for each type of Rule.

I don’t expect this to cause much confusion here. I also want to save the reader of the flow from excessive scrolling by not placing the four scenarios sequentially one after the other. Since Rules are already data that drive the automation's functionality, I don’t want to add another metadata layer of rules to dictate how to handle Rules on top of that. That would make it unnecessarily complex.

Let’s now define each of these four routes.

Move Number of Steps

When a card dictates moving a certain number of steps forward or backward from the current Position, we need to retrieve the Position at that Index number, updating the Position of the inputPlayer and inform the player.

When determining the Index of the Position the player must move to, we need to account for the possibility that the player passes Go .

There is only one Chance card that moves the player 3 spaces backward, and none of the first 3 spaces are a Chancesquare, so for the execution of this Rule, we do not need to consider whether the Player may or may not pass Go .

In the path for Move number of steps we will include the following:

  • Get Records element to retrieve the Position the Player must go to
  • Update Records element to update the Player's Position
  • Screen element to show the player the Rule being executed and the effect it has

Null Check

A best practice is to add a Null check after every Get Records element in a flow: First, check whether the query has returned a result before using the retrieved record variable further in your flow.

You do this with a Decision element. The test in the element is <get records element> is Null false. If the answer to this is true then a record has been found, and you can proceed to use it. However, if the outcome is false, you should terminate the flow with a clear error message for the user, as you cannot optimally execute the rest of the flow without that record.

Move to Position

In the case where the Rule explicitly specifies, via the Position lookup, which Position the Player must be moved to, there is no Get Records element needed.

Something we do need to check, only when the player is allowed to pass Go (the rule will say so), whether they actually do pass Go on the way to the intended Position.

We place that Decision as the first element in this path.

The player would pass Go if their current Position is located after the Rule's Destination on the Board and thus has a higher Index__c value. We only need to check this when the user may pass Go . Therefore the decision will look like this.

If the player has traveled via Go, in addition to updating the Player's Position, the Player's Cash Balance must also be increased by 20,000.

Then we update the Player record's Position.

Finally, we display the screen to the player showing the Rule being executed. If the player passes Go the second Display text element also becomes visible.

Pay Money

When the player needs to pay, the Rule determines the amount and the receiving party. The amount must therefore be subtracted from the Player's Cash Balance and added to the counterparty's balance. Since both records belong to the same object, I combine them into a Record Collection variable and update both records using a single Update Records element.

For the screen in this path, we first copy the screen from one of the two previously created paths and then adjust the copy.

Receive Money

What needs to happen in this path is a lot like what we do in the Pay Moneyroute, so first we copy all the elements of that path and then we will modify them one by one.

  1. First click Select Elements
  2. Select the 3 elements we wish to copy
  3. Click the clipboard icon to copy them

Click the + in the Receive Money path and click Paste 3 Elements.

In the Assignment element, we adjust the label, the API name, and the first two operators, because the money now flows not from the active Player to the counterparty, but in the opposite direction.

In the Update Records element, we only need to adjust the label and the API name, primarily because "Copy 1 of" doesn't look good. Functionally, it’s not strictly necessary.

In the Screen element, we also adjust the label and the API name of the screen itself, as well as that of the Display Text element. And we change a few words in the text plus the Finish button's custom label.

Wrapping up

Our subflow for processing the effect of a Rule and showing the player what happens is complete. We can now save it and activate the flow.

I will use my standard prefix again, so we can see at a glance what type of flow we are dealing with and will call this flow SCR – Execute Rule. By the way, it is a best practice to regularly save the flow while building it.

  • Record Triggered Flows: RTF
  • Autolaunched Flows: ALF
  • Platform Event Triggered Flows: ETF
  • Scheduled Flows: SCH
  • Screen Flows: SCR

Now it’s necessary to include this subflow in the main flow so that, after arriving at a new Position, the associated Rule can also be executed. We’ll address this in the next episode. Then we shall also explore how it works when the Position is a Chance or Community Chest aquare, where the Rule to be executed is actually the top card of a deck.

In Parts after the next one we will dive into buying Assets from the bank and paying rent.

Leave a Reply

Your email address will not be published. Required fields are marked *

Please reload

Please Wait