• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Codeless Save and Load (Multiplayer) - v3.0.1

Information

If you've ever wanted to transfer progress between multiplayer maps, you probably needed to type in a long code.

That is no longer needed with this system. This will allow you to read save data from your WC3 folder and sync it to all other players in the map.

The demo map features:
  1. Load without typing anything
  2. Save Hero
    • Level/XP
    • Items
    • Abilities
    • Hero Name

  3. 5 Save Slots
* Everything is customizable and you can make the system save & load anything you want.

* This system is intended for GUI users.

Installation

To import the system, all you have to do is copy the trigger folders over to your map and save it.

Screenshots


untitled5-png.241496

untitled3-png.241494

untitled4-png.241495

113935-913340d9135dcfb50a7ac3b3dff3e424.png



Credits

Pipedream (optimal save system)
Previews
Contents

Codeless Save & Load v1.3.9 (Map)

Codeless Save & Load v3.0.1 (Map)

Reviews
Awaiting further review
Level 24
Joined
Jun 26, 2020
Messages
1,850
Hello I have a question, this system has problem with multi-instance W3? because I wanted to test map that use this system in multiplayer, but I can't play with others so I opted with myself, but it didn't work properly, so I wanna know if it was my fault or the system is not made for that, and my system is too complex to check it out.
 
Level 3
Joined
Sep 28, 2018
Messages
38
spent nearly a days worth of time trying to get this working in a simple test environment. our intention is to use the -save/-load or rather the write/read to add a nice update an old old rpg. we're able to get the save working but can't (burning with pure frustration, hard to type rn) for goodness sakes cannot simply get the loaded code to spit out. Call Save/Call Load are trigs we were toiling in. trust me i know it looks like almost nothing was done and also trust me that tons of code was added/cut/commented/etc/etc/etc/etc/etc. needless to say dying trying to reinvent the wheel. someone anyone please help. many thanks in advance
 

Attachments

  • thisIsATest.w3x
    169.1 KB · Views: 17
Level 24
Joined
Jun 26, 2020
Messages
1,850
spent nearly a days worth of time trying to get this working in a simple test environment. our intention is to use the -save/-load or rather the write/read to add a nice update an old old rpg. we're able to get the save working but can't (burning with pure frustration, hard to type rn) for goodness sakes cannot simply get the loaded code to spit out. Call Save/Call Load are trigs we were toiling in. trust me i know it looks like almost nothing was done and also trust me that tons of code was added/cut/commented/etc/etc/etc/etc/etc. needless to say dying trying to reinvent the wheel. someone anyone please help. many thanks in advance
What are you trying to do? Because your message is a bit confusing.
 
Level 3
Joined
Sep 28, 2018
Messages
38
What are you trying to do? Because your message is a bit confusing.
read in the saved code as a string. Save is working. Dont need load to do anything more then read a saved code from the file that save is able to successfully create so we can access the saved code as a string.
 
Level 24
Joined
Jun 26, 2020
Messages
1,850
read in the saved code as a string. Save is working. Dont need load to do anything more then read a saved code from the file that save is able to successfully create so we can access the saved code as a string.
  • 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(GetTriggerPlayer(), 1)
  • Custom script: call SaveFile.create(GetTriggerPlayer(), SaveHelper.GetUnitTitle(udg_SaveTempUnit), -1, udg_SaveTempString)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • SaveShowCode Equal to True
    • Then - Actions
      • Custom script: set udg_SaveCodeColored = Savecode_colorize(udg_SaveTempString)
      • Game - Display to (All players) the text: SaveCodeColored
    • Else - Actions
I have understood the code is obtained with the function Savecode.Save and then is saved with the function SaveFile.create
 
Level 3
Joined
Sep 28, 2018
Messages
38
  • 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(GetTriggerPlayer(), 1)
  • Custom script: call SaveFile.create(GetTriggerPlayer(), SaveHelper.GetUnitTitle(udg_SaveTempUnit), -1, udg_SaveTempString)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • SaveShowCode Equal to True
    • Then - Actions
      • Custom script: set udg_SaveCodeColored = Savecode_colorize(udg_SaveTempString)
      • Game - Display to (All players) the text: SaveCodeColored
    • Else - Actions
I have understood the code is obtained with the function Savecode.Save and then is saved with the function SaveFile.create

We tried .save and it's returning something vastly different then what's in the save file. Please see sample and type -save and then -load to view the stored cored (you'll see a lengthy code [path- CustomMapData/CodelessDemo]). When using -load (which utilizes the .save method) we are receiving back "g%" not the code stored in the save file. Also thank you for your swift responses. Much appreciated.
 

Attachments

  • thisIsATest.w3x
    169.2 KB · Views: 13
Last edited:
Level 24
Joined
Jun 26, 2020
Messages
1,850
We tried .save and it's returning something vastly different then what's in the save file. Please see sample and type -save and then -load to view the stored cored (you'll see a lengthy code [path- CustomMapData/CodelessDemo]). When using -load (which utilizes the .save method) we are receiving back "g%" not the code stored in the save file. Also thank you for your swift responses. Much appreciated.
The main problem is you messed up a bit the configuration.
For example here:
  • Call Load
    • Events
      • Player - Player 1 (Red) types a chat message containing -load as An exact match
    • Conditions
    • Actions
      • -------- ------------------- --------
      • -------- 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
      • Custom script: call DisplayTextToForce( GetPlayersAll(), Savecode(udg_SaveTempInt).ToString() )
      • Custom script: call DisplayTextToForce( GetPlayersAll(), SaveCode_ReadSlot(GetTriggerPlayer(),-1) )
      • Custom script: call DisplayTextToForce( GetPlayersAll(), ReadSaveSlot(GetTriggerPlayer(),1))
The SaveLoadEvent_Code is only obtainable with the "SaveLoadEvent equals to 1.00" if you look in the SaveHelper
vJASS:
private function LoadSaveSlot_OnLoad takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local string prefix = BlzGetTriggerSyncPrefix()
    local string data = BlzGetTriggerSyncData()
    local User user = User[p]
    
    call SaveHelper.SetUserLoading(user, false)
    
    if (udg_SaveUseGUI) then
        set udg_SaveLoadEvent_Code = data
        set udg_SaveLoadEvent_Player = p
        set udg_SaveLoadEvent = 1.
        set udg_SaveLoadEvent = -1
    endif
endfunction
My recommendation is redoing everything.
 
Level 3
Joined
Sep 28, 2018
Messages
38
The main problem is you messed up a bit the configuration.

...

My recommendation is redoing everything.

Tried setting all those flags. In fact in the Codeless Save and Load folder there's a file named 'Save Init' which has been setting all the flags for us already.

If you'll allow us to start from the beginning perhaps we may be able to describe what we are trying to do better.

  • Call Load
    • Events
      • Player - Player 1 (Red) types a chat message containing -save as An exact match
    • Conditions
    • Actions
      • -------- ------------------- --------
      • -------- Save to disk --------
      • -------- ------------------- --------
      • Custom script: set udg_SaveTempString = "auiri0ouk9qtvulenxsvoehydiuo4cvsdaiwystx2rgffbdssb"
      • Custom script: call SaveFile.create(GetTriggerPlayer(), "-load ", 1, udg_SaveTempString)
      • // params: Player, string title, integer slot, string save code

A few short lines of code is all that's needed to successfully write a players save code to CustomMapData.

We aren't using TriggerHappy's system to generate a code. The old map we are seeking to update already has a code generation system implemented. No code generation/encoding/decoding/obfuscating required on our part.

What we would like to do is simply add the File.IO used in this library into an old map to act as a middle man. Successfully doing this effectively allows anyone to add automatic saving & loading into any rpg with pre-existing code generation, we believe.

Thus to summarize our current goal is simply to figure out how to read in the save code from the file that the above save trigger is writing to CustomMapData.

*edit: Perhaps foolish in assuming this yet it's still hard to imagine what we're trying to accomplish (reading a simple string in from users disk) is more difficult then writing the save code string to disk.
 
Level 3
Joined
Sep 28, 2018
Messages
38
I was dealing with this system a lot, so maybe I could grant that tutorial.
That'd be helpful! Messaged TriggerHappy themselves regarding a reduced/simplified library which doesn't include any code generation aspects rather simply just the read/write functionality with simple parameters to enable less experienced devs the ability to add codeless saving/loading into older maps that already have a code generation system in place (i.e. fldrName to save to, fileName to save file as, saveCode string to be saved, integer slot [optional param] for maps that would benefit from multiple save files).
 
Last edited:
Level 3
Joined
Sep 28, 2018
Messages
38
@PurpleHephalump , @uiuinpp you need to give the ability Aerial Shackles (Amls) 2 levels instead of 1. And set the Level 2 - Text - Tooltip - Normal to "!". Otherwise it wont work.


THIS. THIS is what caused reading in the load code to not work. THIS. THIS.

THIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIS. Its 2AM and I'm going to bed. WTF. WHY. Why THIS. THIS!!!!

*Edit: Also worth noting if a code is just saved, the load will only work after a game restart.
 
Last edited:
Level 3
Joined
Sep 28, 2018
Messages
38
The Aerial Shackles ability needs 2 levels in order for the system to work.

This is because Aerial Shackles is used in generating the save/load code. The problem: Blizzard made level indices start at 0 in the recent patches, which messed up any existing code that was using 1 to represent 1 (0 now represents 1).

So now the code is attempting to reference level 2 of Aerial Shackles when the ability only has 1 level by default.

Edit: I think you also need to set the Tooltip for level 2 to: "!"

See attached picture!

Why isn’t this info somehow more prevalent so I wouldn’t waste tens of hours debugging 😭
 
Level 24
Joined
Jun 26, 2020
Messages
1,850
@jvhgamer, didn't you know the new natives the levels starts from 0? lol, and that information of the tooltips is granted in the File IO library, no offense, but didn't you look at it?, Ok, is not specified explained, but you have to look at the object editor of the original map for noticing it.

By the way, I finished the tutorial, I hope you find it useful: TriggerHappy's Codeless Save and Load tutorial
 
Last edited:
Level 2
Joined
May 30, 2021
Messages
5
hello i am very new at making maps and the editor, at the moment i even struggle with basic GUI triggers.
So far i used the modified version Ouro provided, made some adjustmenents and i feel im missing something since i can save a hero, then load it in a new game, but then if i load i cant save ever again, any help is welcome.
im using newgen world edit 1.3.2 and warcraft 1.27b it thats of any help.
 

Attachments

  • SAVETEST.w3x
    317.1 KB · Views: 6
Level 4
Joined
Jun 8, 2020
Messages
28
Hi amigo, your issue was fixed, i found a problem. The case was: When you saving character 1st time it is happening seccesfully because you assigning this unit as a variable when he is entering the map. BUT when you loading hero, this unit is not assigned with this variable any more, and it not saving. I added couple of variable and triggers to your map to make it working.
 

Attachments

  • SAVETEST.w3x
    295.2 KB · Views: 14
Level 2
Joined
May 30, 2021
Messages
5
wow! thanks a lot @Ouro i will update the map from your fixed version with many new features i added and contact you if i get someting wrong.
edit: i changed save current gold to save food used, and changed the soldado food used to 0 also made max saved lumber to 0, this way i expected the system to stop saving the gold, i need to save food for another trigger i havent implemented yet and to stop saving lumber and somehow when i loaded my hero i got 40510 gold and 40040 lumber, my rifle mejorado skill lvl 1 was gone and i had 745 str instead of the expected 10 and 596 agility instead of 10
any idea on whats going wrong?
 

Attachments

  • SAVETEST ouro fix.w3x
    331.9 KB · Views: 9
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,509
There are 2 players A and B. The question is: Is this still working if I first save from player A's computer but second time I save from player B's computer
This system saves/loads a file that is stored locally on your pc. You can find it at this directory:
C:\Users\Username\Documents\Warcraft III\CustomMapData
It has no ties to your BNET account or anything like that but there's nothing stopping you from manually transferring the save file between computers. You could even edit/create copies of the file if you wanted to.
 
Last edited:
Level 1
Joined
Oct 17, 2021
Messages
2
Like the Dokumentation
Helped me greatly in understanding how to implement your FileIO for save codes in the open Version of Dark Invasion 2 (just savecode to txt.) - Way more Fun this way
(i will edit when i take the step to codeless)
 
Level 24
Joined
Jun 26, 2020
Messages
1,850
Hello, I'm having an issue with saving a max value, I wanna save a boolean list, and to converting it to an integer I have to use bits, so the max number I would save is 2^(max length of the list), I though that the max length of that list would be 24, because in the bignum library says:
JASS:
//x*BASE() must be less than MAXINT()
method MulSmall takes integer x returns nothing
Where x = 2^24, BASE() = 89 and MAXINT() = 2,147,483,647 = 2^31 - 1
So 2^24 * 89 = 1,493,172,224 < 2,147,483,647
And in case the length is 25:2^25 * 89 = 2,986,344,448 > 2,147,483,647
But for some reason the real max length is 18, because when I set 19, the system breaks, what's wrong?
 
Level 11
Joined
Jul 17, 2013
Messages
544
this is confusing which one do i use for reforged? there are 2 versions. the one that was made in 2017 is recommended for patches up to 1.28 but the one that was made in 2019 supports patches till up to 1.21
 
Level 18
Joined
Mar 16, 2008
Messages
721
Do you save and load a lot in-game? Like hundreds of times? There is a leak in pipedreams savecode system, but you would only notice it after many saves or loads. If you have a replay of this bug it would help.
In my tests it seems to lock you on to one name/account, if you change accounts it gives you this message. Fix is to change map file name and "refresh" everything.
 
Level 11
Joined
Jul 17, 2013
Messages
544
I need help im using this system. I save 3 integer varriables normal win points, hard win points and impossible win points. It works fine in game except for one player slot purple. Whenever purple plays as character named eomer he will lose his victory points it will be set to 0 no matter what value it has been before. If purple plays as boromir issue doesnt occour. I never set varriables to 0. What can be reason of this issue, does it lie inside system? it was made long time ago before reforged
 
Level 18
Joined
Mar 16, 2008
Messages
721
I need help im using this system. I save 3 integer varriables normal win points, hard win points and impossible win points. It works fine in game except for one player slot purple. Whenever purple plays as character named eomer he will lose his victory points it will be set to 0 no matter what value it has been before. If purple plays as boromir issue doesnt occour. I never set varriables to 0. What can be reason of this issue, does it lie inside system? it was made long time ago before reforged
are you using any name change triggers with purple?
 
Level 18
Joined
Mar 16, 2008
Messages
721
Not sure a good way to deal with that.

This system should rely on player IDs as opposed to player names. I think player IDs are constant where as player named can be changed.

EDIT: in a different system, the MMD/parse system from wc3stats.com just sets player names in the first 0-1 sec of the game, then after that, player slots are referenced by the MMD/parse system. So in that system you can change your name and still have a good parse.
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,509
Not sure a good way to deal with that.

This system should rely on player IDs as opposed to player names. I think player IDs are constant where as player named can be changed.
You could store the Player Names in a variable before changing it:
  • Events
    • Map initialization
  • Conditions
  • Actions
    • Player Group - Pick every player in (All players)
      • Loop - Actions
        • Set Variable PlayerNameOriginal[(Player number of (Picked player))] = (Name of (Picked player))
    • Player - Set name of Player 4 (Purple) to RickyBobby
Then in the system code look for where it references Player Names and change it to reference that variable.

You could also add this code to help with the replacing process:
vJASS:
function GetPlayerNameFix takes player p returns string s
    return udg_PlayerNameOriginal[GetConvertedPlayerId(p)]
endfunction
Then you can find and replace all instances of GetPlayerName( with GetPlayerNameFix( inside of the save system code.

The system might already use a similar method.
 
Level 24
Joined
Jun 26, 2020
Messages
1,850
What is someone wanted to save, umm.. maybe up to a hundred thousand variables? Would the save / load process be slow? Possible? Error prone?
If you do hundred thousand of any thing the process would be slow, and also if you write hundred thousand of lines of any code, is more prone to errors, I never tried to save that many values, I at most saved around 615 values and if I get an error, I just found it and solve it, but barely it has to do with the system itself, the errors were mine. The only issue the system would have is the length of the saved code, I think it saves by default at most 2000 characters, but that can be configured.
 
Last edited:
Level 1
Joined
Nov 17, 2023
Messages
1
Hello, I'm having an issue with saving a max value, I wanna save a boolean list, and to converting it to an integer I have to use bits, so the max number I would save is 2^(max length of the list), I though that the max length of that list would be 24, because in the bignum library says:
JASS:
//x*BASE() must be less than MAXINT()
method MulSmall takes integer x returns nothing
Where x = 2^24, BASE() = 89 and MAXINT() = 2,147,483,647 = 2^31 - 1
So 2^24 * 89 = 1,493,172,224 < 2,147,483,647
And in case the length is 25:2^25 * 89 = 2,986,344,448 > 2,147,483,647
But for some reason the real max length is 18, because when I set 19, the system breaks, what's wrong?
How did u solve it?

I'm trying to save a integer value of 500,000,000, but when i try to load it shows me that the code is invalid. How can i solve it?
 
Level 24
Joined
Jun 26, 2020
Messages
1,850
I don't know why, but we can't save a value bigger than 2^18 with this system while the biggest value should be iirc (2^31 - 1) / 76 (I think I asked on the threat of the original system, but none replied), what I said was about high amount of vales, not a high value.
 
I don't know why, but we can't save a value bigger than 2^18 with this system while the biggest value should be iirc (2^31 - 1) / 76 (I think I asked on the threat of the original system, but none replied), what I said was about high amount of vales, not a high value.
Does this mean we can only save a single value or all values up to 262144?
 
Level 9
Joined
Dec 16, 2017
Messages
343
Hi guys, is anyone still sticking around with this save/load system?
I can't make it work in my map and i don't know what is the issue, i've tried many things on it, i tried it even just with the sample from here before editing to add more values into it, and still doesn't work, for instance, the ESC doesn't save and says something like the string is empty, and save command doesn't trigger either.

Thanks!
 
Level 11
Joined
Jul 17, 2013
Messages
544
This system is good and i like it but theres one disadvantage. After i save my data to file replay of played game doesnt follow events that actually have hapenned while game was played. lets say i save data at middle of game min 20 and when i watch replay its all fine to min 20 but since then it shows my characters at one place moving around, they didnt get teleported and arent in places where they have been while game was played. Is it possible to fix it? @Uncle Hey, are u able to help?
 
Level 4
Joined
Oct 31, 2011
Messages
69
Hello guys, is there a solution to the problem that the list of characters to load does not update during the game.

Example: When I save my level 5 hero in slot 2 and he goes up to level 6 or higher and saves in slot 2 again and uses a hero pick up system he returns to the level of the first time I saved in slot 5 and not level 10, but if I create the map again and load space 2 it returns to level 10.
 
Top