Today I want to talk about something all of us love. Numbers.

Well, maybe not numbers, per se. Let’s call it Crunch. Stats. Progression. That magical ingredient that makes Gamelit and LitRPG so fascinating to me and—I assume since you are reading this—you.

A few reviews have said my books aren’t very crunchy. That’s true, sort of. In my books I eschew damage numbers, hit points, and the like. My reasoning is that if you can’t tell the “game” you’re in from real life, then hit points and damage numbers have no place in that game. Hit points aren’t health points! To quote the great man Gygax:

“It is quite unreasonable to assume that as a character gains levels of ability in his or her class that a corresponding gain in actual ability to sustain physical damage takes place. It is preposterous to state such an assumption, for if we are to assume that a man is killed by a sword thrust which does 4 hit points of damage, we must similarly assume that a hero could, on the average, withstand five such thrusts before being slain! Why then the increase in hit points? Because these reflect both the actual physical ability of the character to withstand damage – as indicated by constitution bonuses- and a commensurate increase in such areas as skill in combat and similar life-or-death situations, the “sixth sense” which warns the individual of some otherwise unforeseen events, sheer luck, and the fantastic provisions of magical protections and/or divine protection.”

I could go on quite a bit, but I’ve cut that out in edits!

With that digression out of the way, let’s get to the meaty problem at the heart of LitRPG. You’re writing a book and not documenting a game, so how do you handle the numbers? I’m going to go over a few ways that authors do this, some of which I have used in the past. Then I’m going to show you the way I’m doing it now.

First, though, I want to stress something important that might get forgotten. I write stories. When I do it, the story is more important than the stats. The stats are a literary device, one that gives our characters new limitations as well as options for dealing with the problems they encounter. But in true DM fashion, if the rules get in the way of what the writer wants, the rules have to be bent.

Level 0 – Waving your hands wildly and hoping no one notices

This is a popular style. Basically you make it up as you go along. Stats don’t mean anything at all and you just write them directly in the manuscript. Maybe they follow some kind of progression curve. Damage numbers go up and up as your powers get wildly out of control. Hopefully as an author you can bring the series in for a landing before it all falls apart. This is harder than it seems when you’re making it all up as you go.

Level 1 -Tracking your numbers in a spreadsheet and manually doing sheets

This is the lowest tech way to track real numbers. Spreadsheets for LitRPG tend to get enormous. As an example, here’s a screenshot from one of mine for Blood Eye.

Blood Eye spreadsheet screenshot

That’s just a part of the sheet (it’s very wide) and there are 11 more sheets in that document covering various things like coin income over time, monster stats, experience charts, etc.

Now, your low-tech author spends a bunch of time putting together this sheet and then fills it in, tracking changes throughout the book. Your MC picks up some coin at this point? Note it in the appropriate sheet. Levels up? Gains XP? Note it. Lots of manual tracking of changes. It’s manual, but essential because of the next step.

Now it’s time to get the book ready for readers. That means you need stat sheets! First, you need to make up blank versions of the ones you want, like your character sheet.

Then, you go through your book and everywhere you’ve noted you want a stat sheet you paste a sheet. You either fill it out in place from the data in the spreadsheet, or you paste it in already filled from somewhere else.

This is an incredibly painful process and it hurts me just to think about it. I can’t recommend this for anyone. I’m sure there are some who have done it like this, but not me! This brings me to the next way, and the way I did my first couple of books.

Level 2 – Tracking your numbers in a spreadsheet and using scripting to generate sheets

In real life I’m a programmer and have been for a very long time, so this is second nature to me which is why I didn’t even try any of the lower tech options for my first books. I started at Level 2.

This is much like Level 1, but instead of doing that horrible manual cut and pasting of sheets you do some scripting. For the less tech-savvy writers, that might be doing something in Excel or Google Docs. That’s a viable way to do it. With the right Excel-fu it can generate your sheets for you at each particular point in time. If your day job involves a lot of Excel, this might be the tool you reached for.

For me, I reached for Python, a cool little language that’s great at this sort of thing. I wrote Python scripts that generated all my sheets for me. That included the character sheets, how much money my MC had, all of that.

If you look at that screenshot above you can see the “Event” column. Those are basically points in the book where something changed that I wanted to track, and the name is basically just to remind me where to look.

My Python script would connect to Google docs and pull the data out row by row, and using a template would generate a sheet for each row and place them all into a text file with the “Event” identifier before it to show me where to put it. Like this:

John the half-Planar, level 8

Body: 18
Mind: 14
Spirit: 12

Skills:
Cauterize, beginner 2
Fire Bolt, beginner 7
Herbalism, beginner 1
Improved Fire Burst, beginner 3
Longsword, beginner 9
Lumberjack, beginner 3
Perception, beginner 2
Shields, beginner 6

That worked fairly well, but was still pretty manual. I had to update the spreadsheet, and then after running that script I had to go through and find every insertion point and copy/paste the sheet there. Still, a lot better than the previous levels!

When I was writing Inheritance I began to think about the next level. As a life-long coder, manual processes bug me. The prime virtue of a good programmer is laziness. We want to avoid doing work we don’t have to, and Level 2 is a lot of work I didn’t have to do.

So, of course the solution was to do a ton of work up front to avoid doing this manual drudgery in the future. Foreshadowing: It totally paid off you guys.

Level 3 – Tracking your numbers in the manuscript itself

What’s this? The title makes you think I’ve gone back to Level 0? Hell, no. Never. Let me explain.

When I was writing Inheritance I had some very annoying problems. For instance, I had a disposable laser pistol with X amount of shots and no more. So every time I took a shot, I needed to worry about how many were left. Super annoying! I was tracking that number in my spreadsheet along with air in the way I showed you above with the spreadsheet:

Screenshot of Inheritance spreadsheet

I can’t remember why I called the laser pistol shots “BP Charges”, but there it is. You can also see how much life support was left in minutes, and how many Nanite Clusters Jake had at each point.

My scripts were making the sheets for me, but inserting something like “I saw that my laser pistol had XX charges left” was very painful indeed. These numbers matter!

So when it came time to write Redemption, the second book in The Last Enclave series, I resolved to never feel that pain again. Most authors do that by simplifying their system. For instance, their character regenerates mana so fast they don’t have to worry about it anymore, or they just hand wave that pain away. Full disclosure: I did some of that too!

The first change I made was switch from using Scrivener, which is a great tool for writers to using Sublime Text 3, which is a text editor. Why did I do that? Because I needed my books to be written in plain text. Well, Markdown specifically. The reason is a nerdy programmer reason: I wanted source control to work, and it didn’t with Scrivener’s RTF files. That’s a nerdy rabbit hole and if you’re interested I’ll go into detail there.

Anyway, from my perspective plain text/Markdown is a BIG win. Also, Markdown converts directly into HTML so is pretty trivial to shove into an epub/convert into a mobi.

The second big change was how I tracked my stats. The spreadsheet is gone! Vanished entirely. Let me show you when I introduce the upgraded Krigar Assault Armor in book 2. This is directly copied from the Redemption manuscript.

A icon caught my eye that hadn’t been there before. A bulky, familiar silhouette that clearly represented my Assault Armor. I pressed it and a brand new status sheet appeared.

[!stats]
KAA={}
KAA[‘NC’]=0;KAA[‘NCMax’]=500
KAA[‘LifeSupport’]=14
KAA[‘PUStorage’]=5000;KAA[‘PUStorageMax’]=5000
KAA[‘PU’]=100

[!template]
name=”status/KAAV1″

“Whoa, Metra. You added a stat sheet for the armor?”

A bit of explanation for the non-programmers reading. The [!stats] block is setting some stats, specifically a KAA variable and its properties. The KAA can store 500 Nanite Clusters, but isn’t storing any at this point in time. It also has a battery (PUStorage) which is fully charged and is generating 100 PU/sec.

The [!template] block is inserting the Assault Armor’s stat sheet right there in the manuscript. The template uses the variables I’ve just set, or potentially set earlier in the manuscript to show the current values of the Assault Armor. Here’s that template.

Krigar Assault Armor KAA-8V2

*Armor Integrity Levels:*
All Sections Nominal

Stores:
Bio-consumables: ~60 days
Life support: ~{{ KAA.LifeSupport }} days
Nanite Clusters: {{ KAA.NC }}/{{ KAA.NCMax }}

*Energy:*
Internal Generation: {{ KAA.PU }} PU/s
Auxiliary Generation (Augment): {{ Jake.PU }} PU/s
Internal Storage: {{ KAA.PUStorage }}/{{ KAA.PUStorageMaxPU</p>
*Energy Consumption:*
Propulsion Units: 0/60 PU/s
Gravity plates: 0/20 PU/s

Now you can see I’m cheating a bit here. Not everything is a variable, but it could be. If I wanted I could have a variable for the damage to the armor, or a bunch of them. But since this V1 of the armor doesn’t take a lot of damage before it’s upgraded, it’s not needed.

For another, much simpler example, here’s Jake picking up some loot.

[!stats]
Jake[‘NC’]+=20

“Just like Matty, he’d never forget to loot either,” said a voice from the hole.

Pretty cool, huh? If I don’t forget to do things like that in the manuscript, that means the numbers are always up to date. If I insert a character sheet template there, the NC number will be accurate. I haven’t used it yet, but I could also theoretically insert that particular variable inline, like:

I checked and saw that I had {{ Jake[‘NC’] }} Nanites in my internal storage.

Not exactly the correct syntax, but close enough to get my point across.

So in conclusion…

Hah, I bet you thought I was done, didn’t you? No, sir.

Level 4 – Morgan goes crazy extending his awesome system for Capo

Redemption isn’t out at the time of writing, but it turned out really well. The system works wonderfully. So when I started writing Capo (my Royal Road Gangster Gamelit serial) I of course used it.

NOTE: I’m going to show this off a bit because I’m pretty proud, but we’re getting deep into programmer territory here, so feel free to skip over. If you’ve got questions ask and I’ll answer.

So Capo has got some tracking needs just like The Last Enclave books have. For instance, when Frank sells drugs I need to give him cash, take some of his drugs and add the earned cash to his skills if they were used in the sale. Nasty, right?

But that’s not all. What if he levels up his skill by selling some of his drugs? Do I have to manually check to see if he leveled up, like an animal?

No, sir, I will not.

So here’s how that works in the manuscript now.

[!stats]
#Update cash and skills, reduce inventory
sellDrugs(‘weed’, 5, 50, customerid=2)

That strange tingling feeling hadn’t gone away, and it was bugging me. An itch at the back of my mind. When I scratched at it, I got a popup.

[!template]
name=”SkillLevelUps”

[!stats]
clearSkillLevelUps()

To explain what’s happening. This is summarizing a period of time where Mack sells 5 grams of weed at $50 a dime. During that time, his Customer ID skill successfully activated twice, so it gets credited for two of those sales and gets $100 towards its next level. The other thing you’re not seeing is that Fast Count (the ability to count money in your hand automatically) works every time, so it gets $250 toward its level there and had also leveled up previously (the tingling sensation).

The sellDrugs call does all the accounting of cash, weed and earned xp/cash and also levels up the skills if they pass the threshold.

The next template SkillLevelUps displays any skills that have been marked as leveled up, and clearSkillLevelUps removes that mark so that template won’t show them the next time it’s called.

If you’ve got some programming savvy you may be able to see that I’ve structured this so that theoretically I could just spam the SkillLevelUps template every time I sold drugs, but that would suck. Sure, it would only show skills when they leveled up, but I placed it here because I knew that there was a level up and I didn’t want to litter my book with popups and have to write around them. I think it’s a good balance. After all, this is still a book and not a game.

Finally (for real this time) I want to show off how skills work. This is getting pretty close to actual game dev at this point. This is from one of the “data” files of Capo that’s used to populate static data before the story itself kicks off. I’ve edited it down to just show one skill and its “advancement curve.”

[!stats]
# advancement curves
EarnCurves={}
EarnCurves[‘doubler250’]= { ‘start’: 250, ‘func’: doublerAndAddFunc }

[!stats]
Skills={}
Skills[‘fastcount’]={ ‘name’: ‘Fast Count’, ‘rarity’: ‘F’, ‘desc’: ‘Quickly count up to ${amount} cash in your hand with a brief period of concentration.’, ‘earncurve’ : EarnCurves[‘doubler250’], ‘levels’: [{‘amount’:100}, {‘amount’:200}, {‘amount’:500}, {‘amount’:1000}, {‘amount’:2500}, {‘amount’:5000}, {‘amount’:10000 } ] }

If you’re a programmer and can read that, you can see that Fast Count has 7 levels. At each level, the amount of cash that can be counted goes up until it finally caps at $10k. The “EarnCurve” structure is how I describe how much cash is needed to advance the skill at each level. In this case it’s $250 for the first level, and then double that for every additional level. So $250, $750, $1750 total. I can either do it like that with a formula/function or I can manually specify the values per level.

Anyway, I hope this was an interesting read. It might only be that to a very small subset of LitRPG writers, but I had fun writing it while I waited for 100,000 shaders to compile. Let me know what you think, and please, give my books a read. I dearly want to become that grumpy old writer living in the countryside and cranking out a book every month or two.