DEV Community

Cover image for Canyon Escape - a Power Automate Game
david wyatt
david wyatt

Posted on

Canyon Escape - a Power Automate Game

Welcome to Canyon Escape, you are an intrepid explorer in the model of Indian Jones, while exploring the deepest jungle in Peru you stumble into a canyon. With no way back you trek through, hoping to find an escape, and maybe a lost treasure or two,

game video

Want to play, just
email: Canyon_escape@outlook.com
subject: canyonEscape (case sensitive)

Please note this is running off a dev tenant and will be deleted soon. Additionally the free Outlook account may get banned for spam if over used, so sorry if it stops working. Also this is an outlook trigger so occasionally can take 5 minutes + to get response


In case you didn't know, I like to set myself weird challenges. I find the best way to learn is to do something challenging.
Unfortunately Power Platform work is enterprise focus, so less variation than I hope for in my day job, that's where random self challenges come in. I've been wanting to make a Power Automate game for a while, but couldn't quite think of something, then I read an interesting article on a game called Zork. It was a text-based adventure game created in the 70s. Though it was before my time, it then reminded me of Pirate Island, a BBC Micro game I did play.

zork

pirate island

So my idea is to make a kind of hybrid Zork / Pirate Island inspired text based Power Automate game.

The challenges/areas of game I needed to decide on were:

  1. Interface/UI
  2. Design
  3. Gameplay
  4. Setup
  5. The Flow

1. Interface/UI

Obviously, Power Automate has no UI, but it has connectors, so in theory it can work with any UI. But to keep it in the spirit of the challenge I considered 3:

  • SharePoint
  • Approvals
  • Outlook

SharePoint would have to be a list, or even a text file (triggered on save). The list wasn't practical, but the text file would definitely work.

Approvals would be good because I could pass simple text, read comments and stay within one flow run.

Outlook was the most flexible, I could use with options for one flow run, or emails for full flexibility.

In the end I went with Outlook, it kind of felt a little retro, and allowed anyone (not just people on my org) to use the game.

2. Design

In my mind I had 2 approaches, a single flow run, or multi flow. Single was a lot easier, as I could store progress and player status in the flow. But this limited the interaction, as with Outlook that would require Email with Options, and I wanted this to be text not button based. So that left multi flow, the problem with this is the benefits of single, how do I track the progress of the game. The easy way would be a SharePoint list, each game would be a row in the list, but this didn't feel right to me, it wasn't scalable and wasn't very innovative. So I came up with a different approach, what if I treated the subject of the email like an API call, I could pass the position in the game and the status of the player as parameters. The flow wouldn't need to remember anything, just take the input and return an output.

TriggerCondition?levelID&leftHand&rightHand&status

3. Gameplay

I started with a 10 by 10 board, so 100 squares, well no I had 1 edge square so it ended up 8 by 8 (64 squares, perfect number for a retro game).
The navigation was simple, North, East, South West, but to make sure it wasn't to dull I decided on a chess queen approach. So you don't move one square you move until you hit the next square with something in it.
To make the game a little interesting I decided on some additional actions then just moving.

  • Pick up
  • Use
  • Drop
  • Speak
  • Answer

On certain squares you could do these actions and you can only hold 2 items at once.

The items can be used in 2 ways:

  • Heal/Save life
  • Unlock square(s)

As you have guessed there are squares you can die on, with some the ability to survive, others straight death. The survivable squares have a puzzle to solve, with the Heal/Save life item a clue or answer.

I also added puzzles at some key elements to progress too, this is to either get information or items you need to progress.

The unlock squares works by your status, so using an item will change your status, having right status allows you to access square e.g.
Use boat to set status to sailing to access water square

4. Setup

The story and details to the game are key, but so is how they are setup, as I want to be able to make the story dynamic. First of all this is going to be in Excel and not my usual SharePoint list. This is for 3 reasons:

  1. To be different/learn
  2. I'm using Outlook and not Outlook O365 as this is linked to a temp developer tenant,
  3. It's actually easier to use Excel as I can also use it for the map

The map is the 10 by 10 grid in a Excel tab, here I plan out all the locations.

excel map

Next I transfer this to a table which will be looked up during the game, each column is used for different things:

Column Used For Example
Square Description Jungle
Co-ord Grid Reference D4
ID GUID for subject 1
Text Text returned when step into square You enter the cave, it's very dark
North Row ID of Square to North or message if blocked 8
East Row ID of Square to East or message if blocked The wall is too high to climb
South Row ID of Square to South or message if blocked 16
West Row ID of Square to West or message if blocked You fall off the cliff and die. Game Over
Item Item available to pick up Crossbow
Use Item that can be used Anti-crossbow spray
Person The response to speaking to a person I can't believe you shot me with a crossbow
Puzzle The response if you get the challenge/survive right You use the crossbow to defeat the baddie
Incorrect The response if you get the challenge/survive wrong You die you wimp, Game Over
Answer Answer to the challenge/survive puzzle To get to the other side
Attachment Attachment sent when pick up item crossbow.jpg
Need The status you need to enter this square Sailing

excel table

Finally there is an item table, this is used to get information when using an item.

Column Used For Example
Item Item name (linked to Item column in Map) Crossbow
Action Status it gives (linked to the required column in Map and the status parameter) Fighting
Give Custom message for when the item is used The crossbow made you big and strong

4. The Flow

This is the interesting bit, in this case our flow is basically logic tree, all we are going to do is pass in our inputs, check some parameters and return a value, simple.

I hate nesting and I hate using conditions as branching, so you are going to see the Direct Methodology approach with escape conditions.

->condition
    -true
        action
        terminate
->condition
    -true
        action
        terminate
->condition
    -true
        action
        terminate
Enter fullscreen mode Exit fullscreen mode

Each time we check a condition, if true we do something then terminate. If false we skip the condition for the next condition (the false are empty).

flow condition

As example the subject expression for picking up an item is:

if(not(equals(outputs('Get_a_row_current_Sq')?['body/Item'],'')),
    if(equals(outputs('Extract_Query')[1],'empty'),
        concat(
            'canyonEscape?'
        ,
            outputs('Extract_Query')[0]
        ,
            '&'
        ,
            outputs('Get_a_row_current_Sq')?['body/Item']
        ,
            '&'
        ,
            outputs('Extract_Query')[2]
        ,
            '&'
        ,
            outputs('Extract_Query')[3]
        ,
            '&'
        ,
        triggerOutputs()?['body/Id']
        )   
    ,
        concat(
            'canyonEscape?'         
        ,
            outputs('Extract_Query')[0]
        ,
            '&'
        ,
             outputs('Extract_Query')[1]
        ,
            '&'
        ,
            outputs('Get_a_row_current_Sq')?['body/Item']
        ,
            '&'
        ,
            outputs('Extract_Query')[3]
        ,
            '&'
        ,
            triggerOutputs()?['body/Id']
        )
    )
,
    replace(triggerOutputs()?['body/Subject'],'RE:','')
)
Enter fullscreen mode Exit fullscreen mode

The conditions are:

  • Pick up
  • Use
  • Can't Use
  • Speak
  • Can't Speak
  • Challenge Correct
  • Challenge Failed
  • Condition Survive
  • Condition Die
  • Drop
  • Path not Valid
  • Path Blocked by Status
  • Path Move

And a bonus condition for Start and Cheating (see later).

So we get our current position in the game from the subject and we use condition tree to return next step in the game, how do we convert the subject parameters.

First we split the subject (with a literal split) to get each parameter.

split(
    split(
        triggerOutputs()?['body/Subject']
    ,
        '?'
    )[1]
,
    '&'
)
Enter fullscreen mode Exit fullscreen mode

do until flow

Next we loop over all of our actions and check if the body contains it (I use a Do_until loop as that can stop once found and save it to a variable - stop condition variable not blank). We have an object array that has the possible value and the output e.g.
take is same as pick up, so we want to set the variable to the same as pick up, in this case our condition looks for PickUp.

logic array

We now have our text (action and variable) status, items and our location. But the location is just an id, we use that id to look up at row in our Excel file map table, getting all the key information.

We use the same table to get the next squares detail (North/East/South/West id returns the row and its detail, like required).

There's a couple of wildcards to add:
Start
We use a trigger condition, but what happens on the first stage when we don't have any parameters. Well here I'm using exception handling as a logic. If we fail out split because of missing parameters, then we catch that as a run after failed and send the start email.

start exception flow

Cheating
We know everyone likes to cheat, so how do I stop people just replying to an email 100 times until they get it right, well this is the clever bit. We use the last email as a life, this email is deleted, so if we reply twice, it will fail as we can't delete the email twice. How do I know the email message ID, well I just add it as a parameter to our subject. But what If I want to cheat, well we can add a cheat code, this condition checks if the email body contains the code and skips the delete email.

delete

The full flow is a bit of a monster and pushes the limit of what I normally put in one flow, but it works, and there isn't actually that many actions (just conditions, lots of conditions 馃槑 )

full flow

flow from autoreview


Key Learnings

So what did I learn from building Canyon Escape,

  • Excel is a great config/lookup connector, not far off SharePoint
  • Using Outlook/OneDrive/Excel is just as good as their 365 alternatives, so automating your personal life is just as easy as work life.
  • Power Automate can do logic tress OK, though it definitely has a limit
  • Exception logic works well and though not recommend has its place

Want to make your own, flows and files here, just:

  • Setup free outlook account
  • Upload the map.xlsx and attachment files to that accounts OneDrive root.
  • Edit the map then transfer to the data table and item table

Top comments (10)

Collapse
 
thatcomputerguy profile image
Griff Polk

Hi! Quick question! How would you classify this post? 1 being novice, 2 beginner, 3 mid-level, 4 advanced, and 5 being expert? Thanks! I am a #gamedev mod and want this to be geared toward the right skill level audience. I love this post! I will be trying it out myself.

Collapse
 
wyattdave profile image
david wyatt

Hi ThatComputerGuy, Thank you for kind words. I would say this is 4-advanced, the techniques are not that complex, but pulling it all together adds a little complexity

Collapse
 
thatcomputerguy profile image
Griff Polk

Thanks! As a #gamedev tag mod, it is important to gear it toward the right audience. I really like this post and cannot wait to try it. I will post back on my adventures!

Collapse
 
jonathancgroves profile image
Jonathan Groves

I once wrote a VBA system for Outlook that allowed me as a remote user to use complex creds and commands in the subject of an email to view directory listings and retrieve files from an enterprise IT system. I stopped short of allowing file upload!

Collapse
 
wyattdave profile image
david wyatt

That sounds so cool. I loved VBA, more powerful then most people realise. I did loads of cool stuff with it, though nothing quite at your level 馃槑

Collapse
 
datadragyn profile image
DataDragyn

I could not love this post more. I instantly thought of my Zork days. About 24 hours ago I had just re-posted about Scott Durow Power Laps game he made in Power Apps. I've seen the non-linear narrative in Power BI too. What you have done and your thought process to catch those edge cases is next level. Thank you for sharing the files.

Collapse
 
wyattdave profile image
david wyatt

Thank you for kind words 鈾ワ笍

Collapse
 
rubynolte profile image
RubyNolte • Edited

It's great to immerse in this world of Indian Jones and these magnificent adventures. Lately, I have discovered new directions in this letsgiveitaspinslots.com/ Thanks to streaming, I was able to better understand and understand all the moments that can lead me to a big result.

Collapse
 
jaloplo profile image
Jaime L贸pez

This sentence made me laugh: "...so it ended up 8 by 8 (64 squares, perfect number for a retro game)" 馃槈

Great article!!!! Nice memories when playing with the spectrum 48K.

Collapse
 
balagmadhu profile image
Bala Madhusoodhanan

@wyattdave : love this mate.. triggered a nostalgic journey down memory lane, reminding me of the countless hours I spent immersed in playing Zork on my PC during the 1990s.