Oli's old stuff

Tinkering with retro and electronics

Apr 19, 2020 - 9 minute read - spectrum z80 retro gamedev smeg

Introduction to SMEG

Introducing SMEG

In this post I’m going to introduce the SMEG adventure game system that I’m creating to build my ZX Spectrum point and click adventure.

What is SMEG?

SMEG stands for Scriptable MachinE for adventure Games, a very tenuous play on words that pays homage to Lucas Arts’ SCUMM and one of my favourite TV shows, Red Dwarf.

Rather than just being a fun acronym, it nicely describes the approach and the architecture of the system.

An overview of SCUMM

Why are you talking about SCUMM? I’m here to learn about SMEG!

To understand SMEG, it is worth getting familiar with SCUMM and what it was about.

Let’s start at Wikipedia for a hand. The original version of SCUMM was created by the legendary Ron Gilbert for the game Maniac Mansion.

It’s entire purpose was to provide an abstraction from the machine and the content, allowing people to use commands like walk bob to door instead of having to know that the character bob was memory location $6A00, the door object was at position 130,90 and the walk command involved playing animation, path finding and moving the character between frames.

As mentioned in the Wikipedia article, the system is somewhere between a game engine and a programming language. They exist in a symbiosis that’s balanced around the creation of point and click adventure games.

For a system that was designed and built in 1987, it was very advanced - and is still a very elegant way of approaching the adventure game genre. The idea still persists today in the form of Adventure Game Studio and other similar tools.

Ask me about SMEG

SMEG is my attempt at creating such a system for the ZX Spectrum. It started out as me messing about and making a simple crude Monkey Island-esque demo for the Speccy and it has morphed and blown up into my making SMEG (along with a companion game demo).

I didn’t start intending to build a SCUMM style system, moreover it started creating itself based on the complexity and requirements of building the content in Z80 assembler.

Previously, everything was hard-coded into the demo and I found that adding a new dialog, a new character, a new object, etc became quite a tedious and error prone task. The more items I added, it made it harder and harder to change the data structures and code that used those without breaking things.

A very clear example that stands out to me was adding something as simple as a status flag to the “stage object” structure caused a load of subtle bugs and even crashes when the code worked on that data. Remember that in Z80 assembler we have no type checking, and often accessing the data can mean incrementing the HL register, or some other offset-based lookups. Things broke a lot and I found that I was spending more time fixing existing things after a change that I stopped adding new things for a while.

The SMEG “engine”

SMEG Screenshot

The SMEG engine is currently designed around several core concepts:

  • Stage - A “room”, comprising of actors and props. The background of the room is defined as a tilemap.
  • Actor - A walking, talking being
  • Prop - An interactable object on the stage. It may or not be visible
  • Ego - the player’s actor
  • Inventory - A collection of objects in the ‘pocket’ of the Ego
  • Verbs & Sentences - Verbs are the ‘actions’ that the Ego can perform (Look, Walk, Take, Talk). These are combined with Nouns (such as Actors, Props, Inventory objects) to do something.
  • Dialog - Conversation system
  • Script - A virtual machine that ticks away and schedules the next sentence for execution.

The SMEG engine handles the drawing of the room, the sprites and all of the cursor interactions with the world. The beating heart of the system is a very simple bytecode-based virtual machine that runs the script actions, such as an actor saying a dialog line or walking to a position.

The “verbs” I have chosen are the standard 9 that is used by most SCUMM games, but in reality they may drop to 6, with things like “Use”, “Pull”, “Push” being largely the same, for example.

Verbs are important as they’re the basis for the “things you can do” in the world.

SMEG overview

SMEG Overview

The SMEG System has three phases a project goes through to turn into the end “game” that you can run on your Spectrum.

  1. Content Creation
  2. Content Build
  3. Compilation

These phases are as it is now, and are very likely to change as time goes on - especially the final stage. More on that later.

Content Creation

Content creation is the “fun” part, where I can build scenes, write scripts and generally build the stuff you see and interact with.

Making a room

I’ve adopted the open source map editor Tiled to build the rooms. It’s really easy to use and has a format that is easy to parse and process by my tools.

As you can see in the screenshot above, the room background is made up of a tilemap, with Tiled’s object system providing the basis for how you specify objects and their scripts in the room.

I have a convention-based approach of assigning the verbs to the objects, using the Tiled object property system to hold a lot of the data.

As you can see in the screenshot, there is a rudimentary scripting language (SMEG Script) that lets you direct what happens when a sentence is run.

    walkTo <actor> <position>
    pickUp <actor> <object>
    speech {
        line <actor> <text>
    }

The language is currently based around Tcl, but will likely move more towards a simple C syntax as I feel most comfortable with that.

Anything that lives beyond the scope of a room lives in a SMEG Project file, a simple json file that has information about the actors, the sprites and the rooms.

Dialog and speech currently lives in the Tiled map files, but it is very likely that they’ll move into a separate set of files soon - mostly because it feels the wrong way to be authoring them.

Content Build

The content “build” stage is what takes all of the content files and turns it into something that the SMEG engine can actually use. This stage is captured by a single custom tool called the SMEG Build Tool.

This is a .NET Core project that presently, at least, is a crude Z80 code generator. In essence, this was the utility I created to make it easier for me to get content into the game, without having to write the Z80 structures.

Originally a single-pass emitter, it has gradually moved into requiring two passes over the assets, mostly because it can then perform lookups and validation on those objects.

This is handy as it allows me to move a lot of the validation away from the runtime (where it would be slow) and into this tool - where I can do it much more easily and across the entire project.

The SMEG Build Tool is also the SMEG Script compiler that turns the human readable instructions into bytecode that the SMEG VM can execute.

The Z80 emitted by this tool contains everything the game needs; the sprites, the dialog, the bytecode, the object definitions, the tile maps - everything.

Compilation

The content file emitted is compiled with the engine source by SJAsmPlus into the final SNA/TAP file loadable by the Spectrum.

The reason for them both being compiled together is historical; the code and the content were originally together. The SMEG Build made it easier for me to work on the content, but I still needed to see the assembler to help with debugging.

One thing that I will be moving away from is the content being compiled with the engine. There’s many benefits to this; namely that I can compress rooms to get more into the Spectrum’s limited memory and to allow multiload content, effectively allowing for much bigger games. This is all something that needs to be looked at, but it is really the best direction to be taking.

This likely means that the final compilation stage will turn into one of ‘mastering’, taking the compiled engine code and game data and laying them out in a form that can be loaded by the Spectrum.

The Future

Everything is still very early, but it feels like the foundations are taking shape. I’m building a game demo with SMEG and using that to drive the features and pipelines. I’m not really setting out with a goal in mind, just happy to let things evolve and then refine them as we go on.

When I’m at the stage of being “happy” with where things are, likely near the release of the game demo, I am planning to open source all of this for others to enhance and make their own content with. Open sourcing it now just isn’t the right time, especially as everything’s changing and in flux. The code is also pretty nasty, too :)

Questions

Some questions I have been asked, that I will answer here:

Which Spectrum models are you aiming for?

I’m currently working with 48K, because I’ve not added 128K support to my development emulator (neccy). I’d love to keep things within reach of the 48K models, but I’m not against changing this to 128K only if it becomes too constrained.

Are you targeting the NEXT/ULA Plus/etc?

Not yet. I don’t have either of these systems and trying to target them will mean forking the code - for the NEXT it means that much of the display code will need reworking. I would very much love to target the NEXT in the future, but first I’m focussed on the original model Spectrum.

What about Kempston Mouse support?

Will probably add this, but I don’t have a real mouse to test it on.

What about music support?

Likely to be added in the future. I may need some help here.

Why a new engine instead of porting SCUMM VM?

I wanted to make my own game for the ZX Spectrum, I never really set out to build a SCUMM like system, it just evolved that way.

When are you going to open source this?

When I’m ready.

When can I play the SMEG game demo?

When it’s ready.

Will there be a port for the C64/Acorn BBC/etc?

No idea. I’d love to consider something like this in the future, but right now everything is designed specifically for the Spectrum, so it may not ever mean content is “portable”.