Last Updated:

This is Post Apocalyptic Petra

Bad Sector
Bad Sector my games

I'm trying out Publii, a "Static CMS with GUI" - or basically, the modern incarnation of WYSIWYG web site editors like DreamWeaver and the like.

As a test, here is a quick article about a new MS-DOS game i was working on a few weeks ago for a game jam called Post Apocalyptic Petra.

Post Apocalyptic Petra

Post Apocalyptic Petra is a 3D adventure platform game where you control the titular Petra after she wakes up from cryogenic sleep in an empty room. A computer called L0RD tells her that he woke her up after receiving a command from a remote site and that she is the last person alive in the facility. As expected, she is a bit confused about all this.

Petra, confused.
Petra, confused.

"How do i leave?" Answering that question is pretty much the rest of the game and your goal is to help Petra leave the facility. This isn't as simple as climbing the stairs (though you will do some climbing, stairs included), as a large part of it has been destroyed and the remaining bits are locked tight with access codes and security mechanisms. But like all games involving computer security, the weakest link is always the humans who are too happy to spill the beans to everyone with a working pair of eyes.

Reading a "note disk"

Often this is done through "note disks", little flipping floppies that you pick up and use in computers available throughout the game's levels. These machines are the only means of learning new information as everything else does not work - or is damaged beyond recognition (as Petra will point out at a later point in the game when she finds some books).

Outside of reading notes and entering codes, Petra will also perform more advanced tasks such as pressing buttons and turning valves that will cause stuff to happen - like opening doors or dropping ladders.

Post Apocalyptic Petra is mainly an exploration game with some puzzles and a couple riddles thrown in for good measure. And a bit of platforming - after all when i first started writing the game i was thinking of making some sort 3D platformer like Tomb Raider and while i wanted to add some puzzles, they'd only be just a tiny aspect of it. Turns out making all the animations a good Tomb Raider clone needs is hard, especially when you also have to do everything else and there is a short time available for all that stuff, so i, uh, "pivoted" to making a light 3D adventure game. There is still a bit of platforming though...

Making of...

The MS-DOS Game Jam #2 ran between February 28, 2020 to May 9, 2020. Originally it was meant to be a single month, but then COVID-19 happened and the organizer decided to add an extra month because... why not, i guess? 😛 At the site it mentions that it ended May 10, 2020 but that was an additional day extension to allow for some last minute submissions, though personally i had Petra uploaded at May 9. Having said that, i released several bugfix releases later, though the game content is the same as the original submission (and all versions are available at the itch.io page).

Even though the jam ran for around two months, i actually spent only about 5 to 6 weeks on the game. While i was working on it, GOG decided to release the Dishonored series DRM-free and i bought them - i had never played Dishonored 2 nor the standalone expansion Death of the Outsider, so playing those games took a large part of my time. Then after i finished those games, i accidentally installed Fallout: New Vegas and that too had an impact on the time i had available to work on Petra 😁.

Lazarus with the editor source code

I used Free Pascal and Lazarus (shown above) to create the game. The engine and the game only need Free Pascal (and the libraries that come with it) whereas the editor also needs Lazarus as it uses LCL (Lazarus' framework) for the GUI. Outside of a few math routines that i reused from existing code, all code for the engine, game and tools were written during these weeks.

Another tool i used was Jasc Paint Shop Pro 7 (which in my opinion, despite being 20 years old now, still has the best UX for an image editor) which i used to create the game's 2D graphics and textures.

Paint Shop Pro 7 with some images from Petra (including its palette) opened

The first thing i wrote was a very simple renderer with a software rasterizer running on MS-DOS:

Fullbright Petra spinning on a CRT

The above image is a still from this YouTube video. This is running on a Pentium 3 at ~1GHz with 512MB of RAM (though even the final version of the game is playable at very small amounts of RAM). Initially i had hopes of making the game playable on Pentium 1 machines, like the original Tomb Raider game, so after adding support for gouraud shading i also tried it on a laptop i have with a Pentium 1 at 133MHz (this is another still, from another YouTube video):

Shaded Petra spinning on a LCD

This idea was quickly abandoned after i started implementing some level data structures though as the renderer was quickly becoming too heavy and i had no time for optimizations. I did spent a bit of time trying to optimize the renderer, though the only platform i could get any profiler to run on an old PC environment was Linux... on an emulated Pentium MMX running Slackware Linux. And even that didn't have the functionality i needed so i could only use gprof, which isn't that useful (i'd rather use perf but the emulated CPU didn't support the necessary functionality).

Slackware running Post Apocalyptic Petra under Window Maker through a quickly hacked together SDL 1.2 port

The jam was about MS-DOS though, not any specific CPU 😋. The final game needs a Pentium II to be playable, although a Pentium 3 will be the best for a smooth experience (especially when paired with a good CRT monitor). Perhaps at some point in the future i might revisit the renderer and try to optimize it a bit more.

Another tool i had to write very early during the game's development was an animation editor. The Petra model was made using Blender 2.79 (i prefer this version to the later releases), though that was only for the mesh. The model was actually made of several separate meshes that make up the torso, head, arms, legs, etc and those are rotated around their pivots to make an animated character. This was a common technique for character animation during the 90s and early 2000s.

The animation editor showing an older picking up item animation (the box says idle but that was a bug)

This editor is the only part of the game that i haven't released yet and that is mainly because it is very specific to the model of Petra. Initially i planned to use it to create several models (and the game was also supposed to have three additional characters) but as the deadline was approaching i changed plans and didn't bother to add any of the necessary functionality to create additional models. I'll probably release the tool after i make those changes at some point. It is also the only part of the entire process that doesn't rely on any Petra code and instead uses RTTK, a "tool toolkit" package with a bunch of Free Pascal and Lazarus units for making tools.

If you want to see the editor in action as well as the game at the stage where i was still adding animations and working in the level structure before i made an actual level editor, check this YouTube video - in this video i create the animation to turn around Petra when you press the End key as well as implement the functionality in the game entity for Petra.

Of course things got a bit more interesting once i started working on a level editor.

The editor as it is right now, showing the first map. A bug in the animation editor causes Petra to sink.

The editor is "wrapped around" the engine - essentially a game instance runs inside the editor in a frozen state and you edit the game objects (world, entities, etc) while this instance is running. You can also play the game inside the editor easily - this is done by cloning the editor's game instance and replacing it with the clone for the duration of the gameplay session. Once you finish playing, the cloned instance is deleted and the original instance is brought back (so any changes in the game objects during gameplay are restored).

This was made possible largely thanks to Free Pascal's class system and its extended RTTI. Although Free Pascal does have support object serialization, i decided to write a custom one that was a bit easier to work with. Free Pascal's serialization - or "streaming" as they call it - is based on Borland Delphi's and it was largely designed for serializing GUI forms. In addition it is a bit too bureaucratic and needs some hand-holding that isn't really necessary considering what the language can do.

Still, this custom serialization was made possible because of Free Pascal's support for properties, marking parts of classes as "published" (meaning to be exposed to RTTI), treating classes as objects themselves (and allowing instantiation of a class through those objects) and its RTTI and the entire functionality was implemented in a single afternoon. Thanks to it, you can do something as simple as:

var
  F: TFileStream;
begin
F:=TFileStream.Create('somefile.dat', fmCreate);
  SomeObject.SerializeToStream(F);
  F.Free;
end;

This serializes an object and all the objects it references to a file on disk. Deserialization is similar, except the DeserializeFromStream method is used instead. Also a CreateDeepClone method is provided (which serializes and deserializes an object to a memory stream) to create deep clones of objects - and that is exactly what the editor uses to create a clone of the game for playing inside the editor.

Most modern 3D game engines use a similar system nowadays to allow for easily editable objects and truth be told, the serialization in Petra has several limitations that wouldn't fly in a real project. For example all resource references are done via simple string properties that the objects that expose them handle with setters to do the actual resource loading. However this was fine for a simple game made for a game jam so i didn't mind much.

Besides, the control used to edit the objects wouldn't be able to handle anything better without extra work. I mentioned above that the engine doesn't use Free Pascal's serialization, however it still relies on the same base class as the one used for that serialization - TPersistent. This is only so that i can edit the objects using a property editor control that Lazarus provides (seen at the bottom right side of the editor window). Sadly this control is quite buggy, but again - did the job just fine for the purposes of the game.

Now, i could go on about the game's development - including some stories like how finding adequate documentation for Sound Blaster 16 was a bit harder than i expected for such a popular device (and how my Pentium 3's onboard sound card turned out to only emulate the base Sound Blaster but not Sound Blaster 16), but TBH this entire article was written to try out Publii. And i am already bored typing 🙃. So i'll end the article with a screenshot of a work-in-progress-though-a-bit-frozen-right-now-so-not-really-in-active-progress port of Post Apocalyptic Petra to OpenGL (and hardware accelerated rendering in general):

Petra, in smoothly colored, depth buffered and trilinearly filtered triangles

If you want to see more of Post Apocalyptic Petra's development you can check my YouTube channel videos in reverse order, starting from the one titled "DOS software render test" (the first video linked at the beginning of the article) and going upwards until the one titled "Started second map (also some sounds)". There are 21 videos in total, taken almost day or every other day (Dishonored playtime excluded) while i was working on the game

Also i have to say... the program's name sounds funny: Publiiiiiiiiii 😁.