Skip to content

QuickStart Tutorial

Vera Chellgren edited this page Nov 11, 2022 · 14 revisions

YeetWords Quickstart Tutorial

Welcome! Let's get you up and running right away. For the purposes of this tutorial, we'll create some short narratives.

Make sure you have Ruby

First, make sure you have Ruby installed on your machine. If not, it's easy to install. On PC, download the Ruby Installer for Windows at rubyinstaller.org. The latest version without devkit is all you need for this, but with devkit will work too. After installing, you should restart your computer to ensure the install is fully completed. On Mac, you'll need the Homebrew package manager, you can get it at https://brew.sh/ and then you can install ruby by typing brew install ruby. On Linux, install via your package manager.

Make sure you have the yeetwords.rb file

In your own working directory, make sure you have the yeetwords.rb file from GitHub - if not, download it. Now you have everything you need to get started.

1. The most basic narrative

Before doing anything more complex, let's look at the absolute simplest way of using YeetWords. This quick example won't give you a coherent story just yet, but it's really important to understand the basis of the word subsitution before moving on to create a proper narrative, since word substitution is the most central and important part of YeetWords. After that, we'll move on and learn how to use the additional features you really want for a real story, such as characters, cities, and other things that you can define yourself using ideas in your own head.

YeetWords will look for your words and sentences in two folders that start with word and sentence respectively (not case-sensitive). So go ahead and make those folders now. Inside those folders, let's create some files such as noun.txt, verb.txt, and adjective.txt. NotePad or a similar text-only app is perfect for this.

There are plenty of places you can get word lists, but since this is just an example, we'll fill in a few words manually. Go ahead and do that using an application such as NotePad or similar. Just put each item on one line. In the word folder, your file noun.txt might look like this:

man
table
woman
hamster

And verb.txt might look like this:

walking
playing
singing
falling

And adjective.txt could be like this:

shiny
happy
immovable
incredible

In the sentence folder, create a file mysentences.txt and put these 3 sentences in it. Any word that is enclosed in the underscores shows that it is ready to be replaced with a random word from the corresponding file in the word list:

The _ADJECTIVE_ _NOUN_ was _VERB_
Someone nearby was _VERB_
_VERB_ carefully, the _NOUN_ was _ADJECTIVE_

Now, in your normal working directory, create a file for your YeetWords code. Let's call it tut1.txt. In that file, we'll type the YeetWords command WRITE with parameters as shown below, so we can create a 'story'. YeetWords commands and parameters are not case-sensitive, but I recommend by convention making the commands be uppercase and the parameters be lowercase, like this (type in the following to your tut1.txt file):

WRITE mysentences wfolder 20

This is the simplest type of story you could write. Here's what the command translates to: mysentences means the sentences you want to use (the .txt is ignored), and wfolder is a special YeetWords parameter meaning "everything in the word folder". The number 20 means to do this 20 times. If no number is there, it assumes you mean 1 and would do it once.

Tip: sfolder is also a special parameter meaning "everything in the sentence folder". So it would be equally correct to instead put:

WRITE sfolder wfolder 20

Let's assume you have either of those typed into tut1.txt Then go to your command line and type: ruby yeetwords.rb tut1.txt

It will generate a new file for you with the sentences and words selected randomly, except of course that YeetWords will replace _ADJECTIVE_ with words only from the adjective.txt file, and so on.

Therefore it's really important that you named these both these things the same as each other, besides the .txt Remember it's not case-sensitive, so it doesn't matter what is uppercase and what is lowercase so long as the spelling is the same.

When you open the new file that was produced, it'll look something like mine here:

The immovable hamster was playing. Someone nearby was playing. The incredible hamster was falling. Falling carefully, the man was happy. The shiny hamster was playing. Someone nearby was walking. The incredible hamster was singing. Someone nearby was playing. The happy woman was playing. Someone nearby was playing. Playing carefully, the man was incredible. Someone nearby was singing. The incredible man was walking. Someone nearby was walking. The shiny woman was falling. Falling carefully, the woman was shiny. Someone nearby was playing. Playing carefully, the table was shiny. Someone nearby was singing. Falling carefully, the hamster was shiny.

Now, if you were doing a NaNoGenMo project, you could technically just do a longer version of that (50,000 words minimum) and it would qualify as a completion. But the story isn't very coherent, so let's see if we can come up with some improvements. To accomplish that, let's move on and use some additional features of YeetWords.

Tip: the numerical parameter for WRITE will take a number of words instead of a number of repeats. Just use the letter W to indicate that you're talking about words. So to get to 50,000 words, you would type WRITE sfolder wfolder 50000W *

* Note: The performance is much slower when a number of words is specified (e.g. 50000W) compared to the same number of words generated by cycles instead.

Looking back at our output, did you see how it added periods and spaces to the end of the sentences? You can have full control over that using the FORMAT command. It defaults to capitalizing the first letter of the sentence, replacing 'a' with 'an' as needed, and finally adding a period followed by a space at the end. So for now we'll just leave it set on the default.

Later, you'll want to see a full description of the WRITE command and the FORMAT command, which you can also find in the YeetWords Wiki. But for now, let's move on so we can improve our novel.

2. Creating characters, places, and other complex things

Characters

A story needs some characters, right? Yes, it will be better with some people (or robots or animals) to populate it! You can generate other things the same way - cities, and other complex things that you make up yourself.

In YeetWords, these are called gens. A gen basically means a user-generated set of things. For the purposes of this tutorial, it's easiest if our first gen is a set of characters i.e. people. Not surprisingly, we use the GEN command for this. The GEN command is not just 1 line, it's a block of lines starting with the word GEN and ending with GENEND. Everything in between relates to that gen.

When you create a new gen, you can call it anything you like. But to wrap our heads around it, it's probably easiest if we call it something that relates to what it is, and in the singular. Let's create 4 characters. We'll call the gen person (yes, even though there are 4). Make a new file called tut2.txt. In the file, let's add in some extra words. We are not obligated to do this via creating files every time like we did in the previous tutorial. We can opt to do it via the ASSIGNLIST command. Type in the following code to add in some extra words. Unlike the files we used before though, when you use ASSIGNLIST you need to surround each word or sentence with quotes:

ASSIGNLIST pet = "dog" + "cat" + "rabbit" + "weasel" + "rat" + "spider" + "snake" + "mouse" + "fish" + "lizard"
ASSIGNLIST smallitem = "fountain pen" + "diary" + "USB drive" + "lanyard" + "travel mug" + "skateboard" + "stapler" + "pencil" + "apple" + "beach towel"
GEN person 4 binary
pet 1 pet
carrying 1 smallitem
GENEND

Can you see what we've done there? Our gen is called person, there are 4 of them, the gender is binary meaning randomly male and female. You can read more about the genders in the GEN command in the Wiki. Each person has a pet, which is coming from the list called pet. They are each carrying 1 item, which is coming from the list called smallitem.

Now we can add some sentences and rotate through the characters so you can see how a gen works. Now, when you specify a gender in the first line of the gen command like we did with binary, you get some ready-made words "for free". One of these is name. There is also himher, heshe, hisher, and manwoman. These are available for use for all genders in YeetWords (not just the binary genders). Let's try out some of these using the WRITE command. First, let's define a sentence using ASSIGNLIST and add this to your tut2.txt file:

ASSIGNLIST mysentence = "A _PERSON.MANWOMAN_ approached carrying a _PERSON.CARRYING_. Then _PERSON.HESHE_ said "My name is _PERSON.NAME_ and I have a _PERSON.PET_""

Now we want to write this sentence using our words. Whoops, we need to have all our words together, so let's do an ASSIGNCATALOG command, which puts together lists of words. A catalog is a list of lists:

ASSIGNCATALOG mywords = pet + smallitem

At this point we could do WRITE mysentence mywords but the only problem is that it will only talk about the first person out of our 4. This is because only one of each gen can be considered to be active at a time. No problem though - the SHIFT command lets us move on to the next one in the gen. And we can use the LOOP command to loop through each person (close the loop by using the LOOPEND command). Putting it all together, let's add these lines onto the end of our existing tut2.txt file:

LOOP 4
WRITE mysentence mywords
SHIFT PERSON
LOOPEND

When I do this, I get the following output:

A man approached carrying a USB drive. Then he said "My name is Lennon and I have a dog". A man approached carrying a travel mug. Then he said "My name is Antwan and I have a mouse". A woman approached carrying an apple. Then she said "My name is Roselyn and I have a cat". A woman approached carrying a lanyard. Then she said "My name is Marianna and I have a rat".

Hold on! Where did those people's names come from? Actually, there are a few names hard-coded into YeetWords to make it easier to get started. But there's only a small number of those names, so you probably want to specify your own names to replace these. To do this, make a file in your word directory and call it something meaningful (e.g. femalenames.txt) and put your list of names there, 1 name per line.

Alternatively, you can type out the names manually as an ASSIGNLIST command. I recommend the file method for anything such as this that's likely to get long, as there's less chance of errors and you don't have to type the quotation marks in the file, nor the + signs.

To assign your list of names to a gender, just use the REFGENDER command (see Wiki entry for this command for full details). The syntax is easy:

REFGENDER female.names = yourlistforfemalenames

you can apply this to any of the genders supported by YeetWords, e.g. male.names = ...., nonbinary.names =...., and robot.names = .....

You'll need to make sure you give the REFGENDER command before declaring your gen though! Otherwise, when the gen is created it won't yet know about your own name list and it'll stick with the program defaults instead.

Cities and places

Cities and places can be declared as gens too! They work exactly the same way as characters, except you omit specifying a gender in the first line. You won't get the built-in NAME, HESHE, MANWOMAN, etc, but you probably won't need those for cities and places. As a rough sketch, assuming you already had word lists of city names, tourist attractions, and restaurants, you could do something like this:

GEN city 8
cityname 1 citynames
attraction 2 touristattractions
resaurant 2--5 restaurants
GENEND

Notice how we have the number 2--5? This tells YeetWords that you want any number of restaurants between 2 and 5. So some of your cities might have 2 restaurants, others 5, and others anywhere in between. That's something you can do with any type of gen, whether a character or not. You can even have the gen itself have a range (e.g. GEN city 5--10 to get anywhere from 5 to 10 cities).

The gen we defined above allows you to create sentences along the lines of "They went to _CITY.CITYNAME_ and made a beeline for the _CITY.ATTRACTION_. Afterwards they were hungry so they grabbed a bite to eat at _CITY.RESTAURANT_"

Your own gens!

You can make up your own gen. It can be as long or as short as you want. Be creative! It might be something like this:

GEN dungeon 4
smell 1 smelltypes
monstertype 1--3 monsters
loot 2 treasures
GENEND

Assuming you have the person gen we made earlier, you can do things like

ASSIGNLIST person.carrying = person.carrying + dungeon.loot

If you want to just have the person pick up just 1 item of loot, then you'd want to do something like this:

ASSIGNLIST bounty = dungeon.loot 1
ASSIGNLIST person.carrying = person.carrying + bounty

You can also subtract it from the dungeon if you wish: ASSIGNLIST dungeon.loot = dungeon.loot - bounty

Remember that there is no if/then logic in YeetWords, so don't try to exert conditional control over what happens!

Take a break if you need it

This is a really good place to take a break if you need it, before heading into the last section.

3. More advanced things

Killing off characters and other gens

Going back to the person gen, make a copy of your tut2.txt file and save it as tut3.txt - don't worry if you don't have it, I've recapped it all after this bit:

We're going use the RECITE command to list everyone in the gen in a reader-friendly manner, so at the bottom of the file, add

NEWLINE
RECITE allppl = person.name
WRITE allpl mywords

So the file tut3.txt should look like this at this point:

ASSIGNLIST pet = "dog" + "cat" + "rabbit" + "weasel" + "rat" + "spider" + "snake" + "mouse" + "fish" + "lizard"
ASSIGNLIST smallitem = "fountain pen" + "diary" + "USB drive" + "lanyard" + "travel mug" + "skateboard" + "stapler" + "pencil" + "apple" + "beach towel"
 
GEN person 4 binary
pet 1 pet
carrying 1 smallitem
GENEND

ASSIGNLIST mysentence = "A _PERSON.MANWOMAN_ approached carrying a _PERSON.CARRYING_. Then _PERSON.HESHE_ said "My name is _PERSON.NAME_ and I have a _PERSON.PET_""

ASSIGNCATALOG mywords = pet + smallitem

LOOP 4
WRITE mysentence mywords
SHIFT PERSON
LOOPEND

NEWLINE
RECITE allppl = person.name + all
WRITE allppl mywords

Recite means to list out the items, such as "Fred, Bob, and Amy". In our case, the + all means we want to recite names across all the items in the gen, not just the active one.

Run the tut3.txt file. My output looks like this (remember the output will change each time the program is run):

A man approached carrying a stapler. Then he said "My name is Lionel and I have a dog". A woman approached carrying a USB drive. Then she said "My name is Audriana and I have a fish". A man approached carrying a beach towel. Then he said "My name is Vaughn and I have a snake". A woman approached carrying a skateboard. Then she said "My name is Theresa and I have a weasel".    
Lionel, Audriana, Vaughn and Theresa. 

Suppose one of your characters will die. To assign that, make a subset of your characters using the ASSIGNGEN command and add this to the end of your tut3.txt file and save it as tut4.txt:

NEWLINE
ASSIGNGEN calamity = person 1
ASSIGNLIST whathappened = "Suddenly, lightning struck _CALAMITY.NAME_ and _CALAMITY.HESHE_ died instantly"
ASSIGNGEN person = person - calamity
RECITE allppl = person.name + all
ASSIGCATALOG mywords = mywords + allppl
ASSIGNLIST afterwards = "_allppl_ looked on in horror, stunned"
WRITE whathappened mywords
WRITE afterwards mywords

Then run tut4.txt. This is the output I got:

A woman approached carrying a diary. Then she said "My name is Mina and I have a rabbit". A woman approached carrying a lanyard. Then she said "My name is Pearl and I have a rat". A woman approached carrying a USB drive. Then she said "My name is Kayleen and I have a spider". A man approached carrying a travel mug. Then he said "My name is Lennon and I have a dog".    
Mina, Pearl, Kayleen and Lennon.    
Suddenly, lightning struck Mina and she died instantly. Pearl, Kayleen and Lennon looked on in horror, stunned.

Likewise, you can use this approach for other gens, for example a city could suffer a devastating environmental disaster, and so on.

It's up to you to make sure you don't go down to zero items anywhere. The various ASSIGN statements will allow you to wind up with empty items, but when it comes to the WRITE statement, the program will halt with an error message if your word list is empty or if you reference a gen that is empty.

The Wiki contains full information about how each of the commands we used work.

Randomize your character rotations

It would sound rather artificial if through your entire novel, characters took it in the exact same order to have turns at doing things. To get around this, use the SHUFFLE command, like this:

SHUFFLE person

This shuffles the person gen into a random order - but be aware the active gen stays on the same item immediately afterward, so you probably want to follow up a SHUFFLE with a SHIFT if you want to move onto another character.

By the way, SHIFT accepts numerical parameters; a SHIFT without a number defaults to SHIFT 1, but it's perfectly valid to type SHIFT 3 or SHIFT -2. It doesn't matter if the number is larger than the number of gen items; it just loops around again (i.e. it counts in a circle). You can shift and shuffle any gen, whether it's a person, city, or anything else.

New chapters, lines, and paragraphs and other formatting tips and tricks

Yeetwords will automatically keep track of what chapter you're up to. If you want to put a new chapter heading, then type

NEWCHAPTER

This writes a chapter heading with the correct chapter number automatically added. Slightly similar are the NEWPARA and NEWLINE commands, which commence a new paragraph and a new line respectively. All of these are parameter-less.

The FORMAT command can also handle paragraph and line breaks, as well as a whole lot more. The main difference is that FORMAT applies on the sentence level, so it's applied to each sentence in subsequent WRITE commands. You can change your FORMAT parameters at any time. As mentioned before, the default is ACPS (a/an substitution, capitalize first letter, period at the end, space at the end). You might also like to know that quotation marks surrounding the sentence (Q) is available, as is comma at the end (M), question mark at end (K), italics (I), bold (B), heading (D), subheading (F), no formatting at all (X), and many more options. The FORMAT parameters will be applied in the order you typed them, so make sure you are aware of this. For example, you probably wouldn't want to do FORMAT SP because then the space would be applied before the period.

In the case of dialogue, it is really up to you how you want to handle that - whether you add quotation marks using the FORMAT command, or whether you include the quotation marks yourself in your sentences.

If you wish to specify dialogue with quotes in an ASSIGNLIST command, you may use quotation marks, but you still need to surround the whole thing with quotation marks to show it's a string literal. Don't worry, it will work fine. Here is an example:

ASSIGNLIST dialog = ""My goodness!" he exclaimed. "That's a rather long string literal", he added"

The above is perfectly valid; you can use double quotes and nested quotes.

YeetWords defaults to producing markdown files, but if that's not convenient you can have it make html files instead using the OUTPUT command (see Wiki). In either case, the same FORMAT parameters will give the same final look regardless of whether you're outputting Markdown or html.

Save yourself a ton of typing - adding prefixes or suffixes to words, changing case, and making descs (code blocks)

Let's imagine you have a list of trees (e.g. maple, oak, fir, etc), and you want to create a new list where you add the word "tree" to each item (with a space in between), you can do that using the WORDJOIN command.

WORDJOIN treetype = mytree + " tree"

You can also use to create plurals, e.g. WORDJOIN animalplural = animal + "s"

You can join multiple things together in the order stated in a WORDJOIN command. In all cases, it creates a new list (in the examples above, these lists are called treetype and animalplural). Remember afterward to add the newly created list to your catalog of words using ASSIGNCATALOG

If you got a word list file from someone else and it's all in capital letters, but you want it to be all in lowercase, use the LOWCASE command. It will create a new list with the case converted:

LOWCASE lowitem = item

You also have available the commands UPCASE (converts to all uppercase), SLOWCASE (only the first letter gets converted to lowercase), and SUPCASE (only the first letter gets converted to uppercase).

Descs

DESC is short for describe. It's a code block that you define and can execute at any point you want later. I wouldn't call it a function, since it's unable to accept any parameters, but it can certainly save you a lot of typing and/or copying and pasting of your YeetWords code.

You may define any block of YeetWords code, including nested items, as a desc. If you're defining a desc, that code block won't be executed until you use the CALL command.

A DESC starts with the word DESC, then the name you want to declare it by, then you put the code you want, and you end it with DESCEND (= desc + end, it's just coincidence it makes the word 'descend'). Here is an example of a DESC:

DESC para
FORMAT ACPS
NEWPARA
WRITE normalsentences allwords 2--8
SHIFT person
DESCEND

To use it, you would do:

CALL para

You may call other descs from within a desc. You do not have to define descs in any particular order, so long as the desc is defined before it is called. In other words, if one desc calls another, the order doesn't matter so long as the call command happens after both descs are defined.

You could then make another desc called chapter:

DESC chapter
NEWCHAPTER
LOOP 1000W--2000W
CALL para
LOOPEND
DESCEND

Then you can use CALL chapter

You're done!

OK, that's it for the tutorial, you're good to go! This tutorial has not covered every last detail, but you've got easily enough to get started with your ideas; if you get stuck just look at the Wiki entry for the command you want to use. For a quick overview of program structure, variables, and other theory, you might like to look at the Wiki section on Program Structure and Variables