[Solved] Secret Save / Load System for 1 integer value

Level 5
Joined
Jan 22, 2016
Messages
33
Hello everyone,


I'm looking for a system that secretly saves and loads the highest difficulty a player has beaten on a specific map. I ll explain...

When a player wins, the system should store the highest difficulty they cleared. Then, when they play the map again, they should receive a small head start like a "Medal of Honor" item based on the highest difficulty they previously achieved.


My knowledge is limited to working with the GUI, so from my perspective, I need:


  1. A action/trigger that runs the script that stores the highest difficulty a player has cleared when victory achived.
  2. A action/trigger or function that loads this value when a player selects a hero.

Does anyone know how to achieve this preferably in a way that works with GUI? If JASS or Lua is required a GUI-friendly workaround would be really helpful!


Thanks in advance !
 
Level 5
Joined
Jan 22, 2016
Messages
33
Hey Gnuoy!

Thanks again for pointing me to your map! I checked it out, but I’m kinda stuck trying to figure out how the saving system works. There are so many triggers mixed with other stuff, and I can’t really tell which ones are specifically for the save system.

If you have a bit of time, could you help me out by pointing me to the right triggers? That would be awesome!

Thanks a ton for your help earlier!
 
Level 21
Joined
Mar 16, 2008
Messages
955
Under the folder "Save Load System" the 3 folders:
1) Custom Save Load
2) Variables
3) Codeless Save and Load
are like the core of the system.

4) "Rewards" are triggers the apply upgrades to players based on the loaded integers, this controls what tech they can access based of the loaded variables.

Sorry it's really confusing and Uncle helped me a lot. Sorry I'm not more helpful.
 
Level 5
Joined
Jan 22, 2016
Messages
33
No need to apologize—you’ve already helped me a lot! Seriously, pointing me in the right direction was huge !!

I took your advice and tried importing the system to a dummy map, combining it with some elements from my map. I actually managed to create a save file! But I’m still quite far from figuring out the loading part.

At this point, I think @Uncle might be the only one who can really help me get it working, so I’m hoping he sees this post. I’m uploading the dummy map to share what I’ve got so far.


Thanks again for everything! You’ve been super helpful!
 

Attachments

  • Test Save-Load System.w3m
    75.8 KB · Views: 2

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
You have to Load in the reverse order of how you saved.

1: Save Gold
2: Save Lumber
3: Save Food

1: Load Food
2: Load Lumber
3: Load Gold

I suggest adding a numbered Comment before each "save" and "load" so that you can easily tell the order of things.

Save Trigger:
  • -------- #1 Gold --------
  • ... Save
  • -------- #2 Lumber --------
  • ... Save
  • -------- #3 Food--------
  • ... Save
Load Trigger:
  • -------- #3 Food--------
  • ... Load
  • -------- #2 Lumber --------
  • ... Load
  • -------- #1 Gold --------
  • ... Load
 
Last edited:
Level 5
Joined
Jan 22, 2016
Messages
33
Thank you for your response, Uncle!

In my case, I only need to save and load one integer, so I am not sure if the loading order is the issue. The problem I’m running into is that I always get the message "the save file was not found" when the game starts—even though the save file is clearly in my Documents folder.

Also, when I force-run the load trigger (for testing) when a player selects a Hero, I get "Invalid load code (check your name)."

I’ve kept only the highest standard save option to keep things simple. Here’s what I’ve kept from your system:

Save
  • Custom Auto Save
    • Events
    • Conditions
    • Actions
      • Player Group - Pick every player in players_grp and do (Actions)
        • Loop - Actions
          • Set VariableSet SaveLoadEvent_Player = (Picked player)
          • Set VariableSet SaveLoadEvent_PN = (Player number of SaveLoadEvent_Player)
          • -------- --------
          • -------- --------
          • -------- --------
          • -------- --------
          • -------- PUT YOUR SAVE ACTIONS HERE: --------
          • Set VariableSet SaveCount = -1
          • -------- --------
          • -------- --------
          • -------- HIGHEST STANDARD: --------
          • Set VariableSet SaveCount = (SaveCount + 1)
          • Set VariableSet SaveMaxValue[SaveCount] = 10
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • mode_setting Equal to 1
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • difficulty_setting Greater than highest_standard[SaveLoadEvent_PN]
                • Then - Actions
                  • Set VariableSet SaveValue[SaveCount] = difficulty_setting
                • Else - Actions
                  • Set VariableSet SaveValue[SaveCount] = highest_standard[SaveLoadEvent_PN]
            • Else - Actions
              • Set VariableSet SaveValue[SaveCount] = highest_standard[SaveLoadEvent_PN]
          • -------- --------
          • -------- --------
          • -------- STOP --------
          • -------- --------
          • -------- --------
          • -------- Save to disk: --------
          • Custom script: set udg_SaveTempInt = Savecode.create()
          • For each (Integer A) from 0 to SaveCount, do (Actions)
            • Loop - Actions
              • Custom script: call Savecode(udg_SaveTempInt).Encode(udg_SaveValue[bj_forLoopAIndex], udg_SaveMaxValue[bj_forLoopAIndex])
          • Set VariableSet SaveTempString = <Empty String>
          • Custom script: set udg_SaveTempString = Savecode(udg_SaveTempInt).Save(udg_SaveLoadEvent_Player, 1)
          • Custom script: call SaveFile.create(udg_SaveLoadEvent_Player, "Save", 1, udg_SaveTempString)
          • -------- --------
          • -------- Displays Message to Players (best spot to put this) --------
          • -------- --------
          • Game - Display to (All players) the text: (name_strings_color[SaveLoadEvent_PN] + player_name_array[SaveLoadEvent_PN])
Load (this one runs only when i force run it when "Hero Select"
  • Custom Load Event
    • Events
      • Game - SaveLoadEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Game - Display to (All players) for 15.00 seconds the text: Runs Load
      • -------- Validate: --------
      • Custom script: set udg_SaveTempInt = integer(Savecode.create())
      • Custom script: if not (Savecode(udg_SaveTempInt).Load(udg_SaveLoadEvent_Player, udg_SaveLoadEvent_Code, 1)) then
      • Game - Display to (Player group(SaveLoadEvent_Player)) the text: Invalid load code (...
      • Skip remaining actions
      • Custom script: endif
      • -------- --------
      • -------- --------
      • -------- PUT YOUR LOAD ACTIONS HERE (Reverse Order): --------
      • Set VariableSet SaveCount = -1
      • -------- --------
      • -------- --------
      • -------- HIGHEST STANDARD: --------
      • Set VariableSet SaveCount = (SaveCount + 1)
      • Set VariableSet SaveMaxValue[SaveCount] = 10
      • Custom script: call SaveHelper.GUILoadNext()
      • Set VariableSet highest_standard[SaveLoadEvent_PN] = SaveValue[SaveCount]
      • -------- --------
      • -------- --------
      • -------- STOP --------
      • -------- --------
      • -------- --------
      • Custom script: call Savecode(udg_SaveTempInt).destroy()

Could you please point me in the right direction if you spot anything obvious I might be missing?


Really appreciate your help!
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Look at where you placed your SaveValue[SaveCount] variable in the Save trigger. What does Else - Actions mean? Why would that be a bad spot for it?

Also, please post your triggers like this:
 
Last edited:
Level 5
Joined
Jan 22, 2016
Messages
33
Even if i dont use the if-then-else action at all and just use:
  • Set VariableSet SaveValue[SaveCount] = difficulty_setting
The save file will be created as it did before and i would still get the "the save file was not found" error.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Okay, so if it still doesn't work after putting it in the correct spot then it's probably something here:

1) Make sure your Aerial Shackles ability is configured properly to have 2 Levels.
You can see how it's done in my demo map, try to copy exactly what I did:

2) You need to completely exit the game and relaunch when testing.

So delete your existing save file from your CustomMapData folder (keep that folder open while testing this stuff) and launch the map from the World Editor. Then wait for Autoload to run and proceed to save some new data. Then exit Warcraft 3 entirely and relaunch the map from the World Editor. You SHOULD be able to Load your newly saved data now.
 
Last edited:
Level 5
Joined
Jan 22, 2016
Messages
33
Thank you so much @Uncle !

I actually managed to get it working and even moved the system over to my map!

It turns out the issue was probably with the Aerial Shackles ability configuration… I still don’t really understand what that has to do with the save/load system, but hey — it’s working! 😄

The only thing left now is to test it online with more players, but I have a good feeling it’ll work like a charm there too.

Really appreciate your time and help!
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Thank you so much @Uncle !

I actually managed to get it working and even moved the system over to my map!

It turns out the issue was probably with the Aerial Shackles ability configuration… I still don’t really understand what that has to do with the save/load system, but hey — it’s working! 😄

The only thing left now is to test it online with more players, but I have a good feeling it’ll work like a charm there too.

Really appreciate your time and help!
Glad to hear it.

These save/load systems use a trick where they store your save code into the tooltip of an existing ability. This is due to Blizzard's implementation of their "preload" system which lets you generate a local text file. I assume it's like this for security reasons, so that people don't do anything malicious when generating these files on other people's computers.

To overwrite a tooltip you use a function called BlzSetAbilityTooltip() which you can do in GUI as well (the Action is worded similarly). This function requires
that you provide the Level associated with the Tooltip that you want to modify, since an ability can have different Tooltips at different Levels. The Save/Load system you're using makes the mistake of pointing to Level 2 instead of Level 1, and since Aerial Shackles normally only has 1 Level it breaks everything:

Level 2 wasn't found -> Abort!

I believe the system originally worked fine but Blizzard released a patch that changed BlzSetAbilityTooltip() to use 0-based indexing, meaning the function now treated value 0 = Level 1, 1 = Level 2, 2 = Level 3. The creator of that save/load system doesn't seem to care about informing users of this, I imagine because they've moved on from this game a long time ago, so unfortunately they fail to mention this major (yet easily fixed) issue in the system thread.
 
Last edited:
Top