DEV Community

Cover image for Inspecting Snakes in Pulp
Robert Mion
Robert Mion

Posted on

Inspecting Snakes in Pulp

In the last article I downloaded 21 games.

Two of those games made their JSON files available for download, too.

That means:

  • Their game was built in Pulp
  • I can import the file to inspect all of their game assets

Inspecting Snakes

I'll study each view carefully.


Custom font

I can't tell whether this set of ligatures is custom-made for the game or something the developer downloaded.

But it sure feels appropriate for the material.

Very cool, and shows that even with an 8x8 square pixel region, a lot of creativity is possible.


Custom scripts

It looks like there are eight tile scripts in addition to the required game script.

Each of the exit scripts are identical. Interesting.

on openExit do
  if goldLeft==0 then
    swap "white"
    sound "opened"
Enter fullscreen mode Exit fullscreen mode
  • openExit is some custom event
  • Then a condition
  • And two actions
  • I'm not sure what swap does. Maybe changes a tile?
  • sound likely plays that sound

The darkness script is similar:

on lightHallway do
  if goldLeft==0 then
    swap "white"
Enter fullscreen mode Exit fullscreen mode

The gold bar script has two event listeners:

on checkForGold do
  // figure this out
  goldLeft = 1

on collect do
  sound "beep"
  tell event.px, to
    swap "snake left"
Enter fullscreen mode Exit fullscreen mode
  • A value assignment to a variable
  • Another sound played
  • Hmm, I wonder what tell does
  • If its arguments are X,Y positions, then maybe it is a command to once again change a tile object?

The tongue 2 script is a series of text prompts.

Since they end with playEnding = 1 I assume this script runs after the boss is defeated.

The player script is over 100 lines!

Although, it only includes three event functions:

  • confirm seems to reset the game state
  • cancel seems to prompt the player to decide whether to reset the game state or continue
  • update features all the fun logic

Here I go, line-by-line.

on update do...

playerX = event.tx
playerY = event.ty

prevX = event.px
prevY =
Enter fullscreen mode Exit fullscreen mode
  • Four variables
  • Each tracking an X or Y position
  • Two for where the player moved to
  • Two for where the player was
  • An event object with built-in properties
  • Not sure what the t and p stand for. Maybe target and position?
// check for any gold bar items left in room
goldLeft = 0
emit "checkForGold"
Enter fullscreen mode Exit fullscreen mode
  • Set value of variable to 0
  • Run a function that updates the value of that variable
  • Attached to each gold bar tile
  • When run, it sets goldLeft to 1
  • Maybe that happens only if gold bar is the tile that the player just tried to move to?
// swap exit tile if no gold left
emit "openExit"
Enter fullscreen mode Exit fullscreen mode
  • Run the function openExit
  • Attached to each exit tile
  • That checks the value of goldLeft
  • If it is 0 then the exit tile is swapped for a white tile
emit "lightHallway"
Enter fullscreen mode Exit fullscreen mode
  • Run the function lightHallway
  • Attached to each darkness tile
  • That checks the value of goldLeft
  • If it is 0 then swap that tile for a white one
if!="room 18" then
Enter fullscreen mode Exit fullscreen mode
  • If the current room is not room 18, continue

Next are four if clauses that are largely similar:

if event.dy==-1 then
elseif event.dx==1 then
elseif event.dy==1 then
elseif event.dx==-1 then
Enter fullscreen mode Exit fullscreen mode
  • dx or dy are either 1 or -1
  • Maybe d stands for direction?
  • N, E, S, and W are signified as either -1 or 1 for each axis?
// make sure tile gets drawn behind player
Enter fullscreen mode Exit fullscreen mode
  • This increments or decrements the earlier variable's value
  • I'm not sure how this is working yet
tileNameBelow = name playerX,prevY
Enter fullscreen mode Exit fullscreen mode
  • This sets a variable's value
  • Perhaps to a string that is a combination of two variables' values?
swap "player moving"
Enter fullscreen mode Exit fullscreen mode
  • This changes the tile displayed...I think at the player's current position
// draw wire tile behind player when moving up/right/down/left
if tileNameBelow!="gold bar" then
  if tileNameBelow!="obstacle" then
    if tileNameBelow!="lantern left" then
      if tileNameBelow!="lantern right" then
        if tileNameBelow!="tree" then
      tell playerX,prevY to
        swap "snake up"
      tell prevX,playerY to
        swap "snake right"
      tell playerX,prevY to
        swap "snake down"
      tell prevX,playerY to
        swap "snake left"
Enter fullscreen mode Exit fullscreen mode
  • As long as the name of some tile is one of the open tile names
  • Replace the contents of the previous tile with a snake pointing in the direction of movement

Keywords I learned

  • on ... do
  • if ... then
  • elseif ... then
  • event.: tx, ty, px, py, dx, dy
  • emit
  • swap
  • tell ... to
  • name
  • end
  • ask ... then
  • option ... then
  • toss
  • fin
  • Events: update, cancel, confirm, custom names

The game script is nearly 80 lines.

It features seven functions.

on load do

on load do
  // Game config
  config.inputRepeatDelay = 0.2
  config.inputRepeatBetween = 0.15

  call "init"
Enter fullscreen mode Exit fullscreen mode
  • Sets some configuration flags
  • Calls another function, init

on init do

on init do
  if room!=0 then
    goto playerXSaved,playerYSaved in room
  if hasPlayed==1 then
    log "welcome back!"
    log "nice to meet you."
  hasPlayed = 1
  store "hasPlayed"
  goldLeft = 0
  playEnding = 0
Enter fullscreen mode Exit fullscreen mode
  • Reset the game's variables' values
  • If the room is any other than 0, recall the X,Y coordinates of the player's most recently saved position in the current room
  • Greet the player accordingly in the console
  • Mark the player as greeted
  • Initialize the amount of gold collected
  • Mark the game as not having ended

on loop do

on loop do
  if playEnding==1 then
    call "playEnding"
Enter fullscreen mode Exit fullscreen mode
  • Routinely check for whether the player has marked the game-ending flag, and call the function if so

on start do

on start do
  loop "djent"
Enter fullscreen mode Exit fullscreen mode
  • Perhaps this triggers the on loop do?
  • I'm confused by this logic

on enter do

on enter do
  room =
  playerXSaved = event.px
  playerYSaved =
  store "room"
  store "playerXSaved"
  store "playerYSaved"

  tell "player" to
    swap "player"
Enter fullscreen mode Exit fullscreen mode
  • I assume this code runs when a different room is entered
  • Per the comments: store latest room the player is in so we can easily reset/restore the game
  • Per the comments: put player back to original state

on playEnding do

on playEnding do
  randomX = random 6,18
  randomY = random 3,11
  tell "player" to
    swap "black"
    goto 0,0 in "room final"
  wait 5 then
    tell randomX,randomY to
      swap "black"
  wait 30 then
    // end game and reset saved room
    fin "The End"
Enter fullscreen mode Exit fullscreen mode
  • This is the function called in the loop when the flag is marked, indicated by a variable storing the value 1
  • Two random values are assigned to variables
  • Move the player to the final room in one of the corners?
  • Delay the action of switching a tile to black
  • Delay the action of ending the game

Keywords learned

  • config API
  • restore
  • ignore
  • store
  • loop
  • random
  • goto ... in {room}
  • wait {amount} then
  • Events: load, init, start, enter, loop, finish


This game has over 20 rooms.
Rooms in Snakes

  • All rooms other than card are levels in the game
  • Each level features a maze to traverse, gold bars to collect, and an exit that unlocks when all gold bars are collected

The room labeled start has an added star by its name, possibly marking it as the first room of the game?
Start room



There are many tiles used to paint the world of Snakes.
World tiles


Snakes features a single item: a gold bar.
Gold bar item


Snakes features six sprites: an exit in four orientations, darkness, and a snake tongue.

I now see that the white tile provided as a default tile by Pulp is called 'white'.

Thus, in each exit tile's script where it says swap "white", that does indeed mean to replace the exit tile with a white tile, thereby enabling movement onto that tile.

The same action happens on the darkness tiles.

The snake tongue only appears in room 18 attached to a giant snake.

It now makes sense that all of the prompts are inside that sprite's on interact do function.


Snakes features six player tiles: one static player, one moving player, one moving snake in each of the four orientations.

Player tiles

Only the static player tile has the large script as its behavior.

Each of the other tiles seem to be referenced in the script.

Though I'm not sure how a tile named snake up player is selected when the script only says swap 'snake up'.

By that I mean, how does it find the tile when its name isn't an exact match?


Room 1's exit

Each room's exit connects to another room.

The UI makes it easy to choose which room. And to choose one of three options for an exit:

  1. Connect to room
  2. Connect room edges (Metroidvania style!)
  3. Show ending

Other revelations

  • djent is a song
  • playEnding is 0 until the last level where, after the snake says everything, it becomes 1, thus triggering the end of the game
  • The background of the Font view is always the currently selected room

Before I slither away

  • Inspecting this game's code in Pulp has been so enlightening
  • I learned a ton of PulpScript syntax
  • I learned how pieces fit together in Pulp
  • I learned more about layers and their tiles

I'm sure all this knowledge will make reading the PulpScript documentation easier.

Hopefully the next game, Rescues, will reveal even more about building Playdate games!

Top comments (0)