How I made Eval-em-up! / Part 1: Planning


About the Game Jam

Spring Lisp Game Jam 2023

Lisp Game Jam is an event where all participants create and submit a game within a time limit of 10 days. The game has to be programmed in a Lisp programming language. Apart from this, there are no other restrictions, and there is no theme for the submissions.

I came across this game jam while I was browsing the Racket forums, but I was a little late to the party since it had already begun. I didn’t think I would ever make and publish a game on my own, but right then and there I decided I would make something for the jam.

End Result

Screenshot of Eval-em-up, showing a green player ship, some red enemy ships, and shots from both. The art style looks like sketches on paper.

Game page

Feedback from the other game jammers

Choosing a Genre

I wanted the genre of my game to be a tried-and-true formula that is fun to play even if I can’t add much unique content. Since I was working alone, I expected to feel the pressure of the game jam end date, limiting the amount of stuff I would be able to add.

Even though I’m a great programmer overall, I frequently run into tough situations in Racket. I have also never used a 2D graphics system in Racket before. If the genre I chose needed me to write complex code for the core mechanics, I would very likely end up spending a lot of the allotted time trying to fix my code rather than adding cool stuff to the game.

For this reason, I decided to create a shoot-em-up, since the mechanics and physics and code are fairly straightforward. Once I’ve got the basics implemented, the game will feel good to play no matter how short it is or how much unique content I’m able to add to it.

Coming Up With Ideas

Well, one interesting thing you can do with Lisp languages is evaluate data as code. I decided to integrate code into the gameplay in some way.

The first idea that came to mind was having a full REPL in the game that the player could use to interfere with the game’s own logic. Maybe it would work in an RPG or puzzle setting where the player has to bend the game’s rules to continue, like in Baba Is You or TheZZAZZGlitch April Fools events, but I quickly realised it wouldn’t work in my game since it would be too difficult for the player. Also, a shoot-em-up is about action, not about head-scratching puzzles that put the gameplay on pause.

So rather than having the player write code, the code would need to be in blocks in the game world for the player to interact with. It would still be too difficult to have the player piece together full procedures by combining code blocks in the world, so each block would have to be a standalone unit of code that does its thing alone.

And that’s how I got the idea that each enemy should contain code that executes when you shoot the enemy. There’s lots of potential here:

  • Standard enemies containing the code (hit) that just disappear without anything special
  • An enemy that launches a stronger counter-attack that the player has to plan for, like (explode)
  • An enemy that darts around rapidly, making it hard to read what the code is
  • A switch with the code (open) that you have to hit to open a gate and continue
  • An enemy that provides shields to the other enemies, with the hit code (disable-shields)
  • An object that runs (give-power-up) to give the player a helpful minion that floats around their ship. The minon would contain its own code that activates on hit to benefit the player.
  • A mimic enemy that looks like the power-up object, but actually runs (give-powre-up). See the typo? It would disadvantage the player if it was shot.
  • Some kind of end-game meta-thingy where the enemies’ code gradually corrupts the game

Drawing the Art

Most shoot-em-up games take place in outer space, and I saw no reason to break this trend. However, when I began drawing spaceship concepts, I quickly realised that I would not be able to create a sleek, geometric style spaceship with my current drawing know-how.

I decided to take a gamble and draw all the art with a rough pencil and messy colouring. The goal was to sidestep the geometric style and try to look more like a child’s drawing. This is a gamble because I didn’t know whether others would appreciate this unusual style or perceive it as a lack of skill on my part. With the time limit, I knew that I wouldn’t be able to pivot to a different visual style later. Running out of options, I decided to go for it, and I ended up getting a lot of positive feedback on how it looks, so yay!

Sprite sheet for the player’s ship.

I downloaded a photograph of graph paper from Wikimedia Commons and then digitally drew my spaceship designs over it. I then cut out the graph paper from the rest of the photo as if with scissors.

Most of the sprites have slight variations that are animated. For example, the spaceship has an animated exhaust jet and the basic enemies have animated propellors. I did this by drawing the variations on a separate layer, exporting both options, and combining them into the same sprite sheet.

Sprite sheet for the second ship you encounter.

Sprite sheet for the most basic enemy ship.

Background Images

All sprites are made up of the drawing + graph paper. I wondered whether I should separate the two - this would move the drawings to a floating layer and have the graph paper as the background of the entire window. I could have gone with either path, but based on feedback from others, I decided to keep the paper as part of the sprites. So I needed something different as the background.

Sticking with the classroom supplies theme, I downloaded a picture of a blackboard from Unsplash and edited it so it tiles seamlessly. Then, I asked my good friend Elysia to create some chalk-like digital drawings for me that I could arrange into the background at run-time. This way, no two backgrounds are the same!

Code Structure

Language

Since the theme of the game jam is using a Lisp programming language, I decided to go with Racket. It’s my favourite Lisp out of the ones I’ve tried, and I’m already familiar with the built-in libraries from my experience programming BreezeWiki in Racket.

One disadvantage of Racket in this situation is people have to download my game and run it on their computers. If I were able to target HTML5, people would be able to play it on the web directly from the game page. But I’ve never tried running Racket in the web browser, so I decided to focus on a downloadable version.

Graphics

Racket does have several systems available for 2D drawing, including pasteboard, snip, and mode-lambda. However, I decided not to use any of those. While Racket’s documentation does show lists of what’s available, it rarely provides practical examples of how to do common tasks, and it can be especially tough to get started. Since they are not commonly used, I also wouldn’t be able to find info on forums like Stack Overflow, and I wasn’t interested in wasting my allotted time grinding through the inevitable issues on my own.

I decided to use Raylib for the graphics (and input) since its .h file was self-explanatory and I could find answers to my basic questions online. I also found some simple template code which helped me get started much faster. Raylib is a C library, and Racket talks to it through FFI bindings.

Structured Data

Racket offers two ways to structure data: structs, and classes (via racket/class). Structs are immutable and have a fixed set of fields. Classes are like classic OOP classes - they are mutable and have fields and methods. If I used structs, my code would end up looking something like Elm, where I’d define reducers which would update the game state, and I could easily take exact save states and go back in time by referencing old copies of the structs. If I used classes, mutating values would be less mental effort upfront, and it would be a good opportunity to find out about the class system because I hadn’t used it before. For these reasons, I decided to use racket/class.

That’s the end of the post

The next post in this series will talk about the state of the game on the morning of the last day.

Get Eval-em-up!

Leave a comment

Log in with itch.io to leave a comment.