Announcement

Collapse
No announcement yet.

SaveGame [Info]

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

    SaveGame [Info]

    This thread covers information on Save/Load Game Config structures for UT3
    - Most of the code was provided by myself and the UDK community, but (and i advise this always) you should use RattleSN4K3's Example Provided in his post below
    - Many Thanks for this
    ================================================== ============================
    Original Request:
    ================================================== ============================
     
    Spoiler

    ================================================== ============================

    Save Game requirements:

    • Items/ pickups/ inventory/ weapons - set as true or false when Touched (picked up)
    • Health - amount
    • Ammo - Amount
    • Player - Location & Rotation
    • AI - set to true or false if 'encountered'
    • option to reset level all when killed (to default) {if brestartlevel=true }reset_all_stuff to default
    • ^^ All stuff - saved to config file (somewhere in my documents)- accessed on LoadGame and set to config value
    • command to type SaveGame & LoadGame
    • Link up to UI scene/ map; key input pressed exceutes command. e.g. an images shows text "hit enter to load game"
    • a trigger (checkpoint) that when touched saves the game and all this stuff ^^


    ================================================== ============================
    Links:
    ================================================== ==========================
    *** New Code Fixed by RattleSN4KE (See RS post) ***
    ================================================== ==========================
    OLD DOWNLOAD LINKS
     
    Spoiler

    Thanks

    ================================================== ============================
    ↓↓↓ Code Examples: Thanks to stacey ↓↓↓
    ================================================== ============================
     
    Spoiler
     
    Spoiler

    ================================================== ==================
    ↓↓↓ More stuff here that might work ↓↓↓
    ================================================== ==================
     
    Spoiler

     
    Spoiler

    ================================================== ===

    #2
    You do have a basic shell with that code. So where do you have problems?

    Comment


      #3
      • Updated the original post with a 2nd, easier to manage "game code base". The 2nd link more accurately describes what i am going for. it was the basis for a game by rene (Warstor) & I (TKBS).


      ↓↓↓ Old **** ↓↓↓
       
      Spoiler

      Comment


        #4
        "can someone help?"
        "Link below to be made UT3 compatible Please"

        Hmm. I'm not here to create such system for you but i'm willing to help you if you work on it by yourself.

        Starting by creating a system which stores the health and restores the health once you load the savegame. Extend it for your needs and you're good to go.
        Step-by-step
        • Store/restore trivial values like Player name, location, rotation etc.
        • Stores values like weapons
        • Restore inventories (CreateInventory and set values like ammo etc.)
        • Add exec command to save game
        • Add exec command to load game
        • Save game as per-object (Level name will be the name for the object)
        • Find and load a savegame by its level name
        • Create UI
        • Open UI ingame
        • Create a Trigger-extending volume for LDs
        • ...



        PS: JSON will not work for UT3 as UT3 doesn't allow any input (you cannot read from files; there would be a hacky way tho)

        Comment


          #5
          I updated the First Post but forgot to say.
          ↓↓↓ Unstructructured post ↓↓↓
           
          Spoiler

          Comment


            #6
            Woah. Ehm. Too many questions. Unstructured post. ...

            The "source code" you have linked in your first post is not even a shell, it looks like a complete game type. I'm not sure what I could explain to you as I'm unsure where you got problems.




            InitGame should load the existing game. You can parse a URL paramter in there etc. And change values before the actual game code is initialized (=Pre/PostBeginPlay).
            Serializing and deserializing is stressful to implement in UnrealScript. The basic system is given in the provided source coce. You just have to create a method to replace BasicLoadObject (which is basically what Angel_Mapper has written).


            PS: Keep your posts simple so we can focus on a specific thing.

            Comment


              #7
              is no one able to help with this?
              Keep your posts simple so we can focus on a specific thing.
              sorry, if my post was not simple. I cannot get more simple for you than giving you the code i have and asking for how to get it to work.
              ↓↓↓ Old **** ↓↓↓
               
              Spoiler

              Comment


                #8
                So how to get this working?

                Comment


                  #9
                  I know you don't like it, but have you check the following page:
                  https://udn.epicgames.com/Three/ConfigurationFiles.html

                  It should explain how the engine writes config files (ini). You should also see how they are loaded. The only difference for your needs would be using a perobjectconfig class. There is also nice helping pages (and quite working examples) on the UDN:
                  http://udn.epicgames.com/Three/Confi...ameSystem.html

                  So if you want to store the values like you had in your save game class...
                  Code:
                  class MYSave extends Object
                      config(SaveGame)
                      perobjectconfig;
                  
                  var config string MapName;
                  var config int Health;
                  var config Vector PlayerLocation;
                  var config Rotator PlayerRotation;
                  
                  function save()
                  {
                      SaveConfig();
                  }
                  ... you would basically create a named object from that class, store values into the field and call ObjectInstance.save();.

                  At the time you want to restore your save game, you would need to create the object with the same name. There are also functions in the code base which allows you to find all the given savegames but that is out the scope for the moment.
                  Not sure if you intend multiple savegames per map, but let'S try it to make it very simple.

                  Create 2 exec commands in your game code (subclassed PlayerController):
                  Code:
                  exec function SaveGame(optional bool bOverwrite)
                  {
                      local MYSave MYSaveObj;
                      WorldInfo.Game.Broadcast(none, "Saving game...");
                     
                      MYSaveObj = new (none, "MySaveGameName") class'MYSAVE';
                      MYSaveObj.MapName = WorldInfo.GetMapname(true);
                      MYSaveObj.Health = Pawn.Health;
                      MYSaveObj.PlayerLocation = Pawn.Location;
                      MYSaveObj.PlayerRotation = Pawn.Rotation;
                      MYSaveObj.save();
                  
                      WorldInfo.Game.Broadcast(none, "Game saved.");
                  }
                  
                  exec function LoadGame()
                  {
                      local MYSave MYSaveObj;
                  
                      MYSaveObj = new (none, "MySaveGameName") class'MYSAVE';
                      Pawn.Health = MYSaveObj.Health;
                      Pawn.SetLocation(MYSaveObj.PlayerLocation);
                      Pawn.SetRotation(MYSaveObj.PlayerRotation);
                  
                      WorldInfo.Game.Broadcast("Game loaded.");
                  }
                  This would work for a single named savegame. If you create your savegame with the mapname in it, it would create an unique savegame for each map.
                  Instead of...
                  Code:
                  MYSaveObj = new (none, "MySaveGameName") class'MYSAVE';
                  ... use this:
                  Code:
                  MYSaveObj = new (none, WorldInfo.GetMapName(true)$"_Save") class'MYSAVE';

                  Edit:
                  Fixed the code by swapping the new operator's parameters.

                  Edit2:
                  Removed unused code.

                  Comment


                    #10
                    ↓↓↓ UDN pages never work (stress post LOL) ↓↓↓
                     
                    Spoiler

                    Comment


                      #11
                      It is a local boolean variable called "ret". Forgot to remove it. UT3 does not need an UTUser.ini file, if you create a class with the config specifier of "config(User)" it will store it's config values into the UTUser.ini file. A correct ini file is only used if you use the classes correctly, if the outer is different, the class gets written in the wrong ini.

                      "config(SaveGame)" saves into UTSaveGame.ini.

                      Comment


                        #12
                        If you create the config; x=5 does not get saved to it
                        might aswel quote the whole post back.

                        The config file does not get created, if i create it nothing gets saved to it. It doesn't matter what i call it. Not good to know a simple test with 5 lines of code still doesn't work.
                        This is getting me absolutely no progress, please provide a working example. Code and config, or preferably download my source code/ game, enjoy it and fix the 5 lines of code.

                        - Even if it is the UDN example, if you can show me that working then great i can maybe make something of it.

                        Comment


                          #13
                          Very basic.

                          A package called MySinglePlayerGame.

                          MSPGame.uc
                          Code:
                          class MSPGame extends UTGame;
                          
                          defaultproperties
                          {
                              PlayerControllerClass=class'MSPPlayerController'
                          }
                          MSPPlayerController.uc
                          Code:
                          class MSPPlayerController extends UTPlayerController;
                          
                          exec function SaveGame()
                          {
                              local MSPSavegame SavegameObj;
                              WorldInfo.Game.Broadcast(none, "Saving game...");
                             
                              SavegameObj = new (none, "MySaveGameName") class'MSPSavegame';
                              SavegameObj.MapName = WorldInfo.GetMapname(true);
                              SavegameObj.Health = Pawn.Health;
                              SavegameObj.PlayerLocation = Pawn.Location;
                              SavegameObj.PlayerRotation = Rotation;
                              SavegameObj.Save();
                          
                              WorldInfo.Game.Broadcast(none, "Game saved.");
                          }
                          
                          exec function LoadGame()
                          {
                              local MSPSavegame SavegameObj;
                          
                              SavegameObj = new (none, "MySaveGameName") class'MSPSavegame';
                              Pawn.Health = SavegameObj.Health;
                              Pawn.SetLocation(SavegameObj.PlayerLocation);
                              SetRotation(SavegameObj.PlayerRotation);
                          
                              WorldInfo.Game.Broadcast(none, "Game loaded.");
                          }
                          
                          defaultproperties
                          {
                          }
                          MSPSavegame.uc
                          Code:
                          class MSPSavegame extends Object
                              config(MySinglePlayerGame)
                              perobjectconfig;
                          
                          var config string MapName;
                          var config int Health;
                          var config Vector PlayerLocation;
                          var config Rotator PlayerRotation;
                          
                          function Save()
                          {
                              SaveConfig();
                          }
                          Config file UTMySinglePlayerGame.ini
                          (will also be created with default values if not existing)
                          Code:
                          [MSPGame UTUIDataProvider_GameModeInfo]
                          GameMode=MySinglePlayerGame.MSPGame
                          DefaultMap=
                          GameSettingsClass=UTGameSettingsDM
                          GameSearchClass=
                          OptionSet=DM
                          FriendlyName=My Singlerplayer Game
                          Description=A brief example of saving and loading a game state
                          PreviewImageMarkup=
                          Prefixes=
                          IconImage=
                          bIsCampaign=False
                          IconU=0.000000
                          IconV=0.000000
                          IconUL=0.000000
                          IconVL=0.000000
                          ModGameSettingsScene=
                          ModClientSettingsScene=
                          bRemoveOn360=False
                          bRemoveOnPC=False
                          bRemoveOnPS3=False
                          Creating a game, moving around, getting damaged and type "savegame" into the console.
                          You can close the game, re-open the game and load the same game with the same map. Type "loadgame" into the console, and it will load the old savegame which will put you with the same health on the location you were as you saved the game.

                          As we specified config(MySinglePlayerGame) in our savegame class, the data will be stored in UTMySinglePlayerGame.ini. The data will look like this:
                          Code:
                          [MySaveGameName MSPSavegame]
                          MapName=DM-Deck
                          Health=86
                          PlayerLocation=(X=1662.930786,Y=657.547424,Z=-396.960022)
                          PlayerRotation=(Pitch=63822,Yaw=32245,Roll=0)



                          I created a slightly extended version which allows to save custom named savegames and re-load them individually. There is also a command to list all savegames. You can delete a single named savegame or all savegames as well.
                          MySingleplayerGameExample.zip

                          Of course, the savegames class should load and create the savegames, but I didn't want to overcomplicate it.

                          Comment


                            #14
                            Thank you for this RattleSN4K3, it's poetry when you do that
                            ================================================== ====
                            - Some things i noticed:
                            • "MYPlayerController" is referenced but i write my code like this "MYCodeFolder.MYPlayerController" & The same for the HUD... HUDType = 'MYHUD'
                            • How am i supposed to know which way to write the reference. I assume Full reference is OK ?
                            • a)PlayerControllerClass=class'MSPPlayerController' OR
                            • b)PlayerControllerClass=class'.MYCUSTOMGAME.MSPPla yerController'


                            ^^ both work in this example ↑↑↑ but this might not be true for all cases. Following your example fixed my game loading and my New key binds so the way you reference must be very important

                            Unfortunately the provided code has ↓↓↓ broken most of my kismet & level startup issues ↓↓↓ & it causes a loadgame issue that breaks all of my events.
                            ^6 better now than after 50 maps and 5000 flashing lights lol
                            - Do not come back at me with a fix {yet}, i appreciate what you have done so far, i only think spoon feeding is appropriate in some cases (that was one) and i want to discover how to fix it myself if possible
                            ↓ Explained ↓
                             
                            Spoiler

                            - the future of UT3RTNP
                             
                            Spoiler



                            Q. Is there a resetlevel function that will also reset Kismet events?
                            Thanks again.

                            Comment


                              #15
                              Once you load the game, you should reset the game.
                              Code:
                              ResetLevel(); // inside the game class
                              This would also call reset on each actors. But this won't say that any actor reacts to this call. Also your custom game code must react to it.

                              If you use class literals (class'MyClass') the engine will try to find the correct class during the compile process. It will first check the existing classes and than use the own package to search for that given class.

                              class'MyPackage.MyClass' or class'MyClass' is the same if it's writtein inside an class file of the same package (MyPackage). Don't get it wrong as "MyClass" is not a fully qualified name like "MyPackage.MyClass" - you can't dynamically load classes/assets with just the single class name, it has to be fully qualified.

                              The advantage of not using the full class literal inside the packages is pretty simple. You can rename the package and don't have to update the code. This is useful for versioning (but renaming can also be done after package is compiled).




                              As you requested, I don't write anything more complex to help out out, a just give you hints .

                              You would need to change the logic of your gameclass. In general, UTGame subclassing game types will go into the "PendingMatch" state which waits for input or players. You could force your game into a different state (in the example: MatchInProgress) to skip the pending match process.
                              Code:
                              function PostBeginPlay()
                              {
                                  Super.PostBeginPlay();
                                  InitialState='MatchInProgess';
                              }
                              Also, the PlayerController genereally joins as spectator and waits for the player to press fire. This can be skipped as well. Maybe with a state or a boolean flag. You should investigate . If you know what text is shown, search the text in the *.int files of UT3 and look for the variable name. After knowing the variable name, you can search on all *.uc files for this name (recommended using UnCodeX).

                              Comment

                              Working...
                              X