Stone Sigil Logo Stone Sigil Games Blog

Tombs of Telleran - One Year Retrospective

About a year ago I started development of the roguelike Tombs of Telleran. With a software engineering background with literally zero experience with Godot, what could possibly go wrong?

What I set out to do

I wanted to make a game that would offer interesting tactical turn based gameplay, but also be fun to build. This latter was important as this is a hobby project and working on something fun makes it so much easier to find the energy to put the hours in after long days at the office. Fun to me is solving programming challenges, and I also discovered I quite like dabbling with pixel art. These reasons lead me to building a roguelike and isometric perspective pixel art. Neither are particularly smart if you want to ship a game quickly, but like I said before, having fun is important. This is what it looks like at the moment. It’s a turn based game where you play as a skeleton, explore tombs, find cursed trinkets, and fight your way forward to try and understand why your eternal rest was interrupted.

A print screen of the current state of the game. I have not created walls yet, but plenty of systems are in place! Like the inventory panel to the right.

So I embraced the Dunning-Kruger syndrome, said “how hard can it be?” and got started with Godot. (Always embrace Dunning-Kruger, otherwise you’d never dare start anything!). In this blog post I want to talk about challenges I faced during the first year of the project.

Learning Godot and Tooling

Before Tombs of Tellleran I had never used Godot, but had experience with Unreal Engine and C#. I am also a huge fan of statically typed languages, so I am using C# for all game code. I still have not created a single GDScript file, although I did create a proof-of-concept Godot project using F# (I really like functional programming). That was probably taking things a bit too far into esoteric land, so I decided to keep things in C#.

Testing

Game code is notoriously stateful and UI and UX is very central, making automated testing very hard. I was naively thinking that since traditional roguelikes are turn based, I could take a functional approach (world state + action => new world state) and test that the correct changes were made when expected. I tried for many hours to get gdUnit4Net to work, but it simply refused to discover my tests. The maintainers were very helpful in GitHub issues but in the end I gave up. This was disappointing, and I made the choice to proceed with the development without automated tests. I would like to note that this was a year ago (summer 2024) and hopefully things have improved now. I know a new major version released this year and I’m interested in trying it out some day.

‘Finding the Fun Fast’ vs ‘Not Building a Cursed Spaghetti Ball of Otherworldly Madness’

Balancing when to take programming shortcuts vs trying to build robust abstractions has been a challenge. This is of course to be expected when embarking on a new project in a new problem domain, but it is worth mentioning nonetheless. Let’s take the games entity/component system which is used to create all actors, interactions and items etc for example. This system has been iterated on a bunch of times. First for an initial proof-of-concept. then to add save-load, then to support dynamically adding and removing components in runtime (to support conditions/buffs/debuffs), and then to support composite components (to reuse component configurations across entities). All this has taken a lot of time, but I’ve been constantly learning and solving programming challenges. At times I have felt like I was doing something wrong spending so many hours building systems and not implementing features, but I’ve come to terms that this is simply what it is like to build a traditional roguelike. There are simply many systems that need to be in place, correct, and interact in interesting ways to facilitate gameplay. And that’s very hard to build in a totally scrappy way. And I am of course learning as I go, which necessitates some trial and error!

State Save Load Wiring Up Components

If you go online and look for advice on initializing nodes in Godot you’ll probably find a lot of people advocating for using the _Ready method or another existing handler. I tried for the longest of time to get by using only the built in handlers but eventually came to the conclusion that I needed something custom. _Ready and friends did not cut it for entity state initialization. This is because entities need to wire themselves up to

  1. Communicate with each other (E.g. Destrutible needs to subscribe to Healths HealthDepleted event)
  2. Communicate with the floor they are placed on (e.g. Position needs to notify the floor where it is)
  3. Communicate with the tombs and UI (e.g. the player components need to update UI)

Finally the components also need to be designed to handle save/load cycles. It is important that when state is restored it is done when all necessary subscriptions are created. All of this is big ask when using only the built in methods, so I have introduced custom AddedToEntity EntityLoaded and FloorLoaded handlers which guarantee that parent components are initialized.

Procedural Generation is Challenging

Before starting I heard a lot about how time consuming it can be to build and tweak the procedural generation algorithm of the game. Because of this I decided to pick one of the simplest one, Binary Space Partitioning. The square structures generated also fits the tomb setting of my game which made it an easy choice. Implementing it to a satisfactory level was not too painful and I think I made a good choice going with it. I also release my code for binary space partitioning which felt like a success.

I am happy I have a solid foundation but realize I want more interesting rooms, and am currently looking into a system where pre-designed room layouts (e.g. ‘contains a body of water to the south-east, ‘contains high-ground to the west’) are sampled per room to create more interesting environments.

Setting and Systems

When starting the project I knew I wanted the setting to be skeletons inside ancient tombs. I know dungeon crawls are a dime a dozen, but had recently finished the ‘The Malazan Book of the Fallen’ book series (A massive 10 book fantasy series. It was quite the project!), so archaeology and bony boys were top of mind. I have also read a collection of Lovecraft’s stories and something about the ‘slow descent into madness’ narrative has always been thrilling to me. I took inspiration from this for the game’s corruption mechanic, which works a bit like sanity in the ‘Call of Cthulu’ table top RPG. When outnumbered, you might just want to use the ‘Ember Bellows’ to create a sea of fire between you and your enemies, even if doing so will corrupt you, which will be detrimental to you if pushed too far. Or perhaps when faced with an armored enemy, that armor-ignoring cursed dagger starts looking pretty appealing…

The Current State of the Corruption System

It has honestly been hard to create a satisfying corruption system though. Since the environments and enemies are not particularly varied, I have not been able to create good tactical challenges that can be overcome with the help of corrupted trinkets, to incentivize the player to use them. The current corrupted trinkets have mostly worked as ‘better weapons’. More damage or range or lower costs, which isn’t very interesting. Designing good combat encounters and interesting trinkets will be the central challenge going forward.

Current State of the Game

So. One year in. How far did I get after this time? The game is fully playable with all core systems in place. Most importantly the underlying systems are easily extendible with new actors, interactions, components etc. This feels great as it will let me experiment with adding and removing content and ‘search for the fun’ much more efficiently than if I had done it six months ago. At the same time, the truth is the game isn’t particularly fun yet, so there is still a lot of searching to do. That is probably a pretty bad mark for a year of development, but it’s my first rodeo so that’s okay.

If you read all of this, thank you very much. I know it was long. Did you relate to anything in the article? I’d be glad to hear from you on bluesky If you would like to follow along and read more about developing Tombs of Telleran, feel free to subscribe to my email list below.