Typically PuzzleScript is used to make top down games, like I did with Puzzledorf, but you can in fact emulate some of the elements of side-scrollers, albeit with the limited rules of puzzle script, in that it is still turn based. This tutorial will cover how to make gravity.
I did a bit of an experiment with it for the early Puzzledorf prototype, but making block pushing puzzle games with gravity is a very unique genre. Example:
After completing the tutorial you should be able to make something similar to this Puzzledorf protoype.
Open the sample project. I’ve given a basic level to work with. It has a player and a crate on a ledge, and a door below. What we want to achieve is that when the player pushes the crate off the edge, it falls to the ground. We also want the player to fall to the ground if he walks off the edge.
Falling Stage 1
Here is the first piece of code to use:
down [ Player | no Object ] -> [ | Player ] down [ Crate | no Object no Player ] -> [ | Crate ]
Try pushing the crate off the edge. You will notice that the crate hoves in the air once you’ve pushed it off the edge, but if you take a further step, it falls to the ground. A few things are happening.
First let’s talk about the down keyword. By saying down, you are restricting the rule to only being applied in the downward direction. This is why the crate moved down. If you replaced down with right, you would see the crate get stuck to the right wall like an anti-gravity game. Try it out.
Next, we do something unusual. Instead of checking if the player is next to a specific object like a crate, we check to see if it’s next to a generic object. If you look carefully at the legend in the sample code, you will see that we have defined object as a group of objects, so that any time we use the word object, we mean this group of objects. Knowing that, we are checking if any of these objects are beneath the player. If they are not, we are telling the player to occupy that empty space and leave the previous space he was in, following the downward direction because of the word down.
But you will also notice that the crate doesn’t fall until the next turn after you push it off of the edge, and that it instantly reaches the ground below. You can use the late keyword to fix it’s delayed falling:
late down [ Player | no Object ] -> [ | Player ] late down [ Crate | no Object no Player ] -> [ | Crate ]
But how to make it so that we can see it gradually fall, frame by frame?
Falling Stage 2
Now we’re going to use the random keyword. Rewrite your code like this:
random down [ Player | no Object ] -> [ | Player ] random down [ Crate | no Object no Player ] -> [ | Crate ]
Run your code. This code works very similar to the previous code with one key difference. The crate hovers in the air, but every time you move it falls one space. This is because of the word random. Technically random is intended for creating games with random elements, but it is useful to us here. It forces that line of code to run once time per turn. PuzzleScript runs each rule as many times as it can per turn, before the user sees any graphic changes, which is why before it seemed to hit the ground instantly. But when you use the random word, you restrict it to only falling one space at a time.
Falling Stage 3
Now to introduce the again keyword:
random down [ Player | no Object ] -> [ | Player ] again random down [ Crate | no Object no Player ] -> [ | Crate ] again
Try the game. It is almost perfect. The crate hovers in the air briefly, but once you move once, it falls all the way to the ground nicely. We introduced the again keyword in the previous tutorial which goes into more depth, but basically it means that at the end of the turn, PuzzleScript will read through the code again and try and execute all of the again commands as a separate turn and then pause, then do it again, doing it as many times as it can. The key here is that it pauses between again turns, allowing you to see what’s happening.
Now for the final touch. To get the crate to fall all the way to the ground the instant it is pushed off the edge, we need to add a new line of code above what we just wrote:
[moving Player] -> [moving Player] again random down [ Player | no Object ] -> [ | Player ] again random down [ Crate | no Object no Player ] -> [ | Crate ] again
The moving keyword used in the square  brackets before player means we’re checking to see if the player is moving. What this means is if the player moves, we tell him to keep moving and fire the again command. Then, everything else that uses again will run immediately, in this case the crate falling animations.