This is not exactly a technology post, and it’s not exactly a gaming post, and it’s not exactly a (personal) history post, but in a way it’s all of those things rolled into one. Let me start by telling you a little story.
When I was somewhere in the neighborhood of 15 years old, our family got a new computer: a Commodore 64, which was, at that time, state of the art. I always thought that we bought it specifically for me, but my father corrected me a few years back, telling me that he originally bought it for himself, but he couldn’t really figure out how to work it, so he figured he’d see if I had any better luck. I did, as it turned out, and it was the beginning of my programming career. I think that pretty much anything you do as a career (as opposed to just a job) has to start out with you doing something for fun. Otherwise you’re just in it for the paycheck.
The first program I ever wrote (which was in BASIC) looked like this:
10 PRINT “MY NAME”
20 GOTO 10
The second program I ever wrote was a D&D character generator.
And, the sad part is, I’ve been doing this over and over again for 35 years, and it’s never worked properly. There are a myriad of reasons for this. A character sheet is a huge quantity of interrelated numbers with complex interdependencies, which make it almost perfect to render as a spreadsheet. But the rules are just baroque and irregular enough to make it a breeze for the first 50% and practically impossible for the last 25%. Contrariwise, the amount of dependent recalculation means that it’s a giant pain in the ass to do in a general programming language, unless you fancy trying to reinvent the spreadsheet wheel.3 The amount of data that needs to be stored, as well as the number of set operations necessary, mean that a database solution (such as SQL) is pretty attractive, for certain aspects. But trying to do that much recalculation in a database language is even more terrifying than trying to do it in Perl or C++, and most of the parts Excel can’t handle, SQL is even worse at.
The thing that makes a database application or language really attractive, though, is the place where spreadsheets really fall down: separation of code and data. If I write a program in a general language, I have code and then, elsewhere, I have data.4 In a database application, the line may be a bit blurrier, but the separation is there, and the proof is, I can give you updated code, and that doesn’t change your data a whit. Not so with spreadsheets. With those, the code and the data are one piece. If I give you an updated spreadsheet, it comes with its own data (which is always blank). But say you’ve already got a character sheet: it’s full of your data—
Now start multiplying that problem. If you’re a D&D player, you probably have lots of characters. And how many people are using this spreadsheet thingy anyways? My very first fully functional Excel spreadsheet was only used for one character each by 3 players (i.e. the 3 players in that particular campaign I was running)—
(To delve a bit deeper into the technical side of the problem, what I really want is for someone to invent a spreadsheet that’s actually just an interface into a database. The spreadsheet programmer “ties” certain cells to certain columns of certain tables in the database, and the spreadsheet user is only allowed to enter data into those specific cells. There could be multiple rows in the spreadsheet, corresponding to multiple rows in the table, and it would be easy to add a new one. Sorting or filtering the rows wouldn’t affect the underlying data. The database back-end might need some tweaking as well—
But the problems with realizing the perfect computerized character sheet aren’t all technical. A lot of it has to do with house rules. If you’re not familiar with D&D, this may not make sense. You may think house rules are simple little things, like getting cash when you land on Free Parking in Monopoly. But RPGs (of which D&D is the grandaddy of them all) have a whole different relationship to house rules. House rules can change anything, at any time, and the rulebooks actively encourage you to use them. “GM fiat” is a well-entrenched concept, and that includes pretty much everything involved in character creation. 2nd edition D&D said only humans could be paladins, but many GMs threw that rule out. 3rd edition said multiclassed characters had to take an experience point penalty, but a lot of groups never enforced that. What if a GM wants to change the value of some bonus granted by some feature? what if they want to raise the maxima for something? or lift the restrictions on something else? What if they want to change the frequency of something, like feats gained, or ability score increases?
So it’s not an easy problem, although I often feel like that’s a pretty feeble excuse for why I’ve been working on what is essentially the same program for 35 years and never managed to finish it. But I’m feeling pretty good about my latest approach, so, if you’ll indulge me in a bit (more) technobabble, I’ll tell you basically how it works.
First, after a long hiatus from the spreadsheet angle, I’m back to it, but this time using Google Sheets. Although I’ve already hit the complexity wall6 with ‘Sheets, it took much longer to get to than with Excel.7 Plus it has a number of things I never had with Excel:8 you can sort and filter in array formulae, and you have both
offset, hidden columns, and tabs full of temporary results. (To be fair, I’ve postponed solving several problems, and I have a lot of “insert arbitrary bonus here” input cells, but those actually help out in the presence of house rules, so I don’t mind ’em.)
So I feel like I’m closer now than I ever have been before. Sure, this one will only work for D&D, and only for one edition of D&D,11 but if I can make it work for pretty much any such character, that’ll still be the closest to fulfilling my dream that I’ve achieved thus far. I’ve got a lot more testing to do before I can make that claim, and several more character types to flesh out (I haven’t done very much with spellcasters at all, and monks are alwyays a giant pain in the ass), but it looks promising, and I’m starting to get just a little bit excited about it. Which is why I wanted to share it with you. And also because it’s been consuming a fair amount of my free time lately, so I thought it might be good to get some details out there for posterity. Maybe one day, if you’re a D&D player, you’ll be using a version of my character sheet on your laptop at the gaming table.
Or maybe I’ll still be working on it in the nursing home. Either way, it should be fun.
1 For the 6510, this would have been. Although I didn’t really have any concept of that at the time; in fact, I really only know it now because Wikipedia just told me so.
3 Which, as I mentioned, I actually tried to do once. I didn’t fancy it.
4 Let’s pretend that where “elsewhere” is is not really important for a moment. The truth, of course, is that it’s vitally important. But these are not the droids you’re looking for.
5 Which is not unheard of. A lot of code out there in the world doesn’t really have data entered by a user, and quite a chunk of it doesn’t even have “users” at all. And a lot of programmers work exclusively on such code. For those folks, this is an interesting philosophical debate as opposed to a self-obvious truth.
6 By which I mean the point at which a spreadsheet fails to recalculate certain cells for no apparent reason. Generally if you just delete the formula and re-enter it, then everything works. But it’s nearly always intermittent, and thus useless to complain about or report. Every spreadsheet I’ve ever worked with has a complexity wall, and the character sheet app always manages to hit it eventually.
7 To be fair to Excel, that was a decade or two ago. It might be better now. But I bet it’s not.
8 Again, it’s possible that Excel may have one more of these features by now.
9 Well, except that Google Sheets currently has a bit of a bug with trying to paste values from one sheet to another. But there’s a simple workaround, which is again a perfect reason to have a little code extension to do the steps for you.
10 Google Sheets has a
queryfunction that sort of lets you do pseudo-SQL on your data tables, but you can only refer to columns by letter, not name, so I consider it fairly useless.
11 Specifically, 5e, which I’ve talked about before on this blog.