Image

2
Herding Cats: Your First PuzzleScript Game

In this chapter, we’ll make our own PuzzleScript game. Specifically, it will be a game about herding cats. (You can never have too many games about cats. Remember that when you’re a famous game designer.) You can play it at https://w.itch.io/herding-cats/. After you’ve played the game, we’ll go over how to make it!

Image

In Herding Cats, your goal is to make friends with all the different cats in each level. Press X on your keyboard to start, and then use the arrow keys on your keyboard to move around. You can use the Z key to rewind time if you make a mistake and want to redo your moves. Press R to restart the level you’re on. (Most PuzzleScript games use the same keys to play a game.)

At the start of each level, all the cats will be sleeping. When you wake up a cat, it’ll start following you. A woken cat will follow you everywhere, but it can make it hard to fit through some spots.

The game can get tricky. You don’t have to solve every level to read the rest of the chapter! Just get a feel for how the game works.

Opening a Blank Project

Let’s start with a blank game. Navigate to https://www.puzzlescript.net/ and click Make A Game. Clear your PuzzleScript work area by clicking the Load Example drop-down menu at the top of PuzzleScript and selecting Blank Project.

Image

You should see a totally blank PuzzleScript project like this.

Image

Next, you’ll add a game title and your name at the top of the script, above OBJECTS. Click at the start of the very first line and press ENTER three times to move the OBJECTS section down to make room, and then add these lines:

title Herding Cats!
author anna anthropy
homepage www.puzzlescript.net

The result should look something like this.

Image

If you make a mistake and need to undo it, hold down the CTRL key and press Z. CTRL-Z is almost universally the undo shortcut in the tools you’ll work with.

Now let’s look at how to create objects.

Creating Objects

Every object in your game has to look like something. An object’s appearance gives the player important information about what it does. For example, in the Simple Block Pushing Game, all the pushable objects look like boxes with flat, easy-to-push sides. The player has arms, showing that they can push objects.

PuzzleScript lets you use pixels to draw objects. A pixel (a combination of the words picture element) is just a single dot of color. PuzzleScript objects are 5 pixels wide by 5 pixels tall—25 pixels in total. For example, here’s a door I drew.

Door
Brown White Blue
11111
10001
10001
10021
10001

The pictures you draw are made up of numbers; each number represents a single pixel. Which number the pixel is corresponds to the color you want the pixel to be.

From top to bottom, you see the name of the object on the first line (Door), the colors I want on the second line, and then numbers for the 25 pixels below that. Because I want a brown door with a white frame and a blue doorknob, I enter those colors on the second line as Brown White Blue. These words should display in their colors as you type them.

Next, I use the numbers representing each color to enter where the colors go, one pixel at a time. Computers start counting at 0, so the first color I enter, Brown, is color 0, White is color 1, and Blue is color 2. The numbers representing each color will also display in those colors, so you can imagine what your rendered drawing will look like as you enter the colors. (Keep in mind that in this Door example, if you try to enter a number higher than 2, such as 3 or 4, the number will display as white because you’ve defined the colors using only the numbers 0, 1, and 2.)

NOTE: If you have a hard time remembering that computers start counting at 0, think of a bunch of people standing in line for the bathroom. If I’m at the front of the line, how many people are in front of me? Zero! If I’m right behind the person at the front of the line, how many people are in front of me? One! The next person is 2, the next is 3, and the next is 4. Five people in line would be numbered 0, 1, 2, 3, and 4.

Herding Cats needs some objects, so let’s draw them now!

Drawing the Background

To draw objects in Herding Cats, we first need a Background. Every PuzzleScript game must have a background. Let’s draw one that looks like grass at the beginning of the OBJECTS section:

========
OBJECTS
========
Background
DarkGreen Green
01000
10010
00100
01001
00010

The zeros are dark green and the ones are regular green. I’ve scattered them around like little blades of grass because I’m trying to create an image that, when repeated, will just create a big field strewn here and there with grass.

Remember that with this code we’re drawing just one square of grass that is five pixels wide by five pixels tall. But we’ll never see just one square of grass in the game; instead, we’ll see a bunch of these background squares, like this.

Image

Now we’ll add some walls in the OBJECTS section.

Drawing Walls

To draw the walls with a stacked brick pattern and make them look more like brick walls, use Red for the bricks and DarkBrown for the mortar between them. Then fill out the pixels so the brown mortar crisscrosses the red bricks:

Wall
Red DarkBrown
01000
01000
11111
00010
11111

Mine has four bricks, but you can make your wall look however you want. When there are a bunch of these chunks onscreen, it’ll look like one big, continuous brick wall.

Before we can see what our walls actually look like in the game, we need to add a few more requirements to the LEGEND section.

Adding the Background and Wall to the Legend

Any object we want to appear at the start of a level needs to have a symbol in the LEGEND section. For now, add a symbol for the background and the walls:

=======
LEGEND
=======
. = Background
# = Wall

I chose the . as the symbol for background tiles because it has a lot of empty space around it. Conversely, I picked the # to represent walls because it’s dense, square, and wall-like. Try to choose symbols that remind you of the objects they represent so you can tell at a glance what a level looks like.

Creating the Collision Layers

Whenever we add an object to our game, we have to remember to add it to the COLLISIONLAYERS section as well! Let’s add our wall object like this:

================
COLLISIONLAYERS
================
Background
Wall

Each line in the COLLISIONLAYERS section represents a separate layer. The Background gets its own layer. Everything else—the walls, the player, and the cats—will be on a second collision layer. If walls and cats weren’t on the same layer, cats could walk through walls. That would be impressive, even for a cat.

Image

Creating a Sample Level

Now that we’ve added the wall to the LEGEND and the COLLISIONLAYERS sections, let’s make a sample level in the LEVELS section just to see what our Background and Wall objects look like. Use the symbols for the background and wall to create a level:

=======
LEVELS
=======
###....
#.#.###
#.###.#
#.....#
##..###
.####..

Click Run and then press the X on your keyboard to see the level we just drew. I made my wall very squiggly so I can really get an idea of how my walls look in use.

Image

Now that you can see what your background and walls look like, you might want to change them. When you make changes to any object’s appearance and then click Rebuild, your sample level will update to show the new look. This is a great way to keep track of what your objects look like as you work on them.

Drawing the Player

Now we need a player character. In the OBJECTS section, I drew a player with pink hair, a white dress, and two little hands. (That’s what I was trying to draw, anyway.) You can make your player look the way you want by choosing colors and filling pixels with those colors. But notice the gray periods (.) in the drawing.

Player
Brown Pink White
.111.
.0011
.0011
.222.
02220

When you’re drawing objects in PuzzleScript, a period (.) in the code means that a pixel is transparent. Where there’s a period, you’ll see through that part of the object to whatever is behind it (which is usually the background).

We don’t need to have see-through pixels on the background, because there’s nothing behind it. Also, we don’t really need to see through the walls because the walls can be square. But the player isn’t square, so we fill in the unused parts of their picture with see-through pixels.

Image

Whenever something moves around (like the player), it’s a good idea to give it a see-through background so we can tell what it’s moving around on. Earlier I mentioned trying to show what objects can do by using their appearance. For example, a player standing on top of the grass looks like it can move, whereas the rigid, square walls that don’t share any space with the background look fixed in place.

Drawing Cats

Last and most important, we need to add our cats. Let’s think about the cats in Herding Cats. What do they do? Well, when they’re awake, they follow the player around, but when they’re asleep, they just sleep until someone wakes them up. To make Herding Cats work the way we want it to, we need two different kinds of cats: one that stays in place, which we’ll call SleepingCat, and another that follows the player, which we’ll call AwakeCat.

Image

We’ll start by drawing two different objects in the OBJECTS section to create the two basic types of cats.

SleepingCat
Black Yellow
.....
0.0..
101..
00000
.0000
AwakeCat
Black Yellow
0.0..
101.0
00000
.0000
.0..0

The sleeping cat is lying down. As with most sleeping cats, you can’t see its legs because they’re tucked underneath. This cat looks stationary. But the awake cat is standing up, ready to follow the player.

Image

Click Save at the top of the screen to save your work so far. It’s a good idea to save often in case you accidentally close the window, your computer crashes, or your cat jumps on your keyboard. (If you’ve saved your game, you can click the Load menu next to the Save button to load the saved version of your game.)

This would be a good time to take another break, pet another cat, or make another sandwich. See you in a minute!

Using Your Objects

Before we can use our new objects, we need to tell PuzzleScript what to do with them by adding them to the LEGEND and COLLISIONLAYERS sections of our code. Go to the legend and pick a symbol for the player and the sleeping cat objects, as shown here:

. = Background
# = Wall
P = Player
m = SleepingCat

Image

There’s no symbol for the AwakeCat object because the legend gives PuzzleScript a list of all the objects we want to build our levels from. I picked m for the SleepingCat because it looks like a little cat sitting down with its legs tucked under. (Cute, right?) Because all the levels start with all the cats asleep, we have only sleeping cats at the beginning of a level. The awake cats appear only when a sleeping cat awakens!

Adding More Collision Layers

We’ll need only two collision layers for our objects: the Background and everything else. Add the following lines to the COLLISIONLAYERS section. Next, we’ll want to add the player and both kinds of cats to the COLLISIONLAYERS section.

Background
Player, SleepingCat, AwakeCat, Wall

The background is on its own layer, and everything else moves around on top of it. The player, sleeping cat, awake cat, and wall are on the same layer so they can bump into each other and get in each other’s way. Otherwise, they wouldn’t be able to bump into each other. Walls aren’t really walls if you can walk right through them.

Next, we need to update our test level. But before we do, save your work!

Creating a Test Level

Let’s create a test level to make sure everything in our game works the way we expect it to. Enter something similar to the following code in the LEVELS section, making sure the level contains every object in the legend: Wall (#), SleepingCat (m), one Player (p), and Background spaces (.). Be sure to add a wall somewhere in the middle, too, not just around the edges!

=======
LEVELS
=======
#######
#..#..#
#.m#m.#
#..#..#
#.....#
#..p..#
#######

Click Save and then click Run. You should see the game’s title screen appear in the window at the right side of the screen, as shown here.

Image

Now press X on your keyboard to start the game. You should see the test level that you created.

Image

Cool! Now test your level by moving the player with the arrow keys. The player should move but not through walls or cats. Make sure that all objects are working correctly. The cats will just sit there because we haven’t added rules to tell them what to do yet.

Creating Rules for Cats

Now we’ll add a rule that states when a Player object touches a SleepingCat object, the sleeping cat should wake up and become an AwakeCat object. Add this rule to the RULES section of your code:

======
RULES
======
[ Player | SleepingCat ] -> [ Player | AwakeCat ]

This rule means if the Player is next to a SleepingCat, change them to a Player next to an AwakeCat. Click Rebuild at the top of the PuzzleScript screen to make PuzzleScript add everything you changed to the game you’re already playing. Then try to move the player next to the cats to see if they wake up.

The cats should wake up, but they’re a little late in doing so: instead of waking up when you touch them, they wake up on the next move. To see what I mean, walk up to a cat and then walk away from it. The cat wakes up after the next move the player makes, not right when the player walks up to it. We want the cats to perk up as soon as they see the player! What’s the deal, cats?

To understand the issue with the game play so far, think about how rules work:

  1. The player decides in which direction to move.
  2. PuzzleScript checks all the rules and makes any changes the rules tell it to.
  3. Everything that wants to move finally moves.

You press an arrow key to move the player next to a cat, and the player becomes a moving > Player. Next, PuzzleScript checks the rules to see whether the player is next to any cats. Because they’re not next to any cats yet, the cats stay asleep and the > Player finally moves. Then PuzzleScript waits for the next arrow keypress, and the cat remains asleep! When you press an arrow key again, the player becomes a > Player again, and PuzzleScript checks the rules again. This time it sees that the player is next to a cat, so the cat becomes an awake cat, and the player moves away.

To fix this hiccup in the game play, we add the keyword late to the rule so it will check whether the player is next to a cat right after the player moves instead of right before the player’s next move. The new rule looks like this:

late [ Player | SleepingCat ] -> [ Player | AwakeCat ]

Adding late to the start of a rule tells PuzzleScript to check the rule after objects have moved instead of before. Essentially, we’ve added another step to the way PuzzleScript processes our rule, so this happens:

  1. The player decides in which direction to move.
  2. PuzzleScript checks all the rules and makes any changes the rules tell it to.
  3. Everything that wants to move finally moves.
  4. PuzzleScript checks all the late rules and makes any changes they tell it to.

Now the cats should wake up right after the player moves instead of waiting until the next cycle! Test this code. (You might need to click Run to start a new game if all your cats are already awake.) Your cats should perk up as soon as the player gets close.

Making Cats Follow the Player

Now let’s add this rule to make the awake cats follow the player:

======
RULES
======
late [ Player | SleepingCat ] -> [ Player | AwakeCat ]
[ > Player ] [ AwakeCat ] -> [ > Player ] [ > AwakeCat ]

There are no vertical bars (|) in this rule because [ > Player | AwakeCat ] would mean that the player and the cat would have to be next to each other for the cat to move. But we want the cats to move with the group regardless of what shape the group is in. So the easiest thing to do is to just have the cats make the same movements no matter where or how far from the player they are. As long as a cat is awake, it should move however the player does. To do that, we enclose the Player and the AwakeCat objects in separate square brackets, meaning they don’t have to be right next to each other. The player and the cat can be anywhere, and the rule will still trigger. Essentially, this new rule states that if a player is trying to move, every awake cat will try to move in the same direction.

Click Rebuild and try it out! Wake up the cats and get them moving! Pretend you’re a morning aerobics instructor for cats! Let’s get those tails shaking!

Image

The game still doesn’t work exactly like it should. Right now, groups don’t stick together. For example, if you’re blocked by a wall but a cat friend is not, the cat will keep walking and the group will break up. To make the shape of the group important, we need to make sure the group stays together.

If we make the group stay together, we need to make sure that cats outside the group can add other cats to the group, too. Otherwise, once the player has woken up a few cats, they would be stuck in the middle of the cats and unable to reach any new ones!

We have two challenges: we want the player and the cats to move as a group, and we want to allow cats already in the group to awaken other cats, just as the player does. Fortunately, these two problems have the same solution.

Defining Properties of Objects

To address both problems with our game play, we need the same rules to apply to the player and the cat objects. We could write two versions of every rule—one for the player and another for the cats—but then if we ever wanted to change that rule, we’d have to change it twice. Also, if we wanted to add a new rule, we’d have to write it twice! One characteristic of programmers is that we’re lazy. Why do extra work when we can play with our real cat instead? Let’s make our code clean and efficient the first time.

We’ll use the LEGEND section to tell PuzzleScript to treat different kinds of objects in the same way. The LEGEND section doesn’t just let us tell PuzzleScript what symbols refer to which objects. It also lets us tell PuzzleScript which words refer to which objects, so we can use one word to include the player and cats in a group.

Allowing Cats to Wake Up Other Cats

Let’s add an entry to the legend to describe any object that can be a member of the player’s group, whether that’s the player or the cats following them around. That way, anyone in the group (player or cats) can wake up sleeping cats. We’ll call this type of object a WakerUpper.

WakerUpper = Player or AwakeCat

Now in our rules, instead of checking whether the player is next to a sleeping cat, we check whether any WakerUpper is next to a sleeping cat. Keep in mind that the player and any cat that has already joined their group count as WakerUppers.

We’ll add WakerUpper to our current late rule by changing this line:

late [ Player | SleepingCat ] -> [ Player | AwakeCat ]

to this:

late [ WakerUpper | SleepingCat ] -> [ WakerUpper | AwakeCat ]

Now the cats in the game should be able to wake up other cats. The current rule looks for any objects marked as WakerUpper, and the legend defines the player and awakened cats as WakerUpper. Try playing the game, and then save your work!

Keeping Cats Together

We’ve solved the first problem: cats can wake up other cats. Next, we have to figure out how to stop the group from splitting apart when it moves.

First, let’s determine why the group splits apart. Remember that the > symbol means that something is trying to move. Because of the following rule, whenever the player tries to move, all the cats try to move in the same direction:

[ > Player ] [ AwakeCat ] -> [ > Player ] [ > AwakeCat ]

But if the player tries to move again and their way is blocked, every cat still tries to move anyway and the group splits up.

To keep the player and cats together as a group, we need to stop everyone in the group from moving if any one member of the group is blocked. We can do this by adding another rule and using the keyword cancel:

======
RULES
======
late [ WakerUpper | SleepingCat ] -> [ WakerUpper | AwakeCat ]
[ > Player ] [ AwakeCat ] -> [ > Player ] [ > AwakeCat ]
[ > WakerUpper | Wall ] -> cancel

This rule states that “if a WakerUpper tries to move into a wall, stop everyone from moving.” Everyone stays where they are. Because we used WakerUpper, this rule will check the player and all the awake cats, and the group should stay together.

Image

Keep in mind that PuzzleScript reads all your scripting from top to bottom, the same as you do. PuzzleScript applies your rules in the order they’re listed, starting at the top and working its way to the bottom. We want the “if a WakerUpper tries to move into a wall” rule to happen at the very end, after all the WakerUpper members decide where they’re moving. So make sure this last rule is at the very bottom of your RULES section!

Save your work, and then try to play the game. Do the player and cats stay in a group?

Winning the Game

Earlier, we decided that the goal of the game would be to wake up all the cats and have them join your group. Well, we’ve woken up all the cats in the level.

But the level still hasn’t ended because we haven’t added a win condition for PuzzleScript to check for yet.

Some games can go on forever, but not this one. To win Herding Cats, we need to add a win condition. What win condition would make sense? Well, the goal in Herding Cats is simply to have all cats join the group. To accomplish that, we need to wake up all the cats! Okay then, let’s try this as our win condition:

No SleepingCat

You win if there are no more sleeping cats, and all the cats are now awake cats.

Add the No SleepingCat line to the WINCONDITIONS section, and then run your game to see whether you can win your level. You should see the message Win Condition Satisfied when the last cat wakes up, as shown here.

Image

And you’re back at the title screen.

Image

Adding Sounds

To make the game more interesting and fun, let’s add sound effects to your game. See these little buttons beneath the game screen? Try clicking each of them!

Image

These buttons produce different sound effects like jump sounds, pew pew sounds, and bird tweets. The random sound button at the far right gives you a completely random sound, and the X on the far left clears the information panel below the game screen, along with any sounds you’ve added! Be careful with the X button: you don’t want to accidentally erase any sounds that you like and might still want to use!

Each time you click a button, such as the bird button, a line like birdSound: 40166309 appears. That number is the sound effect in a form that PuzzleScript understands. When you click a number, you should hear the sound. When you find a sound you like, write down its number.

Image

Try to find a sound you could play that would indicate in an exciting way that you won the level! The powerup sound button with the + on it might be a good one. Keep clicking it until you get to a sound you like. Then enter the number of the sound into the SOUNDS section of your game, like this:

=======
SOUNDS
=======
Endlevel 72533508

Image

The keyword Endlevel tells PuzzleScript to play this sound when the level ends. Now run your game again and try to win the level. Do you hear your cool sound when you win?

How about adding a sound to the cats when they wake up? Find a sound effect that sounds meowy, and then add it to your list of sounds, like so:

sfx0 9963503

The code sfx0 stands for “sound effects 0.” If you add another sound effect, you would call it sfx1, then sfx2, and so on. (Remember that 0 is always the number of the person in the front of the bathroom line!)

You can make the sfx0 sound play whenever you want it to by putting it at the end of a rule, like this:

late [ WakerUpper | SleepingCat ] -> [ WakerUpper | AwakeCat ] sfx0

This line tells PuzzleScript to play sfx0 every time the rule for waking up a cat runs, meaning every time a cat wakes up.

Save your game and test it out. Listen to the beautiful symphony of weird video game sounds your game has now. Magnificent!

Image

What You Learned

Now you know all the parts that make up a PuzzleScript game. You know how to draw the objects that make up your game, add the rules that tell the game what to do with those objects, and set up the collision layers that tell the game which objects interact with which objects. You also know that the LEGEND section tells PuzzleScript what words and symbols refer to which objects. You learned about adding a win condition to be able to finish the game and adding sounds to make the game more fun and communicative.

The one important part of a PuzzleScript game we haven’t talked a lot about yet is levels. In the next chapter, you’ll learn how to use PuzzleScript’s handy, built-in level editor to make puzzles for your game. You’ll also learn how to use level design to tell your game’s story. Take another break, and we’ll meet again in Chapter 3!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset