[Tool] ChoiceScript Helper (Currently Unreleased)

Note: I have not yet released this tool, as it is still incomplete, I am simply looking for some feed back on the idea, until such time that I feel it is fully usable.

As a programmer, there’s several things I find to be rather tedious and time consuming to do in ChoiceScript, so for a while, I’ve been toying with the idea of writing a tool to make things easier to do, mostly revolving around the pseudo-arrays that have been implemented somewhat recently. This tool is a result of that idea.

Basically, it works by nesting new commands in ChoiceScript *comment lines, so that the helper can exist along side the legitimate code without interfering. From there, the tool translated these new commands to basic ChoiceScript. So in reality, its not adding anything new, but rather streamlining certain time consuming and tedious tasks. As noted by @CJW, its a pre-processor, so it will take the new lines and translate them into pure ChoiceScript.

As an example, consider the following scenario: You want to create an Inventory system using arrays. Nothing complex, just a list of item names and their descriptions, so you create an array:

*create inv_0_name ""
*create inv_0_desc ""
*create inv_1_name ""
*create inv_1_desc ""
*create inv_24_name ""
*create inv_24_desc ""

… Boy, that sure is a lot of typing! … But hey, say now you wanted to add a third part, like a quantity amount… Why, you’d have to write out another 25 lines! … And if you wanted to increase the number of slots, why that’s even more work.

… With the tool, you can shrink this all down to a single line!

*comment : *csh_array_create inv [0 to 24] ["name" "desc" "qty"] default:["" "" 0]

… Which when processed by the tool will expand to the tedious monstrosity above!

I also have similar commands to fill arrays, create/save/load checkpoint variables, as well as support for the CS Password system I wrote. The program will also parse your entire project all at once, and create backups automatically. In the future, I plan to add the ability to automatically restore back ups, have a toggle for implicit_control_flow, and have a project cleaner, which completely removes all CS Helper lines for when a CS project is complete.

So my question is, would any of you find such a tool useful? And also, does anyone have any other ideas for Helper Commands?

The list of commands currently is as follows (minus the opening ‘csh_’ part):

  • array_create: Created an array of variable type and dimensions
  • array_set: Sets values to multiple array indexes in a single line
  • generated_code_start/generated_code_end: Surrounds generated code, so that when you next run the tool, it knows what code was generated previously, thus will delete the old code before regenerating the updated code.
  • checkpoint_start/checkpoint_end: Used in the ‘startup’ scene to start reading variables to be saved at a check point.
  • checkpoint_generate: Creates checkpoint variables for any variable detected by checkpoint_start/end.
  • checkpoint_save/load: Loads and saves checkpoint values
  • password_start/end_generate: Same as the checkpoint counterparts, but for use with my CS Password system
  • skip/skip_end: CS Helper will skip processing any lines between these two commands
  • skip_all: Skips the remainder of the scene

Edit: Just need to work on ‘array_create’ now, which is the most complicated feature.

Looking forward to your input!

*temp n 0
*label loop
${"*create"} inv_${n}_name ""
${"*create"} inv_${n}_desc ""
*if n > 24
*goto loop

Then copy and paste.

(IDK, I use sublime, so I just type out the numbers real quick, then use multi line edit to insert all the surrounding information.)


Yeah, that works too. I previously had a program that did the same thing for me too, but even that would get tedious to me, with the repeated copy and paste, plus you’d have to custom write a new routine for every variant. The Helper tool will be all automated, complete with backups.

What you’re talking about would be typically be called a pre-processor, transpiler, or extended language (e.g. vJass).

The idea is good, I had actually planned to look into something similar myself but you’ve beat me to the punch.

A few thoughts:

  • Sounds to me like you’re stuffing a bit too much into this one tool (with all the internal flags, checkpoints and password stuff). What if people want the extended commands but not your password system or checkpoint stuff?

  • Correct me if I’m wrong but you make it sound like this tool is a script/mod that works in real-time with CS? If you want to be truly transparent, allowing people to easily publish with CoG/HG and not rely on your tool indefinitely, then I’d go for a stand-alone script that you run over a source file with the new commands. This would then spit out a new (valid) .txt file with identical behaviour.

  • If you did this, you’d also need a source map, so you could translate any errors from the generated code back to your extended macros/extra commands. This would be critical.

  • *array_set sounds fairly useless, isn’t that what loops are for?

  • Do you really need the fluff like delete/delete_end?


@CJW, thanks for the feed back. I’ll touch on the issues you brought up:

  • It’s completely optional as to what someone uses. It’s just code after all. The checkpoint stuff just reads and generates variables, and just copy values between the normal ones and the checkpoint ones. It doesn’t actually add a checkpoint system. Same with my password system (though I plan on adding the option to add it automatically). The tool is primarily for my own use afterall, but if other can use it, I’m glad to share

  • No, the tool is a separate program that turns the helper commands into pure ChoiceScript, and does as you mentioned, backs up the original scene and generates a new version with the changes.

  • Not sure what you mean with the source map. While the code is pretty loose right now, I do plan on adding as many error checks as I can to the tool to reduce errors, though there’s only so much that can be done with a language as loose as ChoiceScript.

  • The ‘array_set’ command currently has 5 variations. The two basic ones can certainly be emulated by a loop, but it can also do things like the following:

*comment : *csh_array_set weapon ["name":"Steel Sword" "cost":250 "desc":"A simple steel short sword"]
*comment : csh_array_set letters ["a" "c" "r" "z" "t"]

… Which I’m fairly sure can’t easily be looped.

  • The delete commands (renamed to ‘generated_code’) are essential for reparsing the code a second time, so that the old generated code will be removed before the new updated code is created.

If you’re generating more code from less code there’s a high likelihood that any runtime errors won’t match up to the original source code. A lot of the time you could probably manually infer the cause of this but as your game gets more complicated it will become increasingly difficult to determine what (if any) extended commands might be causing the issues in the generated code. A source map would allow you to map any errors back to an original csh line in the source code (if applicable), or alternatively adjust the line number to match the original files. Without this crucial component, csh could actually make debugging more difficult, which is definitely not something we need as a community.

Would you consider putting your code up somewhere? The concept looks promising, but I’d like to take a closer (technical) look. Are you committed to extending/supporting this? I had plans to write and including something very similar in CSIDE, but I’d rather foster cross-community support around a few tools than re-invent ten versions of everything. There’s already a few abandoned mods and odd ends hanging about the forums.

That sounds like a very overloaded command. I’d probably suggest moving at least that top one into a more object-orientated instruction? *set_object_attributes?

Again, I like the concept, and I think if it’s done well the CS community could really benefit from this. If you want this to work you’d have to be strict with maintaining it/improving it/etc. It’s not the kind of tool that will mature over night. It’s also one we really wouldn’t want to stagnate with people still relying on it. I also stand by that a source map would be absolutely crucial. I’d make that one of my first/primary focus(es) if it was me.

I’d also suggest a more intuitive name, ‘helper’ is quite vague. How about CS Transpiler, or CSx (ChoiceScript Extended – probably what I would have gone for)? Just a nit.


I find “vanilla” ChoiceScript to be more than confusing enough. However,
I am a rank novice at coding so my opinion should probably carry less weight than others’. If your thing came with very basic, dumbed-down, bonehead instructions it’d probably be cool.

1 Like

Hi all @cjw @stainedofmind. I spent some time looking into the pre-processor idea, as an alternative to using Python to generate code.

I have a first implementation that maps a new *for command (loop) to a series of *if and *goto. Unfortunately, I am hitting some limits of CS. For instance, you can’t nest a for under an if/else statement, because the labels wouldn’t be at the top level. I am looking into *gosub as a workaround.

Another big limit is given by the fact that you can’t programmatically create variables (something like *create base_${var}), which strongly limits what can be done in terms of supporting more sophisticated data structures.

CSIDE looks like it can be a great helper but, as far as I can tell, it’s not extending the language. I’m curious to hear what people are using to build complex games, because keeping track of state can quickly become very baroque. Is everybody reinventing the wheel every time?

1 Like

As I said in your thread on the topic: most people just aren’t. ChoiceScript is not designed for that level of complexity, also it’s target audience is writers first, coders second.

I have toyed around with the idea of extending ChoiceScript before, from within CSIDE, but it would require a transpiler and some effort to get the source mapping/debugging right. Both are essential, else the extensions would just add their own problems: not standardized, hard to debug, supported only by me etc.

If anyone did go down that root, I’d urge you to only add stuff that adds convenience without drastically changing the style of ChoiceScript.
E.g. *create_array and *temp_array I think would be very useful. Looping maybe. But extending it to allow dynamic creation of variables opens up a whole new avenue. I think it’s best to let CoG guide those sorts of decisions and improvements.

What exactly are you trying to do? People might be more able to help you if you have something specific in mind. At the moment it just sounds like you want to make ChoiceScript more flexible/powerful for… reasons?

For example, I’ve found most cases where I’ve needed dynamic memory, I’ve been able to get away with just creating N static variables (where N is the most that I’ll ever need at once) and re-using them.


Hi @CJW. My daughter and I discovered CS to write stories and games to share with friends. But now, every time she sees a new trick, she wants it for our game too. And I’m having a blast pushing the limits.

So, I’m trying to understand how complex games like those you mentioned have been built. In “Lunchtime”, for instance, it must be very complex to manage time and characters if there is limited support to data structures.

1 Like

But are you trying to make lunchtime? If so, take a look at the code there. If not, then what? Exactly what data structure do you feel is missing?

I believe you can at least emulate most data structures, albeit with varying performance tradeoffs.

I’d love to see more adventurous use of ChoiceScript but it’s hard to have an in-depth conversation about a solution to a non-existent problem.

P.S. really awesome that you’re enjoying this as a pastime with your daughter. I’ve always thought ChoiceScript is an especially fun way to get people into basic programming concepts.

1 Like

Thanks @CJW. You nailed the problem with your last sentence. It’s very easy to start and build simple things - that is what brought us in. Unfortunately, as soon as things get more complex, the logic becomes hidden behind all the tricks needed to make it work.

We’re working at a story about Lucius Malfoy’s hairdresser trying to find a missing thestral :blush: Some of our ideas (e.g. you have to visit all rooms, in a certain order, before you can move on) can for sure be implemented, but you need to start emulating sequences and loops - which makes things harder than they need to be. That’s why I was wondering about extensions to the language.

BTW, I started looking into Lunchtime. Again, it’s a really nice and visually captivating game, and the implementation is very clean and readable - much simpler than I expected. Well done!

Oh, another reason we are sticking around is that you have a really nice, welcoming, inclusive community going on! It’s really great.