[Tool] Chronicler - ChoiceScript Visual Code Editor

@SamiFire Redownload the source code. I was working on implementing a 3rd party library last night and was receiving the same errors. Also ensure that you are running Qt 5.5 with the MinGW 32 compiler.

The library doesn’t seem to be working which could be due to at least a 100 reasons. :confused:
I might remove it if it continues to give issues.

If trying the above doesn’t help, send me a PM so we don’t spam the main thread.

@SamiFire I removed the third party library, as I got the normal method of downloading to work.

Essentially I thought I had to use the Dropbox API to download files as simply trying to download the share link was returning an empty response. Turns out that Dropbox throws a redirect, and Qt’s HTTP classes do not follow redirects by default. Once I told it to follow redirects, it worked perfectly.

Hey all, just an update to let you know that ChoiceScript code generation appears to be working!

Don’t rush to download it from github yet though. I still need to implement the GUI for it, and extend it to work with all scenes, not just startup.

Also, I can guarantee backwards save compatibility starting from the update on Sunday (5/29/16), so you can go ahead and start on your projects after that date.


There’s still a long way to go though. I need to implement a screen for project specific settings, as well as one for variables, and a stats screen editor. Not to mention the color palette creator for bubbles, and a play-test feature.

I’ve also been somewhat frantic this week with finals right around the corner, and haven’t had as much time to plan out how certain features should work. It has led to some hacked together code that I need to fix before the project becomes much larger (butterfly effect).


Anyway, was just excited to share the good news with ya’ll.
Have a great rest of the week!

  • BenSeawalker
2 Likes

Hey all, I’ve decided to go ahead and update the Chronicler test build today rather than tomorrow as I’ll be busy then.

I also added a Test branch to the repository which will be the same as the test Windows build.
This frees me up to check in half finished features on the Dev branch without causing issues with folks testing via Qt Creator.

For existing users, make sure that your cloned repository is now checking out changes from the Test branch.
I highly recommend using SourceTree as a GUI for github repositories on Windows and Mac, it might run with Wine on Linux, but don’t quote me on that.


As I mentioned in my last post, ChoiceScript code generation is now working. Your scene.txt files are placed in the same directory as your .chronx project file.

I also added an autosave feature.
Autosaves are also stored in the same folder as your project file with “.backup1.chronx” appended to the filename.
Once “max autosaves” in settings has been reached, it will begin overwriting old autosaves.
You can set the autosave interval to anywhere from one minute to one hour in settings.
In your OS, you can sort folder contents by date modified to see which autosave is the most recent.

As a side-effect of the above additions, I would highly recommend that you store your projects in separate folders so they don’t step on each other’s toes.


One thing I noticed while working on a project is that manually setting the order of a bubble is merely a suggestion to the CS compiler. The bubble attached to Start will be called first, followed by anything it links to, etc.
This is so that bubbles can be nested rather than having labels and *goto statements for every bubble in the scene.

If this is a problem for you, and you wish for your specified order to be forced on the compiler, then I can fix it to be so. Otherwise, I’ll just leave it be.


I still need to add the variables and stats screen editors, and context specific code completion popups, which I hope to have accomplished before this summer.
The reason I mention this deadline, is because I’m going to be in a location without access to the internet for most of June-September.
I will, of course, work on Chronicler whenever I have time but can’t guarantee any further updates until then.


One more thing I need to mention is that the name and email fields in the submit bug reports/feature requests form are optional and may be left blank. I’m not trying to steal your identities haha.


Enjoy the rest of your weekend!

  • BenSeawalker
3 Likes

Oops, forgot to mention that you can now set Chronicler as the default program for opening .chronx files!

2 Likes

Hey, I have to warn you all immediately that your saved .chronx files are likely corrupted if you loaded one and added more bubbles to it.
It was a logic error on my part. Each bubble is given a unique identifier, however I wasn’t updating the list of taken UIDs when loading projects, so new bubbles were getting assigned the same UIDs as existing bubbles. :confused:

Hopefully your projects load okay, and you can copy the bubble text into a new project after the update this Sunday.

Terribly sorry about this.

1 Like

Hey all, the update is live.

I built a temporary workaround in for duplicate UIDs. It simply checks if the UID has already been taken, and generates a new one. This will likely result in connections being attached to the wrong bubbles, but that should be easy enough to fix manually. Again I apologize for this oversight.

More importantly though, I added a palette creator so you can assign color palettes to each bubble. The difference between the palette system and the color picker from the old Chronicler is that modifying a palette updates all bubbles using that palette. For example, if you wanted to change the default color palette for all story bubbles, its as simple as editing that default palette and hitting save!

Palettes can also have names associated with them. In the case of Choice of Dragon for example, I added palettes for “Brutality”, “Cunning”, “Disdain”, and I renamed the default story palette to “Common.” This way you can easily follow which paths of your story affect which variables. (if you apply palettes correctly haha)


Controls for the palette button are as follows:

  • Right clicking on the palette button creates a new palette.
  • Right clicking on an existing palette lets you edit it.
  • Right clicking on a bubble while in “paint” mode will select its palette.

In paint mode the mouse cursor changes to the currently selected palette.


As you can see, it involves a lot of right clicking which is not ideal. I plan to add these actions to the edit menu at some point in the future.

I also need to add the ability to delete palettes. Right now if you create an invalid palette, simply ignore it until you need a new one, and then edit it rather than add.

I also intend to add an “Export Palette” button that lets you choose which palettes you wish to export into a single file, for import into another project.



I feel I should explain a little bit about the UID conundrum. Essentially I needed a way for connections to remember which bubbles they were attached to after saving and loading a project. Simply storing the memory address of the bubble would not work as they would be assigned new ones by the OS at runtime.

So I added a UID (Unique Identifier) to each bubble.
When a project is loaded, it instantiates all bubbles and connections, then loops through the connections and attaches them to the bubbles with the correct UIDs.

The way a UID is generated is simple, I just loop until I find the lowest UID not taken. In other words, if you created 10 bubbles, and deleted the 7th one, it opened up “7” as a valid UID, and the next created bubble would take it.

While not as efficient of a method, it is still better than having a global UID that gets incremented every time a bubble is created. Eventually you would run out of UIDs even though you had deleted a million bubbles.

I could make this more efficient by having a second list of “available UIDs” that have been freed, on top of the global UID. I’ll probably change it to this system eventually, but right now you shouldn’t notice any slowdown until you have thousands of bubbles in your scenes.



I also hate to admit it, but I don’t think I’m going to have time to properly implement the variables or stats screen editors before I’m thrust out into the boondocks for the summer. :confused:

The reason for this is that I don’t want to throw together a hack job like the ones in the old Chronicler.
I want the stats screen editor to be visual, and you can just drag controls around on the page and see how they look in realtime. I will of course have a “code” control that allows for you to type advanced features, but for the most part you’ll just want to drag the bars in and assign variables to them.



One further statement and I’ll stop chewing your ear off haha.

I’ve made my decision regarding Action bubbles. I’m going to keep them in a list, but the list will have varying columns. Each column will have a spinbox that lets you choose the action and relevant data associated with it.

For example:
“*set experience %+ 10”
would have a column for

  • the action (*set)
  • the variable (experience)
  • the operator (%+)
  • and the value (10)

Being spinboxes, they allow you to type whatever you want into them, or let the context provide you with a dropdown of suggestions. The value box would let you type in 10, but would also let you choose one of your variables to use instead.

I feel this makes it modular enough for advanced users, and simple enough for new users to see all the options available to them.



Thanks, and happy Chronicling!

  • BenSeawalker
2 Likes

For the UIDs, why not use a hashing function? Based on bubble type, name and content maybe?

@CJW I did consider that, however they would still need some completely unique variable to ensure unique hashes. As it is, the UID is essentially an unsigned 64 bit integer which should put you in the range of 10^19 UIDs.

The hash might work if I factor in their memory addresses. Since the hash only needs to be generated when a project is saved.

I’ll have to look into Qt’s hashing algorithms, as that does seem like a better option.


I’ve been meaning to ask you about how you were able to keep track of variables while testing a game in your IDE?
I ask because I would like to implement my own playtest function at some point.
A better option might be if your IDE has an API I could hook into for uploading CS code and running it automatically.
What do you think?

Or I could just save their old memory address and use that as the UID. Just let the OS take care of generating a unique value for me haha.

Built in in watch/observe methods on object properties, but that’s extremely expensive and support is sketchy, so I’ve actually dropped it now. No API sadly, not at present anyway. A Dropbox hosted site couldn’t handle the requests (limited bandwidth).

@CJW Hmm, oh well.

I might be able to implement something akin to debug symbols that could be inserted as comments into the generated CS code. From there I could hook into the signals emitted by the Qt HTML widget for when the underlying html is changed, and parse out the needed information.

Alternatively I could write my own viewer that runs directly off the bubbles in each scene, when an action is hit I can update the modified values. This feels like the wrong way to go as it would have to be maintained along with CS itself.

Another option was suggested by a user some months ago where they could specify a set of variables and have popups displaying their values on each bubble in the scene. This is doable and can be calculated with a similar algorithm to the one I use to parse the bubbles into CS code.
I also feel this is better, as the user can just look at the graph to see all the paths at once rather than having to play every route manually.

Thanks for helping out with brainstorming!

2 Likes

Most of anything even remotely complicated that I’m doing at the moment involves overriding CS in some way, it simply wasn’t designed for this level of 3rd-party integration :sob:

Hey all, just a quick update to let you know that I have a Linux build up in the main post.

I tested it on a clean install of Linux Mint (Cinnamon) and had no issues with missing libs.
if it doesn’t run for you, sudo apt-get install qtbase5-dev should provide the needed libs, but I haven’t tested this assertion.

Feedback from users on this would be most appreciated.


Also, I changed the UID system completely. I foolishly duplicated the same method used in the GM:S version, where I used the UIDs for more than just saving the project.

In this case, I only need to generate the UID once right as the project is saved, rather than when bubbles are created and destroyed, making it significantly more efficient at runtime.

As such, I generate a simple hash based on the memory address of each bubble which I reinterpret_cast into a uint64, making it compatible with old saves and avoiding problems with pointers being different sizes on different OS’s and architectures.

1 Like

The ReadMe on GitHub now has a section explaining the controls, and a link to my Dragon.chronx example project.

EDIT: I also cleaned up the main post, and moved a lot of the text over to the ReadMe on the old Git repository.

I finally figured out the formatting for hyperlinks here on the forum >_<

I also added my public Bitcoin address if you feel like tossing some BTC my way.

1 Like

Sorry to keep spamming the thread, but I’m super excited to announce translation support for Chronicler!

I was able to create and apply a Spanish translation file successfully! (using Google translate haha)


The tool for creating the translations is super easy to use, so If you or anyone you know would like to help create official translations, I would much appreciate it. :smiley:

Send me a PM and I’ll get you setup with the tools.

1 Like

This piques my curiosity- I just wish I had a bit more time to be able to check it out (alas, not until I finish work for the month). Please forgive the skim and possibly missing the answers if they’ve been provided for these questions, but- A) Can I pull a pre-existing CS file WIP into Chronicler and have it create a Chronicler template from the data? B) Which link has a download for whatever version is current (for windows 8 or equivalent)? Sorry- I saw like a dozen up there and I figure I could save some time just asking rather than checking them all.

I’ll take a more in-depth look when I have more time available to me.

@Shawn_Patrick_Reed Thanks for your interest. (:

The old version (that isn’t maintained anymore) has the ability to import existing CS code. However, the new version is much superior in terms of performance and reliability.

To simplify things:
The Windows download link is the new version.
The Launcher download link is the old version.

Instructions for the new version can be found here
Instructions for the old version can be found here.


I created the Dragon example project by simply copy/pasting the lines of text into Chronicler. This isn’t exactly feasible though if you have a really large project.

I intend to add CS code import to the new version, but it might not be possible before I’m gone for the summer. I’ll see what I can do this weekend though. (The code’s already written, I just have to translate it into C++)

1 Like

Just here to report that I’ve made quite a bit of progress towards CS import!

As it stands right now I just need to finish up the *if/elseif/else logic, and do some testing on a more complex scene.
I also need to make it work with multiple scenes, but that is easy enough to do.


I’ve implemented things quite a bit differently than in the GM:S version, but *fake_choices and *if’s without *else’s still suffer the same issue as before: They don’t know which bubble to connect with. :confused:

I’ve got an idea floating around in my head for how to get around this, but have yet to see if it will work in practice.


To summarize my logic:

  • I first process each line of ChoiceScript and assign it a label based on it’s type (Text, Action, Choice, etc.).
    In the case of Choices, I push each *choice line onto a stack and every subsequent line that contains a “#” I add as a child to the topmost choice on the stack. When a “#” with a lower indent level is encountered, I pop the topmost *choice line off the stack.
    This takes care of nested choices.
    I follow a similar logic for *if lines, but only pop the topmost off when an *else is encountered.

  • Next I refine these lines into “blocks”
    Blocks simply prepare the lines into data fit for each type of bubble. In the case of Story blocks, it simply combines every subsequent line tagged as “Text” or “Empty”.
    Choice blocks are more complex as I have to deal with each child “#”, and their child blocks.

  • Once blocks have been built, I take them and transform them into bubbles, passing the last created bubble in as a parameter so I can hook it up with the current one. (this is where the if without else problem arises, the previously created bubble will, in all likelihood, not be the *if bubble, but one of it’s children)

  • Finally, I have to take any blocks that had a *goto statement, and hook them up with a created bubble containing the correct label. (this must be done last, as the bubble with the label might not have been created when the goto is processed.)


My idea for the if without else conundrum is to do something similar to nested Choices in the line processing stage, but instead of adding multiple children, I add the line it should be connected to.



Well, I hope at least some of that made sense haha
Look forward to the update tomorrow night, or Monday afternoon if I get roped into solving family problems.

-BenSeawalker

4 Likes

I lied. :confused:

Turns out it was my grandmother’s birthday and we had to setup and cleanup the family reunion.

In any case, I did spend a couple of hours working on CS import, and have it working to some extent. *goto statements are somewhat problematic as the bubble labeled by the goto might not have been processed yet, meaning that I have to defer those connections until later. Not a big issue, and currently solved.

However, games with lots of *gotos just get thrown into a vertical line with only some branching. I would like to do something akin to the CS export where it creates all the bubbles first, then worries about arranging and connecting them. With the current state of affairs, this might not be possible before I’m without internet for 3 months.

I don’t remember exactly, but it seems like the algorithm for import was better at arranging than the one I’m using now. I might just have to go back and duplicate it as much as possible rather than reinvent the wheel here.

I’ll do what I can to get the current iteration of it out by tonight, if you have terrible problems with it, I’ll try to fix them.

2 Likes