Is it safe to store Hard Class reference variables in Save Game Object?

And is it safe to retrieve later? Any info welcome, thanks.

Safe-ish. Ultimately you’ll be saving the class path as a string (even though your property is likely a TSoftClassPtr). I don’t know that raw UClass*/TObjectPtr<UClass> will save in a useful way.

You’ll still have to deal with the class no longer existing or, in the case of blueprints, making sure the class is loaded before you use it. For renames, redirectors and core redirects can help make this safer. But deletions or old saves that rely on redirects that are no longer available (either because they’ve been deleted, fixed up or you’re trying to load a save in cooked where redirectors don’t exist) is something to keep in mind.

2 Likes

So it’s safer to use soft class rather than straight raw class? And I should design my save system around that?

I’m only using blueprints btw.

Definitely safer to use soft classes in your save game. I wouldn’t be surprised if direct references didn’t work, though a) I’ve only done saves from C++ and b) I don’t use Epic’s save game object. But something could be different for blueprint, though usually the thing that the savegame uses to write to disk doesn’t work with direct references.

1 Like

What do you mean by that?

i believe he means you cant save object pointers. A Class is usually ok, if you changed/modify/move things saves are likely to be invalid but that shouldnt happen after ‘release’

1 Like

I’m confused. So should I store hard class/object references in the save game?

Sorry I probably should have used the term hard reference instead of direct, to contrast with soft.

In blueprint there’s really only the Object/Class Reference or Soft Object/Class Reference variable types, but in C++ there are a few varieties that make things annoying to discuss.

So in your save game you’d want to avoid Object and Class References and only use the Soft versions. It’s possible in blueprint a Class Reference would work, but I don’t think so and it’s worth managing that yourself anyway.

1 Like

i can confirm Class Reference do work but that doesnt make it a good idea so i agree on your point

2 Likes

Your save files will eventually break, specially if you’re renaming classes and objects. I would avoid serializing any kind of reference as much as possible if you’re able to.

2 Likes

Do you mean Soft Class Reference too? I need to save references to some classes. You know, actors to be spawned at runtime.

1 Like

I would say, don’t save any sort of class. Just save an int, and your code use that int as an index into an array of soft classes.

The problem with saving class information, is you can end up creating an asset chain running right through your save game. In other words, any time your refer to your save game ( like casting ), the system will load all classes in the save game. It can also lead to inexplicable crashes. I had that. It took about 6 weeks to find…

If you’re not sure, look at your save game in the reference viewer.

1 Like

interesting i’ve not seen these issues, i wonder if you could use the asset registry ID?

or just serialize it to a Byte Array which is what im currently doing

1 Like

It does get serialized anyway. But that doesn’t seem to help :rofl:

yeah wont help if its invalid but will mean the class ref isn’t stored on the SaveGameObject. (I have all Class serialize themselves) so the SaveGame just has an ID/ByteArray

1 Like

Right, but if your save game ‘apparently’ holds these classes, it will still act as a conduit.

In other words, if you cast to it and pull out a thing of type X, then an X will be loaded along with any reference to the savegame.

agreed but i mean i dont hold classes, ie hold a struct with say GUID/ByteArray. Im sure it cant get the class from the ByteArray :wink:

1 Like

Wow, not even Soft Class References? What are they even for then? Should be just a path, right? It’s up to you to do the actual loading of the class, right?

While I don’t think this is a terrible idea, I also don’t think it’s really practical. How does that array get populated? Manually? Automatically? There are struggles with both. There’s a reason that even FNames (which are just ints under the hood) are serialized as strings and not those indices. Because maintaining the stability of indicies can be much more complicated than is worth the effort.

The cast case is completely untrue. We’re talking about soft references so they wouldn’t be loaded anyway. But even in the case of hard references, casts only care about what the ClassDefaultObject is referencing and in the case of a save game, the CDO shouldn’t have any references to anything.

Now, when you load your save, yes you might have to load a bunch of classes but you probably need to do that anyway to restore the state of your game. Hard references (if they worked) might make this easier, but soft references are still probably better since they allow you to control that timing better. Like, you load the save at the main menu but you want to load any class references during the loading screen into your game or (even better) you can guarantee any types would already be loaded by the time you finish loading into the level.

@AllGamesSuck Don’t worry about it, saving soft class references is the expected thing to do as long as you properly handle the fact that they’re soft. I don’t know what ClockworkOcean was doing to cause crashes with their saves, but it’s a perfectly safe thing to do in general.

1 Like

Thanks. Up until now I was actually using hard class references into the save game. I had no issues. But I guess it’s safer to change it to soft then.

1 Like