Posted August 24, 2017
I propose that all software tools adhere to the following motto:
Do your job, then get out of the way.
We all know what it looks like when you don’t follow this rule. You get Adobe Creative Cloud. Or Nvidia GeForce Experience. Or Visual Studio. You get that tool you downloaded for a one-time filetype conversion, only to find it wanted to scan your entire computer first, chew up 75% of your idle CPU time, set up an auto-updating system, subscribe you to its newsletter, and give you handy-dandy tips every time you open the tool.
Think about all the tools you use that assume they’re the center of the universe. Where it feels like the author takes every opportunity to remind you how awesome the tool is, and all the amazing things it does that you don’t want or need.
It sucks, right? Don’t do that.
A good software developer thinks like the user. They pretend they’re just some person who wants to convert three PNGs to JPGs so they can email their mom photos of their dog. What is the software that would best allow them to accomplish this goal? Does this person care at all about reading startup tips? Will they wait around for five minutes while the tool scans your filesystem for images?
The best tools I use are very specialized. They have one job, and they do it damned well. If you want to write a good tool, this is a valuable mindset to take. Not only will it make your tool better at its job, but it will help you:
- Fight scope creep
- Eliminate features that aren’t truly needed
- Keep the UI simple and focused
- Keep your software lightweight and trim (and fast)
There’s nothing wrong with having many sharp, specialized tools, each finely-tuned for one particular job. I’d rather that over one tool that does a mediocre job at many things. I call this collection of tools my programmer’s toolbelt. There’s a reason carpenters carry a hammer, and a drill, and a nailgun, and a saw, and a framing square, and a level, and a tape measure…
My go-to case study for this philosophy is the search program Everything.
You hit a hotkey, a window opens. You type until you see what you want, then select it. The file opens. Everything closes, because its work is now done. Simple. It does its job, then gets out of the way. Everything’s adherence to this motto is why it’s such a joy to use, and why it’s been part of my programmer’s toolbelt since my first job in the game industry.
Posted July 29, 2017
The website now has a comment section! Please post thoughts, questions, and bug reports to your heart’s content. I promise to read every last one.
The Tallest Tower is now on Twitter! Follow us, tweet at us with great vigour, and do all the other twittery things you love to do.
Posted June 21, 2017
Mini-update: I just wrote a “scrapheap” to supplement the D garbage collector. By scrapheap, I mean:
- A 16 MB pre-allocated chunk of memory, acquired from the OS on startup and never released
- Other code can allocate into that chunk using a dead simple bump-the-pointer stack
- The stack is reset at the end of each frame, therefore “freeing” the 16MB and making it available for use again
It’s very desirable to be able to allocate small amounts of short-lived memory without having to think too much about it. For example, when parsing string input, I might do the following:
string optionWords = optionText.strip().removechars(".,!'").toLower().split();
return optionWords == someOtherThing;
Being able to do all that string manupulation in one line is really nice. I don’t have to manually allocate buffers or anything, it’s all taken care of. In D though, normally this allocates several times via the GC, even though once this function returns, I don’t use any of the allocations ever again.
Enter the scrapheap.
To enable it, I add one line to the beginning of this scope:
string optionWords = optionText.strip().removechars(".,!'").toLower().split();
return optionWords == someOtherThing;
This mixin tells the GC that from now until the end of this scope, every allocation should be redirected to the scrapheap. Now all the allocations in this function are practically free (just the cost of bumping a pointer), and deallocation is free (resetting the pointer at the end of the frame). As long as I’m not expecting any of the allocations to outlive the frame, I’m in the clear.
For use cases like this, a scrapheap allocator the best of both worlds. Convenient-to-write code, without any allocation or deallocation overhead or contribution to future GC pauses. And these use cases make up a significant portion of the allocations that occur in the game each frame.
We use a stack to keep track of the currently-active allocator. That way we can switch to scrapheap mode for a large function, but then inside have a single function call that switches back to GC mode, and then inside of that have a subsection that uses the scrapheap, and so on. Switching to GC mode is what you’d expect:
We have a separate allocator stack per thread for obvious reasons. With this model we can easily add new allocators if we decide to in the future.
This whole throwaway memory stack idea is not even remotely new. Despite this, when discussing memory management the conventional wisdom I always remember hearing was “Allocating is always going to be expensive.” But evidently, this doesn’t have to be the case.
Posted May 19, 2017
It is said that after experiencing a creative work of great merit, you are a different person at the end than you were when you first began. I just experienced this, in a game where you roll sausages around with a fork.
Stephen’s Sausage Roll is one of the most challenging, rewarding, and well designed puzzle games I have ever played. Give it a try before reading on, because I’m about to (slightly) spoil one of the levels.
I’m a programmer by trade, so it’s no surprise I like puzzle games. And because of the whole programming thing, I probably have above-average grit when it comes to puzzle games. I won’t look up hints until I’ve spent three or more hours on an individual puzzle, utterly stumped.
There is a puzzle in Stephen’s Sausage Roll called Wretch’s Retreat. I spent six hours total on that level. Two of those were mapping out all possible avenues that might lead to a solution. The other four were checking and re-checking my reasoning, retrying all my attempts in order to figure out what I had missed. In these four hours, I made virtually no progress.
Eventually, I gave in. I turned to the internet to find the tiniest clue possible to nudge me in the right direction. I found this Steam discussion, which turned out to be the perfect hint.
The author outlined all of their assumptions about the rules and logic of this level, and all the possible solutions and why none of them were viable. I nodded along as I read this, these were the same assumptions I had come to. Then, in a reply to their own post, the author said:
Nevermind, I solved it. Unbelievable. Stuck on it for so long, as soon as I make a post it hits me. If anyone is wondering, the error was assumption (#2).
After reading this, I solved the puzzle in thirty seconds.
The hint hadn’t told me what the solution was, or what I should try next, or what about my assumption was wrong. All it told me was that one of my assumptions was wrong. Which, of course it was, otherwise I would have solved the puzzle. But simply being told which one was enough to make me question that assumption in a way I clearly had not yet, and arrive at a solution immediately.
If I had itemized my assumptions in the same way, and mechanically gone through them one by one trying actively to disprove them, I almost certainly would have arrived at the solution on my own. If I had told myself “Okay, let’s pretend for just five minutes that this thing I’m certain is true is actually false, and try to demonstrate why”, I would have found the hole in my reasoning. I’ve done a lot of problem solving in my life, and don’t think I’ve ever explicitly needed to do this before.
Thanks to Stephen’s Sausage Roll, I’ve added a new tool to my problem-solving tool belt.
As an aside, it’s also fun to see the poster of that discussion essentially discover rubber-duck debugging on their own, a well-known problem-solving technique in the realm of programming.
Posted May 7, 2017
For those with a more technical leaning, here’s the rundown on what I’m using for the game:
- Custom engine written in D
- SFML for 2D graphics and windowing
- FMOD for audio (low-level API, likely won’t use FMOD Studio much)
- dear imgui for debug UI
- msgpack-d (ie. MessagePack) for serialization (save games, debug game state snapshots, dialogue database)
- Python for build tools and miscellaneous scripts
I’ll dive into each of these in more in detail at a later date. I’m rolling a custom engine for a few reasons:
- I come from a programming background, so I have some familiarity with the lower-level workings of games
- This will be a 2D game, which makes writing an engine more manageable than for a 3D game.
- I am very picky about my tools, and very picky about making sure the game works exactly the way I want it to.
Where possible I try to give myself total visibility into any source code used in the game, since this allows me to add features and fix issues in library code I’m using. And there are always issues. In its prototype stage, I have already made source modifications to SFML, imgui, msgpack-d, and even the D language runtime and standard library. I anticipate making many more as work continues.
I spent a while evaluating other audio libraries, but none of them had all the features I was looking for. BASS was close, but they don’t sell a source code license. Wwise was another contender, but it appears you’re forced to work from within their designer tool. Using FMOD for audio makes me a little nervous since it’s one of the few parts of the game where I’m using an opaque DLL with no available source code for reference. However I’ve heard positive reviews of the FMOD API, and so far my experience has been good. Also if all else fails, they do sell an (expensive) source code license.
I just finished fully setting up FMOD (I was using SFML’s built-in audio system before as a placeholder). Everything looks golden so far. The next step is to play around with some of FMOD’s dynamic music functionality, which should be good fun.
Posted April 9, 2017
Welcome to the development blog for The Tallest Tower!
Over the last few years, I’ve been doing some thinking about stories in games. I have a lot of thoughts about a particular kind of game I’d like to see made, and how story can be entwined into the experience in interesting ways. When I look around, I see the occasional game with bits and pieces of what I’d like in this hypothetical game. But no game yet has captured the entirety of what I have in mind.
So, I’m going to make it.
I have a full time job as a programmer, so I’ll be developing this in my spare time. I already have the basics of an engine and the first parts of the game up and running. But it is very much a simple prototype at this stage. That will change though, as the game grows and evolves over the coming months.
The name “The Tallest Tower” will certainly change before the game is done, but I needed a working title for the project. So, there you have it. No guarantee of any towers appearing in the final game, tall or otherwise.
I’ll add a comments section to the site eventually. But until then, shoot me an email at firstname.lastname@example.org if you have any questions or comments.
In short, welcome. I’m glad you’re along for the ride.