• 🏆 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!

[GUI] Save and Load in GUI

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183

Easy Save and Load in GUI

-Only works in Single Player until updated!-

Introduction

Greetings. I decided to create a tutorial for saving/loading in GUI. I know that there are existing GUI systems out there. Code Gen and Ace Harts are the most famous ones. However this tutorial is directed for those that want to create their own, or the existing systems lack something that they need in terms of saving, whatever that might be. I also quickly want to mention that I wont explain any GUI actions in this tutorial since it's not for starters, unless you don't understand simple GUI actions yet, you should go and learn some GUI before heading back to this tutorial.

Difficulty

5/10


What is needed?

*above basic knowledge of GUI in general
*New Gen Editor (JNGP) - Download
*FILE I/O - Download
*Local Files enabled (Extensions > Enable Local Files)

What is file I/O and why do we use it?

File I/O allows the user to create and read files which contain information of our choice.

Pros:
*Encrypts/Decrypts the information we decide to store into our files
*Saves us a good chunck of work and effort
*We don't need to care about a save code, which means using this method the user can type "-load" instead of "-load xxx xxxx xxx xx xxxxx"

Cons:
*file I/O is made in vJASS, which forces us to use custom scripts more than we should.


Preperations

In order to understand this tutorial fully you will need to know about GetLocalPlayer().

Once you've done that. We will create our variable for the GetLocalPlayer().

  • Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: set udg_local_player = GetLocalPlayer()
Before we start, you also need to decide on what you want to store. In my example I decided to save the following values.
*Player Name
*Main Hero
*Hero Level
*Player Gold
*Player Lumber

For learning purposes I strongly suggest that you don't start with loading a unit, that's the most annoying part. Try doing it with gold or something like that at first.

Note: You can only save string values, and not other variable types.

This is my setup so I got some values I can save in my map.

  • Just for testing
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player - Add 666 to Player 1 (Red) Current lumber
      • Player - Add 1337 to Player 1 (Red) Current gold
      • Set hero_types[1] = Paladin
      • Set hero_types[2] = Archmage
      • Set hero_types[3] = Mountain King
      • Set hero_types[4] = Blood Mage
      • Set hero_names[1] = Paladin
      • Set hero_names[2] = Archmage
      • Set hero_names[3] = Mountain King
      • Set hero_names[4] = Blood Mage
      • Set hero_count = 4
      • Set spawn_loc = (Center of Spawn Region <gen>)
      • Unit - Create 1 hero_types[(Random integer number between 1 and hero_count)] for Player 1 (Red) at spawn_loc facing Default building facing degrees
      • Set player_hero = (Last created unit)
      • Hero - Set player_hero Hero-level to (Random integer number between 2 and 10), Hide level-up graphics

Saving

Now to the real triggering part of the tutorial.

We'll use the following script to declare (create) a file variable. Note that the variable is of the type "File" and is named "file".
  • Custom script: local File file
That line need to be on the top of the trigger else JNGP will throw errors in your face.

Now that we got our file variable, we need to make some settings before we can actually start to do stuff.

  • Custom script: local File file
  • Set mapName = testMap
  • Set file = exp
*mapName = the folder that the file will be created in.
*file = file name

The result will be: Warcraft III/GameData/mapName/file

Now we're ready to finally start saving values. We need to set our file variable before we can start with the actual saving though.

  • Custom script: set file = File.open(udg_mapName, udg_file, File.Flag.WRITE)
Once that's placed out, we can start to use the file.write() basically it writes something on the first line of a empty text document.

  • Set what_to_save = (Name of (Triggering player))
  • Custom script: call file.write(udg_what_to_save)
In my case the player name will be saved on the first row of the file.

After that you simply repeat the process over and over until everything is saved.

  • GUI Save
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Custom script: local File file
      • Set mapName = testMap
      • Set file = exp
      • Set player = (Triggering player)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • local_player Equal to Player 1 (Red)
        • Then - Actions
          • Custom script: set file = File.open(udg_mapName, udg_file, File.Flag.WRITE)
          • Set what_to_save = (Name of (Triggering player))
          • Custom script: call file.write(udg_what_to_save)
          • Set what_to_save = (Name of player_hero)
          • Custom script: call file.write(udg_what_to_save)
          • Set what_to_save = (String((Level of player_hero)))
          • Custom script: call file.write(udg_what_to_save)
          • Set what_to_save = (String((player Current gold)))
          • Custom script: call file.write(udg_what_to_save)
          • Set what_to_save = (String((player Current lumber)))
          • Custom script: call file.write(udg_what_to_save)
          • Game - Display to (All players) the text: saved!
          • Custom script: call file.close()
        • Else - Actions

Load

Loading the information we've stored use the same method as before with a few changes. We start off just like before.
  • Custom script: local File file
  • Set mapName = testMap
  • Set file = exp
  • Set player = (Triggering player)
However when setting our file variable to a value there is a slight difference. File.Flag.WRITE > File.Flag.READ
  • Custom script: set file = File.open(udg_mapName, udg_file, File.Flag.READ)
To start the actual loading, I use a string variable named "what_to_load" and makes it read the upper row inside our file.
  • Custom script: set udg_what_to_load = file.read()
After that we just need to use that variable for our purposes in. In my case it's the player name.
  • Custom script: set udg_what_to_load = file.read()
  • Player - Set name of player to what_to_load
After that, it's just copy > paste pretty much. re-store the variable, and reuse it.
  • GUI Load
    • Events
      • Player - Player 1 (Red) types a chat message containing load as An exact match
    • Conditions
    • Actions
      • Custom script: local File file
      • Set mapName = testMap
      • Set file = exp
      • Set player = (Triggering player)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • local_player Equal to Player 1 (Red)
        • Then - Actions
          • Custom script: set file = File.open(udg_mapName, udg_file, File.Flag.READ)
          • Custom script: set udg_what_to_load = file.read()
          • Player - Set name of player to what_to_load
          • Custom script: set udg_what_to_load = file.read()
          • For each (Integer A) from 1 to hero_count, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • what_to_load Equal to hero_names[(Integer A)]
                • Then - Actions
                  • Unit - Create 1 hero_types[(Integer A)] for Player 1 (Red) at spawn_loc facing Default building facing degrees
                • Else - Actions
          • Custom script: set udg_what_to_load = file.read()
          • Hero - Set (Last created unit) Hero-level to (Integer(what_to_load)), Hide level-up graphics
          • Custom script: set udg_what_to_load = file.read()
          • Player - Add (Integer(what_to_load)) to Player 1 (Red) Current gold
          • Custom script: set udg_what_to_load = file.read()
          • Player - Add (Integer(what_to_load)) to Player 1 (Red) Current lumber
          • Custom script: call file.close()
        • Else - Actions

Credits

Nestharus - File I/O

 
Last edited:

Deleted member 219079

D

Deleted member 219079

Why not just use gamecache? : )


Without synchronization, File I/O is a glorified gamecache = P

What do you mean by without synchronization?


Also good tutorial, colors look pleasant.
-Only works in Single Player until updated! (I am need to sleep first!)-
Well at the moment this is just as good as game cache.

Also this:
  • Custom script: local File file
  • Set mapName = testMap
  • Set file = exp
You have udg_file and file here, it might be misleading for some GUI users.
 

Deleted member 219079

D

Deleted member 219079

I see, well I'm intrigued to see how OP will turn this to mp :)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
They have to usr my Network lib, which is too slow and needs an update. If they use it, this tut can't be used unless u wanna freeze the game for 5 mminutes while sync takes place.

We already know how to fix Network, all of us that code core resources. The prob is that nobody has time to update it.

If it's updated, you can just use my pure GUI codeless save/load stuff. Will be easier to use and faster.
 

sentrywiz

S

sentrywiz

I really liked this. Until I read it was singleplayer only. In that case, what is the point of this? Save game works much easier and much better and saves the hassle of looking for files, copying a large amount of characters etc... Also like Zwie said.

Its great as a tutorial on how to make your own.

But it sucks if its only for singleplayer.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
I really liked this. Until I read it was singleplayer only. In that case, what is the point of this?
It has a purpose in singleplayer, as the normal method of saving/loading via the game menu will break periodic timers and waits.

Of course, the mapper *can* technically account for these things with workarounds, but more than often it is easier (and also desirable) to implement a manual save/load into a singleplayer map over the menu based save/load.
 
It's basicily a tutorial for GUI users how to use File IO with a few of custom scripts.
Save/Load tequniques usually use some sort of encryption, and also some synchronisation library.

I suggest to screw the idea of making full Save/Load tutorial. They should go with existing systems and learn them to use.
But a simple tutorial for GUI users how to properly use File IO as easy as possible. Why not. ¯\_(ツ)_/¯
 
Top