Chad Perrin: SOB

29 August 2008

calculating XP (and other leveling data) for D&D 3.5

Filed under: Geek,Humor,RPG — apotheon @ 11:20

This is part of my RPG series of entries here at SOB. See the inaugural entry in the series for more details.

This SOB entry could easily have been called “Mathematically Generating the D&D 3.5 Experience Chart”, but I decided against that title.

The D&D 3.5 Player’s Handbook contains an experience chart, “Table 3-2: Experience and Level-Dependent Benefits”. The SRD — a collection of OGL materials released by WotC — does not, on the other hand. The d20 license, used to determine who may or may not display the d20 logo on an OGL product or claim d20 system compatibility, specifically restricts anyone from describing level advancement in a thusly licensed product.

I discussed a little of this very briefly in my D&D 3.5 Experience Level Charts entry here at SOB, along with a reference to how you can use my pfconv Web interface (or the pfconv command line utility, both of which are described in Pathfinder RPG a3 XP converter) to get around certain aspects of the WotC restrictions. It’s far from a perfect solution, however.

This bit of stupidity from WotC is why so many third-party developers for systems that are effectively compatible with D&D 3.5 (even if the closest they can legally come to saying it is “compatible with the world’s most popular roleplaying game”) must choose between describing character leveling or displaying a d20 compatibility logo. When leveling is described, publishers of third-party materials end up creating their own variations on how leveling is accomplished, usually involving a very different looking chart. One example is the Pathfinder playtest releases’ “Table 4-1: Character Advancement and Level-Dependent Bonuses” — against which, by the way, there doesn’t seem to be any copyright reprinting restriction, unlike the equivalent “Table 3-2” in D&D 3.5.

Of course, with a halfway decent lawyer, one could probably get away with reprinting D&D’s “Table 3-2”, as long as one was clever about it, by claiming coverage by the doctrine of fair use. This is not something I particularly care to test, however, as I don’t really care to have to get a halfway decent lawyer to defend something I’ve said in SOB about leveling in D&D. The problem is not that any copyright restriction prevents me from explaining how one increases in level in D&D, but that reprinting “Table 3-2” as printed in the book would involve verbatim copying of copyrighted material — and even slightly altering how it’s presented might be argued to be nothing more than an attempt to circumvent copyright law inappropriately.

On the other hand, I don’t actually have to reprint any useful information in that chart at all to provide a means for those of you with some basic tools at your disposal with a way to calculate the information in “Table 3-2” for yourself. It’s pretty simple, really: I’ll just describe the formulae for generating the information, and provide some Ruby code in case you want to actually generate the numbers yourself.

XP totals:

The formula to determine the XP total for a given level is:

F(L) where:
L = target level, and
F(L) = 0 if L = 1, else F(L-1) + (F(L-1)*1000) if n > 1.

The formula to determine the max ranks that can be put into a single class skill for a given level is:

L + 3 where:
L = target level.

The formula to determine the max ranks that can be put into a single cross-class skill for a given level is:

(L+3) / 2 where:
L = target level.

The formula to determine the number of feats you should have, discounting Fighter bonus feats or the extra feat for being human, is:

1 + (L/3), rounded down, where:
L = target level.

The formula to determine the number of bonus attribute points you get for leveling is:

L / 4, rounded down, where:
L = target level.

I’ve written some Ruby code that produces the output of the above formulae for levels one through twenty in a simple command line utility. To get the XP values, assuming you name your Ruby script phb3-2 (after the chart in the PHB), you would enter the command phb3-2 xp. For max ranks in class skills per level: phb3-2 cl; for cross-class skills: phb3-2 xcl; for total feats: phb3-2 feats; for total bonus attribute points: phb3-2 attributes.

This is the (ugly) code:

def up_xp(n)
  return 0 if n == 1
  return up_xp(n-1) + (n-1)*1000

def format(l,n,s)
  return sprintf("%1$*2$s : %3$*4$s", l, 3, n, s)

if ARGV[0] == 'xp'
  1.upto(20) do |l|
    puts format( l, up_xp(l), 6 )
elsif ARGV[0] == 'cl'
  1.upto(20) do |l|
    puts format( l, l + 3, 2 )
elsif ARGV[0] == 'xcl'
  1.upto(20) do |l|
    puts format( l, (l+3) / 2.0, 4 )
elsif ARGV[0] == 'feats'
  1.upto(20) do |l|
    puts format( l, 1 + (l/3), 1 )
elsif ARGV[0] == 'attributes'
  1.upto(20) do |l|
    puts format( l, (l / 4), 1 )

Unfortunately, I won’t be creating a Web interface for this script the way I did for pfconv, because then I’d be providing you with direct duplications of what’s on “Table 3-2”, and while I’m sure I could defend it in court if it came to that, I prefer to play things a bit more safely. I probably won’t be cleaning up the code to make it more like a really useful command line utility any time soon, either, because I just don’t care enough right now.

So . . . if you are reasonably good at arithmetic or can manage to get some Ruby code working on your system, you now have what you need to calculate all the values on “Table 3-2”, one column at a time, if you didn’t already.

. . . or you could just play Pathfinder RPG instead, and use the OGL (and thus freely reprintable) leveling chart data from the freely downloadable Pathfinder RPG Beta test rulebook PDF, which serves as the equivalent of (most of) both the PHB and DMG, all in one package. There’s also a “softcover” book version of the Pathfinder RPG Beta you can get for $25, if you like having a physical book in your hands.

That’s why I don’t really care to put more effort into this Ruby script than I already have: it doesn’t really matter that much to me, since I’m weaning myself off D&D 3.5 and replacing it with Pathfinder RPG instead.


  1. This post is full of marketing genius, and I will be outraged if people from Paizo don’t come knocking with brownies and paychecks.

    That being said, I keep hearing really lovely comments from the Pathfinder RPG from a lot of people that really liked D&D 3.5 and have not adopted 4th Edition as their new baby. I also can’t be the only one that wants to hear how the games are going, so I sincerely hope that you let us know how is that working for you and also any ideas that you might have for people also implementing the system.


    PS: Good to see you’ve posted a few more entries in the RPG area!

    Comment by the_blunderbuss — 1 September 2008 @ 08:23

  2. This post is full of marketing genius, and I will be outraged if people from Paizo don’t come knocking with brownies and paychecks.

    I won’t be outraged if they don’t — but I’d be quite pleased if they did, and I appreciate your outrage on my behalf. Thanks for the compliment, at any rate!

    I also can’t be the only one that wants to hear how the games are going, so I sincerely hope that you let us know how is that working for you and also any ideas that you might have for people also implementing the system.

    I’ll be sure to share every time I feel inspired to write about it. Pathfinder has me excited about fantasy RPGs in a way nothing else has since Planescape at the latest — and even that wasn’t as big a deal as Pathfinder RPG, since it was just a great setting, while Pathfinder RPG is not only a pretty much pure improvement new edition of the D&D tradition, but also accompanies Paizo’s Golarion campaign world as its default setting (much better than Greyhawk, which in turn was at least incrementally better than Forgotten Realms).

    Good to see you’ve posted a few more entries in the RPG area!

    I’m pretty sure I’ve mentioned before — these things tend to come in bursts. As they come to me, I’ll be sure to share. I’m having a lot of fun with my fantasy RPGs these days, so I’m sure I’ll have a lot to say about D&D and PRPG in the near future.

    Comment by apotheon — 1 September 2008 @ 10:17

  3. Since this article was written the new release of D&D 4th edition have happened. In this release the algorithm have been changed to this:

    Xp needed for gaining first level is 0, as usual, xp needed for gaining the second level also falls out of the algorithm, and has therefor been given another exception in the code. Otherwise the xp-curve is rising exponentially with 250 each time. That results in this code:

    def xp_needed_for_level(n)
      return 0 if n == 1
      return 1000 if n == 2
      return xp_needed_for_level(n-1) + (n+2)*250

    I have simply tested with some sporadic level values and compared it to the xp/level-table in PHB 4.0. So if anyone have any additions or corrections they are welcome.

    Best regards.

    Comment by Emil Kampp — 23 April 2009 @ 04:52

  4. Thanks for adding an algorithm for the 4E level progression system, Emil. I may test it further, myself, at a later date — but I don’t feel any particular urgency, since I don’t actually play 4E.

    Comment by apotheon — 25 April 2009 @ 12:20

  5. A direct way to calculate XP for a given level n in 3.5 is

    0 if n = 0 n*(n+1)*500 if n >= 1

    Comment by Groody — 2 July 2009 @ 03:10

  6. Close. Your results are accurate — but off by one level. It should actually look more like this:

    0 if n < 2
    n * (n - 1) * 500 if n > 1

    I’ve confirmed that works all the way up to 30th level. Of course, this doesn’t do any checking for unexpected inputs or anything like that, so actually real-world usable code should have a little more complexity to it.

    Thanks for contributing a direct formula for determining XP for a given level, even if it required a touch of tweaking.

    Comment by apotheon — 2 July 2009 @ 09:29

  7. Unfortunately, the addition for 4e only works up to 6th level, after that it becomes skewed more and more, leading to only needing 61,750 xp at level 30 using that calculation. When in reality, l,000,000 xp is the target.

    If there is a formula for 4e, I’d -love- to have it, but, unfortunately, I think 4e is just arbitrarily adjusted to match up so they end with 1 million XP.

    Comment by Trinkit — 19 July 2009 @ 11:15

  8. I finally got around to checking out the 4E experience progression table closely enough to see whether any patterns emerged. I gave up when I got up to 11th level. It appears you’re right: there’s no singular pattern to the number of XP needed for the next level. A formula could be worked out, but programmatically describing the algorithm would end up being more complex than just hard-coding all the numbers in an array and checking against the array.

    Thus, a program for 4E would actually look something like this (optimized for less typing on the part of the programmer by getting rid of a zero from each number in the array, then adding it back in with * 10 in the line of code that retrieves values from the array):

    xp_needed = [
    xp_needed[n - 1] * 10

    I guess there must be fewer people who like math working at WotC these days than there were in the D&D 3.x days.

    Comment by apotheon — 25 October 2009 @ 09:52

  9. FYI, I’m no math-wiz by any means, but there is an oddly semi-consistant rate of increase that – usually – runs about four levels before doubling. The prime arbitrations arise for the first two levels of a new “tier” is introduced: at first and second level (0 and 1k XP respectively), eleventh and twelth level (26k XP and 32k XP respectively), and at twenty first and twenty second level (175k and 210k respectively). These levels don’t really ‘fit’ with the surrounding almost-patterns. In heroic tier (1st-10th levels) you have the arbitrary 1st and second level, followed by four sets of XP increasing the rate of requirement (“accelerating”) by 250 each level. After four levels, this doubles to 500. After four levels (ignoring the two for arbitrary tier introduction in the paragon tier [11-20]) this doubles to one-thousand. Something odd happens to the rate of acceleration in the paragon tier, however, as it does a few strange jiggs that almost make it into the pattern, but not quite. Epic tier [21-30] copies hero tier [1-10] in the pattern of 2 levels (arbitration) 4 levels (one value) 4 levels (new value). I don’t know how – if at all – one could make a working formula for this. My guess is that they thought up a nifty pattern, and then almost made it work, but ‘fudged’ it slightly to get to 1 million XP. On the other hand, much of 4E is arbitration (the enemies and monsters have no ability to grow or increase – they are static stat-blocks worth a set amount of XP, for example), so why should the XP charts be different? If I was designing it, and 30th level was to be my capstone, I might have just indicated that by putting the “extra” XP needed to get to 1 million on there. Anyhoo, I was looking for an XP chart generator to see if anyone created a viable pattern from it when I came across this place, and thought I’d throw in my 2 cents. Peace!

    The chart numbers, if it helps:

    Tier Level XP needed Increase Acceleration Iterations Heroic 1 0 0 0 tier arbitration 2 0,001,000 1,000 1k tier arbitration 3 0,002,250 1,250 250 first 4 0,003,750 1,500 250 second 5 0,005,500 1,750 250 third 6 0,007,500 2,000 250 fourth 7 0,010,000 2,500 500 first 8 0,013,000 3,000 500 second 9 0,016,500 3,500 500 third 10 0,020,500 4,000 500 fourth Paragon 11 0,026,000 5,500 500 [+double] tier arbitration 12 0,032,000 6,000 500 tier arbitration 13 0,039,000 7,000 1k first 14 0,047,000 8,000 1k second 15 0,057,000 10,000 2k first !! 16 0,069,000 11,000 1k
    17 0,083,000 14,000 2k
    18 0,099,000 16,000 2k
    19 0,119,000 20,000 4k first 20 0,143,000 24,000 4k second Epic 21 0,175,000 32,000 4k [+itself] tier arbitration 22 0,210,000 35,000 3k tier arbitration 23 0,255,000 45,000 10k first 24 0,310,000 55,000 10k [+1k]
    25 0,375,000 65,000 10k
    26 0,450,000 75,000 10k
    27 0,550,000 100,000 25k first 28 0,675,000 125,000 25k second 29 0,825,000 150,000 25k third 30 1,000,000 175,000 25k fourth

    Comment by tacticslion — 26 October 2009 @ 11:35

  10. I hope I’m not breaking decorum by double posting, but that chart REALLY didn’t come out like it looked for me. Sorry. It’s supposed to be a series of neat rows; since I’m not used to this code, I guess I just didn’t understand what it would look like upon posting. Sorry.

    Comment by tacticslion — 26 October 2009 @ 11:38

  11. If you sign up for an account here, you can use either XHTML markup or Markdown to format your comment. If you use Markdown, you could format a table the way I formatted my source code, by indenting each line of it four spaces in addition to whatever indentation it actually requires. That tells the Markdown translator that you want the four-space indented text to be rendered in a fixed width font and that you don’t want word-wrap.

    Of course, you should do your best to make sure the lines of text are short enough that the word-wrap part of it doesn’t become an issue, because it gets a little ugly if you overrun the word-wrap line length.

    Anyway, thanks for sharing. If anyone has any bright ideas how to simplify the numbers you’ve provided, I hope they’ll let us know, but I don’t see any patterns stable enough to bother developing any algorithms for programmatically generating XP numbers per level.

    Comment by apotheon — 27 October 2009 @ 10:10

  12. I’m sorry to have to break this to you but I have some mathematical comment on your formula (I’m only read as far as the first formula).

    You write: “F(L) where: L = target level, and F(L) = 0 if L = 1, else F(L-1) + (F(L-1)*1000) if n > 1.”

    according to what you are writing here for L=1 F(l)=0 which is correct, now for L>1 you have F(L-1) + (F(L-1)*1000) so let’s try the formula for L=2 in which case we have F(2)=F(1)+F(1)*1000 F(2)=0+0*1000 F(2)=0!!! Actually F(L) will equal zero if you apply this formula for any L that belongs to N*

    A more appropriate function that could define the experience in which you reach a given level would be to say that F(L) equals the summation(for n=1 to n=L) of (n-1)*1000 for L belonging to N* F(L)=sum((n-1)*1000)(1:L)) so some examples: for L=1 F(1)=(1-1)*1000=0 for L=2 F(2)=(1-1)*1000+(2-1)*1000=1000 for L=3 F(3)=(1-1)*1000+(2-1)*1000+(3-1)*1000=3000 and so on and so forth up to infinite number of levels

    now that I got this out of me I will continue reading your post past the first formula!

    Comment by John Thomas — 24 June 2010 @ 07:05

  13. I took the liberty of editing your comment so it is formatted correctly, John. Please let me know if I’ve made any errors.

    I’ll read it in more detail later. I’m just trying to get caught up on a few things right now, and don’t yet have time to give your comment the attention it deserves.

    Comment by apotheon — 25 June 2010 @ 08:54

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

All original content Copyright Chad Perrin: Distributed under the terms of the Open Works License