June 2026 Writer Support Thread

Parameters are great! It’s fun to see someone pretty much going through the same motions I did over the last few months realizing all the things you can do. I still think ChoiceScript could do with a few extra QoL improvements for those of us who are more into complicated code / have coding experience, but you can do a lot of things with it that you might not initially expect, even if you have to go back to basics a bit.

I also wanted to use *script initially but as you said, you can’t use it if you want to be published, so that means we have to get creative!

Of course, here you go!

*comment search database function
*label search_function
*looplimit 10000
*temp term_1 "balderdash"
*temp term_2 "barnacles"
*temp term_3 "endometriosis"
*temp term_4 "liverwort"
*temp term_5 "salacious"
*temp term_6 "sautéed"
*temp term_7 "Yoruba"
*temp term_8 "zoinks"
*temp database_size 8
*comment examples of what your database might look like - must be in alphabetical order, which is the biggest downside of this implementation imo, but you can also probably sort this programmatically if you really want to

*label player_facing_search_box
*temp search_term ""
*input_text search_term
*set search_term "$!!{search_term}"

*temp current_string_pos 1
*temp current_search_scope_end database_size
*temp current_search_scope_begin 1
*temp term_index_number 1
*temp match false
*temp lookup ""

*label search_database_loop

*set lookup "$!!{{\"term_\"&term_index_number}}"

*if (current_string_pos > 1) and (length(lookup) != length(search_term))
    *goto no_match

*if current_search_scope_begin = current_search_scope_end
    *if lookup = search_term
        Term successfully found.

        *set lookup {"term_"&term_index_number}

        Term is: ${lookup}.

    *else
        No terms found!

    *page_break Go again?
    *goto search_function

*if (lookup#current_string_pos) = (search_term#current_string_pos)
    *if match = false
        *set current_search_scope_begin term_index_number
    *set match true
    *if term_index_number < current_search_scope_end
        *set term_index_number + 1
    *else
        *set term_index_number current_search_scope_begin
        *set current_string_pos + 1
        *set match false

*else
    *label no_match
    *if match = true
        *set current_search_scope_end (term_index_number - 1)
        *set current_string_pos + 1
        *set term_index_number current_search_scope_begin

    *elseif term_index_number = current_search_scope_end

        No terms found!

        *page_break Go again?
        *goto search_function

    *else
        *set term_index_number + 1

    *set match false

*goto search_database_loop

Having tested it out, it works quite well and it’s not too bulky code-wise. Obviously you’d have to change a few things if you wanted to fully implement it into a game (converting the database to global variables; implementing some things as parameters if this section is a gosub; etc), but I’m quite happy with it for a start.

Advantages are that 1) you don’t have to store your terms in allcaps, so you can print them into the text freely if you want to, and 2) it also works with any length of word and any number of letters and/or symbols, including diacritics, without the need for verifying the user’s input.

Main disadvantage / possibility to break things right now is probably the fact that your database of terms has to be laid out in alphabetical order as shown at the top (and the number suffixes MUST start at 1 and increment by 1 with no exceptions or gaps). You could probably write exception handlers to imprve stability for these cases and/or write something to sort the terms programmatically (arrays come to mind), but I didn’t get that far.

Let me know if you have any questions or are curious about anything else @myeraland (or anyone else). As I said I love tackling these problems. Coding is like my ice cream that I treat myself to after lots of writing my vegetables.

Side tangent, but it’s also why I love IF so much! There are so few careers where you get to use both logical / mathematical and creative / artistic parts of your brain at the same time, pretty much daily. I understand it’s not for everyone, but we should all cherish it imo! There are lots of good writers and lots of good coders in the world but very few people who are both. Y’all are a special breed!

8 Likes

I’ll show you mine if you show me yours! :laughing: Comparing notes is fun, in all seriousness. I’m curious what you’ve done.

I have seen this! I am stubborn (or just proud?), however, so I’ve stuck to writing stuff myself if and when I need it. Also if I copied everything from here I wouldn’t get to do the fun part myself. :smiley:

Not really. I’ve done some parser-adjacent things where I’ve had to analyze / breakdown player inputs but it’s only very minimal bits and pieces. Examples are a function I wrote to convert a player’s input to all lowercase (which, unlike allcaps, isn’t natively supported in ChoiceScript) and one to check if a string begins with a vowel or not. But both are pretty basic implementations. I haven’t really had the need to do any full-blown data architecture stuff–at least not for my current story. I guess the closest I’ve gotten is the language terms database search function I just posted!

EDIT: Regarding the other discussion (I’m just catching up on the thread and replying as I go, sorry!): I have never in my life heard of double-spacing between sentences until now, and apparently this is something that lots of people have been told to do? I would definitely think it was a mistake if I noticed it in the wild, especially in a published work.

I wonder if it’s age or location based? I’m a 30-something who grew up learning a mix of British / Irish English, if it means anything. But I’ve spent enough time on the internet and around other writers that I would have thought I’d’ve heard of it by now regardless. Bizarre!

6 Likes

Monthly goals: Finish my update for All the Way and if I finish that restart on the update for Sense & Sorcery and the excerpts from that WIP.

I feel like the update for AtW is finally getting there, but sometimes I have the time and I don’t have the energy for one reason or another, and other times I am nearly drowning with energy to write and code that WIP and I have no time for it.

Hope everyone’s writingventures go amazingly well this month.

9 Likes

Update on book titles: I now have a tentative idea that is a direct lift from an in-world book snippet, but I’m superstitious enough to not announce it publicly at this point. :sweat_smile:

I’ve been led to believe it originated from typewriters. And since computers can auto-adjust whitespace between sentences what typewriters can’t, it’s not needed digitally. I could have understood wrong though!

3 Likes

Looks like you have the gist of it! They are really useful for writing ‘modular’ routines, which basically means they can run with any input they are given and don’t refer to specific variables in startup. Of course getting the data back out requires a little trickery but isn’t too hard.

@scriobhaim When I first started messing around with CS the hall of fame was really good for seeing what was possible that I didn’t think was, but I guess, like you, I wanted to do it myself, and I also found I didn’t always like the exact implementation available so would need to rewrite it anyway!

So these are my implementations, as standard practice with everything I write in CS nowadays they rely on using implicit control flow, and use a couple of specific variables for return values. More complex pieces usually get more comments, but I hope they are easy enough for anyone to use.

String search matching

It is called by:
*gosub search_string my_list_of_strings search_term exact_search_bool
and requires two variables called returnVal and returnDatato hold the output values which can then be used for whatever you’re doing with them. In this case, a database of terms would simply be a single string with space-separated values, like so: *create my_list_of_strings “aardvark xylophone Timbuktu”. Terms can be in any order, as it simply sweeps the list until a match is found. If using exact searches it is case sensitive and will attempt to match the entire search term, else it is not case sensitive and will match partial words e.g. searching for ‘aar’ would find ‘AAR’ in aardvark, but if exact search is true, then it would not find anything. It probably wouldn’t be too hard to rejig this to search based on comma-separated-values and then return the entire value on a partial match… if you’re interested?

*comment -- [[ SEARCH STRING ]] --------------------------------------
*comment -- Searches for a term in a string with optional exact matching
*comment -- (srch_string:string, srch_term:string, srch_exact:boolean) -> (returnVal:boolean, returnData:string)
*label search_string
*params srch_string srch_term srch_exact

*temp srch_i 0
*temp srch_j 1
*temp srch_tlen length(srch_term)
*temp srch_slen length(srch_string)
*temp srch_obj ""
*temp srch_comp ""

*if not(srch_exact)
    *set srch_string "$!!{srch_string}"
    *set srch_term "$!!{srch_term}"
*else
    *set srch_string &" "
    *set srch_term &" "

*label srch_iter
*if (srch_i < srch_slen) and (srch_j <= srch_tlen)
    *set srch_i +1
    *set srch_obj (srch_string#srch_i)

    *if (srch_obj = (srch_term#srch_j))
        *set srch_comp &srch_obj
        *set srch_j +1
    *else
        *set srch_j 1
        *set srch_comp ""
    
    *if (srch_comp = srch_term)
        *if (srch_exact) and (srch_j < srch_tlen)
            *goto srch_iter
        *set returnVal true
        *set returnData srch_comp
        *return
    *else
        *goto srch_iter

*set returnVal false
*set returnData ""
*return
To lowercase

This just converts whatever is passed to it into a lower case variant if it can.

*comment -- [[ TO LOWER ]] -----------------------------------
*comment -- Converts the passed string to lower case ignoring non-represented characters
*comment -- (tl_string:string) -> (returnVal:string)

*label to_lower
*params tl_string

*looplimit 1000000 

*temp uppers "ABCDEFGHIJKLMNOPQRSTUVWXYZ,.;:/\?!0123456789ĄĆĘŁŃÓŚŹŻÀÁÂÄÆÃÅĀÇÈÉÊËĒÌÍÎÏĪÑÒÓÔÖÕŌÙÚÛÜŪÝΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
*temp lowers "abcdefghijklmnopqrstuvwxyz,.;:/\?!0123456789ąćęłńóśźżàáâäæãåāçèéêëēìíîïīñòóôöõōùúûüūýαβγδεζηθικλμνξοπρστυφχψωабвгдеёжзийклмнопрстуфхцчшщъыьэюя"

*temp tl_i 0
*temp tl_len length(tl_string)
*temp tl_obj ""
*temp tl_new ""

*label tl_loop
*if (tl_i < tl_len)
    *set tl_i +1
    *set tl_obj (tl_string#tl_i)
    *if (tl_obj = " ")
        *set tl_new &tl_obj
        *goto tl_loop
    *temp tl_j 0
    *temp tl_up_len length(uppers)
    *label tl_srch_upper
    *if (tl_j < tl_up_len)
        *set tl_j +1
        *if (tl_obj = (uppers#tl_j))
            *set tl_new &(lowers#tl_j)
            *goto tl_loop
        *else
            *goto tl_srch_upper
    *else
        *set tl_new &tl_obj
        *goto tl_loop

*set returnVal tl_new
*return

My first parser attempt is available in Clock_for_Choicescript, I was originally planning on using it for a time sensitive game, but I was struggling getting the story started, so put it to one side. More recently I wrote a group of routines to implement something akin to ‘tables’ that you find in lua, which is sort of a cross between an array and a dictionary-object. It works super well in tests so far, but there is more I want to add to it, and it can be quite heavy computationally, not in itself, but because of what it encourages you to do with it!

6 Likes

Your “convert to lower” function is quite similar to mine! Great minds, etc… I wrote mine while ago so it could probably be more efficient, but then again, I pretty much only ever use it once so far, so I’m not exactly losing all that much if it’s not perfect.

*comment takes a given string and forces the first letter to be uncapped
*comment doesn't work with combined characters, e.g. ę́
*comment could be easily modified to decap the entire string or any other specific character
*label glo_decapitalize_string

*params ds_input_string_name
*set func_decapped_string ""
*temp ds_letter_string "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzÅåǺǻḀḁĂăẶặẮắẰằẲẳẴẵȂȃÂâẬậẤấẦầẪẫẨẩẢảǍǎȺⱥȦȧǠǡẠạÄäǞǟÀàȀȁÁáĀāÃãĄąÆæɃƀḂḃḄḅḆḇƁɓĆćĈĉČčĊċḈḉƇƈȻȼÇçꞒꞓĐđƊɗḊḋḌḍḐḑḒḓĎďḎḏĔĕḜḝȆȇÊêỀềẾếỂểỄễỆệẺẻḘḙĚěɆɇĖėẸẹËëÈèȄȅÉéĒēḔḕḖḗẼẽḚḛĘęȨȩŒœƑƒḞḟꞘꞙǴǵǤǥĜĝǦǧĞğĢģƓɠĠġḠḡꞠꞡĤĥȞȟĦħḨḩⱧⱨḤḥḢḣḦḧḪḫꜦꜧỊịĬĭÎîǏǐƗɨÏïḮḯÍíÌìȈȉĮįĪīỈỉȊȋĨĩḬḭİiĴĵɈɉƘƙꝀꝁḰḱǨǩḲḳĶķⱩⱪḴḵꞢꞣꝂꝃꝄꝅĹ壳ĽľḸḹĻļĿŀḶḷḺḻḼḽȽƚⱠⱡŁłḾḿṀṁṂṃŃńÑñŇňǸǹṄṅṆṇŅņṈṉṊṋꞤꞥȠƞƝɲꞐꞑꝊꝋØøǾǿÖöȪȫÓóÒòÔôỐốỒồỔổỖỗỘộǑǒŐőŎŏȎȏȮȯȰȱỌọƟɵƠơỚớỜờỠỡỢợỞởỎỏŌōṒṓṐṑÕõȬȭṌṍṎṏǪǫȌȍǬǭꟀꟁꝐꝑꝒꝓꝔꝕṔṕṖṗⱣᵽƤƥɊɋꝖꝗꝘꝙŔŕɌɍŘřŖŗṘṙȐȑȒȓṚṛṜṝṞṟꞦꞧⱤɽꞂꞃẞߌśṠṡṨṩṤṥṢṣꞨꞩꟉꟊŜŝṦṧŠšŞşȘșⱾȿꟅʂƧƨꟘꟙŤťṪṫŢţṬṭƮʈȚțṰṱṮṯŦŧȾⱦƬƭꞆꞇꞱʇŬŭɄʉꞸꞹỤụÜüǛǜǗǘǙǚǕǖṲṳÚúÙùÛûṶṷǓǔȖȗŰűŬŭƯưỨứỪừỬửỰựỮữỦủŪūṺṻŨũṸṹṴṵŲųȔȕŮůꞾꞿṼṽṾṿƲʋỼỽẂẃẀẁŴŵẄẅẆẇẈẉꝠꝡⱲⱳꟂꟃẌẍẊẋÝýỲỳŶŷŸÿỸỹẎẏỴỵỶỷȲȳɎɏƳƴỾỿŹźẐẑŽžŻżẒẓẔẕƵƶꟆᶎⱫⱬȤȥⱿɀƷʒꝢꝣꟆᶎÞþÐðǷÞȜȝΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσΤτΥυΦφΧχΨψΩωꟐꟑꞄꞅꝹꝺꝻꝼꝾꝿ"
*temp ds_letter_string_pos 1
*temp ds_replaced_char {ds_input_string_name}#1

*label glo_ds_loop_start

*if ds_replaced_char = (ds_letter_string#ds_letter_string_pos)

    *set ds_replaced_char ds_letter_string#(ds_letter_string_pos+1)

*elseif ds_letter_string_pos < 773

    *set ds_letter_string_pos + 2
    *goto glo_ds_loop_start

*else

    *set func_decapped_string {ds_input_string_name}
    *return
    
*set func_decapped_string ds_replaced_char
*temp ds_output_string_pos 2

*label glo_ds_write_new_string_loop

*if ds_output_string_pos > length({ds_input_string_name})

    *return

*else

    *set func_decapped_string func_decapped_string&({ds_input_string_name}#ds_output_string_pos)
    *set ds_output_string_pos + 1
    *goto glo_ds_write_new_string_loop

I also like the search function! You have me beat on lines, and I think your way of handling the database is probably easier in the long run! But I also think I like my iterative way of finding the strings–in a large database it would probably be faster as it will be able to narrow down the prospective matches faster, I think? I also think I opted to keep the database terms as discrete variables so they could be printed in text, which might be important for a language game. But that’s the beauty of this whole thing: we can both go at the same problem from different angles and come up with equally great solutions. I love comparing notes like that though. Gives me great ideas for the future and it can be quite inspiring. :grin:

7 Likes

Maybe we could set up a test environment and use random test to race them :rofl:

Edit: I raced them, using random test on default settings… results are approximate as depending on background processes times can vary, @scriobhaim c.3 secs @CodedQuill c.5 secs

This does make a lot more sense, mine really just checks to see if it is in the list or not. I did put together a concept piece one weekend for a language puzzle game, as I like solving/writing puzzles. If you’re interested I’ll upload it later, but it is quite rough, I just figured it’d be a fun side project. It’s the sort of thing I think helps to have someone to bounce ideas off as you’re trying to come up with puzzle ideas.

6 Likes

After taking a 9 month break (kill me) from writing my first demo I’m finally back to doing it! I was basically almost done with the demo by the time I stopped so I guess my goal for the month is to post it before July!

(Also if the creator of that reddit post encouraging people to post about their unreleased demo’s is on here, thanks! you got me to quit procrastinating sgshsgsh)

11 Likes

Also any fellow queer writers get worried about the reception of their work? Like one of the main characters in the book I’m writing is trans and I keep getting anxious about the inevitable transphobic comments :skull:

7 Likes

Same here actually. It’s not just the worry itself, but I’ve seen how cruel some of the gamer crowd can be towards works that have queer characters just existing and being a part of the narrative without hiding said queerness. But shitty people will be shitty no matter what you do.

Best to focus on those reading your works in good faith. I don’t think sanatizing your works just to avoid complaints will work anyway, so might as well tell the story you want than the story others will react best to

(Also, hi from reddit!)

9 Likes

Don’t worry, I’ll never compromise anything I do for the sake of a couple of bigots. Also thanks! We’re all in this thing together after all

5 Likes

The most humbling experience as a writer is when you’re going through earlier work and spot errors that are so obvious that you have no idea how you didn’t spot them when you wrote it.

The latest example is just going through Chapter Three to make a small change, and I noticed I had used “queue” instead of “cue” in a sentence. facepalm

14 Likes

You’re inevitably going to get hate, transphobic or otherwise. There will always be people who don’t like it. Some are nice, and offer constructive feedback. Others will be haters, and will choose whatever random reason they want.

8 Likes

My first instinct is to write a game that has no pronouns (still unsure how that would even work), and another that refuses to use singular you and uses thou instead. But like I’ve said before, I am a troll descendant.

2 Likes

I actually has a minor character in FH (Ward - one of the mob boss underlings) for whom I use no pronouns. Just because I am curious to see if I could, and what the players perceive.

And about transphobic/homophobic comments…

Honestly. It might just be me. But I get a lot more complaints/bad reviews about the fact that the game costs money, and that there are no graphics.

12 Likes

Is that one of the mob boss underlings? (I’m afraid the name “Ward” will just conjure Grant Ward from Agents of S.H.I.E.L.D. to me…)

But then, try doing that to the whole game! And then remember that “this” and “which” and the like are also pronouns. And then snicker at the thought that people are assigning value judgements to games that include pronouns. Honestly, what a joke.

I’ll admit I’m also extremely curious to what players perceive… so much so that I kinda-sorta want to just go and straight-up ask what they think my gender-selectable charaters read as.

5 Likes

So about personality stats. I’ve noticed in the demo I’m writing that some personality stats have many more opportunities to get increases/decreases than the others. Do you think that’s fine? Or should I find opportunities for the other personality stats get equal love, cause I’ve been trying and sometimes it’s coming out as contrived.

4 Likes

That depends. If you have a system where the player puts in points, and where getting high personality stats is a part of the game, then it’s not fine.

On the other hand, if personality stats is something that arises through play and where the player doesn’t have to choose, then it’s fine.

6 Likes

Although if they’re opposed stats, and it’s easier to get points in one of the pair than the other, I’d say it’s not fine. Unless it’s something that’s intended to be hard.

4 Likes

Yeah it’s mostly dialogue flavor and gain increases and decreases when picking some dialogue options, like for example the personality stats that show up most is Soft/Tough and the ones that show up the least is Close/Distant. Doesn’t affect the ability to choose certain choice paths. At most they dictate how some characters perceive you but that’s about it.

3 Likes