Procedural Sentence Generation

All of these sentences were created with (basically) 1 line of code:

The sun brightly glows above you, flaming your skin. Insects, buzzing and tweeting, glide around your face.

The sun gleams above you, scorching your skin. A hundred-thousand insects swoop around your face.

Dazzlingly, the sun illuminates above you. Bugs, humming and trilling, soar around your face.

The golden-fire sun glistens above you. Buzzing and twittering, ten-million insects glide around your face.

The sun, smoldering your skin, glistens above you. Insects swoop around your face.

Radiantly, the radiant-monarch sun gleams above you. A thousand insects, whizzing and trilling, glide around your face.

Here are some more:

You are traversing the wastes , an expanse of natural countryside.

Exhaustedly, you are crossing the western wilderness .

You are traversing the western wastelands , a spread of wild countryside.

You are traversing the western wastes .

Exhaustedly, you are traversing the wastes , a spread of untamed countryside.

Here’s another example:

The coal-black brute, rustling fronds, treads through the forest.

Gently, the beast strolls through the forest, swishing fronds.

The critter saunters through the woodland.

The brute, rustling fronds, ambles through the wildwood.

The brute strolls through the wildwood.

The ebony-black critter saunters through the forest, swishing vegetation.

The beast, rustling foliage, ambles through the thicket.

(Before you say anything, yes, I know the punctuation is incorrect on some of them. I never got around to fixing it. But just know that that only happens in specific cases, which you probably won’t stumble upon. But if you want to fix them yourself, feel free.)

I love the idea of a game that is infinitely replayable. And I wanted every part of the game I was making to be procedurally generated. So I came up with an idea that is, quite honestly, far too complex for ChoiceScript – but I did it anyway :slight_smile:

This explains how to do everything I did here. And you can re-create everything I did.

(Thank you to twiger_fluff for creating the array system needed for this. I swear, they are an actual genius for making something like that. This is the link: Working String Manipulation (no *script used) (substring, substr, indexOf, contains, replace) )

Basically, I’ve created a system that allows you to generate a vast number of variations from a single “base sentence” by doing these things:

  1. Create arrays (using twiger_fluff’s array system) that include synonyms for each word you want to use synonyms. Also create a variable that has the same name as the list, but with a “1” at the end. Here is an example:
*create ancient "^ancient^antique^archaic^primordial^old"
*create ancient1 ""

(Note: Each list should be only 5 items long – although, if you really wanted, you could change the code for this)
2. If you have any words you want to use that don’t have synonyms, or that you don’t want to make a list for. Define the variable “word1” with what you want. Here’s an example:

*set word1 "western"

(Note: You have to create the “word#” variables in startup for them to work properly. You also have to create the variables with a “1” at the end, which can look rather funny with “word” variables already having numbers at the end. Here’s and example:

*create word1 ""
*create word11 ""
*create word2 ""
*create word21 ""
*create word3 ""
*create word31 ""
*create word4 ""
*create word41 ""

)

  1. Create a ‘*gosub’ that defines the different parts of the sentence you want to generate.

(Note: “gs” stands for “generate sentence”.)

Here is the general outline:


*gosub_scene fetch gs1 "TYPE 1 WILL BE THE EXAMPLE" "the/a/leave empty" "adjective" "noun" "if the noun is plural, put an 's'" "verb" "if the verb needs an 's', put one" "adverb" (I have continued the next part below, because this is where it becomes complicated)
(A "detail" is something that explains more about what is happening. For example "in the forest". This gives context to what is happening.
An "extra" is something that is not necessary, but adds more to the sentence. For example "swaying in the wind". This can be taken out, and the sentence still retains comprehension.
Here is how you write details:
After the adverb, if you want a detail, write what you want. If you have words that you want to substitute for synonyms, write them as "de1", "de2", etc. These must always be written in order. Then, when you want to define the synonym lists you are using, write "def". And after that, write the names of the synonym lists. After that, write "x". You can do the same for extra as well.
This is pretty hard to explain, so I'll just give you an example:
For the code: 	*gosub_scene fetch gs1 "1" "the" "green" "forest" "" "sway" "s" "gently" "in the" "de1" "def" "wind" "x" "de1" "and" "de2" "def" "whispering" "singing" "x"
After the adverb, "gently", I started defining the detail.
"in the" "de1"
After that is "def", which says to ChoiceScript that it is time to define "de1" (and "de2"/"de3"/etc, if you used those).
After "def", there is "wind". This means that "de1" is the synonym list "wind". The code will grab a random synonym from the list called "wind".
After that is "x". This means it is the end of detail or extra. 
Repeat the same process for extra (which is always after detail in the code).

Hopefully, that made sense. If not, I’ve provided some more examples below.

Here’s and example of type 1:

*gosub_scene fetch gs1 "1" "the" "black" "creature" "" "walk" "s" "gently" "through the" "de1" "def" "wind" "x" "de1" "de2" "def" "rustling" "foliage" "x"

This writes something similar to: "The black creature walks gently through the forest rustling foliage

Here’s an example of type 2:

*set word1 "western"
*gosub_scene fetch gs1 "2" "" "" "you" "" "areCrossing" "" "tiredly" "the" "word1" "wilderness" "" "non" "def" "x" "a" "de1" "of" "de2" "countryside" "def" "expanse" "wild" "x"

This writes something similar to: “You are tiredly crossing the western wilderness, a(n) expanse of wild countryside.”

Procedural sentence types:


(1) 1 subject does something
.... "1" "the" "adjective" "noun" "s" "verb" "s" "adverb" "detail" "def" "define detail" "x" "extra" "def" "define extra" "x"
(the) (adj) (noun) (verb) (adverb) (detail) (extra)
Example: The green creature walks quickly through the forest, rattling bushes.

(2) 1 subject does something to a noun
.... "2" "the" "adjective" "noun" "s" "verb" "s" "adverb" "the" "adjective" "noun" "s" "detail" "extra"
(the) (adj) (noun) (verb) (adv) (the) (adj) (noun) (detail), (extra).
Example: The green creature rapidly punches the tall man in the face, shattering his jaw.
(3) description
.... "3" "the" "noun" "s" "verb" "adjective1" "adjective2" "detail" "extra"
(the) (noun) (verb) (adj1) and (adj2) (detail1), (extra)
Example: The houses are ancient and crumbling in Bobville, falling apart at the seams.

(Note: the system even converts “a” to “an”, if needed!"

The actual code for the system:


*comment THIS NEEDS TO BE HERE TO PASS QUICKTEST
*gosub gs "walk"

*label gs
*params
*label returnHereForParam
*if param_count > 0
	*temp word_index
	*rand word_index 1 5
	*set lists_listname {("param_" & param_count)}
	*set lists_index word_index
	*if lists_listname = ""
		*set param_count -1
		*goto returnHereForParam
	*temp firstLetter {lists_listname}#1
	*if firstLetter != "^"
		*set lists_output {lists_listname}
		*goto skipTwigerFind
	*gosub_scene twiger_functions find
	*label skipTwigerFind
	*set {(lists_listname&"1")} lists_output
	*set param_count -1
	*goto returnHereForParam
*return


*label gs1
*params type
*comment defines the variables based on the type of sentence
*if type = 1
	*temp the1 param_2
	*temp adj1A param_3
	*temp noun1A param_4
	*temp s1 param_5
	*temp verb1A param_6
	*temp s2 param_7
	*temp adv1A param_8
	*comment param_9 is where detail starts
	*temp detailStart 9
	*gosub detailParse
	*gosub detailDefine
	*set detailStart (9 + pdeIndex)
	*gosub detailParse
	*gosub extraDefine
	*comment below defines vars
	*gosub_scene fetch gs adj1A noun1A verb1A adv1A
	*if adj1A != ""
		*temp adj1 {adj1A & "1"}
	*if adj1A = ""
		*temp adj1 adj1A
	*if noun1A != ""
		*temp noun1 {noun1A & "1"}
	*if noun1A = ""
		*temp noun1 noun1A
	*if verb1A != ""
		*temp verb1 {verb1A & "1"}
	*if verb1A = ""
		*temp verb1 verb1A
	*if adv1A != ""
		*temp adv1 {adv1A & "1"}
	*if adv1A = ""
		*temp adv1 adv1A
*if type = 2
	*temp the1 param_2
	*temp adj1A param_3
	*temp noun1A param_4
	*temp s1 param_5
	*temp verb1A param_6
	*temp s2 param_7
	*temp adv1A param_8
	*temp the2 param_9
	*temp adj2A param_10
	*temp noun2A param_11
	*temp s3 param_12
	*comment param_13 is where detail starts
	*temp detailStart 13
	*gosub detailParse
	*gosub detailDefine
	*set detailStart (13 + pdeIndex)
	*gosub detailParse
	*gosub extraDefine
	*comment below defines vars
	*gosub_scene fetch gs adj1A noun1A verb1A adv1A adj2A noun2A
	*if adj1A != ""
		*temp adj1 {adj1A & "1"}
	*if adj1A = ""
		*temp adj1 adj1A
	*if noun1A != ""
		*temp noun1 {noun1A & "1"}
	*if noun1A = ""
		*temp noun1 noun1A
	*if verb1A != ""
		*temp verb1 {verb1A & "1"}
	*if verb1A = ""
		*temp verb1 verb1A
	*if adv1A != ""
		*temp adv1 {adv1A & "1"}
	*if adv1A = ""
		*temp adv1 adv1A
	*if adj2A != ""
		*temp adj2 {adj2A & "1"}
	*if adj2A = ""
		*temp adj2 adj2A
	*if noun2A != ""
		*temp noun2 {noun2A & "1"}
	*if noun2A = ""
		*temp noun2 noun2A
*if type = 3
	*temp the1 param_2
	*temp noun1A param_3
	*temp s1 param_4
	*temp verb1A param_5
	*temp adj1A param_6
	*temp adj2A param_7
	*comment param8 is where detail starts
	*temp detailStart 8
	*gosub detailParse
	*gosub detailDefine
	*set detailStart (8 + pdeIndex)
	*gosub detailParse
	*gosub extraDefine
	*comment below defines vars
	*gosub_scene fetch gs adj1A adj2A noun1A verb1A
	*if adj1A != ""
		*temp adj1 {adj1A & "1"}
	*if adj1A = ""
		*temp adj1 adj1A
	*if adj2A != ""
		*temp adj2 {adj2A & "1"}
	*if adj1A = ""
		*temp adj2 adj2A
	*if noun1A != ""
		*temp noun1 {noun1A & "1"}
	*if noun1A = ""
		*temp noun1 noun1A
	*if verb1A != ""
		*temp verb1 {verb1A & "1"}
	*if verb1A = ""
		*temp verb1 verb1A
*temp randTEMP ""
*temp r1
*label sentenceStructures
*comment SIMPLE 1 sub, 1 verb, 1 detail, 1 extra
*if type = 1
	*rand r1 0 4
	*if (r1 = 0) or (r1 = 1)
		*comment EX: The brown dog runs quickly to the door, panting.
		*gosub adv?
		*gosub adj1?
		*gosub extra?
		*gosub an1?
		*if (the1 = "") and (adj1 != "")
			$!{adj1} ${noun1}${s1}
		*if (the1 != "") and (adj1 != "")
			$!{the1} ${adj1} ${noun1}${s1}
		*if (the1 = "") and (adj1 = "")
			$!{noun1}${s1}
		*if (the1 != "") and (adj1 = "")
			$!{the1} ${noun1}${s1}
		${adv1}
		*if (extra = "") and (detail != "")
			${verb1}${s2} ${detail}.
		*if (extra = "") and (detail = "")
			${verb1}${s2}.
		*if (extra != "") and (detail != "")
			${verb1}${s2} ${detail}, ${extra}.
		*if (extra != "") and (detail = "")
			${verb1}${s2}, ${extra}.
	*if r1 = 2
		*comment EX: Quickly, the brown dog runs to the door, panting.
		*gosub adj1?
		*gosub extra?
		*gosub an1?
		$!{adv1}, ${the1} ${adj1} ${noun1}${s1} 
		*if (extra = "") and (detail != "")
			${verb1}${s2} ${detail}.
		*if (extra = "") and (detail = "")
			${verb1}${s2}.
		*if (extra != "") and (detail != "")
			${verb1}${s2} ${detail}, ${extra}.
		*if (extra != "") and (detail = "")
			${verb1}${s2}, ${extra}.
	*if r1 = 3
		*gosub adv?
		*gosub adj1?
		*gosub an1?
		*comment EX: Panting, the brown dog runs quickly to the door.
		$!{extra}, ${the1} ${adj1} ${noun1}${s1} ${adv1} 
		*if detail != ""
			${verb1}${s2} ${detail}.
		*if detail = ""
			${verb1}${s2}.
	*if r1 = 4
		*comment EX: The brown dog, panting, runs quickly to the door.
		*gosub adv?
		*gosub adj1?
		*gosub an1?
		*if (the1 = "") and (adj1 != "")
			$!{adj1} ${noun1}${s1},
		*if (the1 != "") and (adj1 != "")
			$!{the1} ${adj1} ${noun1}${s1},
		*if (the1 = "") and (adj1 = "")
			$!{noun1}${s1},
		*if (the1 != "") and (adj1 = "")
			$!{the1} ${noun1}${s1},
		${extra}, ${adv1} ${verb1}${s2} ${detail}.
*if type = 2
	*rand r1 0 2
	*if (r1 = 0) or (r1 = 1)
		*comment EX: The brown dog runs quickly to the door, panting.
		*gosub adv?
		*gosub adj1?
		*gosub adj2?
		*gosub an1?
		*gosub an2?
		*gosub extra?
		*if (the1 = "") and (adj1 != "")
			$!{adj1} ${noun1}${s1}
		*if (the1 != "") and (adj1 != "")
			$!{the1} ${adj1} ${noun1}${s1}
		*if (the1 = "") and (adj1 = "")
			$!{noun1}${s1}
		*if (the1 != "") and (adj1 = "")
			$!{the1} ${noun1}${s1}
		${adv1} ${verb1}${s2}
		*if (the2 = "") and (adj2 != "")
			${adj2} ${noun2}${s3}
		*if (the2 != "") and (adj2 != "")
			${the2} ${adj2} ${noun2}${s3}
		*if (the2 = "") and (adj2 = "")
			${noun2}${s3}
		*if (the2 != "") and (adj2 = "")
			${the2} ${noun2}${s3}
		*if (extra = "") and (detail != "")
			${detail}.
		*if (extra = "") and (detail = "")
			.
		*if (extra != "") and (detail != "")
			${detail}, ${extra}.
		*if (extra != "") and (detail = "")
			, ${extra}.
	*if r1 = 2
		*comment EX: The brown dog runs quickly to the door, panting.
		*gosub adj1?
		*gosub adj2?
		*gosub an1?
		*gosub an2?
		*gosub extra?
		$!{adv1}, ${the1} ${adj1} ${noun1}${s1}	 ${verb1}${s2} ${the2} ${adj2} ${noun2}${s3}
		*if extra = ""
			${detail}.
		*if extra != ""
			${detail}, ${extra}.
*if type = 3
	*rand r1 0 1
	*if (r1 = 0) or (r1 = 1)
		*comment EX: The brown dog runs quickly to the door, panting.
		*if (the1 = "")
			$!{noun1}${s1}
		*if (the1 != "")
			$!{the1} ${noun1}${s1}
		${verb1} ${adj1} and ${adj2} ${detail}, ${extra}.
*return

*label adv?
*rand randTEMP 0 3
*if randTEMP != 0
	*set adv1 ""
*return

*label adj1?
*rand randTEMP 0 2
*if randTEMP != 0
	*set adj1 ""
*return

*label adj2?
*rand randTEMP 0 2
*if randTEMP != 0
	*set adj2 ""
*return


*label extra?
*rand randTEMP 0 2
*if randTEMP != 0
	*set extra ""
*return

*label an1?
*comment this is for the1
*if (the1 = "the") or (the1 = "")
	*return
*if adj1 = ""
	*temp anWordTesting "noun1"
*if adj1 != ""
	*temp anWordTesting "adj1"
*temp firstLetterTesting {anWordTesting}#1
*if (((firstLetterTesting = "a") or (firstLetterTesting = "e")) or (((firstLetterTesting = "u") or (firstLetterTesting = "i")) or (firstLetterTesting = "o")))
	*set the1 "an"
*return


*label an2?
*comment this is for the1
*if (the2 = "the") or (the2 = "")
	*return
*if adj2 = ""
	*temp anWordTesting "noun2"
*if adj2 != ""
	*temp anWordTesting "adj2"
*temp firstLetterTesting {anWordTesting}#1
*if (((firstLetterTesting = "a") or (firstLetterTesting = "e")) or (((firstLetterTesting = "u") or (firstLetterTesting = "i")) or (firstLetterTesting = "o")))
	*set the2 "an"
*return




*label detailDefine
*if detailPos1 = "non"
	*set detail ""
	*return
*comment the below code defines the variable "detail"
*temp detailDefineIndex 1
*temp detail ""
*comment below is ACTUAL because it is not set to the name of the variable "detailPos(thenumber)", but rather the value of that -- so "through the", for example.
*temp nextDetailDefineACTUAL {"detailPos" & (detailDefineIndex + 1)}
*label returnHereForDetailDefine
*temp currentDetailDefine "detailPos" & detailDefineIndex
*temp nextDetailDefine "detailPos" & (detailDefineIndex + 1)
*if {currentDetailDefine} = ""
	*if (((detail = " non") or (detail = " non ")) or ((detail = "non") or (detail = "non ")))
		*set detail ""
	*return
*if {nextDetailDefine} != ""
	*temp nextDetailDefineACTUAL {{{nextDetailDefine}}}
	*temp firstOfNext nextDetailDefineACTUAL#1
	*temp firstOfCurrent {{{currentDetailDefine}}}
	*temp firstOfCurrent firstOfCurrent#1
	*if firstOfCurrent = "a"
		*if (((firstOfNext = "a") or (firstOfNext = "e")) or (((firstOfNext = "u") or (firstOfNext = "i")) or (firstOfNext = "o")))
			*set {{{currentDetailDefine}}} "an"
*if detailDefineIndex != 1
	*temp detail detail & " "
*temp detail detail & {{{currentDetailDefine}}}
*set detailDefineIndex +1
*goto returnHereForDetailDefine



*label extraDefine
*comment the below code defines the variable "extra"
*if detailPos1 = "non"
	*set extra ""
	*return
*comment the below code defines the variable "detail"
*temp detailDefineIndex 1
*temp extra ""
*comment below is ACTUAL because it is not set to the name of the variable "detailPos(thenumber)", but rather the value of that -- so "through the", for example.
*temp nextDetailDefineACTUAL {"detailPos" & (detailDefineIndex + 1)}
*label returnHereForExtraDefine
*temp currentDetailDefine "detailPos" & detailDefineIndex
*temp nextDetailDefine "detailPos" & (detailDefineIndex + 1)
*if {currentDetailDefine} = ""
	*if (((extra = " non") or (extra = " non ")) or ((extra = "non") or (extra = "non ")))
		*set extra ""
	*return
*if {nextDetailDefine} != ""
	*temp nextDetailDefineACTUAL {{{nextDetailDefine}}}
	*temp firstOfNext nextDetailDefineACTUAL#1
	*temp firstOfCurrent {{{currentDetailDefine}}}
	*temp firstOfCurrent firstOfCurrent#1
	*if firstOfCurrent = "a"
		*if (((firstOfNext = "a") or (firstOfNext = "e")) or (((firstOfNext = "u") or (firstOfNext = "i")) or (firstOfNext = "o")))
			*set {{{currentDetailDefine}}} "an"
*if detailDefineIndex != 1
	*temp extra extra & " "
*temp extra extra & {{{currentDetailDefine}}}
*set detailDefineIndex +1
*goto returnHereForExtraDefine




*label detailParse
*comment below parses and interprets the detail code
*comment param_9 is where detail starts
*temp paramDe1 "param_" & detailStart
*temp paramDe2 "param_" & (detailStart +1)
*temp paramDe3 "param_" & (detailStart +2)
*temp paramDe4 "param_" & (detailStart +3)
*temp paramDe5 "param_" & (detailStart +4)
*temp paramDe6 "param_" & (detailStart +5)
*temp paramDe7 "param_" & (detailStart +6)
*temp paramDe8 "param_" & (detailStart +7)
*temp paramDe9 "param_" & (detailStart +8)
*temp paramDe10 "param_" & (detailStart +9)
*temp paramDe11 "param_" & (detailStart +10)
*temp paramDe12 "param_" & (detailStart +11)
*temp paramDe13 "param_" & (detailStart +12)
*temp paramDe14 "param_" & (detailStart +13)
*temp paramDe15 "param_" & (detailStart +14)
*temp paramDe16 "param_" & (detailStart +15)
*temp paramDe17 "param_" & (detailStart +16)
*temp paramDe18 "param_" & (detailStart +17)
*temp paramDe19 "param_" & (detailStart +18)
*temp paramDe20 "param_" & (detailStart +19)
*temp paramDe21 "param_" & (detailStart +20)
*temp paramDe22 "param_" & (detailStart +21)
*temp paramDe23 "param_" & (detailStart +22)
*temp paramDe24 "param_" & (detailStart +23)
*temp paramDe25 "param_" & (detailStart +24)
*comment detailPos... dictates what is at what position of the detail sentence.
*temp detailPos1 ""
*temp detailPos2 ""
*temp detailPos3 ""
*temp detailPos4 ""
*temp detailPos5 ""
*temp detailPos6 ""
*temp detailPos7 ""
*temp detailPos8 ""
*temp detailPos9 ""
*temp detailPos10 ""
*temp detailPos11 ""
*temp detailPos12 ""
*temp detailPos13 ""
*temp detailPos14 ""
*temp detailPos15 ""
*temp detailPos16 ""
*temp detailPos17 ""
*temp detailPos18 ""
*temp detailPos19 ""
*temp detailPos20 ""
*temp detailPos21 ""
*temp detailPos22 ""
*temp detailPos23 ""
*temp detailPos24 ""
*temp detailPos25 ""
*temp detailPos26 ""
*temp detailPos27 ""
*temp detailPos28 ""
*temp detailPos29 ""
*temp detailPos30 ""
*comment each paramDe# basically has to have:
*temp deInput1 ""
*temp deInput2 ""
*temp deInput3 ""
*temp deInput4 ""
*temp deInput5 ""
*temp deInput6 ""
*temp deInput7 ""
*temp deInput8 ""
*comment de
*temp de1 ""
*temp de2 ""
*temp de3 ""
*temp de4 ""
*temp de5 ""
*temp de6 ""
*temp de7 ""
*temp de8 ""
*temp de9 ""
*temp de1A ""
*temp de2A ""
*temp de3A ""
*temp de4A ""
*temp de5A ""
*temp de6A ""
*temp de7A ""
*temp de8A ""
*temp de9A ""
*comment the below parses through the params
*temp pdeIndex 1
*label returnHereForPDE
*if {{"paramDe" & pdeIndex}} = "def"
	*temp deDefineIndex 0
	*label returnHereForInternalPDE
	*set pdeIndex +1
	*set deDefineIndex +1
	*if {{"paramDe" & pdeIndex}} = "x"
		*goto skipRestOfDetail
	*temp currentDeForDefine (("de" & deDefineIndex) & "A")
	*set currentDeForDefine {"paramDe" & pdeIndex}
	*gosub_scene fetch gs {currentDeForDefine}
	*set {"de" & deDefineIndex} {currentDeForDefine} & "1"
	*goto returnHereForInternalPDE
*if {{"paramDe" & pdeIndex}}  = "de1"
	*set {"detailPos" & pdeIndex} "de1"
*if {{"paramDe" & pdeIndex}}  = "de2"
	*set {"detailPos" & pdeIndex} "de2"
*if {{"paramDe" & pdeIndex}}  = "de3"
	*set {"detailPos" & pdeIndex} "de3"
*if {{"paramDe" & pdeIndex}}  = "de4"
	*set {"detailPos" & pdeIndex} "de4"
*if {{"paramDe" & pdeIndex}}  = "de5"
	*set {"detailPos" & pdeIndex} "de5"
*if (({{"paramDe" & pdeIndex}} != "de1") and ({{"paramDe" & pdeIndex}} != "de2")) and (({{"paramDe" & pdeIndex}} != "de3") and ({{"paramDe" & pdeIndex}} != "de4"))
	*set {"deInput" & pdeIndex} {"paramDe" & pdeIndex}
	*set {"detailPos" & pdeIndex} "deInput" & pdeIndex
*comment PDE3
*comment if it reaches here, then it returns to top, if it hits "extra", then it skips to "skiprestofdetail"
*set pdeIndex +1
*goto returnHereForPDE
*label skipRestOfDetail
*return

Here is the list of synonyms I used.
(Note: some of the lists are 10 words long. Know that only the first 5 are actually being used.)


*comment create lists for each of the following
*create soar "^soar^glide^flit^dart^swoop"
*create soar1 ""

*create traveler "^traveler^stranger^wanderer^nomad^vagabond"
*create traveler1 ""

*comment create lists for spire
*create spire "^spire^tower^obelisk^monolith^column"
*create spire1 ""

*comment do it for rock, anomaly, geology, cloud, horizon, dominating
*create rock "^rock^stone^boulder^pebble^rock"
*create rock1 ""

*create anomaly "^anomaly^aberration^oddity^peculiarity^enigma"
*create anomaly1 ""

*create geology "^geology^geology^geology^geology^geology"
*create geology1 ""

*create cloud "^cloud^cloud^cloud^cloud^cloud"
*create cloud1 ""

*create horizon "^horizon^horizon^horizon^horizon^horizon"
*create horizon1 ""

*create dominating "^dominating^controlling^commanding^overwhelming^dominating"
*create dominating1 ""






*comment VERBS VERBS VERBS
*comment VERBS VERBS VERBS
*comment VERBS VERBS VERBS
*comment VERBS VERBS VERBS

*comment motion

*create walk "^stroll^strut^saunter^amble^tread^trudge^wander^pace^walk^hike"
*create walk1 ""

*create lookAt "^glance at^gaze at^stare at^peer at^squint at^ogle^glimpse^observe^watch^survey"
*create lookAt1 ""

*create shiver "^tremble^quiver^shudder^shiver^tremble^quiver^shiver^shake^shudder^shake"
*create shiver1 ""

*create turn "^rotate^twist^pivot^swing^revolve^spin^swerve^turn^veer^wheel"
*create turn1 ""

*create struggle "^battle^grapple^endeavor^effort^fight^labor^strive^struggle^wrestle^tussle"
*create struggle1 ""

*create sway "^swing^swing^rock^undulate^oscillate^rock^sway^tilt^oscilate^sway"
*create sway1 ""

*create fly "^soar^glide^flit^dart^swoop"
*create fly1 ""

*create blow "^gust^sweep^blast^blow^blow"
*create blow1 ""


*create areCrossing "^are crossing^are traversing^are crossing^are crossing^are traversing"
*create areCrossing1 ""





*comment sound

*create buzz "^buzz^hum^murmur^whir^drone^whizz^sizzle^purr^throb^vibrate"
*create buzz1 ""

*create chirp "^chirp^tweet^peep^trill^twitter^sing^chitter^warble^cheep^pipe"
*create chirp1 ""

*comment to be

*create is "^is^is^is^is^is^is^is^is^is^is"
*create is1 ""

*create are "^are^are^are^are^are^are^are^are^are^are"
*create are1 ""

*comment ... ing verbs
*comment ... ing verbs
*comment ... ing verbs

*comment sound
*create whispering "^whispering^murmuring^muttering^hushing^murmuring^mumbling^sighing^breathing^whispering^sighing"
*create whispering1 ""

*create singing "^singing^crooning^singing^caroling^chirping^humming^trilling^serenading^chanting^intoning"
*create singing1 ""

*create buzzing "^buzzing^humming^whizzing^whirring^buzzing"
*create buzzing1 ""

*create chirping "^chirping^tweeting^chittering^trilling^twittering"
*create chirping1 ""

*create rustling "^rustling^rattling^shaking^swishing^rustling^shaking^rippling^stirring^crinkling^quaking"
*create rustling1 ""

*create shattering "^smashing^breaking^crushing^shattering^rupturing"
*create shattering1 ""

*create crossing "^crossing^traversing^passing^transiting^bridging"
*create crossing1 ""


*create shine "^gleam^glow^glisten^sparkle^illuminate"
*create shine1 ""

*create burning "^blazing^flaming^scorching^smoldering^igniting"
*create burning1 ""

*comment attack
*create hit "^pummel^cuff^strike^jab^wallop"
*create hit1 ""

*comment NOUNS NOUNS NOUNS
*comment NOUNS NOUNS NOUNS
*comment NOUNS NOUNS NOUNS
*comment NOUNS NOUNS NOUNS

*create you "^you^you^you^you^you^you^you^you^you^you"
*create you1 ""


*comment travel
*create path "^trail^route^lane^road^way^track^passage^avenue^path^path"
*create path1 ""

*create wind "^breeze^wind^gale^draft^breeze^wind^gale^draft^wind^wind"
*create wind1 ""


*create foliage "^foliage^leaves^fronds^grass^vegetation^shrubs^bushes^undergrowth^plants^plants"
*create foliage1 ""

*create leaves "^foliage^fronds^leafage^leaves^vegetation"
*create leaves1 ""

*create sun "^sun^sun^sun^sun^sun"
*create sun1 ""

*create tree "^tree^tree^tree^tree^tree"
*create tree1 ""

*create expanse "^stretch^spread^expansion^vastness^expanse^space"
*create expanse1 ""

*create wilderness "^wilderness^wastelands^wastes^wilderness^wastes"
*create wilderness1 ""



*create castle "^fortress^keep^palace^fort^citadel^stronghold^tower^mansion^chateau^manor"
*create castle1 ""

*create village "^hamlet^town^community^settlement^colony^burg^thorp^outpost^shire^parish"
*create village1 ""

*create house "^home^dwelling^residence^abode^habitation^quarters^bungalow^cottage^villa^manor"
*create house1 ""

*create field "^meadow^plain^tract^pasture^acre^land^prairie^farmland^field^grassy expanse"
*create field1 ""

*create forest "^forest^wilderness^woodland^thicket^wildwood^forest^wilderness^woodland^thicket^wildwood"
*create forest1 ""

*create ocean "^sea^deep^brine^main^blue^depths^marine^ocean^briny^vastness"
*create ocean1 ""

*comment living things
*create creature "^beast^animal^monster^brute^critter^creature^organism^entity^lifeform^specimen"
*create creature1 ""

*create bug "^bug^insect^bug^insect^bug^insect^bug^insect^bug^insect"
*create bug1 ""

*create enemy "^foe^adversary^opponent^rival^antagonist^nemesis^invader^attacker^aggressor^assailant"
*create enemy1 ""

*create people "^folk^persons^individuals^humans^citizens^inhabitants^population^community^masses^society"
*create people1 ""


*comment emotions


*comment misc.






*comment ADJ ADJ ADJ ADJ ADJ
*comment ADJ ADJ ADJ ADJ ADJ
*comment ADJ ADJ ADJ ADJ ADJ
*comment ADJ ADJ ADJ ADJ ADJ

*create cold_adj "^frigid^freezing^chilly^icy^frosty^cool^wintry^nippy^gelid^cold"
*create cold_adj1 ""
*create heat_adj "^warm^fiery^boiling^scorching^blazing^burning^heated^torrid^sizzling^hot"
*create heat_adj1 ""


*create ancient "^old^antique^archaic^age-old^prehistoric^primordial^bygone^antiquated^historic^venerable"
*create ancient1 ""

*create luxurious "^opulent^lavish^sumptuous^extravagant^plush^grand^rich^elegant^luxurious^magnificent"
*create luxurious1 ""


*create harsh "^severe^stern^strict^rigorous^rugged^rough^grim^harsh^tough^brutal"
*create harsh1 ""

*create wild "^untamed^feral^natural^uninhabited^wild^free-roaming"
*create wild1 ""


*comment size

*create long "^lengthy^extensive^long^elongated^drawn-out"
*create long1 ""


*create massive "^massive^huge^enormous^gigantic^tremendous^colossal^vast^immense^monumental^gargantuan"
*create massive1 ""

*create tall "^high^lofty^towering^grand^tall^imposing^statuesque^elevated^sky-scraping^giant"
*create tall1 ""

*create million "^thousand^million^billion^hundred^thousand^million^billion^hundred^thousand^hundred"
*create million1 ""

*create aMillion "^a thousand^ten-thousand^a million^a hundred-thousand^ten-million^a thousand^ten-thousand^a million^a hundred-thousand^ten-million"
*create aMillion1 ""



*comment color
*create red "^crimson^scarlet^ruby^cherry^rose^garnet^vermilion^cerise^carmine^brick"
*create red1 ""

*create green "^verdant-green^emerald-green^jade-green^lime-green^olive-green^mint-green^sage-green^chartreuse-green^viridian-green^pine-green"
*create green1 ""

*create blue "^azure^sapphire^indigo^sky^navy^teal^turquoise^cobalt^cerulean^periwinkle"
*create blue1 ""

*create yellow "^gold^amber^canary^lemon^mustard^saffron^sunshine^butter^maize^flaxen"
*create yellow1 ""

*create purple "^violet^lavender^plum^lilac^amethyst^mauve^magenta^orchid^eggplant^wine"
*create purple1 ""

*create gray "^gray^slate-gray^ash-gray^silver-gray^smoke-gray^steel-gray^pewter-gray^flint-gray^dove-gray^charcoal-gray"
*create gray1 ""

*create black "^ebony-black^raven-black^coal-black^obsidian-black^jet-black^ink-black^sable-black^pitch-black^onyx-black^midnight-black"
*create black1 ""

*create white "^ivory-white^pearl-white^snow-white^alabaster-white^chalk-white"
*create white1 ""

*create orange "^tangerine^apricot^peach^melon^coral^pumpkin^carrot^ginger^marigold^amber"
*create orange1 ""

*create sunDesc "^golden-fire^radiant-monarch^golden-tendril^molten-red^crimson-gold"
*create sunDesc1 ""

*comment location



*comment ADVERB ADVERB
*comment ADVERB ADVERB
*comment ADVERB ADVERB
*comment ADVERB ADVERB

*create brightly "^brightly^luminously^brilliantly^radiantly^dazzlingly"
*create brightly1 ""

*create harshly "^crudely^harshly^coarsely^brusquely^bluntly^roughly^rudely^abruptly^starkly^briskly"
*create harshly1 ""

*create crazily "^crazily^crazily^crazily^crazily^crazily^crazily^crazily^crazily^crazily^crazily"
*create crazily1 ""

*create gently "^gently^softly^tenderly^calmly^lightly^caressingly^gracefully^calmly^quietly^peacefully"
*create gently1 ""

*create abruptly "^abruptly^suddenly^unexpectedly^instantly^rapidly^swiftly^quickly^immediately^precipitously^hastily"
*create abruptly1 ""

*create calmly "^calmly^peacefully^serenely^tranquilly^composedly^quietly^placidly^relaxedly^untroubledly^calmly"
*create calmly1 ""

*create carefully "^carefully^cautiously^attentively^meticulously^conscientiously^prudently^thoroughly^deliberately^precisely^scrupulously"
*create carefully1 ""

*create lazily "^lazily^leisurely^languidly^sluggishly^slowly^lethargically^indolently^casually^relaxedly^nonchalantly"
*create lazily1 ""

*create joyfully "^joyfully^happily^cheerfully^gleefully^merrily^jovially^delightedly^elatedly^joyously^blissfully"
*create joyfully1 ""

*create elegantly "^elegantly^gracefully^refinedly^stylishly^exquisitely^classily^neatly^tastefully^sophisticatedly^chicly"
*create elegantly1 ""

*create violently "^violently^fiercly^ferociously^vigorously^vehemently"
*create violently1 ""

*create tiredly "^wearily^exhaustedly^fatiguedly^tiredly^tiredly"
*create tiredly1 ""


If you don’t want to use the GS1 system (the system that builds the sentences for you), you can use the GS system. This just allows you to substitute words for their synonyms by using gosub and params. (This is also included in the code I provided!)

I never finished coding this system because I eventually realized that, if I’m going to be coding a game like this, then I should move to a language that can better accommodate my needs. I’m going to transfer all the work I’ve done to Python, because it has things like NTLK and SpaCy that can make this much easier. Although, I don’t have much experience at all in coding with those. My end goal is to be able to give the system a sentence and have it automatically rewrite the sentence using synonyms and other things. So far, that’s not really working (hahaha). If you have any suggestions, please tell me!

Anyway, I hope this helps someone. I would really love to play something like a procedurally generated Fabled Lands. (If that happens, I’ll just die on the spot). And if not … Well … I kind of wanted to share this code anyway, lol.

11 Likes

This is really interesting and I’m definitely going to take a proper look when I’m not on a phone. Thank you for sharing!

Now I am thinking about trying out making something short using it when I have some spare moments…

2 Likes

Sorry, forgot to say this, but if you don’t want to use a “detail” or “extra”, just put “non”. And then after “def”, don’t define anything and put “x”. Here’s an example:

*gosub_scene fetch gs1 "2" "" "" "you" "" "areCrossing" "" "tiredly" "the" "word1" "wilderness" "" "non" "def" "x" "a" "de1" "of" "de2" "countryside" "def" "expanse" "wild" "x"

Also, I realized that, when I was explaining type 1 sentences, one of the examples I used was type 2. This probably confused some people, so I went back and fixed it. :smiley:

2 Likes