Embedded Micro Generators for Dungeons & Dragons Blogs

JDJarvis over at Aeons & Augauries inspired me to write this with his little generators like the Foul Tomes of Carcosa.

You can include generated content in you blog posts by adding a script like the ones below. Put the code into your post using your blog editor's text/HTML mode (on Blogger, click the "HTML" button next to the "Compose" button). Each example is entirely self-contained. Cut, paste, and tinker!

d20 Example

Here we click a button to generate a random number.

The Code for d20

<script>
function roll20() {
    var min = 1;
    var max = 20;
    var roll = Math.floor(Math.random() * (max - min + 1)) + min;
    var outputSpan = document.getElementById("d20result");
    outputSpan.innerHTML = roll;
}
</script>
<div>
<button onclick="roll20();">d20</button>
<span id="d20result"></span>
</div>

Magic Tower Example

Here we combine random selections from various lists, and do it without a button.

Click this paragraph to generate a Magic Tower (then click it again to generate another).

The Code for Magic Tower

<script>
function generateMagicTower() {
    function arnd(a) {
        // Return random element of array a.
        var i = Math.floor(Math.random() * (a.length));
        if (typeof a[i] === 'function') {
            return a[i]();
        }   
        return a[i];
    }
    var colors = ["Red", "Black", "White", "Gray", "Pearlescent", "Lurid", "Hoary"];
    var structures = ["Tower", "Spire", "Turret", "Belfry", "Citadel", "Seculsium"];
    var outputParagraph = document.getElementById("magictower");
    outputParagraph.innerHTML = "The " + arnd(colors) + " " + arnd(structures);
}
</script>
<p id="magictower" onclick="generateMagicTower();">Click this paragraph to generate a Magic Tower (then click it again to generate another).</p>

Dynamic Hit Points Example

In the paragraph below, the hit points are randomly generated each time the page loads. Reload this page to see the hit points change.

An Ogre (HP ; AC 5; Move 9"; HD 4+1) glowers from the cave entrance.

The Code for Dynamic Hit Points

<p>An Ogre (HP <span id="ogrehitpoints"></span>; AC 5; Move 9"; HD 4+1) glowers from the cave entrance.</p>
<script>
function rollHitPoints(hdNumber, hdPlus, hdSize) {
    hdNumber = hdNumber || 1;
    hdPlus = hdPlus || 0;
    hdSize = hdSize || 6;
    var hitPoints = 0;
    for (var i = 0; i < hdNumber; i++) {
        hitPoints = hitPoints + Math.floor(Math.random() * hdSize) + 1;
    }
    hitPoints = hitPoints + hdPlus;
    return hitPoints;
}
var ogreHitPoints = document.getElementById("ogrehitpoints");
ogreHitPoints.innerHTML = rollHitPoints(4, 1);
</script>

Magic Item Type Example

Here we have the classic Magic Item Type select table from page 23 of Monsters & Treasure.

The Code for Magic Item Type

This script selects items from a table that has one result for a range of rolls. The list syntax is slightly different than we've seen. It's a list that contains lists.

<script>
function getMagicItemType() {
    var magicItemTypesTable = [
        [20, "Swords"],
        [15, "Armor"],
        [5, "Misc. Weapons"],
        [25, "Potions"],
        [20, "Scrolls"],
        [5, "Rings"],
        [5, "Wands/Staves"],
        [5, "Misc. Magic"]
    ];
    function randomTableValue(table) {
        // How large is this table? What's the maximum roll? d12, d100, or what?
        var max = 0;
        for (var i = 0; i < table.length; i++) {
            max = max + table[i][0];
        }
        var roll = Math.floor(Math.random() * max) + 1;
        // Find our roll result in the table:
        var countUpToRoll = 0;
        for (var i = 0; i < table.length; i++) {
            if (roll <= table[i][0] + countUpToRoll) {
                return "d" + max + " = " + roll + ": " + table[i][1];
            } else {
                countUpToRoll = countUpToRoll + table[i][0];
            }
        }
    }
    var itemType = document.getElementById("magicitemtype");
    itemType.innerHTML = randomTableValue(magicItemTypesTable);
}
</script>
<div>
<button onclick="getMagicItemType();">Roll Magic Item Type</button> <span id="magicitemtype"></span>
</div>

Arena Fighter Name Generator

We can slightly vary the generated content with randomness and conditional execution.

Math.random() returns a value between 0 and 1.

<script>
function arenaFighterName() {
    function arnd(a) {
        // Return random element of array a.
        var i = Math.floor(Math.random() * (a.length));
        if (typeof a[i] === 'function') {
            return a[i]();
        }
        return a[i];
    }
    function namePart1() {
        return arnd([
            "Al", "En", "Ro", "Fel", "Ston", "Hal", "Jo", "Nel", "Ve", "Ga"
        ]) + arnd([
            "rick", "bert", "wick", "thor", "ky", "son", "frey", "sley", "gil"
        ]);
    }
    function namePart2() {
        var x = Math.random();
        if (x < 0.25) {
            return "the " + arnd([
                "Brave", "Bloody", "Bold", "Cruel", "Clever", "Cunning",
                "Indomitable", "Destroyer", "Quick", "Heartless", "Sly"
            ]);
        } else if (x < 0.5) {
            return "of " + arnd([
                "Green", "New", "River", "Dun", "Lun", "North", "Wolver",
                "Tam", "Chapel", "Wit", "Bran", "Mor", "Ep", "Grims", "Gos"
            ]) + arnd([
                "thorpe", "by", "ford", "bury", "ham", "shire", "ton", "don",
                "ly", "field", "beck", "gate", "well", "holme", "wick", "port"
            ]);
        } else if (x < 0.75) {
            return namePart1();
        } else {
            return "";
        }
    }
    var name = namePart1() + " " + namePart2();
    var outputSpan = document.getElementById("arenafightername");
    outputSpan.innerHTML = name;
}
</script>
<div>
<button onclick="arenaFighterName();">Arena Fighter Name</button>
<span id="arenafightername"></span>
</div>

Dynamically Chosen and Arranged Images (Geomorphs!)

We can play with images as well as text.


<script>
function shuffleGeomorphs() {
    function arnd(a) {
        // Return random element of array a.
        var i = Math.floor(Math.random() * (a.length));
        if (typeof a[i] === 'function') {
            return a[i]();
        }   
        return a[i];
    }
    var geomorphImages = [
        "img/g01.png",
        "img/g02.png",
        "img/g03.png",
        "img/g04.png",
        "img/g05.png",
        "img/g06.png",
        "img/g07.png",
        "img/g08.png",
    ];
    var imageOutputs = document.getElementById('geomorphgrid').childNodes;
    for(var i = 0; i < imageOutputs.length; i++) {
        imageOutputs[i].src = arnd(geomorphImages);
    }
}
</script>
<button onclick="shuffleGeomorphs();">Shuffle Geomorphs</button>
<div id="geomorphgrid">
<img src="img/g00.png">
<img src="img/g00.png">
<img src="img/g00.png">
<br>
<img src="img/g00.png">
<img src="img/g00.png">
<img src="img/g00.png">
</div>

Learn More About JavaScript

You can learn a lot of JavaScript using free tutorials on the web.

Start a cheat sheet and keep track of what you learn. Refine it over time as your understanding increases. Here's my JavaScript cheat sheet, for example.

You may also want to keep a code clipping file to store useful and clever little bits of JavaScript to reuse.

Mozilla Developer Connection has a good JavaScript reference. It's a better than many of the alternatives that rank higher on Google results. (In fact, when I search for JavaScript reference info, I include "MDN" in my search terms.)

If you want to learn from books, these are good:

If you start writing scripts of more than a dozen lines, get yourself a good text editor. For Windows, try NotePad++. For Mac, try TextWrangler. If you're on Linux, you probably already have a favorite text editor, but if not try gEdit (or go all hardcore and learn vim).

Finally, you should at least be aware of JSLint and JSHint. They're alternative sites that find errors in JavaScript code. JSLint is more rigorous/harsher. If your JavaScript gets an error you can't solve, these tools may help you find it.

About These Micro Generators

This code was written by Paul Gorman of the Quickly Quietly Carefully blog. You may copy, reuse, redistribute, and modify the example code however you see fit.