Using symbols in strings to separate words

And now we get to one of the most universally useful techniques useable with strings, using symbols to separate words! This concept is best explained visually, but basically in other words, we use uncommonly used characters (such as @, !, ^, &, *, (, ), - and =) in order to define sections, ranges and delimiters within a string. (Delimiters are any symbols used to contain portions of text, i.e. with Jake, Jeff, Joe, the delimiters are commas).

We have mentioned already that strings can be used to mimic arrays in a sense. In our array tutorial, our implementation took a disorganized set of data and made it organized to do our bidding! Muahaha! Since strings can also do this, in the following tutorial you'll get to see how to not only group disorganized data together, but give it attributes, too.

Tutorial 7: Colorful clothing shop

Let’s say that while we’re making an RPG Dream, we have come to realize that our world is missing a shop. Oh no! We also can’t spare any more arrays or PhoenixSpeak data because not only are we cheap, we are conserving the memory for the player stats! What do we do?

By mimicking how arrays organize data, we can make our own shop! Instead of using arrays, though, we'll use strings to group the data we need, and also give it attributes that we need for selling stuff, such as the item number that represents what we're selling, the name of the item, and then the cost!

So, we'll start by taking a look at the items on hand, what we’d like to call them, and the intended price of each item:

  • Item 2486 - Black Beret, intended cost is $10
  • Item 2876 - Ruby Slippers, intended cost is $300
  • Item 1005 - Blue Apron, intended cost is $50
  • Item 2737 - Silk Heart Boxers, intended cost is $30
  • Item 345 - Yellow Jacket, intended cost is $100
  • Item 463 - Pink Hair Ribbon, intended cost is $1000

Tip: As you can see from that list alone, it is important to take the time to organize your data effectively before jumping straight into string DS, as it can get complicated without proper planning!

We also need to give the Dream a way to detect what a shop is, so for this example, we'll use Floor 500. Now we'll plan out a general idea of how the shop will work:

  • A customer moves on to a shop tile, Floor 500.
  • DS checks which item is in the position they have moved into, then sets the item number to a variable.
  • DS makes a copy of the inventory to another string so it can be freely manipulated without overwriting the base string.
    • Alternatively, the customer can say ‘buy’ and the DS will do almost the same thing, just with a few extra steps.
  • Item name and price is emitted to the customer.
  • If the customer says ‘buy’, and has the cash, the item will be placed in their hands, and money will be deducted.

So now that we've planned how to implement the system, we can begin defining our string! Let’s set up our shop’s inventory string when the Dream starts up, using the string labeled ~stock:

(0:0) When everything is starting up,

(5:250) set message ~stock to { (2486)Black Beret[10](2876)Ruby Slippers[300](1005)Blue Apron[50](2737)Silk Heart Boxers[30](345)Yellow Jacket[100](463)Pink Hair Ribbon[1000] }.

This may look intimidating at first, but let's break it down by looking at just one item in the ~stock list. We'll start with (2486)Black Beret[10]:

  • First we have the item number in parenthesis, which is (2486). This is the item number as listed in Dream Editor, and we have given it ( and ) as delimiters.
  • Next we have the name of the item, Black Beret, sandwiched between ) and [. We will use those symbols as delimiters for the name of any item up for sale.
  • Finally, we have the price of the item 10 using [ and ] as the delimiters.

Tip: You may also have noticed that the first and last character of the full ~stock string are empty spaces. Usually string manipulation at this level tends to work better with those characters being present.

With the string set up, and the first part of the explanation out of the way, let's move on to the bulk of the string processing DS. We'll put the full set of triggers at the bottom of the tutorial for your reference. Here's just the first part:

(0:2) When someone moves into floor 500,

(5:251) copy message ~stock onto message ~shop.

(5:351) set variable %buy_position to the X,Y position the triggering furre moved to.

(5:381) set variable %item_selected to the item type at (%buy_position).

(5:283) set variable %dname_get to the total number of characters before {(%item_selected)} appears in message ~shop (or zero if not found).

So this is what happens first when the customer moves into shop floor:

  • A copy of the string ~stock (which stores the data for our shop items) is written to the string labeled ~shop. This is necessary because we’ll be tearing the string apart in the process of extracting data. We won’t want to mess up the original!
  • Variable %buy_position is set to the location the customer is moved to, which sets up the function for the next line..
    • Where the variable %item_selected is set to the item the customer moved into.

For the purpose of this tutorial, we'll assume that the player moved into item 2737 on floor 500. We will also illustrate what string ~shop contains after each modification to it. Shop currently contains these contents:

{ (2486)Black Beret[10](2876)Ruby Slippers[300](1005)Blue Apron[50](2737)Silk Heart Boxers[30](345)Yellow Jacket[100](463)Pink Hair Ribbon[1000] }

Next, this would appear below the previous DS:

(5:274) chop off the beginning of message ~shop, removing the first %dname_get characters of it.

(5:278) remove the first 1 copies of {(%item_selected)} from message ~shop.

In this section:

  • Variable %dname_get is set to the amount of characters before (%item_selected)/(2737) is found in string ~shop.
  • Those characters are then chopped off from string ~shop.

The sole purpose of variable %dname_get is to slice the string up into little pieces to extract data. Think of it as a box cutter with an adjustable blade length. After that last operation, our string should contain only these contents:

{(2737)Silk Heart Boxers[30](345)Yellow Jacket[100](463)Pink Hair Ribbon[1000] }

Notice how (2737) is now the first entry of this string, and everything before it is gone? This was the desired effect.

Now that our item number is at the front of the list, we can move on to the next line that would appear below the previous DS:

(5:283) set variable %dname_get to the total number of characters before {[} appears in message ~shop (or zero if not found).

  • This line deletes (%item_selected)/(2737) from string ~shop. This makes it easier to extract the name of the item.

String ~shop now contains:

{Silk Heart Boxers[30](345)Yellow Jacket[100](463)Pink Hair Ribbon[1000] }

We are at the home stretch now! On to the next three lines:

(5:272) set message ~providename to be the portion of message ~shop from position 0 to position %dname_get.

(5:282) set variable %item_price to the first number in ~shop.

(5:200) emit message {Item <b>~providename</b> costs %item_price dollars!} to the triggering furre.

  • The next line reuses variable %dname_get to count the number of characters before [ appears in our modified ~shop message.
  • We then introduce a new string labelled ~providename to do just that. It copies the characters from the very start of string ~shop to the last character before [ is bumped into using variable %dname_get as a measuring tape.
  • Since none of our item names contain any numbers, we can use the last line to scan for the first number in string ~shop in order to get the price of the item. In this case, the value is 30. We set that to %item_price.

At this point, string ~shop was unchanged, but string ~providename now contains {Silk Heart Boxers} and variable %item_price is now equalled to 30. The last thing to do here is emit the name and price of the item the player is browsing!

Here's the full set of triggers all together, although there is also a separate set of triggers to the second part meant to handle buy processing:

(0:0) When everything is starting up,

(5:250) set message ~stock to { (2486)Black Beret[10](2876)Ruby Slippers[300](1005)Blue Apron[50](2737)Silk Heart Boxers[30](345)Yellow Jacket[100](463)Pink Hair Ribbon[1000] }.

(0:31) When someone says {Buy},

(1:17) and they (moved from/is standing at) floor 500,

*OR*

(0:2) When someone moves into floor 500,

(5:251) copy message ~stock onto message ~shop.

(5:351) set variable %buy_position to the X,Y position the triggering furre moved to.

(5:381) set variable %item_selected to the item type at (%buy_position).

(5:283) set variable %dname_get to the total number of characters before {(%item_selected)} appears in message ~shop (or zero if not found).

(5:274) chop off the beginning of message ~shop, removing the first %dname_get characters of it.

(5:278) remove the first 1 copies of {(%item_selected)} from message ~shop.

(5:283) set variable %dname_get to the total number of characters before {[} appears in message ~shop (or zero if not found).

(5:272) set message ~providename to be the portion of message ~shop from position 0 to position %dname_get.

(5:282) set variable %item_price to the first number in ~shop.

(0:2) When someone moves into floor 500,

(5:200) emit message {Item ~providename costs %item_price dollars!} to the triggering furre.

Now that the complicated bits are out of the way, let’s add in the Buy command:

(0:31) When someone says {buy},

(1:17) and they (moved from/is standing at) floor 500,

(1:1004) and they are not holding item 0 in paws,

(5:200) emit message {You're currently holding something, please empty your paws first.} to the triggering player.

*Buy no money

(0:31) When someone says {Buy},

(1:17) and they (moved from/is standing at) floor 500,

(1:1002) and they are holding item 0 in their paws,

(1:603) and the PhoenixSpeak info {Money} about the triggering furre is less than %item_price,

(5:200) emit message {You do not have enough cash to buy the <b>~providename</b>.} to the triggering furre.

*Buy with money

(0:31) When someone says {Buy},

(1:17) and they (moved from/is standing at) floor 500,

(1:1002) and they are holding item 0 in their paws,

(1:602) and the PhoenixSpeak info {Money} about the triggering furre is more than %item_price,

*or*

(0:31) When someone says {Buy},

(1:17) and they (moved from/is standing at) floor 500,

(1:1002) and they are holding item 0 in their paws,

(1:600) and the PhoenixSpeak info {Money} about the triggering player is equal to %item_price,

(5:610) remember the PhoenixSpeak info {Money} about the triggering furre, and put it in variable %money.

(5:304) take variable %money and subtract %item_price from it.

(5:600) memorize that the PhoenixSpeak info {Money} about the triggering furre will now be %money.

(5:200) emit message {You bought the <b>~providename</b>! You now have %money dollars.} to the triggering furre.

(5:76) place item %item_selected in the triggering furre's paws.

Account E-Mail

Password