Number Reading / Spelling Function

Hey there.

So, I was reading ITFO, where you get your dynamic numbers neatly spelled out, and I was like “hey, I want this in my game too!”

So I wrote some code for it. It’s probably pretty crude, but… it works. And to make the most of my suffering, I’d like to share it with you:

Instructions:
Installation: Download tech_number_reading_functions.txt and put it where your other game files are.

(Assuming that the number reading function code is saved in a separate file called tech_number_reading_functions; you can, of course, call the file anything you want, just change it appropriately in gosub_scene.)

NUMBER = number you want to have spelled out

NUMBER_SPELLED = temp for the result (spelled out number). Can also be a normal var of course

*set number_count_1 length(NUMBER)
*set number_count_1b NUMBER
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp NUMBER_SPELLED number_count_1_result_total

After that, if NUMBER is 123, the sentence

“Numeric value ${NUMBER} spelled out is ${NUMBER_SPELLED}.”

would give this result:

“Numeric value 123 spelled out is one hundred and twenty-three.”

There are three different settings for this code.

ON (*set number_reading_function_mode 1) means that, when called, the number reading function will spell out all numbers smaller than or equal to a billion.
Numbers above one billion will be given as “more than a billion”.

OFF (*set number_reading_function_mode 0) turns the function completely off (duh), numbers will stay numeric.

HYBRID (*set number_reading_function_mode 2) is the same as ON, but numbers above one billion will stay numeric.

To use this function, you also need to declare the following vars in your startup.txt (you can just copy&paste from here):

*create number_reading_function_mode 1
*create number_count_1 0
*create number_count_1b 0
*create number_count_1_1 0
*create number_count_1_2 0
*create number_count_1_3 0
*create number_count_1_4 0
*create number_count_1_5 0
*create number_count_1_6 0
*create number_count_1_7 0
*create number_count_1_8 0
*create number_count_1_9 0
*create number_count_1_result_total “”
*create number_count_1_result_0 “”
*create number_count_1_result_1 “”
*create number_count_1_result_2 “”
*create number_count_1_result_3 “”
*create number_count_1_result_4 “”
*create number_count_1_result_5 “”
*create number_count_1_result_6 “”
*create number_count_1_result_7 “”
*create number_count_1_result_8 “”
*create number_count_composite_ones_tens_done false
*create number_count_composite_ten_thousands_thousands_done false
*create number_count_composite_ten_millions_millions_done false
*create number_0 “zero”
*create number_1 “one”
*create number_2 “two”
*create number_3 “three”
*create number_4 “four”
*create number_5 “five”
*create number_6 “six”
*create number_7 “seven”
*create number_8 “eight”
*create number_9 “nine”
*create number_10 “ten”
*create number_11 “eleven”
*create number_12 “twelve”
*create number_13 “thirteen”
*create number_14 “fourteen”
*create number_15 “fifteen”
*create number_16 “sixteen”
*create number_17 “seventeen”
*create number_18 “eighteen”
*create number_19 “nineteen”
*create number_20 “twenty”
*create number_30 “thirty”
*create number_40 “fourty”
*create number_50 “fifty”
*create number_60 “sixty”
*create number_70 “seventy”
*create number_80 “eighty”
*create number_90 “ninety”

(number_reading_function_mode can be set to 0, 1 or 2 here depending on what you want as default.)

  • “There’s a mistake/something is missing!” Where? What? Please tell me!
  • “This could’ve been done way easier, by simply doing xyz” Yeah, that’s what I thought. Wish I would’ve researched for more than 10 seconds before starting this, but what’s done is done.
  • “Someone already did this!” Really? I didn’t find anything in the abovementioned 10 seconds. Fml I guess
  • “Why up to a billion? Nobody needs that…” Probably true. It was only supposed to go up to… I don’t remember, but a far more sensible, lower number. Then I thought I accidentally missed some numbers, so I expanded, then I saw it was now capable of even bigger numbers, got confused, and went all in.

Feel free to do with this code whatever you want.

7 Likes

UPDATE: bugfix when calling the function repeatedly (some variables would be retained and alter the subsequent results).
Either copy/paste the new version from Github, or just add these lines (re-initializing the affected variables after each run of the function) before the second-to-last *return:
*set number_count_1_1 0
*set number_count_1_2 0
*set number_count_1_3 0
*set number_count_1_4 0
*set number_count_1_5 0
*set number_count_1_6 0
*set number_count_1_7 0
*set number_count_1_8 0
*set number_count_1_9 0
*set number_count_composite_ones_tens_done false
*set number_count_composite_ten_thousands_thousands_done false
*set number_count_composite_ten_millions_millions_done false

My heartfelt thanks my friend.

With this if your player is a Liege whose advisor is blurbing-out numbers, that means…

hmmm…

Scene:

[i]The royal council chamber. Your advisor, 
Chancellor Elric, presents the 
kingdom's monthly expenses.[/i]


*set upkeep 452
*set number_count_1 length(upkeep)
*set number_count_1b upkeep
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp upkeep_spelled number_count_1_result_total

Chancellor Elric clears his throat. "Your Majesty, the treasury records indicate 
that this month's upkeep amounts to [b]${upkeep_spelled} crowns."

He continues, "This includes provisions, garrison wages, 
and maintenance of the royal stables."

Would print:

The royal council chamber. Your advisor, Chancellor Elric, presents the kingdom’s monthly expenses.

Chancellor Elric clears his throat. “Your Majesty, the treasury records indicate that this month’s upkeep amounts to four hundred fifty-two crowns.”
He continues, “This includes provisions, garrison wages, and maintenance of the royal stables.”

also

Scene: *

[b]Troop Equipmt. Status[/b]
*line_break
[i]The armory. Quartermaster Brynn reports on the army's equipment.[/i]
*line_break
*set swords 120
*set number_count_1 length(swords)
*set number_count_1b swords
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp swords_spelled number_count_1_result_total

*set shields 85
*set number_count_1 length(shields)
*set number_count_1b shields
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp shields_spelled number_count_1_result_total

Quartermaster Brynn reports, "We have [b]${swords_spelled} swords[/b] and [b]${shields_spelled}[/b] shields ready for deployment, my $!{Lord_Lady}."

whould print:

Troop Equipment Status

Setting: The armory. Quartermaster Brynn reports on the army’s equipment.

Quartermaster Brynn reports, “We have one hundred twenty swords and eighty-five shields ready for deployment, my Lady.”

and lastly:

[b]Market Revenue from Trade

[i]The docks. Merchant Guildmaster Liora discusses recent trade profits[\i]

*set silk_bales 37
*set number_count_1 length(silk_bales)
*set number_count_1b silk_bales
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp silk_bales_spelled number_count_1_result_total

*set spices_crates 24
*set number_count_1 length(spices_crates)
*set number_count_1b spices_crates
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp spices_crates_spelled number_count_1_result_total

*set revenue 15800
*set number_count_1 length(revenue)
*set number_count_1b revenue
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp revenue_spelled number_count_1_result_total

Guildmaster Liora smiles, "Our latest voyage brought back [b]${silk_bales_spelled} bales of silk [/b]and [b]${spices_crates_spelled} crates of spices. The market sales have yielded ${revenue_spelled} crowns[/b] in profit."

would be:

Market Revenue from Trade

The docks. Merchant Guildmaster Liora discusses recent trade profits.

Guildmaster Liora smiles, “Our latest voyage brought back thirty-seven bales of silk and twenty-four crates of spices. The market sales have yielded one thousand five hundred eighty crowns in profit.”

Sincerelly, your tool makes the game feel more like a real CYOA handbook that if the numbers were speeled in indu-arabic al-charisms. It make the prose more immersive and the text more pleasant to the eye.

thank you for sharing my dudette!.

(By the way, I am a little dumb and my google-fu failed me, what is a IFTO? :sweat_smile::: )

hmm. Can this be simplified by the use of a header label?

For example:

original:

*set number_count_1 length(NUMBER)
*set number_count_1b NUMBER
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp NUMBER_SPELLED number_count_1_result_total

with header:

*gosub numSpeech NUMBER
*temp NUMBER_SPELLED return

You see?
Other examples:

*temp upkeep 452
*gosub_scene num_speech numSpeech upkeep
*temp upkeep_spelled return

Chancellor Elric reports, "Your Majesty, the monthly
 upkeep is ${upkeep_spelled} crowns."

You see? Esse approach streamlines the process, making it more accessible for writers to incorporate number-to-speech functionality without delving into the underlying mechanics each time.

By the way.
And by header I mean a shorthand label in each scene that simplify commands, like this:

*label header
*comment ==================================
*comment ==================================
*comment please paste this header label on 
*comment the topmost of each scene in your 
*comment scenes folder:
*comment ==================================

*label numSpeech
*params this_number
*temp number_len length(this_number)
*temp return ""

*set number_count_1 number_len
*set number_count_1b this_number
*gosub_scene tech_number_reading_functions number_reading_function_1
*set return number_count_1_result_total

*return

*comment ==================================
*comment ==================================
*label /header
1 Like
  1. Thank you for your kind words
  2. ITFO = I, the Forgotten One - quite the popular IF, especially at the time I initially made this
  3. Your examples were very nice to read, but still almost gave me a heart attack - if the code spelled out “15800” as “one thousand five hundred eighty”, that’d mean there’s a bug in the string length parsing. Thankfully, a quick test of your code came out okay ^^"
  4. I’ll probably make a 2.0 version of this someday to reduce the necessary setup input from the user. If I use temps everywhere (which I loathe, but should work in this case), far fewer variables will have to be *create’d in startup, and the dual declaration of number_count_1 and number_count_1b can easily be reduced to a single declaration of number_count_1b by having the code copy it to number_count_1 by itself. Probably should also use more easily understandable variable names… in my defense, I wrote all this in a sleep-deprived nightly marathon, otherwise I’d have done all that before releasing it to the public
2 Likes

hmm. Can this be simplified by the use of a header label?

For example:

original:

*set number_count_1 length(NUMBER)
*set number_count_1b NUMBER
*gosub_scene tech_number_reading_functions number_reading_function_1
*temp NUMBER_SPELLED number_count_1_result_total

with header:

*gosub numSpeech NUMBER
*temp NUMBER_SPELLED return

You see?
Other examples:

*temp upkeep 452
*gosub_scene num_speech numSpeech upkeep
*temp upkeep_spelled return

Chancellor Elric reports, "Your Majesty, the monthly
 upkeep is ${upkeep_spelled} crowns."

You see? Esse approach streamlines the process, making it more accessible for writers to incorporate number-to-speech functionality without delving into the underlying mechanics each time.

By the way.
And by header I mean a shorthand label in each scene that simplify commands, like this:

*label header
*comment ==================================
*comment ==================================
*comment please paste this header label on 
*comment the topmost of each scene in your 
*comment scenes folder:
*comment ==================================

*label numSpeech
*params this_number
*temp number_len length(this_number)
*temp return ""

*set number_count_1 number_len
*set number_count_1b this_number
*gosub_scene tech_number_reading_functions number_reading_function_1
*set return number_count_1_result_total

*return

*comment ==================================
*comment ==================================
*label /header