Announcement

Collapse
No announcement yet.

Save/Load your game in End-Users My Documents folder

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Save/Load your game in End-Users My Documents folder

    Hello everyone

    In this tutorial i will tell you how to save your game to end-users My Documents folder with any file extension you want. This tutorial will make use of UDK’s DLLBind feature and to create this DLL i used C# language.

    NOTE: Download includes C# source code including the DLL file + UnrealScript files. In case you want to change anything you will need Microsoft Visual Studio Express (FREE) or above.

    DOWNLOAD FILES

    1: Download the above file and extract the DLL file to your UDK Installation Directory\Binaries\Win32\UserCode folder.

    2: Copy/Paste SaveGameBase.uc and CustomPlayerController.uc and CustomGameInfo.uc to your UDK Installation Directory\Development\Src\MyMod\Classes folder.

    SaveGameBase.uc
    PHP Code:
    /**    * ===============================================================================================================================================================
        * SaveGameBase - The base class for Saving and Loading Game.
        * This class uses DLLBind feature to save and load game in My Documents folder.
            
        * USAGE: Feel free to use this in your Commercial and Non-Commercial Projects. I expect a little credit somewhere inside your game but its your choice :)
            
        * Created by Satheesh P.V (a.k.a RyanJon2040)
        * Visit: http://unrealxeditor.wordpress.com
        * ===============================================================================================================================================================
    **/


    class SaveGameBase extends Object
    dllBind
    (SaveGame);


    var 
    vector Loc//Sample variable that saves player position.
    const SAVE_VERSION 1//Change this number incase you dont want to load old save files.


    /**
     * Saves the game to end-users MyDocuments folder. Auto-increment of file names is supported.
     *
     * @param SaveTo The folder that you want to create inside MyDocuments folder. eg: If you type MyAwesomeGame the result will be: "C:\Users\<USERNAME>\Documents\MyAwesomeGame"
     * @param SaveName The filename that you want to use when saving your game.
     * @param Extension The file extension you want to use for your savegame. Feel free to use any extension you want. eg ".bin" or ".sav"
     *
     */
    dllimport final function string SaveGameToMyDocuments(string SaveTostring SaveNamestring Extension);


    /**
     * Loads the specified gamefile from end-users MyDocuments folder. NOTE: The arguments should be the same as what you used in SaveGameToMyDocuments().
     *
     * @param LoadFrom Folder Name that this DLL will look under MyDocuments folder
     * @param LoadName The filename that will be used to load your game.
     * @param Extension The file extension that will be used for the filename.
     * @param FileNumber Loads the save game specified by the FileNumber. eg: "SampleGame_<FileNumber>.bin"
     *
     */
    dllimport final function string LoadGameFromMyDocuments(string LoadFromstring LoadNamestring Extensionstring FileNumber);


    defaultproperties
    {
        

    CustomPlayerController.uc
    PHP Code:
    /**    * ===============================================================================================================================================================
        * CustomPlayerController - Created to demonstrate SaveGameBase functions.
        * Basic PlayerController class intended as a Template to demonstrate SaveGameBase functions.
        
        * WARNING: If you plan to use multiple folders inside My Documents it is VERY IMPORTANT to set double slash in string FolderName. Failure to do so will crash UDK.
          See FolderName under DefaultProperties.
            
        * Created by Satheesh P.V (a.k.a RyanJon2040)
        * Visit: http://unrealxeditor.wordpress.com
        * ===============================================================================================================================================================
    **/


    class CustomPlayerController extends UTPlayerController;


    /** Declare our SaveGameBase. */
    var SaveGameBase SGB;


    /** Folder name that will be used in SaveGame() and LoadGame(). Defined in DefaultProperties */
    var string FolderName


    /** Save File name. Should be same in SaveGame and LoadGame. Defined in DefaultProperties */
    var string SaveFileName;


    /** Your custom file extension. Use any extension you want. Eg: ".bin" or ".sav". Defined in DefaultProperties */
    var string SaveFileExtension;


    /** Saves the game. Bind this function to a key (like F5 or F6 or something like that) in DefaultInput.ini */
    exec function SaveGame() 
    {
        
    /** The string that will hold the absolute path of save location */
        
    local string SaveLoc;
        
        
    /** Since we extended the SaveGameBase from Object we must use "new" to create a new one */
        
    SGB = new class'SaveGameBase';
        
        
    /** Assign the players position to Loc variable inside SaveGameBase (SGB) */
        
    SGB.Loc CustomPawn(self.Pawn).Location;
        
        
    /** Calls the DLLFunction which returns MyDocuments\FolderName\SaveFileName.SaveFileExtension */
        
    SaveLoc SGB.SaveGameToMyDocuments(FolderNameSaveFileNameSaveFileExtension);
        
        
    /** Finally call the Engine Function to save all the SGB variables to the specified location */
        
    class'Engine'.static.BasicSaveObject(SGBSaveLoctrueSGB.SAVE_VERSION);
        
        
    /** [TESTING ONLY] */
        
    WorldInfo.Game.Broadcast(self"Game Saved.");
        
    WorldInfo.Game.Broadcast(selfSaveLoc);
        
    WorldInfo.Game.Broadcast(self"Player Position: "$SGB.Loc);
    }


    /** Loads the game. */
    exec function LoadGame(int LoadVersion)
    {
        
    /** Holds the path to load the save game */
        
    local string LoadLoc;
        
    SGB = new class'SaveGameBase';
        
        
    /** Calls the DLLFunction which returns MyDocuments\FolderName\SaveFileName_LoadVersion.SaveFileExtension */
        
    LoadLoc SGB.LoadGameFromMyDocuments(FolderNameSaveFileNameSaveFileExtensionstring(LoadVersion));
        
        
    /** If everything goes well and SGB.SAVE_VERSION is correct then load the file */
        
    if (class'Engine'.static.BasicLoadObject(SGBLoadLoctrueSGB.SAVE_VERSION))
        {
            
    /** Change the players position to whatever is defined in SGB.Loc */
            
    CustomPawn(self.Pawn).SetLocation(SGB.Loc);
        }
    }


    defaultproperties
    {
        
    FolderName "My Game Or Company Name" //For multiple folders: "My Company Game\\My Game Name\\Save Games". It is IMPORTANT to set double slash!!
        
    SaveFileName "BoogieSave" //The file name that will be used in SaveGame and LoadGame.
        
    SaveFileExtension ".goo" //File Extension. You can use any extension you want.

    CustomGameInfo.uc
    PHP Code:
    class CustomGameInfo extends UTGame;

    defaultproperties
    {
        
    PlayerControllerClass=class'CustomPlayerController'

    3: Do a full recompile and Start UDK Game using CustomGameInfo and use the functions SaveGame and LoadGame functions.

    I hope you enjoy this.

    I have commented everything in UnrealScript files. If you have any doubt feel free to post here.

    #2
    Thank you for posting this Ryan Jon!

    You're awesome!



    Rama

    Comment


      #3
      This is awesome, thanks a lot!

      Comment


        #4
        Must admit! Pretty uber stuff here!
        Thanks for this

        Comment


          #5
          Thank you evernewjoy, ZeJudge and caster_0

          Comment


            #6
            Hi,

            I'm using the latest July 2013 Build of UDK and get these errors. Any ideas as I really need a load save system.


            E:\UDK201307\Development\Src\MyMod\Classes\CustomP layerController.uc(66) : Error, 'CustomPawn': Bad command or expression
            E:\UDK201307\Development\Src\MyMod\Classes\CustomP layerController.uc(38) : Error, Bad or missing expression for token: CustomPawn, in '='
            Compile aborted due to errors.
            Warning/Error Summary
            ---------------------
            E:\UDK201307\Development\Src\MyMod\Classes\CustomP layerController.uc(66) : Error, 'CustomPawn': Bad command or expression
            E:\UDK201307\Development\Src\MyMod\Classes\CustomP layerController.uc(38) : Error, Bad or missing expression for token: CustomPawn, in '='

            Any help very much appreciated.
            I dont know why its added a space in the customplayercontroller.uc but that's not in the code. just on this post.

            Comment


              #7
              You're supposed to replace the word CustomPawn with the name of your custom pawn class. But in this case, there is actually no need for CustomPawn.

              Just replace "CustomPawn(self.Pawn).Location" with "Pawn.Location" and both errors should disappear.

              Do the same for "CustomPawn(self.Pawn).SetLocation(SGB.Loc)", replace it with "Pawn.SetLocation(SGB.Loc)".

              Comment


                #8
                Great stuff, thanks for sharing.

                I apologise in advance if I'm hijacking the thread, but I would like to get some input on a possible extension of this code.

                A while back I thought about writing a tool which would trawl through all the classes in a project and generate code for saving and loading all custom variable values too.
                This is obviously a massive task, and I'm not sure how viable it even is to get code like that into a fairly usable state.
                It would involve a huge amount of manual labour as well, e.g. for KActors you also need to save and load the StaticMeshComponent and its velocity, angular velocity (RB stuff) etc. Add to the mix that many of these are consts which cannot be set directly, and it seems like an even bigger task.

                So this system needs to be quite intelligent in identifying components as well as simple class properties. It would even need a parser to identify which lines of Unrealscript are variable declarations.

                So to summarise, do you guys think something like this is worth pursuing? I mean, if there are many people contributing it might be possible, but I doubt a single person would be able to pull that off.

                I'd be very interested to hear some opinions on this, and please do feel free to point out that I might possibly be insane.

                Comment


                  #9
                  Originally posted by staticvoidlol View Post
                  do you guys think something like this is worth pursuing? I mean, if there are many people contributing it might be possible, but I doubt a single person would be able to pull that off.
                  Honestly? No.

                  I'm not gonna talk about the feasibility and the amount of time it takes to create that. Actually before you think about whether a system is possible or if it's too difficult, you should be able to answer the question "why that's necessary in the first place?", if you can't find a good reason for that question, you shouldn't go to the next level. In other words the first step in creating a new system is the "feel to need".

                  Besides, best-case scenario, you did it without much trouble, and it works perfectly, there a very big problem attached to it: in any project no matter what size it is, you usually need *5% of the variables or less* to be saved (in some weird type of project maybe 10 tops - In most my projects for instance, it's mostly between 1-2%). That means you're saving a whole bunch of useless data, which results in a couple issues: The file size would be 15-10 times bigger than it actually need to be, the save process will take a lot longer, as well as the load one, let alone more room for things to go wrong (like a system power down) because of the extra time.

                  I can think of more, but don;t get me wrong, I'm not saying this idea is all problems, there's a couple advantages to it too, at least for some special projects out there, but like I said before you can't give a good enough answer to the first question for any system, there's not much point in evaluating the pros/cons of that.

                  Comment


                    #10
                    Your Awesome man , thanks for this code, seems to be much more simple than the udn gem. Also, I have to admit with Farshad, you should replace every CustomPawn(self.Pawn) with just "Pawn".

                    Comment


                      #11
                      So basicallly what does this it's, save the vector " location " and then when you load game the actor is set to the location " actor.setLocation" to a destination , so the same can be accomplished with inies right? what's the sense of storing it in to a C file? just curious i don''t really know what could be the advantage of this buty i'd love to know it : ) .

                      well so, to make a perfect save game it's not that hard i guess , you just run a " foreach all pawns " , if pawn == not a companion save in some array of pawns in some class to specifically.
                      Wich taht array would be a struct containing the weapon , the health and the location ...

                      So then you would just run a function that would spawn all of em i guess..

                      That is how is done right ? well i don't see another way hehe...

                      Comment


                        #12
                        It's nice, because it shows how to use the save game system. And those files are jsut very easily expandable, because it saves every variable of the savegame base object. Also, using the config files would be actually too cheater friendly, as those save fiels aren't rly readable for a human without additional programms, and i remember games doing it with config files, you could just go in and change the variable. So this is just cleaner, is located in documents, so doesn't get deleted when uninstalling game, and can is actually very easy to understand for new programmers.

                        Comment


                          #13
                          yep i understand the fact that then they are so cheatable , but the real cheater will cheat anyways with a c file plus the non cheater will just leave the inies alone...
                          But well the thing it's this is that c file easily readable, or changable ?

                          Comment


                            #14
                            But you still need to put some effort in, and those cheaters, who don't go farther than using console or editing inis, won't have the programms, and will be too lazy to get them, to modify those save files (or the dll file).

                            Comment


                              #15
                              true true , but im too lazy to get visual ... well it can be my way to get back a Little to c++ i don't write it since i met Unrealscript pretty much.

                              Comment

                              Working...
                              X