Start with Randomness and Inspiration.

We need to talk about a few tools that I think can be helpful. These are also fun recreational programming topics. So much so that I’ve pitched talks at programming conferences about these.

Overview —- Why any of this matters

The point is to stimulate thinking — offer inspiration — in tight places. We all reach those places where we’re running low on ideas, and everything we’ve tried has seemed very good.

I. World-Building for Fiction (and Games)

Drama is conflict: spaces vs. tabs, inheritance vs. delegation.

Some of us find limits to what we can imagine. It gelps to turn to models to create examples.

II. Things we can simulate in Python

  1. Terrain. We'll look (briefly) at a way to evolve a map incrementally.

  2. Character Descriptions. We'll look at making weighted random selections.

  3. Story Arcs. We'll look at ways to create a narrative from a few randomly-selected elements.

  4. Languages. We'll revisit some weighted random selections. We'll touch (briefly) on grammar transformation rules.

III. Resolution

Creating fiction and creating games is a lot like creating software.

When faced with difficult design and architectural choices, consider how to create models to help influence the decision-making process.

With this context, we can examine each tool in a little more depth.

Terrain

There are a few synthetic terrain algorithms. I did no real research beyond looking around a little.

Also, I want top-level view of the overall continent, not ground-level view of terrain in the background. A lot of the work on terrain generation is for gaming where it’s background. It comes, in part, from the aircraft simulator market. A long time ago, that was high-cost military software.

Here’s my approach. The foundation is wrote some software to color in a hexagonal tiling. I’ve read game designer essays on the uselessness of hex grids. The flat-at-the-top hexagons don’t model E-W movement well. (Square grids don’t model off-axis movement well.) The math is fun. See Hexagons.

Once we have a hex grid, plop down a handful of centers. Cities? Capitols of nations? Mountains? Lakes?

The generator then grows the lands aroound the cities. In matplotlib, this is a pleasant state change to the relevant hexagonal polygons. A little collision-detection to keep shapes more-or-less convex was a help. And a little gap-filler to strive for concavity at the end.

It looks pretty cool.

example

Characters

Somewhere — likely an issue of Dragon magazine, talking about supplemental D&D rules — I think I saw some ideas for generating character descriptions. What I wound up with is a list of features: hair length, nose, chin, ears, etc., etc. And a little normalish distribution to allow big-normal-small kinds of details. I included a really rare missing/broken option.

(Reality suggests some concrete numbers. This is for fiction and TTRPG. Reality isn’t as appropriate as cool results.)

The nuance is mapping to a normal distribution. The random.choice() function is equi-probable.

There are two tidy solutions. One is to use the bisect module to locate a value in a list that maps numeric ranges to the big-normal-small-missing normal curve. The other is to repeat values a number of times.

Story Arc

At some point I discovered the way Tarot fortune-telling cards provide a story arc. A full “reading” involves a lot cards and a lot of twists and turns. There are smaller “spreads” with the essence of a tidy three-act story.

My favorite is to have a “coming-from” - “obstacle” - “going-to” spread of cards. This is supplemented by a “need” and “avoid” pair. To get where you’re going, there’s a thing you need and a thing you must avoid.

This application is little more than selection of 5 blocks of text from an array of 78-or-s0 cards in a deck. Any deck will have a kind of guide to the images and symbolism. IRL, the pictures are helpful because sometimes the visial symbols form their own arcane language. Capturing all that content in a Python app is a pain.

Also, the interpretations given in common books are — like horoscopes — generic fluff that requires interpretation. In a TTRPG context, this interpretation can be cooked into the card text. Specific factions, governments, religions, etc., can be folded into the card text. This — by itself — is inspiring.

This isn’t some quirky AI application where we’ve digested 1,000 Project Gutenburg open-source books and use an LLM to generate stuff. This is simply a display of ideas to help inspire the writer (or Game Master for TTRPG) with some details that might be a little quirky or unexpected.

Need a non-player-character with a less-trope-filled backstory? Whip out the tarot cards. Interpret the three from-this-to-that cards. The “avoid” is the thing most people don’t get about their own lives. The NPC is chasing down the thing they should really be avoiding. The “need” card only relevant if the NPC surfaces in a more heroic context and has to succeed at something.

Languages

Languages are tricky. We’re not talking natural languages — which have a bewildering variety. We’re talking constructed languages (conlangs) which — sometimes — might all look alike.

Sure, you’re TTRPG game is rife with made-up alphabets. Or maybe you reused someone else’s runic alphabet. Or maybe you used historical runes. This is important, but, it’s only the most superficial of presentations for the language.

Real languages are spoken first. Writing comes later. Writing often reflects historical (and political) issues that might be lost on modern readers. Do you write résumé with or without accents? What is the rôle of diacritical marks in modern English? Pronouncation shifts. The tough coughs toughfully as he ploughs the dough.

What I think is far more important for a conlang is grammar rules. The nuanced lexico-grammatic connection between “word”, “sentence”, and “thought.”

The Python nltk package offers some help here. The idea is to parse English utterances into a structure of pairs: (part-of-speech word). These pairs nest. (Sentence (Noun I) (Verb Am)). The various NLTK tools have various encodings for PoS. There are tools to parse English and emit these annotated parse trees.

I’m not interested in parsing English. I’m a writer. I have specific things the speakers of the conlang need to say in their conlang. It’s not everything. Indeed, if I won’t want readers to delete the book from their reader, I need to keep the conlang stuff to a few colorful things in places where the opacity adds color, rather than obscures meaning.

But. I need consistency. So I have grammar rewrite rules to consume a sentence in English, and emit conlang with things reordered, and some things turned into prefixes and other things turned into suffixes and simple concepts expanded to phrases. All that jumbling, done according to a few, fixed rules. It leads to delightfully obscure — but consistent — results.

This, BTW, isn’t random.

When it comes to the conlang lexicon, weighted letter choice is a plesant way to proceed for an alphabet-based language. For pictograph languages, random selection isn’t needed, art is needed to create the pictographs. To create English-like words, a table of digraphs is the starting point. Simple letter frequency is unhelpful. Letter pair frequency is wonderful.

Can I share this?

I may. Right now, it’s a jumble of bits and pieces. A real science project.

At some point, I may polish it up a bit, and create something shareable.

I need to finish book II of my Western Horror series.

I need to finish my current non-fiction book.


Published

Category

Writing

Tags

Contact