Fiction Word / /
Lukawiv
| |

A friend of mine who was working on creating a language for a fantasy novel he was writing mentioned to me that the most difficult / tedious part of creating a language was coming up with the vocabulary. While some words are derivations or combinations of other words, much of the vocabulary needs to simply be made up.

He asked me if it was possible to write some code that would, based on a set of rules for what a word can be, generate random words. I thought it was an interesting idea and apart from uses in creative projects, it could possibly also be useful in generating secure, yet still memorable passwords, so I thought I'd give it a go.

First, I needed the code to decide how long of a word to make. I wanted most of the words to be relatively short but I also didn't want to rule out the possibility of long words either. So rather than have a totally random length in a range, I thought I would weight it by starting with a length of 1 then giving it a 90% chance of changing the length to 2, then an 80% chance of making it 3, 70% of 4, and so on until it gets to below 5% then it hangs there.

let wordLength = 1;
let inProgress = true;

while (inProgress) {
 let odds = Math.max(5, 100 - (wordLength * 10));
 wordLength++;
 inProgress = theOdds(odds);
}

Once the odds say to move on (the function theOdds() simply checks a percent against a random number and returns true or false), then the main word gen function starts. The main function works by basically constructing a word, letter-by-letter / cluster-by-cluster, alternating between vowels and consonants, until it matches the determined length then returning the letter.

More specifically it works by looking at the word so far and determining which of the following arrays are viable options for what's next (with the 'marked' letters to be used sparingly):

const prefixes = ["str", "pre", "dia", "gh", "wh", "psy"];
const suffixes = ["tion", "ing", "ies", "ed", "er", "ght", "gh", "ck", "ff", "que", "nd"];
const vowels = ["a", "e", "i", "o", "u", "y"];
const consonants = [
    ...["b", "c", "d", "f", "g", "h", "j", "k", "l", "m"],
    ...["n", "p", "q", "r", "s", "t", "v", "x", "z", "w", "y"],
];
const marked = ["z", "x", "j"];
const consonantCluster = [
...["tr", "sc", "th", "sh", "ch", "br", "bl", "cl", "cr"],
...["ff", "que", "qu", "dr", "sw"],
];
const dipthong = ["ee", "ea", "io", "oo", "ou", "eau"];

After the initial fun of creating the words, I thought that the script could be useful as a tool for creating lorem ipsum like text. So I expanded it to include a function which created sentences and another which created paragraphs.

const makeSentence = (length?: number): string => {
  // Defined the range of the number of words in the sentence
  const bottom = budgeByOdds(15, 10, "down");
  const top = budgeByOdds(20, 10, "up");

  // The length is either that which was specified by the user
  // or a number between the top and bottom of the range
  // specified earlier
  length = Math.max(1, length || range(bottom, top));
  let sentence = `${capitalizeFirstLetter(makeWord())} `;
  for (let i = 1; i < length; i++) {
    sentence += `${makeWord()} `;
  }

  return `${sentence.trim()}.`;
};

You can create words and give them definitions at thedukeofnorfolk.com. I intend to, eventually, create a crowdsourced dictionary of fictional words.