How To Start Programming in Puzzle Script

You can either watch this tutorial on Youtube below, or otherwise skip past it and read the text version (not all of the Puzzlescript tutorials are on Youtube yet but I plan to do that eventually).

This tutorial will teach you how to start programming in Puzzle Script for your own Sokoban games. It requires no prior programming knowledge, but assumes you completed the previous Puzzle Script tutorial on making your first game. The code itself is very simple, and this is a very gentle way to get into programming, before moving on to learning bigger engines like Unity, which is what I used to make Puzzledorf (however I’m considering Monogame for future games).

Puzzledorf example

 The Code

Open the sample project here. Programming code is down the left side of the screen and is divided into sections: Objects, Legend, Sounds, etc. The Rules section is where you define how objects in your game interact. Scroll down to it. There should be one line of code as follows:

[ > Player | Crate ] -> [ >  Player | > Crate ]

What the above line of code means is, if the player is next to a crate and walking towards it, move the player and push the crate. To explain how this works, understand that Puzzle Script code follows the pattern of:

[ Condition ] -> [ Event ]

What it’s saying is:

[ If this condition is occurring ] -> then [ Do this ]

Puzzle Script checks the conditions on the left side of the arrow to see if they are true, such as, is a player object next to a crate object. Then if the condition is true, do something, ie, push the crate.

Example Conditions

Here is an example condition:

[ object1 | object2 ]

The above condition checks if object1 is next to object2. You check if two objects are next to each other by putting a straight | line between them, typed by pressing ‘shift + \’. Conditions are always enclosed in square [  ] brackets.

[ crate | crate ]

The above checks if two crates are next to each other.

[ crate | crate | crate ]

The above checks if three crates are next to each other.

[ crate target ]

The condition above checks if a crate is on top of a target, because there is no straight | line between the two objects. Objects can be on top of each other if they are in separate collision layers, which is discussed in later tutorials.

Keeping It Equal

Rules have to be balanced. Both the condition check and the event that follows need to be described the same way. I will show you what that means.

[ player | crate ] -> [ player |   ]

The above line of code destroys a crate if the player is next to one. You cannot have:

[ player | crate ] -> [ player ]

Because the condition on the left is checking if two objects are next to each other in two separate grid spaces, but the event only describes the single grid space that the player occupies. Puzzle Script needs to know what to do with the spaces it was checking. Really what the correct code for destroying a crate is saying is:

[ If player | is next to a crate ] -> then [ player does nothing | remove the crate ]
[ player | crate ] -> [ player |   ]

So even the blank spaces in your code can have meaning. The following is, however, allowed:

[ player target ] -> [ player ]

Because you are only talking about a single grid space in your condition and the event describes that same grid space.

How To Move Crates

Back to our original line of code.

[ >  Player | Crate ] -> [  >  Player | > Crate  ]

In other words:

[ If player moves towards crate | and is next to crate ] -> then [  move player | push crate  ]

The arrow > emphasises movement.

Sometimes you want to write comments to remind you what code does. Puzzle Script ignores comments – they are for our eyes only. To write a comment, put curved braces around a piece of text. Write a comment above the existing rule that describes what it does:

(The player pushes a crate)
[ >  Player | Crate ] -> [  >  Player | > Crate  ]

Now, underneath your crate pushing code, write this:

(The player pulls a crate)
[ <  Player | Crate ] -> [  <  Player | < Crate  ]

The reversed arrow means if the player moves away from a crate, the player pulls the crate. Press ‘Run’ to test. You should be able to pull and push crates. With programming, if you type even one letter wrong, the computer won’t understand, so fix any typos. When you make code changes, press ‘Run’ again to load the changes. If it doesn’t behave as expected, try pressing ‘Rebuild’ to wipe the programs memory and then press ‘Run’.

Sometimes you want to deactivate a line of code. Just turn it into a comment so it’s still there later. Now comment out the crate pushing code so that you can only pull crates, like this:

(The player pushes a crate)
([ >  Player | Crate ] -> [  >  Player | > Crate  ])
(The player pulls a crate)
[ <  Player | Crate ] -> [  <  Player | < Crate  ]

If that worked, comment out the crate pulling code and try the following:

[ <  Player | Crate ] -> [  <  Player | > Crate  ]

If the player moves away from a crate, the player and the crate will move in opposite directions. The arrows dictate which direction an object either is moving or will move. Now comment that out and try this:

[ >  Player | Crate ] -> [   Player | > Crate  ]

The crate moves, but the player stays still. Experiment with ^ and v (the letter v) to to see how objects move in response.

Errors

Let’s deliberately write a rule that’s wrong and see what happens. Type this:

[ <  Player | Crate ] -> [  <  Player  ]

Try running the program. You should see a message like this:

line 81 : In a rule, each pattern to match on the left must have a corresponding pattern on the right of equal length (number of cells).

Usually Puzzle Script is good at describing the error. Sometimes, however, Puzzle Script gets it wrong. In such cases, you have to read through your code and guess where the error is.

Experiment Some More

Try experimenting some more and writing rules of your own. Here are a few examples.

[ >  Player | ... | Crate ] -> [  >  Player | ... | > Crate  ]

In this example, the player will push the crate if they are anywhere on the same line of the level, and the player moves towards the crate.

[ >  Player | Crate ] -> [  Crate | Player  ]

The above will swap the player and the crate.

[ > Player | Crate ] -> [ Player | Target ]

In the above, if the player is next to a crate and moves towards it, the player will stop moving but the crate will become a target. The best part of puzzle script is how easy it is to come up with something new and experiment.

Conclusion

See the finished sample project here. The next tutorial discusses creating objects and doing simple pixel art for your Sokoban game so you can start to get more creative.

Next Tutorial >

If you liked this article, please check out Puzzledorf to show your support. If you enjoy playing, leaving a review helps the games visibility on Steam.

12 thoughts on “How To Start Programming in Puzzle Script

Add yours

  1. The sliding game physics is now working brilliantly thanks but now need to know how to position a boulder when the player is at rest (a bit like a chicken laying an egg).

    I tried [ Action PlayerStill ] -> [ Boulder PlayerStill ] and many other variations but nothing happened when I hit the spacebar.

    The idea is that the player has an option of placing a boulder at the same location as PlayerStill (indicated by a sound effect). The boulder only becomes visible when the player moves off and it will behave in the same way as wall when the player returns.

    Like

    1. Unfortunately that’s a rather individual idea that I’ve not experimented with so not totally sure how to help you there. It may not even be possible to spawn something under the player. Could be one where it’s worth asking the creator of Puzzlescript, he might have some idea, or look and see if there’s any other games that spawn an object under the player.

      You could probably make a boulder spawn next to the player, and could probably specify a direction with LEFT, RIGHT, etc, though getting it to spawn on the direction you want could be hard.

      Like

  2. If the wall is on the same level as the playing object (usually the case) it will prevent the playing object from going any further which is absolutely fine. That’s not the issue here.

    It seems that 95% of PuzzleScript games move objects one step at a time. Also, if holding a directional key down, the playing object will keep travelling until it hits something or when a key the released. Both of theses scenarios are not what I am looking for.

    IceCrates is different, as the playing object will keep moving even when a directional key has been released. So once the playing object is set in motion, nothing can be done to alter its projection until it comes to rest against another obstacle on the same layer, for example a wall. But in IceCrates, the playing object is a little slow over longer distances and the code too complicated for me to start editing.

    I can’t really explain any more than that, however there are games like Atomix by Volker Stepprath (2004) that uses the same game physics, or I could send you a link to one of my own games (PC only) that I programmed with Clickteam Fusion.

    Thanks,

    Dave S.

    Like

    1. Ok I’m still trying to work out what your problem is. Are you saying, you want the object to continuously move / slide, like in that game, but you don’t know how to slow it down? In other words, you’re asking me how you might slow it down? It might help if you link the game. Generally speaking, ice sliding type mechanics are quite complicated in puzzlescript, though if it’s done in the usual way, assuming the speed of the object is your only issue, speeding it up should be simple when you know what to look for.

      Like

      1. Are you saying, you want the object to continuously move / slide, like in that game…”

        YES.

        but you don’t know how to slow it down?

        NO.

        In other words, you’re asking me how you might slow it down?

        NO.

        It might help if you link the game.

        https://www.puzzlescript.net/play.html?p=6877049

        Generally speaking, ice sliding type mechanics are quite complicated in puzzlescript, though if it’s done in the usual way…

        The usual way?

        assuming the speed of the object is your only issue,…

        That is the second issue. The first is that I can’t get the playing object to slide.

        speeding it up should be simple when you know what to look for.

        Great but I don’t know what to look for.

        I think I will just ask around to see if anyone can program the game for me.

        Thanks.

        Like

        1. The “usual” way of doing sliding mechanics in Puzzlescript is to use the “again” command, which means, keep trying to run this rule “again” until it can’t be run. And also, using a combination of both specific direction ie, “RIGHT”, “LEFT”, combined with left, right and other directional versions of the player graphic and anything else that wants to slide. It’s very complex. But using the L and R graphics helps to check which direction the player is moving.

          I might end up doing a tutorial on it at some stage as it’s not a simple thing to explain.

          The speed is the time between when an “again” rule is run, the pause, and then when it is run “again”. To speed it up, you reduce that pause, or the time interval between “again” running each time.

          You just need to add:

          again_interval 0.01

          To the top of the file, here:

          title IceCrates
          author Tyler Glaiel
          homepage twitter.com/tylerglaiel
          run_rules_on_level_start true
          noaction
          again_interval 0.01

          Try different values to get your speed.

          To understand complex code, break things down into small chunks. Don’t try analyse all of the code at once. Make a copy of the project for testing. Try removing lines of code and then adding them back in to see what happens, for example.

          I would scrap all of the code for walls and water, and the crate, just leaving the game logic and code for the player ice sliding. Having less code to analyse will make it easier to understand. Like this:

          [ LEFT PlayerStill ] -> [ PlayerL ]
          LEFT [ PlayerL | Wall ] -> [ PlayerStill | Wall ]
          [ PlayerL ] -> [ LEFT PlayerL ] again

          You can see that when you move LEFT, if the player graphic is “PlayerStill”, then it will become “PlayerL”.

          On “LEFT”, if PlayerL hits a Wall, it will being PlayerStill and will not run “Again”.

          If PlayerL still exists and did not become PlayerStill, then move PlayerL LEFT, then try and run it “Again” as long as it is true. This is how the sliding works – it keeps trying to run it until it hits a wall. Experiment to understand the rest.

          Like

  3. I like that collision detection is on separate layers but how do I get the player object to butt up against a wall from afar? For example, when the player object is moving it should only stop when it collides with an obstacle or wall.

    I suppose it is similar in concept to the Nemo game except that the player object should finish in front of the fruit instead of on top (and deleting it).

    I find programming quite difficult but enjoy creating games, making up challenges and drawing the game objects (5×5 pixel block is quite challenging but fun).

    Many thanks,

    Dave S.

    Like

    1. Have you read the next tutorial, that has collision layers? https://stuartspixelgames.com/2016/05/14/how-to-create-objects-in-puzzle-script/

      I might add some more information to it. But basically, if they are on the same layer, then that will happen by default.

      So if the layers are:

      player, crate
      wall

      Then the player will stop walking when they reach a crate, but they will move through the wall because it is on a different layer.

      To create an interaction with an object on a different layer, you can do that when you specify the rules of the interaction in code. So, in this case, if we wanted the player to stop when they come up to a wall, you would do:

      [> Player | Wall] -> [Player | Wall]

      Which means, when the player is next to a wall, and moving towards it, stop moving. Then this will treat the wall as solid. However, unless you had a good reason to have the wall on a separate layer, like, maybe you want it to be solid for the player, but not for crates – unless there was some special reason, it would be easier to do the layers like this:

      background
      player, crate, wall

      And just put everything that is meant to be solid against each other on the same layer. That way you don’t need to code anything. However, if you wanted the crates to pass through the wall, or some other unexpected interaction, then you might want them on separate layers.

      Like

      1. Thanks for replying so soon. Yes, I have read most of the articles.

        The game physics I want to use is similar to the game IceCrates (shown in the gallery). Hitting one of the directional keys will propel the playing object in that direction and will continue to move until it hits an wall or an obstacle. There’s no changing direction in mid flight.

        But in IceCrates, the playing object is a little slow in getting from A to B and the code looked over complicated.

        Hope this helps,

        Dave S.

        Like

        1. Okay. I’m not sure what you’re actually asking me now though. Does that code example I just showed you help or not, or if not, what is the exact issue you’re running into? I’m not sure I’m quite clear on that. The code I showed you should make the player stop when they walk up to a wall. Or are you finding the ice sliding mechanics are making things weird and doing something else?

          Like

Leave a reply to SPG Cancel reply

Blog at WordPress.com.

Up ↑