• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Maxou NSL (New Save Load)

Edit (11-11-2025): Updated to Maxou NSL (Maxou New Save Load)
Edit (13-11-2025): Updated to use only one custom ability as buffer with multiple levels instead of many abilities

Features in this save load system

  • Code are bound to player names, makes code sharing impossible.
  • Code is secured to avoid tampering or attempts at editing it.
  • Semi-codeless (using -save <name> and -load <name>) integration out-of-the-box.
  • Supports multi-versioning for codes (example included within the map).
  • Beginner-friendly API with a plug'n'play approach.
  • GUI support and easy integration.
  • Can now work with negative values.
  • Works with integers, avoids some floating number precision error corrupting some save codes (Pipedream save system -- used in Codeless -- suffers from this, at least, from my own experience, which is why I created this system in the first place).
  • Lots of documentation provided within the map.

Disclaimer
  • Saving your hero (or item) will require you to store their types into an array and save your hero (or item) index into that array (example included).
  • Still need to work with integers only, anything you want to save has to be turned into an integer.



Just another save code system written from scratch.

Features in this save load system

  • Player name bound code.
  • Anti-tampering code.
  • Works with integers, avoids some floating number precision error corrupting some save codes (Pipedream save system -- used in Codeless -- suffers from this, at least, from my own experience, which is why I created this system in the first place).

Disclaimer

  • This system is low level, it focuses only on saving into a code, and reading a code, if you want to write file to disk, you'll have to look around for the preload native.
  • Saving your hero (or item) will require you to store their types into an array and save your hero (or item) index into that array (example included).
  • Anything you want to save HAS to be turned into an integer, if you're trying to save floating numbers, define a precision and multiply as needed to achieve an integer representation.
  • Warning : it can not save negative values.

This system is vJASS only, and not very suitable for GUI users.

Multiple examples provided inside the map.
Contents

Maxou NSL (New Save Load) (Map)

Maxou Save Load (Map)

Reviews
Antares
A nice light-weight system for storing any type of data with a code. I like that it doesn't implement any specifics about what kind of data can be stored. This makes it very flexible and easy to use. My main gripe is that you're using lower-case L...
A nice light-weight system for storing any type of data with a code. I like that it doesn't implement any specifics about what kind of data can be stored. This makes it very flexible and easy to use.

My main gripe is that you're using lower-case L and upper-case I as part of your charset. For a system that expects players to enter the code, that strikes me as just a very bad decision. These characters are nearly indifferentiable and I think should just not be used.

The SAVE_SIZE_STRICT_LESS_THAN variables, as far as I can tell, are unnecessary. I don't see why the user can't just enter any number specifying the maximum value of his stored integer and your script figures out how many bits you need at runtime.

Approved
 
I created a GUI friendly, codeless version of this map. See attached map below.

I was tired of pointing people to TriggerHappy's system which hasn't been updated in 6 years, so I figured why not make a safe alternative for GUI users. That being said, I can't promise that it's fully functional - my 2 player LAN tests seemed to work fine, but who knows what'll happen online.
 

Attachments

Last edited:
Hi,
You did a nice job

I have a question is it possible to add more chars in the Charset variable?
(if I upload the CharsetLength var) or it is done to work with 64 chars?

I ask that because I generate a very long string, I was thinking maybe with more chars the string will be smaller, right?

Have a nice day

Unfortunately not really, since the system binary encodes, anything that is not 2^n will most likely fail -- I haven't tested much increasing but right away that's the issue I can see.

I created a GUI friendly, codeless version of this map. See attached map below.

I was tired of pointing people to TriggerHappy's system which hasn't been updated in 6 years, so I figured why not make a safe alternative for GUI users. That being said, I can't promise that it's fully functional - my 2 player LAN tests seemed to work fine, but who knows what'll happen online.

Thank you !
 
@Uncle I've been working on an update with basic GUI integration, but the entire system has been revamped, should I upload it as another resource or update this one ?
Cool, looking forward to it. But I'm not the best person to ask about that.

Assuming that the update makes things codeless then I'd say just update this resource. I imagine most users will overlook this as long as it's not codeless.
 
Last edited:
@Uncle I've been working on an update with basic GUI integration, but the entire system has been revamped, should I upload it as another resource or update this one ?
hello.. if you can update this source stay with v1.36, that would be great.. i don't know which warcraft version you need to use to make it cpdeless, i would suggest to create a legacy.. that unnecessary if you need version 1.36 to make it codeless, tho..
 
hello.. if you can update this source stay with v1.36, that would be great.. i don't know which warcraft version you need to use to make it cpdeless, i would suggest to create a legacy.. that unnecessary if you need version 1.36 to make it codeless, tho..

Unfortuately I'm not going to spend the time to support 1.36 --- I'm exclusively using the latest editor whenever I use it. So I wouldn't be able to predict if it'll be supporting 1.36 in the updated version.

@Antares (sorry for ping, but since you reviewed and Uncle said he wasn't the best I guess you should be?) : it might be better to create another thread for the updated system I guess then ? and keep the lightweight barebone system as is ?
 
hello.. if you can update this source stay with v1.36, that would be great.. i don't know which warcraft version you need to use to make it cpdeless, i would suggest to create a legacy.. that unnecessary if you need version 1.36 to make it codeless, tho..
Local files have been around for 10+ years, I'm sure you've encountered a text file with save data before. It'd be in your CustomMapData folder. That's how all of those popular maps, particularly RPGs, have been doing it all of these years.

But I highly doubt that the system won't work with 1.36, that's well beyond what's considered old and outdated. Plus the odds that they would add a new native that would somehow need to be incorporated into this seems extremely slim.
 
Local files have been around for 10+ years, I'm sure you've encountered a text file with save data before. It'd be in your CustomMapData folder. That's how all of those popular maps, particularly RPGs, have been doing it all of these years.

But I highly doubt that the system won't work with 1.36, that's well beyond what's considered old and outdated. Plus the odds that they would add a new native that would somehow need to be incorporated into this seems extremely slim
I think so. The system might work with version 1.36, but the latest version of the map cannot be opened with WE 1.36. As the creator stated, he's only using the latest version.

Some other creators are posting their code. Maybe he can do it too.

Unfortuately I'm not going to spend the time to support 1.36 --- I'm exclusively using the latest editor whenever I use it. So I wouldn't be able to predict if it'll be supporting 1.36 in the updated version.

@Antares (sorry for ping, but since you reviewed and Uncle said he wasn't the best I guess you should be?) : it might be better to create another thread for the updated system I guess then ? and keep the lightweight barebone system as is ?

I see.. if you say so, then fine.. I also have the latest version, but I usually use 1.36, purposely for more player scope..

i think you can also ask deepstrasz for map posting..
 
Last edited:
It was easy to integrate and the documentation helped a lot, although at first sight I was like "oh not again! I have to spend time to comprehend this much stuff". One suggestion though: "GUI codex ver1" should just be named GUI Load or be specified in the documentation that it is for loading. I got a bit confused by that name.

Changed it!
 
Update: So I was about to play with 5 other players and when I loaded my save, 2 of them disconnected at the same time. I would suppose there could be something that desynced and disconnected them. It was green and purple if that helps. But this just happened one time so it needs further testing...Also I think it's very possible that they didn't finish loading the game and that could be the reason. Maybe you could (or I could) create a condition to disable the -load command until everyone loaded the map?
 
Last edited:
Update: So I was about to play with 5 other players and when I loaded my save, 2 of them disconnected at the same time. I would suppose there could be something that desynced and disconnected them. It was green and purple if that helps. But this just happened one time so it needs further testing...Also I think it's very possible that they didn't finish loading the game and that could be the reason. Maybe you could (or I could) create a condition to disable the -load command until everyone loaded the map?
Could be related to players not restarting the game in between lobbies or having played something else before. The -load command can't really be used before everyone loaded the game tho' ?

Also there's like a pletora of possible issues with reforged that could also be the reason, I've had desync happen on game start for no reason, custom UIs with fullscreen (instead of windowed fullscreen) was also a source of desync (frames not being created due to the game being minimized and being interacted with by other players for example).
 
Could be related to players not restarting the game in between lobbies or having played something else before. The -load command can't really be used before everyone loaded the game tho' ?

Also there's like a pletora of possible issues with reforged that could also be the reason, I've had desync happen on game start for no reason, custom UIs with fullscreen (instead of windowed fullscreen) was also a source of desync (frames not being created due to the game being minimized and being interacted with by other players for example).
So I tested it more and it didn't happen again. I made sure I waited for everyone to load in the game and move their character. Could the system be made to wait like 30 seconds before you can load to prevent that, and inform the player trying to load about that?
 
So I tested it more and it didn't happen again. I made sure I waited for everyone to load in the game and move their character. Could the system be made to wait like 30 seconds before you can load to prevent that, and inform the player trying to load about that?
It looks like the system already has that feature for both Saving and Loading:
  • GUI AllowPlayerSave
    • Events
    • Conditions
    • Actions
      • Set VariableSet NSL_AllowPlayerSave = True
      • -------- When finished checking, set NSL_EventCheckSaveCompleted to 1.0 --------
      • Set VariableSet NSL_EventCheckSaveCompleted = 1.00
^ Delay setting that to True until everyone has proven that they're "ready". Note that this is basically impossible to prove, but adding a little buffer COULD help. You could also be dealing with an unavoidable, slim chance for desyncs. Warcraft 3 is infamous for this unfixable situation, especially since Reforged.

You could also try something like this for both GUI Save and GUI Load if the above feature doesn't work the way I think it does:
  • GUI Save
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Elapsed time for Game_Started_Timer) Less than or equal to 3.00
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • ... DO NOT TOUCH THE REST OF THE ACTIONS ...
^ Start a one-shot Timer at the 0.00 second mark and prevent these triggers from running their Actions while it's on. Unsure if this is necessarily safe, though.
 
Last edited:
It looks like the system already has that feature for both Saving and Loading:
  • GUI AllowPlayerSave
    • Events
    • Conditions
    • Actions
      • Set VariableSet NSL_AllowPlayerSave = True
      • -------- When finished checking, set NSL_EventCheckSaveCompleted to 1.0 --------
      • Set VariableSet NSL_EventCheckSaveCompleted = 1.00
^ Delay setting that to True until everyone has proven that they're "ready". Note that this is basically impossible to prove, but adding a little buffer COULD help. You could also be dealing with an unavoidable, slim chance for desyncs. Warcraft 3 is infamous for this unfixable situation, especially since Reforged.

You could also try something like this for both GUI Save and GUI Load if the above feature doesn't work the way I think it does:
  • GUI Save
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Elapsed time for Game_Started_Timer) Less than or equal to 3.00
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • ... DO NOT TOUCH THE REST OF THE ACTIONS ...
^ Start a one-shot Timer at the 0.00 second mark and prevent these triggers from running their Actions while it's on. Unsure if this is necessarily safe, though.

That would work -- it might still be an issue related to alt-tabbing while in fullscreen, I can't bother myself testing things out but there's basically no way to figure out if players are all "ready" since the game is just half-rendering/half-processing things while alt-tabbed (if fullscreen).

I usually recommend players suffering from desyncs or crash upon game start to switch to windowed fullscreen, it usually helps.

Until then, I'll just say that's on Blizzard side of things to clean up reforged but we all know that's not going to happen.
 
Hello again! I have a little problem. I have added a second object to unlock in the new version of my map. So naturally I added to the GUI save and GUI load a new If/then/else which saves "1 as 2 of NSL_PLAYERID in NSL_GUIHastable" (the first one saves 1 as 1). However, this time loading dosen't seem to work. The old save (I type -load 1) loads normally, but the second one which I had just saved in this version (-load 2) gives an error code version 5 is unsupported.Could you help me with this and tell me what I am doing wrong?
 
Last edited:
Hello again! I have a little problem. I have added a second object to unlock in the new version of my map. So naturally I added to the GUI save and GUI load a new If/then/else which saves "1 as 2 of NSL_PLAYERID in NSL_GUIHastable" (the first one saves 1 as 1). However, this time loading dosen't seem to work. The old save (I type -load 1) loads normally, but the second one which I had just saved in this version (-load 2) gives an error code version 5 is unsupported.Could you help me with this and tell me what I am doing wrong?

Hello, could you post the triggers ? Especially : GUI Save / GUI Load and GUI Init.
 
Okay, so, on save:
  • if Myrmydon is unlock → Save 1 as 1.
  • if Tauren is unlock → Save 1 as 2.

On load:
- Load 1 → but code has no data since it wasn't saved (if it wasn't unlocked).

You should save 1 if unlocked, and 0 if locked, that way you can actually load it.

Also the code works sequentially, the first value in the code will in 1, the second value will be stored in 2, and so on...
Another thing, to support the compatibility with the underlying system, the saver looks up the NSL_GUIHashtable for values until it finds no value, if it have no value at index 1 (which does happen whenever Myrmidon is locked) it stops reading.

aka. if it has no value at index 6, it stops looking up for values whenever saving (there's no way predicting how far you'd have to read otherwise)

You should make sure you always save as much as you'll trying to read on load, you only lack the Save 0 as 1 in the else blocks in GUI Save.

I guess the system fails to save if nothing is unlocked due to having no data internally.
 
Okay, so, on save:
  • if Myrmydon is unlock → Save 1 as 1.
  • if Tauren is unlock → Save 1 as 2.

On load:
- Load 1 → but code has no data since it wasn't saved (if it wasn't unlocked).

You should save 1 if unlocked, and 0 if locked, that way you can actually load it.

Also the code works sequentially, the first value in the code will in 1, the second value will be stored in 2, and so on...
Another thing, to support the compatibility with the underlying system, the saver looks up the NSL_GUIHashtable for values until it finds no value, if it have no value at index 1 (which does happen whenever Myrmidon is locked) it stops reading.

aka. if it has no value at index 6, it stops looking up for values whenever saving (there's no way predicting how far you'd have to read otherwise)

You should make sure you always save as much as you'll trying to read on load, you only lack the Save 0 as 1 in the else blocks in GUI Save.

I guess the system fails to save if nothing is unlocked due to having no data internally.
That seems to have been the problem, it works now, thank you man! I didn't think about that, that was just me being used to just leave things as they are when there is no obvious reason to put something in.
 
Back
Top