A Few Notes About the Engine


I first got interested in game jams with the Lisp Game Jam, because it looked like a cool way to learn Lisp. I evaluated a few Lisps, then decided to go with Racket (which is actually a Scheme instead of a Lisp, but it all looks mostly the same (to the uninitiated), so whatever). My first game was almost a stream of consciousness sort of thing, everything was hardcoded and I was kind of throwing stuff in as I thought of it.

As I understand it, a "game engine" is a framework that lets you describe your game at a higher level of abstraction and it handles the details. For a long time, the code for the games I made was deeply intertwined with the game itself. Only the most trivial sections could be re-used for a different game. I started thinking about how I could change this with Steam*Spark and Zode-Trip. The framework I wrote for this game is the culmination of everything I've learned so far. 

This is the first time almost everything that makes the game is specified outside of the core code (the Engine). 

This has a lot of implications. It means that changes and maintenance are a lot simpler because once the core is reasonably well debugged, my changes will mostly be to the data defining the game instead of actual code. And of course that helps with writing it too -- if I think of some new room or scene, I can just change the data, not the game code. The code itself is also more compact.

The game definition data is kept in several global variables FRAME_STYLES, CHARS and ROOMS. The FRAME_STYLES describes how to draw the dialogue balloons that appear at the bottom of the screen. CHARS describes the basic information for the game characters. Finally ROOMS (which could also be thought of as "scenes") describes the various locations available and what happens there. You don't need to be able to program Lisp to modify those -- they're just simple JavaScript data structures. However, for ROOMS, I have a trick which makes it even easier, which I'll talk more about in another post.

FRAME_STYLES seems a bit of a mixed bag, but it's fairly simple -- it describes the styles used for the dialogue frames. The default style is used for anything that doesn't have an override. It's intended mostly for character speeches. The ink property is an CSS/HTML colour for the text which is written inside the frame. The portrait property indicates if there's a character portrait to be drawn -- for the default style there always is. And the rest of it is one or two letter codes -- nw, n, ne, w, c, e, sw, s, se??? Those are coordinates for the corners and lines of the dialogue box in the spritesheet. It expects nine tiles at 32x32 pixels each.  They're assembled into the box, and the text is drawn over it.

CHARS describes the characters that walk around on the playfield. The base and size properties describe where to find the character data on the spritesheet. Successive frames stretch out to the right. The anim property describes what frames to use for each character state. For example, the hero IDLE state looks like `[[0, 1], 0]`. This means show frame zero (the idle sprite for this character) for 1 frametime, then start again from frame zero -- forming a loop.

The ROOMS data structure is the most complex (for certain values of complex...). There is an entry for any place that can be shown on the screen (a "room"). Each entry has a list of handlers, the most important of which is onenter, because it gets run every time the scene changes to that room.

If I can do a little more work on this, maybe next time, I can develop the story instead of the engine!

Leave a comment

Log in with itch.io to leave a comment.