Posts in Games
Making my own numbers stations

Creation

Last weekend, I got to run a game of Monster of the Week for some friends. It was the first time in a while, and knowing our luck it will probably be a while yet until the next one. Something in me decided to go big, and I found myself doing more preparation than I’ve done for any game in a very, very long time.

I made my own numbers stations.

You can listen to the bits I gave to the players here: link.

Setup

The audio was accompanied by an encoded journal, which I made a fumbled attempt at weathering, and handed to the group towards the start of the game.

IMG_0937.jpg

After playing an initial radio broadcast from my computer, I handed over an iPad with the page above loaded up, along with a pair of headphones, so that the players could browse and decode at their own pace.

The conceit being, of course, that something is sending out these cryptic radio signals, and the mysterious figure that dropped this notebook was somehow related.

Play

Luckily for me, play worked out pretty much how I anticipated: one player (the team’s hacker) assumed the role of the decoder, while the other players went around gathering clues. I used their rolls towards Investigate the Mystery and Read a Bad Situation feed back into clues about the code itself, which the players then relayed back to the person doing the decoding. The decoder then finished a page, relayed its contents to the rest of the group, and they used that information to inform where to go investigate next.

It all culminated in the party taking turns wielding a giant magical sword against a seven-headed alien child that had been manipulating catholic imagery for centuries, and narrowly avoiding an apocalypse-initiating explosion. So, you know, pretty typical stuff.

Building the thing

The stations operate under the idea that somewhere in the world (a notebook, in this case), you have at last one key and a variety of codes. The station reads off numbers that line up with a code, and when the number from the code is subtracted from the number from the station, you get a result that lines up to one of the keys.

In my game, I used four different keys, and had the station call out both the key and page number at the start of each transmission.

To quickly create the various keys, I wrote a bit of javascript that ran in my browser’s console (though you could easily improve on it aesthetically if you wanted):

const createCypher = () => {
  var cypher = [];
  while(cypher.length < 26){
    var c = Math.floor(Math.random()*100);
    if(cypher.indexOf(c) === -1){
      cypher.push(c);
    }
  }
  console.log(cypher);
}

I repeated that function until I had four arrays of 26 numbers, and plopped those into an object. I also made sure to have an array with each letter of the alphabet, like this:

const alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
const cyphers = {
  'man': [4, 56, 82, 11, 0, 35, 85, 73, 14, 98, 80, 32, 43, 57, 21, 88, 78, 45, 19, 83, 66, 97, 89, 72, 12, 86],
  'lion': [62, 11, 40, 58, 78, 49, 21, 94, 87, 77, 96, 95, 7, 6, 27, 34, 83, 26, 5, 33, 72, 70, 91, 8, 42, 98],
  'calf': [97, 48, 86, 10, 53, 54, 65, 69, 80, 58, 23, 38, 71, 55, 24, 88, 79, 82, 12, 64, 34, 57, 8, 42, 41, 77],
  'eagle': [33, 32, 8, 79, 12, 45, 38, 64, 15, 39, 19, 89, 14, 58, 37, 18, 30, 24, 20, 91, 2, 53, 86, 98, 36, 28]
};

The array names correspond with the keys that I wrote into the physical book, they could really be anything (they don’t even have to be named, technically).

Finally, I wrote out each of the passages that I wanted to encode in all-caps strings, assigned a key to each string, and plugged them into this function to create the final ciphers:

const encodeText = (input, cypher) => {
  var cypher = cyphers[cypher];
  var input = input.replace(/[^\w]/g,'').toUpperCase().split('');
  var result = [];
  var code = [];
  var audio = [];
  for(var i = 0; i < input.length; i++){
    var p = alphabet.indexOf(input[i]);
    result.push(cypher[p]);
    var a = Math.floor(Math.random()*125);
    audio.push(a);
    var c = a - cypher[p];
    code.push(c);
  }
  console.log("Audio:",audio);
  console.log("Code:",code);
  console.log("Result:",result);
  console.log("Text:",input);
}

The final result here is that I have the text that goes to our audio, the code that I write into the notebook, the result of audio-code which should match up with the key that I entered, and the text, which is what I put in. I suppose, looking back at it now, I could have had this function double-check my work by subtracting each item in code from the corresponding item in audio, then grabbing the correct letter from alphabet according to the key, but alas. I was in a hurry.

Creating the stations

To create the audio, I dropped the “audio” variable into a TextEdit document, and used Apple’s Automator program to create a folder workflow, which takes incoming text files, and uses the “Text to Speech” feature to get an MP3 of a voice reading the numbers, along with my text stating the key and page number, four times.

I finished it off by dropping these into Audacity along with a downloaded clip of radio noise, and a vaguely creepy version of the Doxology. Well, it was vaguely creepy in context, anyway. You could recreate the voice on a PC by using the Narrator feature, and recording the output directly into Audacity.

I uploaded the files all at once to a page on this site, which you have a link to at the top of the page, and used a bit of CSS to hide the usual Squarespace header and links.

Future adjustments

In the end, I found it was a pretty effective, if labour-intensive, way to help tell the story I was trying to tell. If I were to do it again, I’d definitely use a different music sample (think something along the lines of Stranger Things 3), and I’d have someone do a live read of the numbers, rather than relying on the computer (which I felt read a bit fast).

Using a micro-RPG to "ramp up" new players into D&D

TL;DR: I wrote a simplified version of D&D that evokes the feel of the game, without the nitty-gritty. It’s great for new or hesitant players, gets up and running in five minutes, and is free to download here:

Choosing whether or not to play Dungeons & Dragons in 2018 (soon to be 2019) is an interesting dilemma. Independent games are on the rise across the Internet and local game stores, and offer fresh, exciting, and arguably more “fun” takes on the tabletop role-playing game genre. Meanwhile, despite several attempts to streamline Dungeons & Dragons for new audiences, the game requires books with hundreds of pages, and a minimum investment of $180 USD for a new group to get started. Not to mention the hours on hours of reading, explaining, and re-reading those rules to get started. For many groups, the first session of D&D involves one player walking the rest through character creation for three or four hours, while trying their best to convince them that it will be more fun once they actually start playing. The current creative director of the D&D franchise has even gone on record on Twitter stating that the Dungeon Master (the player who “runs” the game by putting forth obstacles and playing many of the characters in the shared imaginary world) shouldn’t have fun while playing the game.

And yet, we continue to want to play Dungeons & Dragons.

For those of us who played through the days of Satanic Panic (which I was fortunate enough to only see the tail-end of, and is high on my list of “Things to Write About” in 2019), continuing to play D&D might be a show of loyalty. Many, in more ways that one, have earned the right to continue playing the game that has been accused of summoning demons (or worse), and don’t want to let those days go to waste.

It’s also a matter of investment. While packing up to move to the UK, I realized that I had conservatively $800 worth of Dungeons & Dragons material, which now sits in a storage space back in Oregon. This is a low number for a lot of people, too, as I’m not including many of the 3.5e books that were given away (or ruined), and I didn’t buy anything for 4th edition. Lauren and I have collectively spent something like $400 on 5th edition alone, just for the core rules and a selection of campaign reference books. This also doesn’t count the time and emotional investment that goes into preparing for Dungeons & Dragons, especially if you are creating any content (adventures, maps, character races or classes) for yourself. The homebrew community for Dungeons & Dragons represents its own kind of investment in the hobby, and transmogrify it from the game that you read about on the back of the box, into something else entirely. For players who have invested anything above and beyond the norm, be it financial or otherwise, continuing to play D&D reflects a sort of “making good” on those payments.

Lastly, thanks to its years of market domination, media references (like some great episodes of Community), and the recent rise in “actual play” podcast and live streams, Dungeons & Dragons is what new players have actually heard of. Unless they’re already in the role-playing game community in some way, it’s likely that most people will know the Dungeons & Dragons brand, and not much else. For the most part, new players don’t ask, “How do I get into role-playing games?” Instead, they’ll express interest specifically in “learning Dungeons & Dragons”, because so far as they know that’s the only game in the genre. And, to me at least, it feels disingenuous to give them anything else.

The trouble for me is that, when it comes right down to it, I’m not sure that I want to be playing D&D over other games these days. I also worry that new players will be repelled by the text, or the hours of character creation, or the maths that may not come easily to everyone. It’s a big ask to get someone who has never played a TTRPG before to come in and play “real” D&D in their precious free time. At the same time, I don’t want to be the person keeping new players from that experience, if it turns out that is what they want. I also don’t want to disregard the legacy of D&D, and its importance in the larger games space. The real trouble, then, is finding an easy way to bring new players into the world of Dungeons & Dragons that gives them a real idea of what the game is like and do it fast enough that they feel like they’re actually playing a game. If they leave the table not knowing what D&D is, or like they spent the whole time solving some word problem, then I’ve failed them.

In past games, introducing new players to the game has looked like doing the majority of the prep work for them. Lauren and I will typically roll up new character sheets, or print the pre-made sheets from the WOTC website (the existence of which prove the necessity of what I’m talking about), and present the new players with a selection between two or three options, rather than twenty-plus. We then attempt to introduce the rules of the game to the players as we play, so that they don’t have to stress about reading or prep beforehand, and can leap more-or-less directly into the game. While this meets the “actually play the game” criteria, it fails in a couple of important respects:

First, part of the experience of playing Dungeons & Dragons is making your character in a tangible, hands-on way. The mechanics of rolling for stats, selecting race and class, and debating the various pros and cons of equipment choices helps the player build a more concrete understanding of who their character is, and how they operate in the fictional world.

Second, while teaching rules as they come up keeps the paperwork at a minimum, we’ve seen it limit the options that players feel they have at the table. While the rule of thumb given to them is always, “Just say whatever you feel like your character would do,” many players don’t assume that anything is an option, unless a word on their character sheet prompts them. For some classes, such as Paladin or Barbarian, this isn’t an issue, as most everything the character would do is there in the text. For other classes, such as any of the spellcasters, the choices aren’t so clear. When the choices are unclear, often new players will default to inaction.

When friends approached us recently with a desire to learn how to play D&D, the opportunity presented itself to try and resolve these two issues. Once we had figured out schedules, it would be myself as the DM, along with Lauren (who’s been playing for as long as I have), two people who had never played, and a fourth who had played before, but felt that they “weren’t good” at D&D, and were a little hesitant to get back into it.

This became the brief: develop an experience that would show new players what D&D felt like, a player who had less than ideal past experiences that the point isn’t to “be good” at D&D, and still be entertaining and interesting for an experienced player. You can download the finished product here:

While I initially only wanted to create a simplified character sheet, the end result here is a sort of micro-RPG that uses the terminology of D&D, gives off the feel of D&D, but relieves the pain points of getting a new player into the game.

Character creation is done by selecting one “look”, and “training”, which replace race and class. The names give a better idea of what they mean for the character, and each come with a selection of what the character is “great”, “good”, or “bad” at. This gives a new player a one-line synopsis of what they’re getting themselves into with their selection. They also pick two pieces of equipment that are more-or-less exact replicas of their D&D 5e counterparts— they do the same damage and damage types, though we’ve gotten rid of cost or weight, for sake of simplicity. Finally, they select between “Great”, “Good”, “Okay”, or “Bad” for each of the classic D&D attributes (one great, two good, two okay, one bad).

Notice that we’ve completely gotten rid of numbers in our attributes. I’ll be honest, this is 75% because I’m tired of explaining the difference between attribute numbers and modifiers. The other 25% is because this let me right an explanation of what to roll right there on the sheet: if your attribute or skill is “great”, you roll three times, and use the highest result. If it’s “good”, roll twice and use the highest. “Okay”, roll the once and take what you get. Lastly, if it’s “bad”, roll twice and take the lowest.

Those with experience in D&D 5th edition will recognize this as a modified take on the advantage/disadvantage system. What it allows us to do is keep challenge difficulties the same, monster AC the same, and players are given agency in determining how likely they are to accomplish certain actions. I’ve also listed the relevant skills underneath each attribute, which (at least in play-testing) helps alleviate the issue where players don’t know what actions to attempt.

Spellcasting has had a revision since the last test, as initially it had a more PbtA-style fluid vibe. Originally, you could choose what effect you wanted the magic to have, and that would affect the roll’s difficulty. In this version, I’ve created a pared-down spell list, with basic instructions for casting each spell. This further helps give players the “feeling” of playing D&D by bringing in classic spell names, the proper spell terminology (like “saving throws” and “spell slots”), and at least a bit of distinction between different kinds of training.

Finally, the advancement table is listed directly on the character sheet. The rolling system lets us keep all of the same difficulty classes, so we can keep the same XP goals for each level, which helps DMs a bit. Because all of the classes are on the same sheet, the advancement is an approximation of what all classes have in common. At level 3, they may select another training to act as the “specialization” offered by traditional D&D classes, At level 4, they can improve an attribute (maybe someday I’ll feel like writing up a list of feats to choose from instead), and at level 5 they gain an extra attack. While this isn’t 100% accurate for all classes, it provides a close enough representation of what it feels like to advance to level 5. By that point, hopefully the player has a good enough idea of whether they want to play “real D&D” or move on to something else.

So far, this has been pretty successful, especially with new or hesitant players. Character creation is typically done in about five minutes, and we’re able to play fairly intricate one-offs, with the players driving a lot of the action (which is fun for me as a DM). I’ve used monsters straight out of the book with minor editing, and the “feel” of play is very similar to real D&D on both sides of the screen. Up next, the goal is to use these sheets along with official campaign books, editing as little as possible from the text. Something like “Dragon Heist” should play quite well, though if I have players who are into the idea, I may try for “Curse of Strahd” to see how it translates.

Games, HacksTylerD&D
A New Game Appears! "I Wanna Be The Rock!"

Do you ever have a song stuck in your head, or a random assortment of words that you just can’t get out until you’ve written them down? For me, unfortunately, those take the form of tabletop games.

I Wanna Be The Rock!

In “I Wanna Be The Rock!”, you play as alternate-universe versions of Dwayne “The Rock” Johnson, each with their own unique attributes and abilities. From Dwayne “The Flock” Johnson, with the ability to turn into birds, to Dwayne “The Spock” Johnson, a wholly illogical being of brains and brawn.

The free PDF comes with 6 unique Dwayne Johnson cards, and a reference sheet for DMs (Dwayne Masters).

GamesTylerThe Rock
Building a Roguelike in iOS Shortcuts

Diverging off of my last post about using iOS Shortcuts, an app built with the intention of productivity, for purely useless reasons, I’m going to go into detail on another one of my ill-conceived Shortcuts-in-progress: Roguemoji.

Link: https://www.icloud.com/shortcuts/a8b49fe817ed43f4b20b78322b2d8d07

With a bit of elbow grease and repetition, Shortcuts actually allows us to build a fairly plausible roguelike game, complete with random maps and items that we can pick up. No monsters yet, that’s on the way.

How it works

At its core, the roguelike “loop” reads very similarly to the text adventure outlined in the previous post: Find the player’s current position, draw the surroundings accordingly, allow the user to change position, repeat. What it does differently is incorporate graphics into the equation, allowing us to visualize a maze (dungeon,. labyrinth, what-have-you) around the player character, rather than relying on just text. Even though it may be more accurate to tradition to use ASCII characters, the iPhone gives us plenty of emoji to play with, so we’ll use them.

As with the text adventure, we start by defining all of our required variables outside of the main “loop”. Most importantly, we’ll need to know what our Map looks like, what our player’s Position is, and since we’re bringing graphics into this, we’ll define a Camera element, as well. The idea here being that we don’t want to show the entire map at once, and show instead a small part of it, centered around the player.

To define the Map, I recommend using the Text function, and drawing in a map of your liking using the Black Square emoji for walls, and the White Square emoji for walk-able floor tiles. The map should be a rectangle of any width/height you prefer, though I recommend keeping the width to something like 12 or 13 characters, as I found that gave me the best legibility while working in the app. Then, use the Set Variable function to save the Text as a variable that we can call up later.

Note: You’ll notice that in the example provided, I used a variety of different Text functions, and assigned them to a list. This allowed me to pseudo-randomly generate a map, which works well enough most of the time. Procedural map-building is a hallmark of the roguelike genre, but not yet a strength of mine, so this will be something we revisit later on. For the time being, feel free to use a single, static Text command to make your Map.

For example purposes, let’s say that we have a map that is 12 emoji wide, with a good spot for the player to start off in at 3 spaces in, and three lines from the top. Our first bit of the Shortcut should then look something like this:

Text: [Map of emoji blocks here]

Set Variable: Map

Number: 12

Set Variable: Map Width

Number: 3

Set Variable: Player X

Set Variable: Player Y

Notice that we’re using two separate variables for X and Y. Since our emoji map exists in a Text function, we can manipulate it into letting us use the two-dimensional arrays that our text adventure lacked. We’ll come back to that, though. Next, let’s look at the camera.

Because there’s only so much space on the phone screen, we don’t want to show the whole Map all at once. Instead, we want to show the player just a segment of it, centered on the player character. This should have enough information of the player character’s surroundings to be useful, but not so much that it becomes cumbersome or difficult for the program to load. After some experimenting, I settled for showing the player a 5-by-5 square, with the character positioned in the camera’s center as often as possible. To achieve this, we first set the Camera’s beginning X and Y positions by subtracting from the player position:

Number: 3

Set Variable: Player X

Set Variable: Player Y

Calculate: Subtract 3

Set Variable: Camera X

Set Variable: Camera Y

Number: 5

Set Variable: Camera Width

Set Variable: Camera Height

Using this, when the Player is at X,Y {3,3}, for instance, the Camera will be at {0,0}, showing us the first 5 characters of the first 5 rows of the Map. If this doesn’t make sense just yet, keep going, and play around with it later. You could also replace the “3” in the Calculate command with a variable that you can easily change later on, so that you can find a balance that you prefer.

Disclaimer: I’m sure you’ve already noticed something about Shortcuts: it takes a while to do literally anything. It certainly isn’t as efficient as programming this sort of thing in C++, Java, Bash, Python, or whatever. Hell, you could probably do this faster in BASIC if you wanted. Shortcuts does not equal programming. This is just how my brain works: taking something that is clearly intended for being useful, and making dumb games with it. Savvy? Okay, moving on.

The Camera

Now that we’ve done all of our setup for the Player and Camera positions, we have to turn that into something that actually does something, right? We’ll do this by returning to the “Nigh-Infinite Repeat” trick that we used for the text adventure in my previous post, which starts like this:

Number: 99999999999999999999999999999

Repeat: [Number] times

We’ll place that at the bottom of the program, under our setup functions, and put our gameplay “loop” inside. For starters, let’s go ahead and figure out what the Camera sees of the Map. I’ll write out what the functions look like first, then explain it line-for-line after. Feel free to also consult the example I provided for a less-than-perfect reference as you go.

Get Variable: Camera Height

Get Variable: Camera Width

Repeat: [Camera Height] times

Get Variable: Camera Y

Calculate: Add [Repeat Index 2]

Set Variable: Row To Get

Get Variable: Map

Split Text: New Lines

Get Item From List: Item at Index [Row To Get]

Set Variable: Current Row

Repeat: [Camera Width] times

Get Variable: Camera X

Calculate: Add [Repeat Index 3]

Set Variable: Character To Get

Get Variable: Current Row

Split Text: Every Character

Get Item From List: Item at Index [Character To Get]

Set Variable: Current Item

Get Variable: Character To Get

If: Equals [Player X]

Get Variable: Row To Get

If: Equals [Player Y]

Text: [Whatever emoji you want to represent your character]

Set Variable: Current Item

End If

End If

Get Variable: Current Item

Add To Variable: Row To Draw

End Repeat

Get Variable: Row To Draw

Split Text: New Lines

Combine Text: Custom [Leave blank]

Add To Variable: What The Camera Sees

Nothing

Set Variable: Row To Draw

End Repeat

Text: [What The Camera Sees]

Alright, wow! That was a lot. It looks like a lot. It is a lot.

But!

That is the core of what we’re doing here today. Everything else is secondary to this, and it’s not that hard once we break it down. Let’s do that now:

First, we’re going to put two more Repeat functions into our big Repeat function (yo dawg, etc., etc.). This is how we create the “square” of what our camera sees: the first Repeat looks at five rows, starting at Camera Y then adding the Repeat Index 2 each time to move to the next row down. Notice that it’s Repeat Index 2, because Repeat Index would correspond to our “master” repeat, and be no use at all. The second Repeat then takes whatever row we’re looking at, and breaks it up into individual characters. From there, we grab the Camera X value, and add Repeat Index 3 to find the individual character that we’re looking to draw.

If the result of Camera X plus Repeat Index 3 matches Player X, and If Camera Y plus Repeat Index 2 matches Player Y, that’s where the character is! Let’s draw that emoji instead of whatever’s on the map.

Whether we’re drawing the Player character or whatever’s at that place on the map, we’re going to Add To Variable to add it to our “Row To Draw”. If you’re playing around with the Add To Variable function, you’ll see pretty quickly that it adds whatever’s passed to it into a new line in the variable. While this would be fine if our map was one character wide and an infinite number of characters long, it doesn’t suit our two-dimensional look. That’s why, after we’ve gone through all of the steps in the second Repeat function (getting the characters out of the row), we Split Text on the “Row To Draw” variable, then immediately Combine Text. Combine Text allows us to combine a List (which is what Split Text gives us) using a Custom value, which we’re just going to leave blank. That takes our vertical column, and returns it as a horizontal row of the proper characters. We then Add To Variable again, adding this nice horizontal row to “What The Camera Sees”.

Before looping back around and going to the next row, let’s use the Nothing function to set the “Row to Draw” variable back to nil. Otherwise, we’ll just keep adding to that variable, and things will get real weird.

Once we have all of the rows that the Camera sees, we’ll use Text to neatly wrap them all up, and if you’re feeling intrepid, you can use Quick Look to check your work.

A Few Notes Before Braving Forth

So far, we’ve done a handful of things:

  1. Trick Shortcuts into letting us use Text as two-dimensional arrays

  2. Used those arrays to display only a small part of the overall map

  3. Separated our camera from our player

The first two things are essential parts of bringing the roguelike genre to this format; if we showed the player the whole map at once, that would not only ruin some of the surprise element, but also not fit on the most mobile device screens (although the iPhone XS is massive so, like, who knows).

The third thing is a simple one, probably, but one that I’m really proud of. That’s because it’s a fundamental element of making games that are set in the third-person (where you see your player character on the screen): the Camera object and the Player object are two separate entities, and can be moved independently. This means that as the Player character approaches the edges of the map, we can have them move all the way up to that edge, without the Camera trying to show the “great beyond” that doesn’t exist.

As an example of this in our roguelike game, imagine that the player wants to move to a space at Row 1, Column 1 (Shortcuts only uses 1-indexed arrays, so there’s no real 0,0). Using what we’ve set up so far, once the player moves to that space, placing them in the middle of what the Camera is showing would first require pulling two empty rows, then two empty characters, before showing the player. You would be using only about a quarter of the space we set up for our Camera to display on, and risk errors or funky display issues.

Using what we’ve set up now, we can let the Player move all the way to that corner, and simultaneously make sure that the Camera doesn’t go past that point. The player would temporarily move out of the Camera’s center while they explore those edges, but come safely back to center once they turn back and explore the rest of the map. It’s a small thing when you put it into words, but speaks volumes for the quality of the final product.

Okay, coming down off my soap box. Now that we’ve set up the base variables, and our loop for using the camera to the player and the map, let’s set up the interface for actually playing the game.

Actually playing the game

If you’ll remember from our previous Text Adventure example, the main cruft of the game revolved around using the Choose From Menu function in a loop, wherein the choices adjusted the Player’s X and Y positions. Here, we’re going to do roughly the same thing, with some extra If functions to keep our Player and Camera in line, and from going off the map. Let’s start with dropping in the Choose From Menu, which we’ll place after the Text function we used at the end of the last section, and before the End Repeat at the end of the function (we want this to take place within our main loop).

Text: [What The Camera Sees]

Choose From Menu: [What The Camera Sees]

Up

Down

Left

Right

End Menu

Nothing

Set Variable: What The Camera Sees

End Repeat

Pretty basic so far. We display “What The Camera Sees”, then ask the player to choose from the four cardinal directions. If you wanted to get more fancy, you could add more things to the Text function (health, inventory, etc.) and use that in the menu instead, or add diagonal directions for a fun isometric feel. For now, we’ll keep things as simple as we can, probably.

We also pass Nothing back to the “What The Camera Sees” variable, so that we don’t just keep adding to it with each repeat.

Within each of the four options (which you’re welcome to rearrange or rename as you like, I ended up using emoji), we’re going to add If statements to make sure that there’s space that direction, then update the Player and Camera positions as needed. Because these get pretty big, pretty fast, I’ll take a look at each direction separately, then we can look at the Menu as a whole. Let’s start with the easiest one:

Up

Get Variable: Player Y

If: Is Greater Than 1

Calculate: Subtract 1

Set Variable: Player Y

Get Variable: Camera Y

If: Is Greater Than 1

Calculate: Subtract 1

Set Variable: Camera Y

End If

End If

We’ll start with the obvious: If the Player’s Y value is greater than 1 (I keep having to remind myself that Shortcuts uses arrays that start at 1), then we subtract 1 from that value, and assign the result back to Player Y.

If the Player changed positions, we’ll also check to see If the Camera has space to move, as well. We do this in the exact same way: If Camera Y is greater than 1, we subtract one from that value, and return it to Camera Y.

Challenge: We can apply that same basic function to the Left option in our Menu, but trading in Player X and Camera X for Player Y and Camera Y. Give it a shot!

We’ll now tackle the more complex movements:

Down

Get Variable: Map

Count: New Lines

Set Variable: Map Height

Get Variable: Player Y

If: Is Less Than [Map Height]

Calculate: Add 1

Set Variable: Player Y

Get Variable: Camera Y

Calculate: Add [Camera Height]

If: Is Less Than [Map Height]

Get Variable: Camera Y

Calculate: Add 1

Set Variable: Camera Y

End If

End If

At lot of the same notes as the other direction, but with some important additions. First, unlike the “Map Width” variable, we didn’t set a variable for getting the Map’s height, so we use Count to get the number of lines in “Map”, representing the number of rows we have to work with. You could do this right up top with Map Width, I supposed, but calling the action here allows us a degree of dynamism (Is that the right word? Probably not.) and gives us the opportunity to change the height of the Map between actions (secret rooms!).

Second, we grab Camera Y and Calculate where the bottom of the frame is, by adding the “Camera Height” variable that we set a forever ago. This way, we are actually checking to see if the bottom of the camera’s viewport is going to go off the edge of the map, then adjust the Camera Y value if it is not.

Challenge: This same concept can be applied to the Right option in our Menu, using Map With, Player X, and Camera X. Can you figure it out before we put everything together?

Putting Everything Together

By now, we have something resembling the structure of a basic, top-down game, with the potential for roguelike elements. Moving into those specific elements will complicate what we’ve done today, at least in my own brain, so I’m going to compile an overview of what we’ve done here, then go into more depth in my next post. If you have questions or comments, let me know! I’m positive I fucked something up somewhere, so don’t be shy.

If you’ve been following along, here’s likely what you have so far in your Shortcut:

Text: [Map of emoji blocks here]

Set Variable: Map

Number: 12

Set Variable: Map Width

Number: 3

Set Variable: Player X

Set Variable: Player Y

Calculate: Subtract 3

Set Variable: Camera X

Set Variable: Camera Y

Number: 5

Set Variable: Camera Width

Set Variable: Camera Height

Number: 99999999999999999999999999999

Repeat: [Number] times

Get Variable: Camera Height

Get Variable: Camera Width

Repeat: [Camera Height] times

Get Variable: Camera Y

Calculate: Add [Repeat Index 2]

Set Variable: Row To Get

Get Variable: Map

Split Text: New Lines

Get Item From List: Item at Index [Row To Get]

Set Variable: Current Row

Repeat: [Camera Width] times

Get Variable: Camera X

Calculate: Add [Repeat Index 3]

Set Variable: Character To Get

Get Variable: Current Row

Split Text: Every Character

Get Item From List: Item at Index [Character To Get]

Set Variable: Current Item

Get Variable: Character To Get

If: Equals [Player X]

Get Variable: Row To Get

If: Equals [Player Y]

Text: [Whatever emoji you want to represent your character]

Set Variable: Current Item

End If

End If

Get Variable: Current Item

Add To Variable: Row To Draw

End Repeat

Get Variable: Row To Draw

Split Text: New Lines

Combine Text: Custom [Leave blank]

Add To Variable: What The Camera Sees

Nothing

Set Variable: Row To Draw

End Repeat

Text: [What The Camera Sees]

Choose From Menu: [What The Camera Sees]

Up

Get Variable: Player Y

If: Is Greater Than 1

Calculate: Subtract 1

Set Variable: Player Y

Get Variable: Camera Y

If: Is Greater Than 1

Calculate: Subtract 1

Set Variable: Camera Y

End If

End If

Down

Get Variable: Map

Count: New Lines

Set Variable: Map Height

Get Variable: Player Y

If: Is Less Than [Map Height]

Calculate: Add 1

Set Variable: Player Y

Get Variable: Camera Y

Calculate: Add [Camera Height]

If: Is Less Than [Map Height]

Get Variable: Camera Y

Calculate: Add 1

Set Variable: Camera Y

End If

End If

Left

Get Variable: Player X

If: Is Greater Than 1

Calculate: Subtract 1

Set Variable: Player X

Get Variable: Camera X

If: Is Greater Than 1

Calculate: Subtract 1

Set Variable: Camera X

End If

End If

Right

Get Variable: Map Width

Get Variable: Player X

If: Is Less Than [Map Width]

Calculate: Add 1

Set Variable: Player X

Get Variable: Camera X

Calculate: Add [Camera Width]

If: Is Less Than [Map Width]

Get Variable: Camera X

Calculate: Add 1

Set Variable: Camera X

End If

End If

End Menu

Nothing

Set Variable: What The Camera Sees

End Repeat

At the end of it all, we have a map built from emoji, a camera that displays only part of that map, a player character right in the middle, and a way to move them around. That leaves us with a certain set of new challenges!

  1. At the start, I mentioned that I used White Square and Black Square emoji for drawing our map. How do we keep the player character from passing through Black Squares? (I did this in the example, check it out.)

  2. How would we go about creating random maps?

  3. How do we handle item interactions?

  4. Can we add random enemies to the map, with their own discrete movement and actions?

I’ve tried my hand at the first three items, and will be tackling the last one soon. In the next post, we’ll go into detail about some potential ways to make this happen, and try it out ourselves.

GamesTylerShortcuts
Text Adventures in iOS Shortcuts

Like a lot of people, I was aware of Workflow as an iOS app that seemed to be a slightly more robust version of IFTTT, but didn’t see an immediate use for it until iOS 12 was released, and the app was re-branded as Apple’s official Shortcuts app.

Only problem was, by that time, I had very little left in my life that I really cared to automate. Something about being sad and unemployed? I don’t know, it sounds vaguely familiar. Anyway.

For Android users, or at least people who don’t care, Shortcuts is a tool that allows you to use a drag-and-drop programming interface to put a limited amount of functions together. The end result of this being a new app, which harnesses the power of other apps on your phone. This can range from things like, polling the Weather app to see whether you will need an umbrella today, and giving you a push notification letting you know when and where the rain will fall. Or, for the smart-homed, curating intricately-choreographed “scenes” far beyond what the Home app is capable of; perhaps texting your entire home an emoji, and watching as the lights, temperature, entertainment center, and coffee machine all work in unison to fit a certain mood.

You could also, if you’re a true Portlander and are so inclined, use it to brag about how many coffee shops are within walking distance.

Though the new tool, with the ability to run programs that brought apps together using Siri, Home Screen buttons, or even the Widgets panel, was designed for those with a will to capital-O Optimize their everyday life, I saw in it a very different potential.

This started with the discovery of Space Alert, a “crappy text adventure” that takes advantage of the branching “Choose from Menu” function. While it’s a short game all told, it proffered a revelation: While the functions provided within are small, they contain all of the necessary elements of a variety of text and turn-based games. And so I set to work.

What unfolded over the last month has been an exploration, of sorts, into the practicalities of building games within a program that is all but explicitly not decided for making games in. Many of them are still a work-in-progress, but it’s proving to be a deeper well of experimentation than I anticipated. Below are two of the methods that I’ve been exploring, with some detailed reference for trying it out yourself.

If neither of them interest you, I’ve also figured out how to make a roguelike with Shortcuts, but that’s… a much longer post. Stay tuned.


Choose-Your-Own-Adventure

Starting with the example set forth from Space Alert, you can use a combination of the Show Alert and Choose from Menu functions to create a narrative with branching paths. Because of the visual nature of the Shortcuts interface, the results of a choice get “nested” inside the choice in the code, so it may be wise to create “routes” that diverge based on choice, then eventually come back together.

Roughly, that looks like this:

Show Alert: “Hello! Welcome to the game. You are in a room with two doors.”

Choose From Menu: “Do you want to go Left, or Right?”

Left

Show Alert: “You have chosen the left path.”

Right

Show Alert: “You have chosen the right path.”

Show Alert “You win!”

Reading that back, you’ll first see an alert saying “Hello! Welcome to the game. You are in a room with two doors.” You will then be presented a menu, allowing you to choose left or right, resulting in the respective alert shown. Then, regardless of choice, you’ll be shown the alert “You win!”

Of course, this can get more complicated as you go deeper and deeper into the branches. You can place a “Choose From Menu” inside a “Choose From Menu”, for example, or even list the result of a previous choice as an option for a new menu to list. Space Alert does a great example showing this off, so I won’t try to provide my own reference outside of that.


MUD-Style Text Adventure

Example: Simple Text Adventure Framework

One of my earliest and most important memories of playing videogames with my dad involves playing my first “MUD”, or “Multi-User Dungeon". A precursor to MMOs and MMORPGs, a MUD allowed a bunch of users to connect to the same server, and play a simple text adventure game together. Typically, this would follow a stereotypical ZORK-like pattern: “You are in a very dark room. You are likely to be eaten by a grue. Exits are NORTH, SOUTH, and WEST.”

You would then have to type commands like, “go NORTH”, or, “attack GRUE” and see how the world responded.

The reason this particular memory stuck with me, however, is that the game we played took place over a large expanse of “rooms” with various descriptions. Sprawling mansions, open marketplaces, creepy dungeons, all of which rendered only in text, without a map to keep them all organized. If you wanted to remember which way you’d turned previously, so that you can make your way back out of the labyrinth before the minotaur catches you, you had better keep track of that somehow. So, we would spend hours together, drawing out each action and movement onto a large sheet (and quickly several large sheets) of graph paper. The game, just a virtual fantasy, soon had a weighty physical counterpart, that we had built ourselves.

In Shortcuts, it’s possible to recreate this same sort of game on a smaller scale by replicating the core conceit of the text adventure above, but adding a few more functions from the Shortcuts arsenal, namely List, Variables, Calculate, and Repeat. All very simple ideas unto themselves, but can be combined powerfully.

Let’s start with how we want the game to look, and work backwards from there. I would like to have the game described to me a fictional room that I’m in, and provide a list of directions, which I can then use to move to the next room, which will then be described to me, and so on…

This is the core “loop” of the game, and since Shortcuts applications are only designed to be run all the way through once, this is achieved through the Repeat function. As of yet, there isn’t a “repeat infinitely” option, however we can set a Repeat of something like 1,000,000,000,000 times, which is basically the same thing. Inside that “loop”, we will do four things:

  1. Calculate what room the player is in

  2. Show that room’s description

  3. Allow the player to choose from a list of available exits

  4. Update the player’s position accordingly

If, like me, you’re prone to draw out maps on graph paper, you’re probably used to thinking about locations and positions in terms of X and Y coordinates. Picturing the top-left corner of the page as the origin, subtracting from a player’s Y value moves them “up” the page, whereas adding to it moves them “down”. Same for the X value with left and right. Once you have the X and Y position of the player, all you have to do is return the room that matches that value, and you’re off to the races.

Well, almost.

Shortcuts, not being an app that’s designed for such purposes, doesn’t allow us an easy method for creating two-dimensional arrays, which is what we typically want for X/Y coordinates. So, we have to get creative (“yaaaaaay,” I hear you saying).

What we’re going to do instead, is take advantage of the List function: a one-dimensional array that we can trick into becoming a two-dimensional array.

To do this, let’s take a look at the total amount of space you’re looking to create. How many rooms wide and how many rooms tall will it be? For the purposes of example, I stuck with three rooms wide, and three rooms high, for a total of nine spaces altogether in our “map”. We then specify the Map Width and Map Height as variables, like this:

Number: 3

Set Variable: Map Width

Set Variable: Map Height

Note that we only have to set the Number once here, as the Set Variable function passes its input on to the next action. If we wanted the height to be different from the width, we would place another Number in-between the two Set Variable commands.

With those numbers in mind, we’ll now create a List of our rooms, with the idea that we will be listing 9 rooms, in imaginary rows of 3. You could conceivably picture them as columns of 3, as well, but I prefer rows, so there. In my example, the list looks roughly like this:

List: “Northwest Room”

“North Center Room”

“Northeast Room”

“West Room”

“Center Room”

“East Room”

“Southwest Room”

“South Center Room”

“Southeast Room”

Set Variable: Room Title

Using the three-by-three layout works well enough for these purposes, but remember that you can adjust this to fit any width or height that you need. You can then use the Set Variable command to save this list for easy use later.

If you want to get more detailed, as I did in the example Shortcut provided above, you can create multiple lists that all correspond to the same rooms. For example, you could have a list of Room Titles, another list of Room Descriptions, and another list of Room Items, just making sure that the order of each list lines up with the order of the others. To determine what item in our lists to return, we will use not X and Y, but the player’s “Position”, a gestalt of the two dimensions.

“Position” will represent the player’s current spot in our many lists, and moving the position up or down will affect what room is display. This is where knowing the width of your map ahead of time is important, because that allows us to fool the list into thinking that it has more dimensions than it really does. To move the player to the right or left, we simply add or subtract 1 from the player position as needed. To move the player “up”, or “down”, we will add or subtract the Map Width variable. This will have the effect of simulating vertical movement in our imaginary map.

In the example we’ve laid out so far, let’s say that we set the Player Position to 5, like so:

Number: 5

Set Variable: Player Position

We can use that number to then return the information that we have about the room at that position, using the Get Item From List function, like this:

Get Variable: Room Title

Get Item From List: Item at Index: Player Position

Show Alert: Get Item From List

When you create the Show Alert, you can use the Select Magic Variable option to pull the result of the Get Item From List directly, rather than having to set/get more variables. When this is all run together, we’ll see an alert telling us that we are currently in the “Center Room”.

With our map and our initial positions set, we must now find a way to move around, which we’ll accomplish by returning to our old friend Choose From Menu. First, we’ll create a menu giving us four options, which we’ll name “North”, “South”, “East”, and “West”, to keep with tradition. Inside each option, we will get, adjust, and set the “Player Position” accordingly:

Choose From Menu: “What direction would you like to go?”

North

Get Variable: Player Position

Calculate: Subtract “Map Width”

South

Get Variable: Player Position

Calculate: Add “Map Width”

East

Get Variable: Player Position

Calculate: Add 1

West

Get Variable: Player Position

Calculate: Subtract 1

End Menu

Set Variable: Player Position

Note that while we Get Variable in each option, to ensure that we really are dealing with the Player Position, we only Set Variable once at the end. Since the Choose From Menu function passes any result to the next action, we can rely on the correct calculation being applied to our variable in the end. If you’re a fan of redundancy, though, feel free to add Set Variable to the end of each choice (like I did in the example I linked above).

With the Player Position updated, we will now loop back around to the beginning of this diatribe, get the correct room from the list, display it, and start all over. In the briefest possible outline, here is how all of that looks within your Shortcuts program:

List: “Northwest Room”

“North Center Room”

“Northeast Room”

“West Room”

“Center Room”

“East Room”

“Southwest Room”

“South Center Room”

“Southeast Room”

Set Variable: Room Title

Number: 5

Set Variable: Player Position

Repeat: 9999999999999999 times

Get Variable: Room Title

Get Item From List: Item at Index: Player Position

Show Alert: Get Item From List

Choose From Menu: “What direction would you like to go?”

North

Get Variable: Player Position

Calculate: Subtract “Map Width”

South

Get Variable: Player Position

Calculate: Add “Map Width”

East

Get Variable: Player Position

Calculate: Add 1

West

Get Variable: Player Position

Calculate: Subtract 1

End Menu

Set Variable: Player Position

End Repeat

And that, as they say, is that. Every time you select a direction, the loop will reset, grab the new Player Position, and return the relevant room.

Now, obviously, that isn’t the whole story, but you’ve read enough! There are a number of remaining questions that I’ve attempted to answer in the example I linked to at the start of this, and invite you to try and answer in your own version of this:

  1. How do you keep the player from moving out of bounds?

  2. Can you make the limited number of Repeats interesting?

  3. Can you update the exits dynamically, forcing the player into corridors and such?

  4. Can you add elements of interactivity, such as items, puzzles, or enemies?

  5. Can you add graphics?

Happy hunting, my friends. As always, if you have questions or comments about any of this, please reach out! The amount of research being done into this avenue of using Shortcuts seems relatively limited, so I’m curious to hear what thoughts are out there.

Like I said at the start, I’ve also been working on a roguelike game, following similar principles to those outlined above, just… much more complex. I’ll work up a new post about that soon.

GamesTylerShortcuts
That Which Is Known

I enjoy the physical act of writing-- sitting seriously in a coffee shop somewhere, putting my headphones in, typing away at nothing in particular. Looking into the middle distance for long periods of time, accomplishing nothing. You know the kind. 

That said, what I've run into a lot lately is that I often lack (or think that I lack) the things to actually write about. While the flesh is willing, the spirit is weak, as they say. This listlessness quickly turns into mindless googling, and before I know it I've spent all my dedicated writing time reading about the history of a particular Bulgarian thatching method on Wikipedia. 

To try and stave off this feeling, I made a game called "That Which Is Known", which you can read more about here:

GamesTylergames, pdf, rules
Storytelling game for Teenagers With Attitude!

A few weeks back, I wrote into one of my favorite podcasts, Teenagers With Attitude. It's a wonderful weekly Power Rangers recap podcast, which some people may recognize as one of the inspirations for You Activated My Podcast!. I wrote in because I'd finally made good on a promise that I thought I had made a year ago-- turns out, I'd written to them nearly two years ago to the day, commenting on the announcement of Rita Repulsa's wardrobe for the then-upcoming Power Rangers reboot movie. At the end of my email way back when, I'd mentioned that I was working up a since-abandoned role-playing game called "SPEEDPUNKS", based on a since-abandoned inside joke in the show. 

"SPEEDPUNKS", which was going to be a Rangers-inspired mess of kicking and driving and monsters and rolling far more dice than can be held in two hands, was put on hold after a time as the Power Rangers Hyperforce RPG and Hyper RPG Twitch streams were announced last year. It didn't seem to me that there was really a need for two Power Rangers role-playing games to exist in the world at one time.

Then about a month ago I was going through some old files, and realized that that was fucking bullshit, and I could do whatever I wanted. And I'll be damned if these weird folks didn't deserve a game that represented their (in their words) unique brand of bullshit. So I made one, and sent it to them, and I'm really proud of it. 

The game is aptly titled "Teenagers With Attitude", and it's a pseudo-role-playing, story-telling game for 3-6 players, in which you collaboratively create and tell a new episode of Power Rangers. You can listen to the podcast episode where they talk about it here, and download the 3-page PDF of the rules here. While it does help to be a fan of the podcast before playing the game, it should be fun even if you're just a fan of Mighty Morphin'. 

I hope you enjoy! Please go listen to the podcast, and may the Power protect you, always. 

THE REBEL FLEET & Dice-less Mechanics

Been considering lately how little I enjoy d20 mechanics when it comes to large-scale encounters. While rolling a d20 and adding Dexterity is a decent fit for getting your dwarven fighter across a pit trap set deep into the mine, it rings somewhat hollow when applied to commanding legions across the field of battle. 

In a Star Wars game, for example: while it is exciting to roll dice and follow standard mechanics from the perspective of a single fighter pilot, it is somewhat less exciting to play the role of a general using the same mechanics. 

As an alternative, consider the following:


The Rebel Fleet

A game for 3+ players. Requires a long hallway or open space, and a stack of standard letter-sized paper.

One player takes the role of the Narrator. The other players are ace pilots in The Rebel Fleet. The Rebel Fleet can be any aerial force– be it World War II, outer space, or an alternate universe where lizardfolk ride tamed pteradons.

To create your vehicles (effectively your characters), each player should use one piece of paper to make a paper airplane. There are no rules for the shape that this plane must take, only that it must consist of a single piece of paper (8.5" x 11" if you’re American, A4 if otherwise). As an optional benefit, you can use a staple or paperclip to weigh down the nose of your craft.

The Narrator sets the scene. First, they should make one paper airplane for each major aircraft in the enemy fleet. For small squads, make one plane to represent a group of 5 or 10 (so you don’t waste all that paper). While making their planes, the Narrator describes the powerful regime that has ruined everything, which the Rebel Fleet is fighting against. Describe the battle that is taking place, and the broad strokes of the rebel fleet’s goals. Then, they ask what the players would like to do to achieve that goal.

Depending on how the players respond, the Narrator can engage the players in a series of challenges, using any and all relevant paper planes. These challenges can take place in two forms, or a combination/derivation of the two:

Race: The players and Narrator all stand on the same side of the space, and at the same time throw their planes in the same direction. The plane that makes it the farthest is the victor. This is used to represent outmaneuvering other planes, making it to destinations quickly, or rapidly closing on a target.

Battle: The players stand on the opposite side of the space from the Narrator, and then simultaneously the two sides throw their planes at each other. Make note of the planes that collide. If a plane crashes its nose into an enemy ship, it deals damage to it. Most enemy ships can only withstand one damage, while named ships (the players, or important enemies) can withstand five. Repeat until all named enemy ships are defeated, or until the players are defeated, or until the players opt to try a different approach.

At the end of each challenge, take a moment to discuss as a group how that maneuver took place, and describe how it moves the battle along. Continue until the players have achieved the goal stated at the beginning of the game.

 

GamesTyler Robertson