chimp.ceo cross-posted this post in Game Development 3 years ago


GOBLINFINITE.app Dev Log #2 - Rules For Some Neat Names

in Programming & Dev3 years ago (edited)

intro-banner.png

Random generation makes the heart sing...

Usually the song is some kinda horribly jumbled mess of corrupted lyrics and high pitch screeches, but it sings nonetheless!

If last dev log's theme was all about images, atlases, and goblin bodies, then these next two themes are random generation, random generation, and random generation. If we have time, I might touch on random generation as well.

Let us begin this wonderful code-heavy journey, by getting some good goblin names generated. Once again, I'll be posting the direct copy of my GDScript code, and then writing down pseudo-code step-by-step outlines so you can better understand what's going on as well as translate it into whatever your programming language of choice is.

divider.png

What's A Goblin Without A Name?

a freaky lookin' frog...

So, we have our ugly subjectively cute goblins generated and ready to go, but they don't have a name! We could just randomly choose a number and then pick that many letters from the alphabet at random, but that doesn't really feel like a name. For example

- xggzyhkb
- niiijsnjht
- sptgnhvwgskb

Those don't feel real, do they? They look like what they are, a bunch of garbled text. We're not making entries in the Library of Babel here, so let's try something else.

How about just pulling a bunch of popular human names, adding them to a large array, and then randomly choosing from there? Sure, but... Let me ask you something. Be honest...

LUNGEEPPEE BELTDANGLER BodyDisplay.png

Does this motherfucker look like a "Brian" to you? Nah. Goblins wouldn't follow western English naming styles, I don't even think they speak English. They speak... I dunno, goblinese? Point is, it feels weird to have all these wild & wacky characters only to slap "Bob" under them. Every once & a while that can be funny, but we can do better.

Enter: The Random Name Machine 9000

image.png

Sitting at nearly 300 lines long, this marvelous script can generate such great names as:

- Lungeeppee Beltdangler
- Strangling Iddihoozz
- Jumps The Pie
- Bingobbee The Ole Mutt
- ToeGuzzler
- Brutal-Bottom ( ͡° ͜ʖ ͡°)

Now THOSE feel like goblin names! If you're a fan of patterns, you might notice one forming in the names there. Do they look like they follow some sort of... ruleset? Well, that's because they do. Several, in fact.

RULE 1: Curated Lists

Some of these goblin names look more like nicknames and include what could be interpreted as attitude descriptors, hobby events, and appearance tags. In GOBLINFINITE.app, we use 12 lists (or arrays) that lay the fundamental groundwork for our random name generation.

  • adjectives
    • words like runny, chipper, lost, one, rust, always, many
  • verbs
    • words like eat, bash, feast, stab, crash, grab, snack
  • things
    • words like bucket, door, bottom, hole, tunnel, pit, bubble
  • pluralized_things
    • pluralized versions of the things list because, unfortunately, it's not as easy as just adding an 's' to the end of the words, for instance: bug -> bugs, but dung -> dung, or elf -> elves
  • body_part_names
    • words like nose, skin, leg, eye, snout, gut, mouth
  • pluralized_body_parts
    • again, pluralized versions of the body_part-names list
  • prepositions
    • words like toward, from, through, into, above, across, against
  • vowels
    • a, ee, i, o, oo, u, because these sound the best in names
  • consonants
    • all the other non-vowel letters
  • doubles
    • good pairings of double letters, like bb, mm, tt, dd, nn, not all double letter pairs sound good, so we curate our own list
  • combos
    • kl, kr, kw, pl, again, not all letter pairings feel right in names, so curation is important
  • santas_naughty_list
    • a very naughty list of words that we check against to make sure our goblins don't get us canceled

With all of our lists populated and ready to draw from, it's on to...

RULE 2: Follow A Formula

In GOBLINFINITE, we have 28 formulas to choose from when picking a name. Maybe a goblin's name should be something like name + "the" + plural thing. Or maybe it should be adjective + "-" + plural_thing. Or body_part + _nounify(verb). The 28 different formulas are essentially the "recipes" for the names, while the lists act as ingredients. Of course, this is where the recipe metaphor stops, because randomly choosing ingredients from a list might not make for the most appetizing dishes... But for goblin names, it works quite deliciously!

There are a few things I glossed over there, however.

First, how do we generate just a random name? With nothing else attached? Well, we actually have 2 ways we go about that:

  • Variation 1
    1. chunks = 0.
    2. Start with a random consonant or combo. chunks += 1
    3. Add a random vowel. chunks += 1
    4. Randomly choose either a consonant, double, or combo. chunks += 1
    5. GOTO 3.
  • Variation 2
    1. chunks = 0.
    2. Choose a random vowel. chunks += 1
    3. Add a random consonant, double, or combo. chunks += 1
    4. GOTO 3.

The chunks counter helps stop super long words from generating. The longer the name gets, the more likely it is to end. 1 chunk = 0% chance of ending, 2 chunks = 10%, 3 = 30%, 4 = 50%, 5 = 80%, 6 chunks = 100% chance of ending.

The only time chunks ending percentage doesn't matter, is when ending on a combo. Never end on a combo, even at 100%. Just add a random vowel and end it there.

Using that formula, we will never go past a name length of 14 characters.

Cool, neat, fun. So what is that _nounify() function? That's a custom function I wrote to be able to the verb passed into it, into a noun.

image.png

English grammar has a few rules around how nouns should behave, so this function loosely follows them to make verbs into somewhat correct nouns.

if verb.ends_with("e"): return verb + "r"

Pretty straightforward, if the verb ends with the letter "e", then just tack on the letter "r" to the end of the word, and you're good. Dance -> Dancer, Smile -> Smiler, Bake -> Baker.

elif _is_vowel(verb[verb.length()-2]) && not _is_vowel(verb[ver.length()-1]):
    return verb + verb[verb.length()-1] + "er"

A little more complex here. _is_vowel() is just a real quick little function that I can use as a shorthand to check whether the letter being passed into it is a vowel:

image.png

Notice how we don't include "y" there? That's because y has to get its shit together and figure out whether or not it wants to be a vowel. No more of this "and sometimes" bullshit. Get your shit straight y, jesus christ...

Anyways, we pass into _is_vowel() this: verb[verb.length()-2]. The cool thing about GDScript is that it treats all strings sorta like arrays, so doing some_string[0] will return you the first letter in that string. Or more clearly, you could do return "hello"[0] and it will return "h". Neat, right? So verb.length()-2 is the second to last letter, since arrays start at 0.

"hello"["hello".length()] would give you an error, because "hello".length() returns 5, but with arrays starting at 0, "hello"[5] is invalid.

"hello"["hello".length()-1] would give you "o", because "hello".length()-1 returns 4, and "hello"[4] is "o".

See how that works? So back to the main code, we are checking to see if the second to last letter is a vowel AND the last letter is not a vowel. If both of those conditions are true, then we should double the last letter (verb + verb[verb.length()-1] is just duplicating the last letter), and then adding an "er" to the end. Run -> Runner, Jog -> Jogger, Sit -> Sitter.

else: return verb + "er"

If none of the above checks are met, then just simply stick an "er" to the end of the verb. Learn -> Learner, Pretend -> Pretender, Nigg -> -- Uhh... That reminds me, let's move on to that santas_naughty_list thing...

RULE 3: Let's Try Not To Get Cancelled

Fun fact: English slurs follow English construction guides.

Also fun fact: If you make a random name generator that also follows English construction guides, you will end up generating a surprising amount of slurs.

Doing some tests, I found that for every ~2,000 random names generated, our algorithm would make about 12 slurs. It may only be a 0.6% chance, but I enjoy having calm & relaxing days, not spending my time dealing with freaked-out crazy people yelling at me on Twitter because the silly goblin app put a no-no word on their screen.

Plus, I'm not the only name attached to this. I don't wanna get my boy ROLLINKUNZ canceled. So, we have a simple list of slurs that, upon every completed name generation, we check against. If any word in the freshly generated random name matches any entries in said list, we opt for a little easter-egg replacement.

image.png

That's right, if you use GOBLINFINITE.app and ever end up with a goblin named either "ROLLINKUNZ" or "CHIMPCEO", you know 2 things:

  1. That's a very rare goblin name, less than 1% chance. Cool!
  2. Your real goblin name was highly offensive... Cool!

And, with those simple rules, you now have PROPER GOBLIN NAMES!

USOO PANTOOTTER BodyDisplay.pngCLAWFUL OSKIBARR BodyDisplay.pngLOUD-SMITE BodyDisplay.png

Much better 👍

divider.png

Lots of code for this one was very GDScript-specific, so the ruleset layout in this post was in effort to make it more like a "guideline" on how to generate your own names. Feel free to play around with the formulas in rule #2, change the list items in rule #1, or be a little rascal and completely remove rule #3.

Next, we're going to cover rolling random stats, and generating random backstories for our little goblin pals.

Until next time, stay safe, keep healthy, and get cozy. See you all soon!
- Chimp CEO 🐒


Sort:  

Congratulations @chimp.ceo! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s) :

You received more than 800 upvotes.
Your next target is to reach 900 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out the last post from @hivebuzz:

Hive Power Up Day - September 1st 2021 - Hive Power Delegation