PDA

View Full Version : Save/load



bez
11-05-2009, 12:27 PM
1.Is the quicksave and quickload exec functional in the UDK ?
2.What would the file format be for saving ?

joeGraf
11-05-2009, 12:32 PM
Quicksave/load were removed

Solid Snake
11-05-2009, 03:34 PM
The way I plan to do this for my projects is to write an external program which resides in memory while the UDK is run. There will be two aspects to this project.

a) Writing a program which handles sending and receiving data from sources such as off site files or on site files. This program opens a TCP connection on a particular port.
b) Unrealscript communicates with this program using TCPLink.

So given that I can get data in and out of Unreal Engine using this method handling data outside of UDK would be 'easy'. The trick now of course, is to implement what you want to do with this data.

And one of those can be Quicksave and Quickload.

* I haven't actually written this but I believe this method will probably work as all of the appropriate classes seem to exist such as TCPLink.

ambershee
11-05-2009, 03:39 PM
To add to the above, it's certainly possible. In a previous UT3 mod project, we used a launch program which acted very much like a local server and interfaced with the game via TCPLink in order to handle loading and saving. The external application handled player profiles and games saves, then fed UT3 what it wanted to know on startup.

bez
11-05-2009, 04:18 PM
Quicksave/load were removed

Why was they removed ? and will they be put back in future versions

Sir_Brizz
11-06-2009, 12:33 PM
Having an external program to handle saving and loading is massively and totally hacky. One of the draws to having UDK is being able to set up complete commercial game experiences. The way it is set up right now, it would be difficult to "recreate" any game that uses a user-based saving system. You'd need to use a checkpoint system, which just doesn't fit the design of some games.

bez
11-06-2009, 12:44 PM
Yeah totally agree It stop me dead in my track when modding for ut3 as I couldnt find a solid solution for saving data and my game design wouldnt work on a level progression basis.

Solid Snake
11-06-2009, 10:02 PM
It is a bit of a bummer that the config functions still appear to be commented out meaning that we probably can't use them as of yet as it would be able to solve a lot of these sorts of issues. DataObject was also fantastic back in UT2004 as that allowed you to save any kind of data whatever way you liked.

Using an external program is a hacky but it does work and perhaps we just need to get things working rather than just complaining about it (like documentation).

languard
11-06-2009, 10:23 PM
I don't think a launcher, as long as it's done well, is all that hacky. Just how many games have them? A lot. Granted most of the launchers are skipable, but still. Users are very used to having to go through a launcher to get to the game.

Since I saw this thread, I've been giving some thought to this. I'm thinking a .Net launcher would be the way to go. A well written .Net app is far easier to extend that a well written C++ app (at least in my experience) and there's no real performance difference in this scenario. Thoughts?

Solid Snake
11-06-2009, 10:25 PM
Go for it.

Sir_Brizz
11-07-2009, 01:43 AM
I don't think a launcher, as long as it's done well, is all that hacky. Just how many games have them? A lot. Granted most of the launchers are skipable, but still. Users are very used to having to go through a launcher to get to the game.
Users don't know if they are going through a launcher or not, but it's not going through the launcher that is the hacky part. It's having an external application that handles something that the engine should be able to do for you natively (or at least have the right hooks for you to handle it yourself.

Think about what this solution is. You're running a second application. You're creating a TCP connection to that application. You are running data THROUGH that TCP connection. That's pretty inefficient and exactly what I'd call hacky.

Most games who have launchers use SecuROM or something and most users who know about such things hate having the additional application running in the background as well.

ambershee
11-07-2009, 01:46 AM
Nevertheless Brizz, an external application would be required in order to facilitate a complex save / load system.

DragonSpawn
11-07-2009, 10:58 AM
This makes me wonder "What type of save/load does UDK in fact offer to begin with?"

musilowski
11-07-2009, 11:35 AM
Is it possible to export data to an .ini file? Things such as gamestate, player location/position, inventory, mission(s) status, etc. Can this stuff be read before the game is launched and adjust the beginning of the game properly?

Sir_Brizz
11-07-2009, 12:03 PM
Nevertheless Brizz, an external application would be required in order to facilitate a complex save / load system.
No it wouldn't, unless you mean something like storing save data on a remote server, which would be a more appropriate use of TCPLink in this case.

If you're writing a game via script, you know what data you need to store if you're doing something complex. Simple Reader and Writer classes could just as easily facilitate writing data to a file as running it through a local remote service.

I realize that there is currently no other option, but that doesn't mean I have to like it. :p

marcusmattingly
11-11-2009, 04:53 PM
Wait a minute, am I understanding that there is no way to save game data using UDK?

That's crazy! How can you make any kind of a game if you can't save/load data?

I hope I am misunderstanding all of this. :(

Marcus

Taxxem
11-11-2009, 05:01 PM
I believe all the posts are pointing to the fact that you can do a save/load but the options aren't the best and you have to write your own save/load code its not handed to us.

elmuerte
11-11-2009, 05:12 PM
You can save and load data, you just can't create "savegames". You can not freeze the world and save it to a file to be restored at a later time. But you could easily implement a simple techpoint system.

marcusmattingly
11-11-2009, 05:37 PM
Ok, if I can save and load data then where does that data go and where is it read from?

I guess what I am getting at is I was expecting there to be some kind of class somewhere that simply lets me open a file, and read/write text to/from it. Does this not exist in UnrealScript? If not, then how would I make ANY kind of save system. Can this type of functionality be created by using C++ and creating some kind of extension to the engine?

I am not looking to have it handed to me, but I need to know what is possible and what is not. I am looking to create a very simple RPG. RPGs are worthless unless you can save your stats, level, inventory, location, quest progression, etc.

Geez, talking to an external app via TCP/IP seems crazy for saving a single player game.

Sorry, I know I kind of rambled here. I am just worried that now I won't be able to use UDK for what I want to do.

Marcus

elmuerte
11-11-2009, 05:50 PM
you can still use the configuration files to store data, special when using the PerObjectConfig directive you can get a long way:
http://wiki.beyondunreal.com/Legacy:PerObjectConfig
and also see:
http://wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files

marcusmattingly
11-11-2009, 06:08 PM
elmuerte,

Thanks so much for those links, I will certainly check them out. I guess writing my custom data to a custom section of a config file will work in a pinch. It's better than nothing.

I know the Mass Effect games are UE3 powered RPGs, but I can't imagine this is how they save games.

Is this a limitation of the UDK only? My understanding was that the UDK is the same tools that the big studios use. Is this not entirely true?

Thanks again for the replies. You have been a huge help.

Marcus

Solid Snake
11-11-2009, 06:23 PM
When you are a licensee, such as BioWare, you are granted access to the source code to the engine itself. With this you can do whatever you want.

In the UDK you only have Unrealscript.

elmuerte
11-11-2009, 07:25 PM
iirc Mass Effect uses a "DataObject" like savegame system, so it doesn't make an image of the world (like a real savegame system), but just saves a complex data record. For this reason you can't save during fights in Mass Effect.

Sir_Brizz
11-11-2009, 11:01 PM
This limitation only really applies to saving the complex world state in a non-standard file format. It's easy to setup a checkpoint system with what is available in UDK and you could hack together a save file system, but it would be uglier than it should.

marcusmattingly
11-12-2009, 11:03 AM
I certainly appreciate all of the replies. Everyone has been very helpful. Basically what I am dealing with here is a limitation of UnrealScript. Licensees don't have a problem because they can work at a lower level than us hobbyists/indies because they have paid for the source code.

I will do some Googling on creating a checkpoint system and see if that will work for me. Although my initial thoughts are that a simple checkpoint system may not work for an RPG, even one as simple as I plan on making.

I wonder if they will ever extend UnlrealScript to add some basic file read/write capabilities? Seems like an important issue for Indie developers. I guess it was never an issue before because Unreal development for Indies was limited to mod development before the release of the free UDK. You basically don't need any save feature other than what UT3 provided when modding.

I would love to see the spread of UDK-developed Indie games. Unreal is such a slick engine and there are some very talented and creative Indie developers out there. I know the free UDK was probably primarily released for education and non-commercial purposes, but EPIC's licensing is so Indie-friendly now that I can foresee a lot of small commercial activity.

Thanks again everyone!

Marcus

LordAero
11-20-2009, 10:02 AM
@Marcus: Hi, i'm having the same issue, i camed to the forum looking for specific info and this thread proved most useful, i'm up to make a new version of an old game, and i would need two aspects to work, one was the save/load... the other is a quest sistem, and since you are making an RPG i suppose you have this solved... any pointers on where to look for info implementing it ?

marcusmattingly
11-20-2009, 10:55 AM
@LordAero:

I am still in the early stages of exploration on this so I haven't really specifically solved anything yet. I am obviously going to need a quest system as well so it sounds like we may end up tackling the same issues. I would be glad to stay in touch should I find a concrete solution for save/load, etc.

By the way, I am curious, what game are you remaking? I personally am looking to make a more modern take on the old Bard's Tale RPG games. I plan to have my own story, races, etc but I want to stick with the old-school gameplay to keep it as simple as possible.

I'm sorry I can't be of more help right now, but I am just getting going on this. Good luck!

Blade[UG]
11-20-2009, 12:43 PM
marcus: prior UT engines had saving functions. There are save functions in the UT3 game code, but it doesn't look like anyone has got around to implementing them in the engine (yet?)

marcusmattingly
11-20-2009, 01:22 PM
;26992013']marcus: prior UT engines had saving functions. There are save functions in the UT3 game code, but it doesn't look like anyone has got around to implementing them in the engine (yet?)

Really? Hmmm, I sure hope that is something they add to the UDK in the near future.

Thanks for the reply.

Blade[UG]
11-20-2009, 07:32 PM
There's at least a "quicksave" command that does something (doesn't appear to be anything useful), but the corresponding "quickload" does nothing. :D

Angel_Mapper
11-20-2009, 08:29 PM
Here's an example from the system I made for Prometheus, maybe you will find it helpful. And if you do, give me credit. :p

Level progress save system (spawned from my GameInfo class):


class SaveLoader extends Actor
Config(MyConfig);

const NUMSEGMENTSTRING = 4; // Number of different values for each segment.
const NUMRANDOM = 8; // Random values for filler.
const NUMSEGMENTS = 4; // Number of segments in the complete string.

// Struct for segments.
struct Segment
{
var array<string> SegmentString;
};
var array<Segment> LevelSegments, RandomSegments;

// Value that stores what level the player has reached.
var int LevelProgress;

// Obfuscated string holding the level progress and random filler.
// Change the name of this to something the player won't find suspicious.
var config string ObfuscatedString;

// When this actor is spawned, get the player's progress from the config file.
function PostBeginPlay()
{
local string CombinedSegments;
local array<string> SavedSegments;
local int i, j, k;

// Grab the entire string from the config file.
CombinedSegments = ObfuscatedString;

// Break the string into 3 letter segments.
while(Len(CombinedSegments) > 2)
{
SavedSegments[SavedSegments.length] = Left(CombinedSegments, 3);
CombinedSegments = Right(CombinedSegments, Len(CombinedSegments) - 3);
}

// Check each segment to see if it matches any of the level segments, if so, set level progress.
for(i=0; i<SavedSegments.length; i++)
{
for(j=0; j<LevelSegments.length; j++)
{
for(k=0; k<LevelSegments[j].SegmentString.length; k++)
{
if(SavedSegments[i] == LevelSegments[j].SegmentString[k])
LevelProgress = j;
}
}
}

// Each time the game is run, generate a new set of segments to further obfuscate the config value.
GenerateConfig();
}

function GenerateConfig()
{
local int i, k;
local string FinalString, Segments[NUMSEGMENTS];

// Fill each segment with values from the random filler array.
for(i=0; i<NUMSEGMENTS; i++)
Segments[i] = RandomSegments[Rand(NUMRANDOM)].SegmentString[Rand(NUMSEGMENTSTRING)];

// If there is any level progress, choose one of the segments to save one of the appropriate level segments to.
if(LevelProgress >= 0)
Segments[Rand(NUMSEGMENTS)] = LevelSegments[LevelProgress].SegmentString[Rand(NUMSEGMENTSTRING)];
else
Segments[Rand(NUMSEGMENTS)] = RandomSegments[Rand(NUMRANDOM)].SegmentString[Rand(NUMSEGMENTSTRING)];

// Combine all of the segments.
for(k=0; k<NUMSEGMENTS; k++)
FinalString = FinalString $ Segments[k];

// Save the combined string to the config file.
ObfuscatedString = FinalString;
SaveConfig();
}

function int GetLevelProgress()
{
return LevelProgress;
}

function SetLevelProgress(int NewLevelNum)
{
// Check if the level just finished is ahead of where the player was before to prevent writing lower values.
if(NewLevelNum > GetLevelProgress())
{
LevelProgress = NewLevelNum;
GenerateConfig();
}
}

defaultproperties
{
LevelProgress=-1

LevelSegments(0)=(SegmentString[0]="32f",SegmentString[1]="eb5",SegmentString[2]="05c",SegmentString[3]="304") // Level 1 complete
LevelSegments(1)=(SegmentString[0]="73d",SegmentString[1]="0ee",SegmentString[2]="64f",SegmentString[3]="0b3") // Level 2
LevelSegments(2)=(SegmentString[0]="3f5",SegmentString[1]="1d8",SegmentString[2]="8cf",SegmentString[3]="5a3") // Level 3
LevelSegments(3)=(SegmentString[0]="6f3",SegmentString[1]="893",SegmentString[2]="3a6",SegmentString[3]="80a") // Level 4
LevelSegments(4)=(SegmentString[0]="7a9",SegmentString[1]="85d",SegmentString[2]="7bc",SegmentString[3]="061") // Level 5
LevelSegments(5)=(SegmentString[0]="0a7",SegmentString[1]="34e",SegmentString[2]="6d7",SegmentString[3]="8e2") // Level 6
LevelSegments(6)=(SegmentString[0]="53d",SegmentString[1]="115",SegmentString[2]="c9b",SegmentString[3]="de5") // Level 7
LevelSegments(7)=(SegmentString[0]="ad4",SegmentString[1]="02b",SegmentString[2]="cae",SegmentString[3]="ef0") // Level 8
LevelSegments(8)=(SegmentString[0]="ec4",SegmentString[1]="c65",SegmentString[2]="ac9",SegmentString[3]="667") // Level 9

RandomSegments(0)=(SegmentString[0]="b99",SegmentString[1]="2b9",SegmentString[2]="d3d",SegmentString[3]="ff9")
RandomSegments(1)=(SegmentString[0]="145",SegmentString[1]="553",SegmentString[2]="4a3",SegmentString[3]="911")
RandomSegments(2)=(SegmentString[0]="177",SegmentString[1]="ba6",SegmentString[2]="9c7",SegmentString[3]="907")
RandomSegments(3)=(SegmentString[0]="83c",SegmentString[1]="b5e",SegmentString[2]="4d1",SegmentString[3]="073")
RandomSegments(4)=(SegmentString[0]="20f",SegmentString[1]="a77",SegmentString[2]="a9a",SegmentString[3]="42e")
RandomSegments(5)=(SegmentString[0]="ea5",SegmentString[1]="a5d",SegmentString[2]="cf5",SegmentString[3]="1c8")
RandomSegments(6)=(SegmentString[0]="121",SegmentString[1]="447",SegmentString[2]="fd4",SegmentString[3]="2fb")
RandomSegments(7)=(SegmentString[0]="b30",SegmentString[1]="a13",SegmentString[2]="792",SegmentString[3]="6c4")

bHidden=true
}

So, for example, say the player finished level 3. The script would choose a value from the level 3 array, like 8cf, and three random values from any of the random arrays, like 553, 4d1, and cf5. Then it would arrange these in a random order, say 4d1, 8cf, 553 and cf5, then combine the entire thing into 4d18cf553cf5 and save that to the config file. If anyone opened the config they would see this:


[MyProject.SaveLoader]
ObfuscatedString=4d18cf553cf5

When the game is started up, it breaks the string down into 3 letter segments, so back to 4d1, 8cf, 553 and cf5, then check these against all of the level values to find 8cf, and set LevelProgress to unlock the levels. It also changes the entire string every time the game is run.

It's not perfect, but it will keep most people from messing with it.

docmorbid
11-20-2009, 09:13 PM
Thanks for sharing, very helpful.

Are you guys planning to release docs and source for Prometheus like the Whizzle team did?

I wonder if something like that is planned for The Ball as well, interesting projects.

LordAero
11-21-2009, 06:44 PM
@angel_mapper: Thanks a lot for sharing that info !
@marcus, it's a pirates game, there is not a single cool one, i like akella's saga for the basics, then is the graphics wich are way too old (dx8 shaders)

horstdraper
11-24-2009, 09:39 PM
Hey check this out: http://udn.epicgames.com/Three/SaveGames.html

The doc mentions some interesting functions.
In particular couple serialization functions: CopyCompleteValue, SerializeItem
It also mentions couple functions in UWorld, SavePackage and LoadPackage, that can save out entire level, but what is UWorld? I can't find it...

Blade[UG]
11-25-2009, 01:14 AM
I'm guessing that is the reference to the game world from the engine source, pretty sure that is not something that we have access to.

Chris2009
11-25-2009, 01:50 AM
Hey check this out: http://udn.epicgames.com/Three/SaveGames.html

The doc mentions some interesting functions.
In particular couple serialization functions: CopyCompleteValue, SerializeItem
It also mentions couple functions in UWorld, SavePackage and LoadPackage, that can save out entire level, but what is UWorld? I can't find it...

This document is in the UDK documentation section. So is it relevant tot he UDK or not?

It talks about saving and loading packages with level data in them.

Is it possible to use this in the UDK?

guineapig
11-25-2009, 06:32 AM
Isnt the ini-method alright? I mean for instance in a single player fps you store all actors' positions, ammo, health, pick-ups and mission progress. Seems doable. So I am wondering if I miss any technical limitations here?

immortius
11-25-2009, 09:21 AM
I know in UT2004 people had issues with the ini baulking at overly complex structures. There might be some array and string length issues as well. But it is probably doable with a bit of work.

horstdraper
11-25-2009, 09:58 AM
Uh, that's why i guess some pages were blocked, so that we don't drool over features we can't use :)

There is one ini-method limitation. Each class can have only one config instance and therefore one saved state, isn't that right? Then how are you going to handle multiple save files and different user profiles? Even a simple checkpoint system can't be implemented because there's no way to have more than one.

So that explains why TcpLink-method is so popular, it doesn't have those limitations, write anywhere you want, how you want, load whatever you want :).

(EDIT: sry, i'm wrong.. again. You can save stuff into ini per object too(not just per class))

marcusmattingly
11-25-2009, 11:02 AM
In my situation (a simple RPG) the ini method just doesn't seem to fit very well. Not only do I want to save the party information, quest progress, etc but I also want to have files I read in for data relating to monsters, items, dialog, etc.

I guess I can try the TCPLink method but I hate to communicate with an external program for something like this. It's looking like I won't have much choice though. I've done a lot of forum reading and Googling and I keep coming up with the same answers.

I still love the UDK and think its release is great for gaming as a whole, but this little issue seems to limit what you can do in my opinion. Maybe Epic will rectify it by adding some new UnrealScript functionality at some point.

guineapig
11-25-2009, 12:00 PM
Couldnt this limit be solved by making kind of a save-crawler-class? Once you press save it collects all necessary data and move it in a single file?

What I read about the TCPlink method you need something running (a server?) in the background. In an end-user perspective this looks rather suspicious :(

marcusmattingly
11-25-2009, 12:08 PM
@guineapig
I'm not sure how the save-crawler-class you are referring to would work. Are you talking about writing to config files? My understanding of the TCPLink method is you do need an external program running on the same PC (written in C++, C#, or whatever). It is basically a launcher program that listens on a port and recieves data from your game. This program would write it to disk. Yes, I have concerns about this method. For one you need to make sure that if they try to close that app, it warns them and closes the game as well or else essentially it breaks your game.

elmuerte
11-25-2009, 04:36 PM
(EDIT: sry, i'm wrong.. again. You can save stuff into ini per object too(not just per class))
Yes, I got tired posting this link every time: http://wiki.beyondunreal.com/Legacy:PerObjectConfig


In my situation (a simple RPG) the ini method just doesn't seem to fit very well. Not only do I want to save the party information, quest progress, etc but I also want to have files I read in for data relating to monsters, items, dialog, etc.
Why not? I don't see a reason why this can't be achieved with the existing config system.

n321
11-25-2009, 05:48 PM
elmuerte:

could you please give an example of how saving to an ini could be possible with and RPG type of game. since UDK was released I have been prototyping somthing similar to Mass Effect (but smaller). I have procrastinated on the save / load system due to the fact that I cant figure out how to save xp, skills, items, equipt items, dialogue progress, quest progress, event progress, ect.

I thought about doing it in multiple ini files but I just cant fathom what the script could even look like to do this. I have even considered using my media and some prototypes and moving to more of a prince of persia style adventure game as itd be easier to get a save system working. I dont want to do this as itd be a waste of work.

anyways maybe a simple description of how you are thinking it could work?

roychr
11-26-2009, 02:53 AM
Now do not throw me rocks but lots of games are starting to have internet connection requisite. If you want to sell your game on steam, to name only that one, it does make sense to simply save content on a server via https. Think about it, only people with valid account on your server or steam could save while playing. To me its a plus, because it discourages piracy. Now the hard part is make encryption within Unrealscript if the facilities do not exist, but from what I see, you could probably port any encryption lib to UnrealScript, the downside maybe only speed. So to me SolidSnake has a very good approach, I cross my fingers that UDK does secure http transfer. If it does not please Epic include it for people that do want to do business with UDK.

An thanks for this thread we should put info on how to access disk anyhow, at some point some of us will need to load xml or other proprietary data.

elmuerte
11-26-2009, 09:45 AM
elmuerte:
anyways maybe a simple description of how you are thinking it could work?

I might write a short tutorial on the UDN on how to abuse the config system tonight/this week.



Now do not throw me rocks but lots of games are starting to have internet connection requisite. If you want to sell your game on steam, to name only that one, it does make sense to simply save content on a server via https. Think about it, only people with valid account on your server or steam could save while playing. To me its a plus, because it discourages piracy. Now the hard part is make encryption within Unrealscript if the facilities do not exist, but from what I see, you could probably port any encryption lib to UnrealScript, the downside maybe only speed. So to me SolidSnake has a very good approach, I cross my fingers that UDK does secure http transfer. If it does not please Epic include it for people that do want to do business with UDK.

An thanks for this thread we should put info on how to access disk anyhow, at some point some of us will need to load xml or other proprietary data.

A few years ago I did implement the RSA algorithm in UnrealScript. But it's powers are very limited due to 32bit integers. If you can implement a BigInt type for UnrealScript you can improve the algorithm to feature better encryption (better than 23bit at least). You can see the implementation here: http://wiki.beyondunreal.com/Legacy:RSA

On an related not: I'm finishing up a generic library for the UDK which provides a full featured HTTP client. Not sure under what terms I will make it available.

LordAero
11-26-2009, 09:56 AM
@elmuerte: Seems to me you know a whole deal about Unreal and scripting... i would be nice to se a tut from you...
In advance i would like to ask, if you actually write it, please make it beginner friendly ! (more learning, less asking)

elmuerte
11-28-2009, 11:56 AM
I might write a short tutorial on the UDN on how to abuse the config system tonight/this week.
It took me about 2 hours to write an example showing off how you can use the configuration system to create a save system for an RPG like game.
It'll take me a while to write a document for it.

elmuerte
11-28-2009, 01:13 PM
Ok, wrapped up the whole example and document. It will be available here (shortly): http://udn.epicgames.com/Three/ConfigSavegameSystem

marcusmattingly
11-28-2009, 01:17 PM
@elmuerte

Wow, thanks so much! I will certainly take a look at it.

Marcus

Vald
11-28-2009, 01:23 PM
@elmuerte

Thanks tons mate!

JasonG
11-28-2009, 02:07 PM
I agree that TCP link is probably hacky for just save/load game. However, RPGs require more data persistence than other types of games. If I were going to persist data using UDK i would probably use a lightweight, in memory database like SQLLite. In that case using TCPLink would not be unreasonable. In fact, while working on an MMO in Torque3D we used the HTTP object in Torque script to make calls to a SQL Server database and it worked great.

elmuerte
11-29-2009, 06:58 AM
Ok, it appears that the public version of the page has finally been created: http://udn.epicgames.com/Three/ConfigSavegameSystem.html

bez
11-29-2009, 10:07 AM
Good job elmuerte
very nice document and example I totally appreciate the time you've put into this
Thanks for sharing

Vald
11-29-2009, 10:11 AM
Ok, it appears that the public version of the page has finally been created: http://udn.epicgames.com/Three/ConfigSavegameSystem.html

That's really awesome man thnx

What about saving Quests?

marcusmattingly
11-29-2009, 10:58 AM
A top notch contribution to the UDK community. Thank you so much for all of the time and effort you put in to creating this. I see no reason why I shouldn't be able to adapt this to anything I need to do in my game.

I also like the clever name. :)

elmuerte
11-29-2009, 12:30 PM
What about saving Quests?
You should be able to figure that out after going through the example. It would be pretty much the same as the inventory+item system was set up.

bez
11-29-2009, 04:41 PM
Last year I written a save/load using INI but it seemed impossible to maintain and buggy the more I added to the game. Your example has given me a new outlook on how it should be done Thanks elmuerte

A couple of questions you may be able to answer

1. When saving the whole level to and INI

..........example................
Player, pos, rot, vel ,inv ,health, state, weap in hand, and What Ever Else Needed
Enemy, pos, rot, vel, weapon, health, and What Ever Else
Floor items, pos, rot, vel, attributes N that
Plus what ever else the game has in its world.

Would an INI file be able to hold all this ever growing data ?

2. How would one go about having multiple savegame INIs as the config name is not changeable in runtime. What would be the best approach for multiple savegame slots. I know one could back up there INIs but I would like to avoid something like that.

Thx

elmuerte
11-29-2009, 06:10 PM
1. I don't know. That's something you'll have to benchmark.

2. You can have multiple slots. It's just all saved to a single file. In the sapitu example, just image every character is a single slot.

bez
11-29-2009, 08:37 PM
thx for reply elmurte

I just came across this http://udn.epicgames.com/Three/SaveGames.html

It points out the possible ways too save. The part about Save Anywhere and being able too dump the whole level is what interests me. Is this just for licences users or is this possible to pull off with the udk ?


Document Summary: This document will cover the save game system used in Gears of War
as well as dicusss other options that are possible in your own game.



Save anywhere

Being able to save anywhere is a relatively popular solution for PC games (which have the benefit of almost limitless storage). Here are several methods that could be used:

SavePackage:

In Unreal 1, when the game was saved, the current level was saved out, basically as if if the editor saved the level. This method creates an exact copy of every actor, and even the level geometry, basically creating a new map file. To load the savegame, Unreal just opened the savegame file, like any other map.

Naturally, in the day of much larger level data, especially on console with limited storage space, this is not ideal. However, a similar method could be applied with special handling in the save package to not save any non-dynamic-actors (other than Kismet). So, if you call SavePackage on the UWorld object with a code that knows to skip over static things, much less data will be saved out.

Then, when it is time to load the savegame, unload/reload the level (or destroy everything tht is dynamic), and call LoadPackage on the savegame file. If there are actors in the savegame that have the same name as loaded dynamic actors, they will be recreated in place, with the values specified in the savegame file.

immortius
11-29-2009, 09:24 PM
I believe that article is mostly discussing techniques that licensees can use. SavePackage doesn't exist in UDK.

bez
11-29-2009, 09:32 PM
I don't know why its under UDK Technical & Programming Home if its not possible. It got my hopes up for a second.

elmuerte
11-30-2009, 02:49 AM
It's available because it contains some information on how you could perform savegames

Blade[UG]
11-30-2009, 07:07 AM
bez: Because aside from that point, it talks about things that you can do. And we also discussed that page in this thread, and the ways of doing things that make more sense now. You can very likely save everything that you will need to re-create a state to a reasonable, or desired, degree, probably without saving the ENTIRE state of the game. elmuerte isn't going to design and write whatever it is you need to do, so you'll need to perhaps use his as a base, and design your own.

bez
11-30-2009, 02:56 PM
I have come across a problem and hope someone can help
I pick up and item now I have the Item in my inventory and save to INI, alls good and loads back as expected.
Now I drop the Item and have an empty inventory and save again all seems good game wise. But the fact is it isn't removed from the INI so it appear back in the inventory next time loaded. How is it possible to reflect the games changes in the INI file with no way to clearconfig ?
It seem you would just have an ever growing inventory list.
Any advice appreciated.

TheSpaceMan
11-30-2009, 03:05 PM
Wasn't there a reference in the config rules on how to remove items as well.

Kyben
11-30-2009, 03:10 PM
I have come across a problem and hope someone can help
I pick up and item now I have the Item in my inventory and save to INI, alls good and loads back as expected.
Now I drop the Item and have an empty inventory and save again all seems good game wise. But the fact is it isn't removed from the INI so it appear back in the inventory next time loaded. How is it possible to reflect the games changes in the INI file with no way to clearconfig ?
It seem you would just have an ever growing inventory list.
Any advice appreciated.

I've been having to do something like this:


//Clear ini.
SavedNPCs.Remove(0, SavedNPCs.Length);
SavedNPCStatus.Remove(0, SavedNPCStatus.Length);
SavedInitialNPCs.Remove(0, SavedInitialNPCs.Length);
SaveConfig();

//Save stuff
//*Vars that you want to save go here.*
SaveConfig();

Theres also the function ClearConfig(), but that didnt seem to want to work for some reason.

elmuerte
11-30-2009, 04:03 PM
ClearConfig() isn't available in the current UDK, I hope they bring it back in the near future, because that's the only way to clean up the ini file/actually delete saved objects.

Blade[UG]
12-02-2009, 10:50 AM
Interestingly, I have a config class that I've been messing with, that does not load it's config when it's spawned, and does save it's config, but saves a new copy of each of it's variables every tiem, so the file just gets bigger and bigger...

horstdraper
12-02-2009, 10:44 PM
@elmuerte, thank you for your example, it helps great deal, i would never come up with something like that!

@bez, I tried adding a drop item function to sapitu example and it worked as expected. You just need to remove item from inventory arrays and call saveChar. Even though inventory does accumulate in INI file, it doesn't appear in character inventory, because it's no longer listed in array. You just gonna need to figure out what items you no longer need and remove them from ini one by one(which i don't know how...), but normally items rarely removed from game world they just move from one container to another. Maybe in more advanced save system you would write something like garbage collector that removes unreferenced items from save file.

@Kyben, so you save your data as plain strings? That's a lot of work... I hope ClearConfig is soming back.. :)

Also i think SapituCharacter.removeItem function from example has a little bug:

if (i != INDEX_NONE) return false;
it should be ==, or it will return if character has the item to be removed.

One question. UTUIDataStore_MenuItems, that save system relies on, sounds like something UT specific. So since this GetAllResourceDataProviders function is declared as native is it possible to move this declaration to some other class and use it from there? It would make sense for stripped version of UDK where all of UT classes have been removed.

elmuerte
12-03-2009, 02:43 AM
Also i think SapituCharacter.removeItem function from example has a little bug:

if (i != INDEX_NONE) return false;
it should be ==, or it will return if character has the item to be removed.

Oops, copy-past error. Good catch.


One question. UTUIDataStore_MenuItems, that save system relies on, sounds like something UT specific. So since this GetAllResourceDataProviders function is declared as native is it possible to move this declaration to some other class and use it from there? It would make sense for stripped version of UDK where all of UT classes have been removed.

No, you cannot simply move native functions to other classes and still have it work. I don't know if you can do the same thing using a non-UT datastore class.
Anyway, you are allowed to use the UTGame code in any UDK application. Its only the art content that you cannot use in commercial products.

bez
12-03-2009, 12:56 PM
Also i think SapituCharacter.removeItem function from example has a little bug:

if (i != INDEX_NONE) return false;
it should be ==, or it will return if character has the item to be removed.


Nice one I didnt see that but yeah your correct it now remove from the array in INI. nice one m8

giggles
12-03-2009, 09:19 PM
This should help

http://udn.epicgames.com/Three/ConfigSavegameSystem.html

elmuerte
12-04-2009, 06:45 PM
yes, that's the document I wrote and posted earlier in this thread

danielmd
12-04-2009, 09:10 PM
Great piece of info. Isn't there a way to do a string compare or key value compare and overwrite certain values so that the INI files don't get fat?

Really going to have to think about a way to abstract and create a generic framework using the INI files...

Just thinking out loud:
"Rush" a character of warrior class, can hold a 15 item inventory. Needs to save position, quest, good/evil decision log, etc...
The problem seems to be that if i add items i can't later remove them. So the only way to handle this in a slightly efficient way is to create a pre defined number of items or create a null inventory, or a Null item... if it goes into null it can be deleted from INI... the only way to delete it is to save the null class with null values at x time or end of quest, etc... So it looks like a reusable NULL item could be the solution, it would act like a pointer and i only need one instance of it.

In conclusion: If there is a number one wish list for next beta of UDK is to have save load (Persistence Layer) exposed in unrealScript :)

punk129|alive
12-04-2009, 09:12 PM
didn't read through the thread for now, but maybe this could be handy:

http://udn.epicgames.com/Three/DLLBind.html

danielmd
12-04-2009, 09:40 PM
didn't read through the thread for now, but maybe this could be handy:

http://udn.epicgames.com/Three/DLLBind.html

Haha :eek: :cool:

immortius
12-04-2009, 09:53 PM
didn't read through the thread for now, but maybe this could be handy:

http://udn.epicgames.com/Three/DLLBind.html

Best piece of news all week. :)

elmuerte
12-05-2009, 06:10 AM
Great piece of info. Isn't there a way to do a string compare or key value compare and overwrite certain values so that the INI files don't get fat?

Of course you can. I just took the easy way out in the example and decided not to reuse object names. But it's quite trivial to write an "name pool" that keeps a record of "free" object names. You just need to implement a reset method that resets the object to it's "clean" state when you reuse the object/name,

elmuerte
12-05-2009, 06:17 AM
didn't read through the thread for now, but maybe this could be handy:

http://udn.epicgames.com/Three/DLLBind.html

Great, that'll give people a completely new route to crash the engine even worse than it sometimes does. Anyway, it's a nice addition which will be abused a lot by people so they can avoid unrealscript.

Of course that functionality doesn't give you access to the UnrealEngine object system, just primitive access. Which is good enough to use most 3rd party support libraries.

immortius
12-05-2009, 07:59 AM
Great, that'll give people a completely new route to crash the engine even worse than it sometimes does.

At least it is better than everyone using TCPLink for everything.:rolleyes:

eAlex79
12-05-2009, 12:22 PM
This makes the engine plain perfect. :D Really good move, thx to the guys at Epic!

TheSpaceMan
12-06-2009, 08:33 AM
As with anything, a dll access must be handled with care. But it will open up so many more possibilities. Possiblie to implement systems as you need, as long as you can return it as the necessary values. since we only had int, string and float right?

Damn this would make it possiblie to make xmlparsers etc as well. Nice.

immortius
12-06-2009, 09:03 AM
Possiblie to implement systems as you need, as long as you can return it as the necessary values. since we only had int, string and float right?

There are bytes and a few array types too. You can bring across any data in a byte array, just a matter of converting it to what you need afterwards.

elmuerte
12-06-2009, 11:10 AM
Damn this would make it possiblie to make xmlparsers etc as well. Nice.
Barely. Forget about doing anything similar to DOM, SAX or StAX using this functionality. It can make certain slow string operation faster, but you still have to write the parser unrealscript side. Actually, I already have a XML parser using the SAX method written in pure unrealscript.

TheSpaceMan
12-06-2009, 11:15 AM
Barely. Forget about doing anything similar to DOM, SAX or StAX using this functionality. It can make certain slow string operation faster, but you still have to write the parser unrealscript side. Actually, I already have a XML parser using the SAX method written in pure unrealscript.

Why can't you implement the parser on the dll side?
What you essentialy want back is the things you query for, well atleast me, it seems like the parsing should be the slow part.

Edit:
Ah you are talking about streaming stuff realtime I would probably stuff the entire thing in to memory, and write function to retrive what i need in a different way.

joeharner
02-18-2010, 09:29 AM
I'm rather new to UDK myself, but after looking around, I found this link.

http://udn.epicgames.com/Three/ConfigSavegameSystem.html

It should (if you can figure out how to use it) allow you to set up a save game system. Like I said, me and my team are n00bs, so I can't help you out further than this link just yet. Once my people get a bit further into UDk maybe I can help out more, but for now, we seem to be more clueless than you.

Anyways, I hope the link helps.

Chaosnet
03-28-2010, 11:27 PM
The sapitu system just crashes for me on UDK march release. When I use "loadChar elmuerte" in console, udk just crashes and same problem for also createrandomitem. What can be the cause of this problem.

kopik
04-10-2010, 04:36 PM
The sapitu system just crashes for me on UDK march release. When I use "loadChar elmuerte" in console, udk just crashes and same problem for also createrandomitem. What can be the cause of this problem.

Probably the change in tree classes. I changed one line in Sapitu.uc and work fine. Sapitu.uc -> loadItemDB() Here change line to:
local array<UDKUIResourceDataProvider> ProviderList;

Gmax5
07-23-2010, 02:50 PM
Quicksave/load were removed

don't they have the quicksave/load function in the UT3 Code?

Ayalaskin
07-23-2010, 08:26 PM
Hey check this out: http://udn.epicgames.com/Three/SaveGames.html

The doc mentions some interesting functions.
In particular couple serialization functions: CopyCompleteValue, SerializeItem
It also mentions couple functions in UWorld, SavePackage and LoadPackage, that can save out entire level, but what is UWorld? I can't find it...

There is still that functions? I mean SerializeItem, or something like the fwrite from c++?

Blade[UG]
07-24-2010, 05:10 AM
Those are native functions, you can't really get to that. quicksave/quickload didn't really work/do anything .

elmuerte
07-24-2010, 05:22 AM
UE3 never had world serialization (this is what used to be saving in the UnrealEngine). UE2 had a partial working world serialization.

The game world has become to complex to simply serialize within decent time. So, to save a game progress you will pretty much always need to write your specialized save game system for your game. Most games don't to much than save inventory, location, completed tasks. But quite often large parts of the world state are not saved. It's simply too much data.

Ayalaskin
07-24-2010, 05:10 PM
But there is no other kind of serialization? Something near java?
Something like: class Lalalal extends UTSerializable.
So I can make a data class and save it.

Blade[UG]
07-24-2010, 10:36 PM
that's what the config options do, allow you to save class data to an INI file.

KConny
08-18-2010, 10:37 AM
I have come across a problem and hope someone can help
I pick up and item now I have the Item in my inventory and save to INI, alls good and loads back as expected.
Now I drop the Item and have an empty inventory and save again all seems good game wise. But the fact is it isn't removed from the INI so it appear back in the inventory next time loaded. How is it possible to reflect the games changes in the INI file with no way to clearconfig ?
It seem you would just have an ever growing inventory list.
Any advice appreciated.

I solved this by making an Item struct and an array of these wich the character holds. This way when you save by overwriting the old character the entries in the ini will be replaced. So there is no longer need for the records.


ClearConfig() isn't available in the current UDK, I hope they bring it back in the near future, because that's the only way to clean up the ini file/actually delete saved objects.

Clean up is possible in the sense that you can replace an old object with a new one with empty arrays and such. That was enough in my case.
Also, thanks for sapitu. :)

McTavish
08-18-2010, 09:33 PM
Nice to have a launcher app to handle other things too such as settings so that players can get things right for their machine before entering the game.