Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How to variables across saved games without the possibility of abuse (Sugarcube 1.x)

edited July 2016 in Help! with 1.x
Hello everyone. Quite new to Twine, and I've been working on a simple turn based JRPG as a solo non-profit project for the last couple of months. Basically the game has 3 classes: Mage, Rogue, Warrior (generic stuff), and currently, I'm trying to encourage players to create "alts" by enabling the transfer of $gold across characters through the use of a stash.

What I tried to do was this: <<remember $stash_gold to 10000>> for example, and when a player starts a new character, that new character would be able to check the stash and withdraw the gold to give that new character a head start. I also want to implement a system where a player's "main" character could pay $gold to grant a global experience bonus (to level up alts faster).

Here's the problem: I realized the possibility of a player "stashing" 10000 gold, then reloading to a save where he had not spent the gold, and repeatedly "stashing" it again, resulting in an infinite gold abuse. Same goes for purchasing the global experience bonus... the player can just buy it, then reload a save.. since the <<remember>> macro allows the set variables to persist across saves.

Can anyone suggest a better way of going around this? I really want to implement this system that encourages rolling alts, but it has occurred to me that the <<remember>> macro is a terrible and highly abusable way of doing it. Any help would be greatly appreciated :)

Note: I haven't tried my hand at javascript stuff, and I've pretty much built the whole game in Sugarcube 1.x, but I'm willing to learn and try anything to get this to work.

Edit: Just in case, I'm sorry if this question has been asked before.

Comments

  • edited July 2016
    You could implement checks on what the gold value of each character is each turn and not allow a player to stash more than that.

    eg something like

    <<set $gold to 10000>>
    <<set $goldrecord to $gold>>

    I'm too tired to think through exactly where you'd go from there, but that would be one way of implementing a security check. But in general you wouldn't allow a single character to donate more than what their $goldrecord number is. So you'd also need to keep track of stash donations.

    Each time the character donates to the stash then you'd record it in a separate variable like <<set $stashcontribution>>

    You could block off further donations if they exceed the goldrecord. Eg

    <<if $stashcontribution gte $goldrecord>>Can't use stash right now.<</if>>
  • Hello Claretta.

    Thanks for the reply, but unfortunately that would still allow a player to stash 10000 gold, then reload a save at an earlier passage where the $goldrecord variable wasn't set yet. This way, they could still transfer 10000 gold without losing the 10000 gold on that character. I have no way of making the $goldrecord persist across earlier saves without using the <<remember>> macro, which in itself is a problematic macro.

    What I'm looking for is perhaps a better alternative to the <<remember>> macro. One that is not so abuseable. My goal is to be able to transfer $variable data between characters across different saves. Is there a way to do that? Or perhaps there exists a more creative solution?
  • The main issue with both SugarCube's <<remember>> macro and the story format save systems is that all the relevant data is stored locally within the user's web-browser cache sub-system, this means that the user can modify that data if they want to.

    SugarCube makes modify the data contained within saves a little harder because it encodes that data but the information needed to decode it is contained within the source code, so I believe that with a little effort on the users behalf they would be able to overcome the encoding.

    Of the top of my head I can't think of a method to achieving the result you want with a Twine story, but someone else may.
  • edited July 2016
    puppetz87 wrote: »
    Hello Claretta.

    Thanks for the reply, but unfortunately that would still allow a player to stash 10000 gold, then reload a save at an earlier passage where the $goldrecord variable wasn't set yet. This way, they could still transfer 10000 gold without losing the 10000 gold on that character. I have no way of making the $goldrecord persist across earlier saves without using the <<remember>> macro, which in itself is a problematic macro.

    What I'm looking for is perhaps a better alternative to the <<remember>> macro. One that is not so abuseable. My goal is to be able to transfer $variable data between characters across different saves. Is there a way to do that? Or perhaps there exists a more creative solution?

    SugarCube save games save variables so you don't need to use the remember macro for what you want to do. I have an extremely complex game which will eventually take 10 hours to play and I'm not using <<remember>> once, and it works fine. So I'm not quite understanding the problem here.

    As for earlier saves, my idea was to use the $goldrecord variable from the start and just continually update it parallel to picking up gold, so the player couldn't go back before the macro started recording.

    Otherwise, you can disable custom saves entirely and only allow autosaving at predefined points.

    greyelf wrote: »
    SugarCube makes modify the data contained within saves a little harder because it encodes that data but the information needed to decode it is contained within the source code, so I believe that with a little effort on the users behalf they would be able to overcome the encoding.

    I believe you can make it as a nw.js app and host that online within a web browser. That makes data much more secure.

    You can never totally protect against hacking though without an online authentication, and I think that's going a little too far for a simple game.
  • Claretta wrote: »
    I believe you can make it as a nw.js app ...... That makes data much more secure.
    It may be more hidden but that is not the same as being more secure, a node-webkit NW file is just a ZIP file with a different extension.

    It is very difficult to secure a web-based application if the user has access to the source code which is the case of Twine based stories, you can use techniques to increase the effort required by the cheater but if you are planing to charge money for features then you need to either:

    a. live with fact that people will be able to cheat.
    b. convert the web-based Twine story to something other than web-based.
    c. use something other than Twine to make your story.
  • edited July 2016
    You can apply a 64 character AES randomised password to the zip file and that protects it from random extractions. NW.js still reads the info and displays it from inside but you can't just unzip a properly protected nw.js file without serious effort.

    I'm sure there might be methods to crack such passwords or decode it from RAM, but no one is going to be able to use Universal Extractor on a properly protected nw.js program anytime soon.

    Electron, nw.js's main competitor also offers a similar feature.





  • edited July 2016
    Claretta wrote: »
    SugarCube save games save variables so you don't need to use the remember macro for what you want to do. I have an extremely complex game which will eventually take 10 hours to play and I'm not using <<remember>> once, and it works fine. So I'm not quite understanding the problem here.

    Ah, I see I didn't clarify the situation, I apologize. Basically, due to how my game works, to roll an alt, a player would need to restart the game entirely and select a new character class from the introduction passages. This new character would be fresh, and all the variables (including $gold) would reset due to the storyinit passage. This new "alt" would need to be saved in a separate save slot, and I was attempting to transfer the $gold variable between saved slots using the <<remember>> macro. I suppose I could just incorporate "character slots" within the game's passages itself that could function identically to saving and loading, but with $gold excluded upon loading the variables of each character, but that would mean I would have to design a custom saving mechanism which stores every single variable state in the game, and I would have to redesign story progression... which would be quite a hassle.

    Claretta wrote: »
    As for earlier saves, my idea was to use the $goldrecord variable from the start and just continually update it parallel to picking up gold, so the player couldn't go back before the macro started recording.

    I'm sorry, but I don't quite follow (I'm still getting into all these coding logic and stuff). If the $goldrecord macro constantly updates alongside the $gold macro, won't loading an earlier save (i.e. before a player stashed $gold and $goldrecord updates) also load the earlier $goldrecord value?

    Claretta wrote: »
    Otherwise, you can disable custom saves entirely and only allow autosaving at predefined points.

    And yea... I considered this. I think it's probably the best solution, however, I have another question as a result: If a player starts a new character (i.e. restarting the story completely and storyinit resets all variables), won't the autosave feature erase the previous character? Or is there a way to enable multiple autosave slots for different characters? Additionally, can an autosave be stored to disk?
  • edited July 2016
    I still think a behind-the-scenes check at predetermined points is the best way to address the issue.

    I'm sure it would be possible to design a check that would limit contributions to stash on a time basis. I'm pretty tired so I won't go into specifics, but I can't think of why this would fail.

    Eg if they make a contribution once, a guarding <<remember>> variable is set against future contributions from that turn and any and all previous turns. So you're not just remembering how much gold, but also how many deposits per turn, and denying any attempt to stash more than once a turn. Just as an outside perspective, it seems your main problem is being caused by you wanting the player to save and contribute to the stash whenever they want.
  • Claretta wrote: »
    You can apply a 64 character AES randomised password to the zip file and that protects it from random extractions. NW.js still reads the info and displays it from inside but you can't just unzip a properly protected nw.js file without serious effort.
    Could you post a link to the documentation on this feature of NW.js

  • edited July 2016
    I couldn't find documentation. I just know if I try to extract my own game it demands the password I put on it.
  • Claretta wrote: »
    I still think a behind-the-scenes check at predetermined points is the best way to address the issue.

    I'm sure it would be possible to design a check that would limit contributions to stash on a time basis. I'm pretty tired so I won't go into specifics, but I can't think of why this would fail.

    Again, I guess I wasnt very descriptive as I should've been about my game. Unfortunately, the game is very exploration heavy and is pseudo open world-ish... meaning the player character is allowed to backtrack to previous passages whenever they please, so stopchecks can't work.

    For now I'll just not implement a "twinking" system to kickstart alts until I find a better way of doing it :(

  • edited July 2016
    Hence why the suggestion was for time-based. You can track the number of turns that have passed even in an open world. Or you can put predetermined stash points in and <<remember>> every time they are used, preventing resubmitting into them.
  • Claretta wrote: »
    if they make a contribution once, a guarding <<remember>> variable is set against future contributions from that turn and any and all previous turns. So you're not just remembering how much gold, but also how many deposits per turn, and denying any attempt to stash more than once a turn. Just as an outside perspective, it seems your main problem is being caused by you wanting the player to save and contribute to the stash whenever they want.

    Yeah I guess you're right. Thanks very much for your time and input. I think I'll do the <<remember>> guarding variable as you said.
Sign In or Register to comment.