Bogan Ipsum: Building a mildly notorious random text generator before LLMs

February 26, 2026

Bogan Ipsum: Building a mildly notorious random text generator before LLMs

Every time someone demos an LLM generating plausible-sounding nonsense, I think back to 2011, when a small team at a Melbourne digital agency smashed something very similar together on a Friday afternoon. Except instead of billions of parameters and transformer architecture, we had 330 slang words, a MySQL database, and a rand() call.

This is the story of Bogan Ipsum, an Australian slang lorem ipsum generator that got us a bit of notoriety in the Melbourne WordPress and PHP scene. It's also a look back at what "going viral" even meant before social media algorithms took over the internet.

The Origin

It was 2011. I was working at Eleven Media in Melbourne (yes, I have to link to the Wayback Machine - it was that long ago and times have changed that much), and someone in the office had discovered Hipster Ipsum - one of the many themed lorem ipsum generators that were popular at the time.

For the uninitiated: lorem ipsum is filler text used during the design and layout phase of print and web projects. The real stuff is mangled Latin that's been in use since the 1500s, but a whole cottage industry of novelty generators had sprung up to make dummy copy a bit more fun.

Anyway, the conversation quickly turned to: what would an Australian version look like? Not just Aussie - specifically bogan. Colloquial, larrikin, slang-heavy. The concept came from @xavierverhoeven, and it stuck immediately.

So we started planning it out. @BlazRobar would handle design, @AaronRutley would do UI and frontend, and I'd build the generator itself.

The Formula

The first problem to solve was: how do you generate sentences that sound like they belong together, without them being completely incoherent?

I had a think about this and settled on a fixed sentence template:

Phrase + Word + Connecting Phrase + Phrase 2 + Word 2.

So for example, you'd have:

  • Phrase 1: "Grab us a..."
  • Word 1: "tinnie"
  • Connecting phrase: "no dramas"
  • Phrase 2: "mad as a"
  • Word 2: "chook"

Combined: "Grab us a tinnie no dramas mad as a chook."

Grammatically questionable, but good enough for the lorem ipsum vibes.

The sentences didn't need to mean anything - they just needed to feel like they could have come from a real conversation overheard at a Bunnings car park or a Saturday arvo at the footy. That was the whole point.

Building It

The data side was straightforward: three MySQL tables.

  • bogan_words: 330 slang terms and nouns
  • bogan_phrases: 25 sentence-starter phrases
  • bogan_fillers: a handful of connecting phrases

Aaron had sourced a solid list of words from an urban dictionary-style site. Getting the phrases right was the trickier part - they needed to work as sentence openers that could grammatically accept a random word afterwards.

On the PHP side, the generator worked like this: connect to the database, load all three tables into arrays, then loop through and randomly assemble sentences and paragraphs.

// vars
$words   = array(); // to hold our DB data or to store words in directly
$phrases = array(); // regular phrases
$fillers = array(); // connecting phrases
$paras        = 4; // Number of paragraphs to generate
$sentence_max = 9; // Max number of sentences in a paragraph
$sentence_min = 5; // Min number of sentences in a paragraph

After loading the data from the database into those arrays, the generation loop was pretty simple:

// generate paras
for($i=1; $i <= $paras; $i++) {

    // generate sentences
    $sentence_per_para = rand($sentence_min, $sentence_max);
    echo '<p>';

    for($j=1; $j <= $sentence_per_para; $j++) {

        // generate words
        $word1   = strtolower(rtrim($words[rand(1, sizeof($words))]));
        $word2   = strtolower(rtrim($words[rand(1, sizeof($words))]));
        $phrase1 = rtrim($phrases[rand(1, sizeof($phrases))]);
        $phrase2 = strtolower(rtrim($phrases[rand(1, sizeof($phrases))]));
        $filler1 = rtrim($fillers[rand(1, sizeof($fillers))]);

        $sentence = $phrase1.' '.$word1.' '.$filler1.' '.$phrase2.' '.$word2.'. ';
        echo $sentence;
    }

    echo '</p>';
}

The outer loop controlled paragraphs, the inner loop controlled sentences. rand($sentence_min, $sentence_max) meant each paragraph had a slightly different length, which made the output feel less mechanical. Each sentence was assembled by grabbing one item from each array at random and concatenating them together.

That was essentially it. The whole generator was maybe 60-70 lines of PHP including the database queries.

Going (Mildly) Viral

Bogan Ipsum featured on Lifehacker AU, September 2011

Let me be upfront: we're not talking millions of views here. This wasn't a Reddit front page moment. But when we launched boganipsum.com, it did the rounds through Melbourne's WordPress and PHP community, got shared by some people in the local design and dev scene, and earned us a bit of genuine notoriety. For a hack project smashed out on a late afternoon, that felt like plenty.

"Going viral" in 2011 had a very different ceiling to what it means today. There were no TikTok algorithms pushing content to millions overnight. Growth was grassroots: someone with a decent following tweeted it, their followers retweeted it, someone blogged about it. Slower, but you could actually trace the path it took, which was kind of satisfying in its own right.

The site stayed up and kept getting quiet, steady traffic for years. One of those projects that outlives the afternoon it was built by a long stretch.

Then vs Now

Here's what hits differently in 2026: what we built with a sentence template and a rand() call is basically the same idea behind large language models, just unimaginably cruder.

An LLM generates text by predicting the next most probable token given everything that came before it, learned from trillions of words of training data. Our generator predicted the next token by calling rand() on an array of 330 words. It's basically the same idea, if you squint - both are answering the same question: given a partial sequence, what comes next?

The difference is that our "model" had no understanding of context, no way to learn from feedback, and exactly one sentence template. An LLM has billions of parameters and has read most of the internet. The outputs are obviously worlds apart.

But there's something kind of charming about the naivety of the 2011 approach. We weren't trying to fool anyone into thinking the text was real - the whole joke was that it wasn't. Lorem ipsum was always a placeholder, and ours just happened to be a funnier one.

If we built Bogan Ipsum today, the temptation would be to throw a fine-tuned LLM at it and get genuinely coherent bogan dialogue. But I'm not sure that would actually be better. Part of the charm was the random juxtapositions - the completely senseless combinations of phrases that somehow still felt Australian. A smarter model might actually optimise that charm right out of it.

Vibe coding alone vs hacking with mates

There's also something that gets lost in the "one person, one prompt" version of this project. The afternoon we built it, Blaz was doing the design, Aaron was getting the words into a table, and I was wiring up the code and logic - all at the same time, all in the same room. That kind of parallel chaos, where you're all just figuring it out together and yelling across the desk, is a big part of why it was fun. A solo vibe coding session is impressive, but it's a different thing entirely. You skip straight to the result and miss all the bit in between where the actual memory gets made.


Big thanks to the original team: @AaronRutley for UI and frontend, @BlazRobar for design, and @xavierverhoeven for the concept. The original build guide from my old site is still accessible via the Wayback Machine.