I've been fascinated by the concept of fantasy consoles ever since I learned about them. For those who don’t know, a fantasy console is essentially an intentionally limited development environment setup for the creation of games. Think something akin to the NES but with more modern tooling. While I've dabbled in making things in fantasy consoles, I rarely got much farther than some rudimentary building blocks. This is mostly due to not having a clear concept in mind going in. For this project, I knew what I wanted: a (Dark) Souls-like experience in a diminutive, 2D setting.
So how did I go about achieving this? First thing to say is I went with the “just get it done!” philosophy on this little project, so I don’t claim to have written the cleanest, most performant code possible. However, I think the overall architecture is pretty slick in its simplicity.
The general code structure relies on three main things:
- Using (abusing?) Lua’s reliance on tables as much as possible.
- Finite State Machines are king!
- Callbacks! Callbacks! And more callbacks!
PICO-8 is Lua based – which, as an aside, happens to be my favorite scripting language – and Lua loves its tables. Nearly everything is a table in Lua. Even objects are essentially just fancy tables. I used this to create “objects” for key things in the game, such entities, hitboxes, and effects. The overall style in this project is primarily procedural, but there’s no reason I couldn’t have gone for a more strict OOP approach. I simply went with what flowed well during development.
Anyone who has ever double in game development has likely heard of state machines. For AI, state machines and decision trees are two of the most commonly used data structures. For this project, I only used FSMs, as the AI logic didn’t need much more than that. The FSM “object” itself is fairly simply. Its mostly a container for three callbacks: enter, update, and exit.
Which leads to the third main component of the project: callbacks! I used them all over the place. The FSM changes states? Call exit on the previous state and enter on the new one! An animation enters the frame where the sword starts its downswing? Execute a callback to create a hitbox! I even chain callbacks at times, in the sense that a callback on an animation may create an effect which in turn has a “destroy” callback that ensures the related hitbox is removed with it.
With the tech talk down, what was the main goal of this project? What do I mean when I say I wanted to make this game “Soul-like?” My core goal here was to capture the strategic feeling of a Souls fight. Fighting in Dark Souls ultimately comes down to recognizing and responding to patterns. Certain sound effects, animations, or even just counting off a mental timer can help the player dodge and strike at the proper time. That’s exactly what I wanted to achieve here. That’s why this “game” doesn’t have any levels or minor enemies, its essentially just a boss rush.
Well that’s my little write-up on the Souls-like project I made in PICO-8! My friend affectionately refers to it as “Atari Souls,” so feel free to adopt that title yourself if you want. You can find the link to play it below:
https =//bojjenclon.com/projects/pico-8/souls_like.html