💾 [TOOL] Softly -- A Soft Save System for ChoiceScript (Discontinued)

That’s a good use case. Take a look in the original post for an idea of how to expose the choice of saving to the player. Just always keep in mind that it’ll only save the global variables.

Hey, just discovered this and wanted to say that it’s absolutely amazing, thank you!

I was digging around for options for save-systems when dashingdon’s built-in plugin is no longer an option, and this is by far the simplest (cause I don’t have to do anything!)

1 Like

Thank you! I’m really happy this is helpful. :grin:

1 Like

Thanks for the help so far, looks like it’s coming together.

Sorry for the constant questions, but I tested it today and at the save point, I got the following error:

off_season line 1077: savesys doesn’t contain label save_1

Idk if this is something I’m doing wrong, or a problem with Dashingdon, but would appreciate some assistance please.

It shouldn’t have that label indeed. Can you tell me how you’re calling the subroutine? Could you perhaps be calling as *gosub_scene savesys save_1 instead of *gosub_scene savesys save 1?

Was saving it as:
*gosub_scene savesys save [1]
Yeah, guess that was it. Thanks.

1 Like

Okay, I am having issues I don’t understand.

At the very start of chapter 12 (the first one in my game) I have this line to save:

*gosub_scene savesys save 1 "chapter12" "variables"

And in the stat screen I have the following choice:

  #I would like go back to the [b]last checkpoint[/b].
    *gosub_scene savesys load 1
    *redirect_scene savesys_slot_1_scene savesys_slot_1_label

But when I try to use it, it says that the file doesn’t exist, even though I have passed that point.

I am using Choicescript IDE.

Also, another question. Should I list savesys in my scene_list or not? If I do, it breaks the quicktest. if I don’t, it also breaks the quicktest,

3 Likes

Hi @malinryden! I’m really glad to hear to you’re considering including a save system despite the extra work. I love your game :blush:.

You have to wrap the variables with curly braces, otherwise, ChoiceScript will think you’re trying to reach a scene literally named savesys_slot_1_scene and a label literally called savesys_slot_1_label.

Try this instead:

*redirect_scene {savesys_slot_1_scene} {savesys_slot_1_label}

I realize it’s wrong in the tutorial. I’ll fix it later (I’m at work right now :face_with_hand_over_mouth:). Thanks for the question, otherwise, I wouldn’t have noticed this.


About the scene_list, there’s no right answer. Usually, you would include only mandatory scenes you want your players to reach. But it shouldn’t be a problem if you include it at the end of the list after a scene you are sure to include an *ending command. If you’re not in the habit of using *ending commands and just rely on the fact the game will hit the end of the scene list and thus automatically end, then I would counter-advise including those files.

In regards to failing the quicktest, I would have to take a deeper look. Unfortunately, quickest is known to be very quirky and doesn’t like fancy code. Even though Softly uses pure ChoiceScript only, it makes use of some exotic features and clever coding. Something might not be sitting right with quicktest.

But like I said, I’ll have to take a better look later.

3 Likes

That worked a wonder! I should have guessed the curly brackets, I did already switch *redirect to *redirect_scene (also an error in the tutorial)

I would not inflict Retribution on people without at least a limited checkpoint save system. It’s kinda massive. :sweat_smile:

EDIT: This is the error that I get when doing the quicktest:

ERROR: couldn’t open savesys.txt

EDIT: I put savesys last in the scene_list, removed the text instructions in it, and added this as the first line:

*if ((choice_quicktest) or (choice_randomtest))
  *ending

Quicktest now gives the error


ERROR: couldn't open .txt

BUT randomtest works!

Progress.

6 Likes

Hi, I’ll take a look at this now. I had a busy week and the next one will continue the trend. :face_exhaling:

1 Like

@malinryden I figured out the issue and uploaded a new version of the generator.

If you are curious, the problem was that quicktest did not like the file had “nothing” so now I’ve added a label followed by a *finish to the top of savesys.txt.

1 Like

Hi @cup_half_empty
It works fine with the latest version of ChoiceScript.
However, quicktest still gives an error message:

QUICKTEST FAILED
ERROR: couldn't open savesys.txt
1 Like

Did you generate with the new version? In the savesys file, it should display v0.0.4 as the version.

I’ve tested a couple of scenarios but the issue with quicktest doesn’t happen on my end.

I did one with the new version, worked perfectly! Thank you!

2 Likes

ONE BIG QUESTION.

Okay, sorry for the caps. First, I just wanted to warn people that in case you have too many variables, you will get an error because the save system loops more than 1000 times and you have to up the looplimit.

But more importantly, I can’t figure out why it does this:

I have the saves at the start of every chapter, like this (varying for chapter and scene name of course:


*gosub_scene savesys save 1 "chapter13" "openingfirst"

However, when I try to load from a checkpoint, things gets weird.

Let’s say I have 5 chapters. There is a *gosub_scene at the top of all of them like above.

If I am in the middle of chapter 1 but want to go back to the checkpoint at the start, it instead loops you to the end of the game, with the restart/play more games like this choice.

If I am in the middle of chapter 2 and wants to go back to the checkpoint at the start of chapter 2, it instead moves me to the start of chapter 1. BUT it seems that the stats are from chapter 2.

I have no idea what is going on here!

Good catch!

I would guess the saving and restoring are working, but there might be a problem with the chapter and scene optional parameters. I’ll take a look later today.


Thanks for reporting these problems, I would never catch them myself. :grin:

I couldn’t reproduce the error on my side and the code looks correct. Can you give me more info on how you’re calling the subroutines?

Okay. I will be posting the savesys.txt first, because it’s slightly different from yours to make it work (CoG helped out with it)

*label start
*ending

*comment @function [slot: int] (scene: str) (label: str)
*label save
*params slot
*set savesys_slot[slot] choice_time_stamp
*set implicit_control_flow true
*gosub init
*comment BEGIN REPEAT LOOP
*comment @loop repeat
*temp repeat_times savesys_var_length
*comment ci == current_iteration
*temp ci 1
*label savesys_repeat_save
*looplimit 3000
*if (ci <= repeat_times)
    *set { "savesys_" & (savesys_var[ci] & "_${slot}") } { savesys_var[ci] }
    *set ci +1
    *goto savesys_repeat_save
*comment END REPEAT LOOP
*set implicit_control_flow true
*if (param_count > 1)
    *set {"savesys_slot_${slot}_scene"} param[2]
*if (param_count > 2)
    *set {"savesys_slot_${slot}_label"} param[3]
*return


*comment @function [slot: int]
*label load
*params slot
*set savesys_load_used choice_time_stamp
*gosub init
*comment BEGIN REPEAT LOOP
*comment @loop repeat
*temp repeat_times savesys_var_length
*comment ci == current_iteration
*temp ci 1
*label savesys_repeat_load
*looplimit 3000
*if (ci <= repeat_times)
    *set { savesys_var[ci] } { "savesys_" & (savesys_var[ci] & "_${slot}") }
    *set ci +1
    *goto savesys_repeat_load
*comment END REPEAT LOOP
*set implicit_control_flow true
*return


*comment @function [slot: int]
*label clear
*params
*if (param_count = 0)
    *bug savesys.clear requires at least 1 parameter, 0 given.
*comment BEGIN WHILE
*comment @loop while
*label savesys_while_clear
*looplimit 3000
*if (param_count > 0)
    *set {"savesys_slot_${param[param_count]}"} 0
    *set param_count (param_count -1)
    *goto savesys_while_clear
*comment END WHILE
*return


*comment @function
*label clear_all
*gosub clear 1
*return


===========================================================


*comment @function
*label init
*temp savesys_var_length 2106
*temp savesys_var_1 "implicit_control_flow"
*temp savesys_var_2 "playtestenabled"
((and so on for all the variables, cut for space))
*return
*finish

Then we have the option to load a save from the stat screen:

  #I would like go back to the [b]last checkpoint[/b].
    *gosub_scene savesys load 1
    *redirect_scene {savesys_slot_1_scene} {savesys_slot_1_label}

Then we have the things in the startup file:


*comment SOFTLY SAVESYS
*create savesys_load_used 0
*comment SLOT 1
*create savesys_slot_1 0
*create savesys_slot_1_scene "savesys"
*create savesys_slot_1_label "start"
*create savesys_implicit_control_flow_1 true
*create savesys_playtestenabled_1 false
((and so on, for all the variables))

And then we have the various chapter saves:

Chapter 12:

*label start
*gosub_scene savesys save 1 "chapter12" "start"

[b]Los Diablos. One month ago.

Chapter 13:

*label openingfirst
*gosub_scene savesys save 1 "chapter13" "openingfirst"
*set status "fine"
[b]Los Diablos, the Millennial Span Bridge. Three months since ${villain_name}'s debut.

Chapter 14:

*gosub_scene savesys save 1 "chapter14" "variables"
*label variables
*temp leave false

Chapter 15:

*gosub_scene savesys save 1 "chapter15" "variables"
*label variables
*set wound "no significant wounds"

And so on…

And let me tell you, I have had every error in the book so far.

So, even with the changes, it’s still not working? Just to clear that out.

I’ve ran the example using CSIDE and by compiling the game using ChoiceScript source code directly. Both ways it runs fine. Quicktest will throw warnings, but warning are not errors, it won’t prevent the game from running. And randomtest ran okay.

I have to amend something I said in an earlier post. It seems that you have to include all game files in the *scene_list when compiling with ChoiceScript’s source, but you don’t need when running with CSIDE (?). I don’t know why, but in any case, you should include the file in the scene_list.

About looplimit, it only affects random test and because each limit is so sensitive to the requirements of each game, I would rather not set it myself, but let authors do it themselves. I can leave a notice in the original post above.

The lib was also built in a way as not to require implicit control to be set to true. In fact, I ran your exact example without implicit control and it ran just fine. And again, I would rather not set it myself, because this could drastically change someone’s game.

If you could share the errors you are getting I could perhaps help more.

1 Like

Okay. I will try to detail more.

First of all, there are no errors in quicktest or randomtest. They work perfectly. That has never been the issue.

But when I choose to load a scene from the stat screen, that is when the weirdness happens.

I start a new game, then go past the first checkpoint, and about halfway through the chapter. If I go into the character selection screen and press the “load from last savepoint” like I described above, I get the classic “play again image”

BUT if I then press “Show stats” to get back to the stat screen, and then “return to the game” I return to the game at the very moment I decided to go back to a checkpoint, not to the checkpoint itself. I will DM you a link so you can see for yourself.

1 Like