#about GUIDs

1 messages · Page 1 of 1 (latest)

mellow fractal
#

@rain gate I'm going to create a thread here so I can reference back to it if needs be

rain gate
#

That works too 🙂

mellow fractal
#

reposting your last message so I can remember it

"The implementation of it can be on "Begin Play" of that actor, you read the Map from the save game object and if it finds the GUID in the Map, then it manipulates itself based on the data in the map for that particular GUID. If there is no data present, then that item can behave as it was just placed in the level. You would likely need some way to indicate whether or not the actor should be destroyed in this case, so that the actor can remove itself from the level if it was destroyed at runtime.

Saving then is just adding a value to the Map with the desired data.

Dynamic items spawned at runtime would need their own map which would need to contain data about each of the objects, like what their class is that should be spawned, their location, and any other properties - you'd probably want a custom structure. You'd use begin play of say your game mode or game state to then read this separate map, loop through the keys, spawn the objects assigning their GUID to them based on the map key, and then reading their value from the value of the Map and applying it to the actor that was spawned. Upon destroying one of these dynamic actors, you would want to remove the GUID from the Map in your save game so that it would no longer be loaded."

#

@rain gate so where would I assign the GUID? Is that on beginplay too?

rain gate
#

Depends on the object.
You probably want one to be assigned in the construction script if there isn't one already assigned to the object (i posted this screenshot before) - this ensures placed actors are uniquely identified.

You probably also want to have an exposed variable that can assign it so whenever you spawn an actor you can feed it a GUID. This then handles assignment of a GUID for any dynamically spawned actors.

mellow fractal
#

I see, something I got before when I implemented this is, I had 4 copies of an ORB object and 2 copies of a SWORD object on the map, only one of each of those generated an actual GUID when the level loaded

rain gate
#

Case 1:
Placed Actor - GUID is assigned when it gets placed automatically VIA construction script.

Case 2:
Dynamically Spawned Actor (existing for the first time) - Spawns Actor with the GUID variable field left blank on the spawn node.

Case 3:
Dynamically Spawned Actor (loading from save) - Spawns Actor with the GUID variable fed in through the spawn node.

mellow fractal
#

the SWORD and ORB each are child actors of a test item, that test item had the code on its construction script and it would add them to the map

I then had a keys node come out of the map, did a for each loop, and on a key press I had set up it would read out every GUID on the list... and despite there being 6 items on the map, it only printed 2

rain gate
#

Can't comment on child actors. I've never used them.

mellow fractal
#

@rain gate so, it's not generating GUIDs at all... I have all of this set up on the construction script of the items and when I launch the game none of these print strings are coming up

rain gate
#

Not sure if the print string can work in construction script.

What is important is that the GUID is being assigned a value only if no valid GUID exists.
First image: Item has a GUID variable exposed.
Second Image: Code showing a GUID being set on the actor. HOWEVER, if you set it up like this, then whenever you change the object a new GUID is generated (so like, moving it arond the scene).
Third & Fourth: Showing the GUID is different in this circumstance just because I moved it.
Fifth & Sixth: Showing what happens if you check if the GUID is valid first before assigning a GUID and moving it.

mellow fractal
#

ok so, I'm running into a problem I ran into before...

#

@rain gate all the copies of the same item in the level are sharing the same GUID, they aren't generating new ones

rain gate
mellow fractal
#

like is there a way to automate it?

rain gate
#

Automating it would require you have some means of knowing whether a GUID is in use already and regenerating if so.

#

Otherwise you'd have to click this back arrow thing and it'll "reset to default value" which would trigger the construction script part again.

#

If you weren't stuck using blueprints, you could definitely have something set up in C++ to automatically reset when an object is duplicated.

mellow fractal
#

there is one way I can sorta automate it in BP

#

have all the items in a folder in the map editor, right click the folder, select all children then click the reset to default next to GUID, it scrambles it for all selected items

#

it's just something I'd need to remember to do after editing a level

rain gate
#

Sure.... But I think that would only work if they're all the same object type. And you may not necessarily want to do that later on in development as you could end up ruining people's saves as the GUIDs aren't what they were in the past.

#

You basically only want to have a GUID on any particular actor modified once.

mellow fractal
#

thing is... my project has C++ enabled because I needed it to get rid of that annoying "tab cycles between ui elements" shit UE5 has in by default.. so I can add C++... as long as it doesn't fuck up my existing blueprints and you'd be willing to give me the code I'd be fine just plugging it in there

#

just as long as I don't have to code it myself I'm good XD

#

like I'm not averse to the idea of having some C++ in my game, I'm likely gonna need it, but I want to keep it to a minimum so if something breaks, I can have a much easier time figuring out what's wrong instead of scrambling to figure out code I know nothing about.

rain gate
#

You'd basically have to override the PostEditDuplicate() function in the actor classes that you want to have a GUID, which means you'd need to have C++ base classes for any actor classes you'd intend to use and then reparent your blueprints to use them. It's more work than I'm willing to provide.

mellow fractal
#

ok. I'd just have to remember which are the new items then and scramble the GUIDs.

#

so that brings me to my next question, now we have the GUIDs working and a method of storing them, the whole thing of finding the item's GUID and deleting it if it's not on the list happens in an item's beginplay right?

rain gate
#

For placed items, yes.

mellow fractal
#

how would I separate out what are placed items from what are spawned during runtime?

rain gate
#

You can have a bool set on the actor for when it is dynamically spawned. Set true only when you use "Spawn Actor from Class"

mellow fractal
#

also the other major question here is, what about inventories and stuff because sure this establishes what actors should exist and to an extent you can determine where, but what about containers and their contents? Would I still use my struct for that?

rain gate
# mellow fractal also the other major question here is, what about inventories and stuff because ...

A Map acts as a container. It can hold the identifier and the values for that identifier.
Not all actors will have the same storage requirements, so a single structure likely isn't going to handle everything you may possibly want to save.

So as long as you can identify something with a GUID, you could potentially make a separate container with a structure that contains the values it needs.

So an inventory, yes, could hvae its own GUID assigned to it, but you wouldn't look up that GUID in your "Spawned Actor Map" you'd store it in a separate map "Inventories". The structure of the data could contain an array of structures that then have details about each of the items within that inventory.

mellow fractal
#

so would that be instead of it being a GUID to BOOL map it would be a GUID to Struct Array Map?

rain gate
#

Something like that, yea

#

GUID > Data about that GUID basically.

mellow fractal
#

can you assign GUIDs to components?

rain gate
#

And then you have different Maps with different Data for the GUIDs it holds.

rain gate
mellow fractal
#

so in this case, where am I putting the destroy actor node?

#

I have the list of actors in the level, I've pulled the spawned actors list from the save file

#

would it be if either of them are false? because surely if it's an item that's found and it's on the list then it's part of the level right?

#

because the idea is this is the list of items in the level, the GUID is removed from the list when the item is destroyed, so if either are false then the item should be destroyed because it's not on the list... or am I getting this really wrong

rain gate
mellow fractal
rain gate
#

Ok, I wouldn't call that container "Spawned Actors" then, these are "Placed Actors".
In this case the Destroy Actor node should be on the last true.
1st True: You found the GUID in the list.
2nd True: The bool is set for it to be deleted.

#

If either one of those are false, you don't want to delete it.

#

When you pick up the item, you are:
Adding the GUID to the Map
Marking the bool within the Map to true, denoting you want it deleted.
Destroying the Item

So then when you are Beginning Play on that actor:
You're looking to see if the GUID is there.
If it is, checking if it should be destroyed.
If it should, you're destroying it.

This gives you the continuity as you've saved the state of whether or not the item should be destroyed.

mellow fractal
#

thanks

#

I'm just trying to find where the hell I put the code to destroy the item on pickup so I can add some extra to say "also remove its GUID from the save data list"

rain gate
#

Why would you want to remove its GUID from the save data list at that point?

mellow fractal
#

would you just set its bool to true to set it as a picked up item?

rain gate
#

Yes

#

You add it to the list only if its being changed.

mellow fractal
#

how do you change the bool on a specific GUID entry?

rain gate
#

You re-add the GUID to the Map with its new data.

#

First exists (in editor): GUID is created.
Begin Play Starts: it can't find its GUID in the map, so you program to act as-is, no further changes.
Some time later (even several play sessions later): You finally pick that item up. It adds itself to the Map, marking that it was picked up. You destroy the object.
Next Time the Begin Play Starts (could be several play sessions later): It finds its GUID in the map, it sees that it is marked as picked up. It destroys itself.

mellow fractal
#

@rain gate actually sorry to bother you so soon, when spawning an item, whe's the best time to set dynamically spawned? like what would be the load order here?
Will any code executed on the spawned actor from its return value node activate prior to beginplay occuring?

rain gate
mellow fractal
#

I think I got a solution, from the item data item class I cast to the parent class that all the other items come from which then gives me the proper node on spawn actor, I tested it out and items I dropped did have the check box

rain gate
mellow fractal
#

@rain gate so, ran into another head scratcher. How do you assign a GUID to a player character? They get spawned in every time you run the level which means every time you play you get a new GUID

rain gate
mellow fractal
rain gate
#

You don't store it as a GUID either.

mellow fractal
#

so, where do the container inventories get saved?

#

also this whole thing is becoming such a mess... please tell me this save system is the hardest part of making an RPG

#

like this is just the item code for saving and loading..

#

granted I went.. probably further than I should have done and implemented a system where it saves the position of each item during a save event and loads them again when you load.. so you can throw an item across the room, save, exit, reload, and it's still there

rain gate
#

If you want to use a common component for storing inventories, you can absolutely have the player's inventory done in such a way too, but then you have to figure out when it is best to give it a GUID but I don't think it really makes sense to as your player character is a unique entity, as is your player's inventory, and this system is designed to save things about things that aren't unique.... Like enemies where you may have 30 of the same type of mob spawned in at random times and places, or many hundreds of items that could be strewn about. This means for unique things where you know for certain you only want to save a single time, you may want to use a child class of your inventory component that you use exclusively on your player character that handles saving its data differently - it could literally be the exact same thing just with an override to its save and load functions so it reads a specific variable in your save game.

#

Saving and loading data is a mess.

#

It's about taking all the details out of something, storing those details, then reading those details again, and resetting that something back to its state it was based on those saved details.

mellow fractal
#

so.. I'm running into another issue

rain gate
#

Don't cross execution lines.

mellow fractal
#

?

rain gate
#

The first time this code executes, if the first branch is true, the cast isn't hit, but you're pulling off the cast for a value.

mellow fractal
#

ok yeah that fixed the issue I was getting

#

so for saving inventories, would it be an idea to have it set up so that in inventory component, if parent is player character save to an array but if parent isn't player character save to a map of arrays?

#

the map of arrays being the inventory and equipment of enemies, npcs, contents of chests etc?

rain gate
#

Eh... I wouldn't say I'm fond of that solution, only because it puts emphasis on checking if the owner is a controlled instance of something.. It's not necessarily expandable, and doesn't cover the scenario of what if the player isn't currently possessing the character but you need to save?

#

That's why I suggested the child class... Basically would keep everything the same, just overide how it saves and loads itself.

mellow fractal
#

I guess, so what's the alternative? Because saving inventories is the biggest issue I've been wanting to cover this whole time

#

so how would the child class work?

#

because at the moment the inventory is a component.. I'd have to re-rig the entire inventory system to make it its own class..

rain gate
#

no

#

You create a child class of that component.

#

It would end up having all the same logic involved.

#

What you'd want to do is create functions in the parent component for saving and loading.

#

You change those functions in the child so it does something different.

#

You then use the child component on your character.

mellow fractal
#

how do you create a child class of a component?

rain gate
#

Right Click on the Component.... Create Child

mellow fractal
#

ok, so how would I store the actual data? like if there's a chest, I open it, I loot its contents, I hit save, how do I tell the game to save the data for both my inventory and the chest's inventory using this?

rain gate
#

You get references to the inventories involved and call their save function.

mellow fractal
#

they don't have any kind of save function at the moment though that's what I'm asking

rain gate
#

Create one.
In the standard inventory you'd use the GUID > Save whatever data you want save in a structure.
In the player inventory override of the save function, you'd just save the data in a single variable of that same structure, probably named "Player Inventory"

#

Loading then would be....
Standard... Read the GUID map for the GUID of the inventory and read the structure and populate the inventory component.
Player.... Read the Player Inventory variable and populate the inventory component.

mellow fractal
#

so.. I replaced the inventory component on the player character with a child class of the inventory component.. and it completely broke everything

#

I can't pick up items anymore, the inventory has no slots, and I get this error

#

pretty much all the object interaction data was built into the inventory component in the form of functions...

rain gate
#

If all you did was relpace the inventory component on the player, then this error indicates that you were directly referencing the player's inventory in the inventory component itself, or within your item class.

#

Like, doing a cast to your character's class and getting a reference to the player's inventory component.

mellow fractal
#

I think this may be part of it

#

this is how interactions get started

#

like, the interactions, the population of the inventory, sending out stuff to the item data so it can be deleted when picked up, putting the widgets on screen, all of that is handled in the inventory component

rain gate
#

where does it take you when you click on these links?

mellow fractal
#

to this "is valid" in the middle of the screen

#

this is where all the item data is

rain gate
#

So there's the problem, you're specifically referencing the player's inventory.

mellow fractal
#

yeah well that's on the interaction,

rain gate
#

The input to that interface should just be an actor. You'd grab the component of class (inventory) from the actor.

mellow fractal
#

so basically that sits on the items to say "if I'm interacted with go to player's inventory and delete me"

rain gate
#

If you want to keep it as is so you don't have to refactor more, then just do a grab of the component of class (inventory) from the player character reference there.

rain gate
#

Should, yes.

mellow fractal
#

I just ran the game and it doesn't seem to be throwing any errors

#

so, when it comes to child classes of the inventory system, would it make sense to have 1 for player and 1 for everything else, or should I split up enemies from chests?

#

since enemies can equip and consume items would there be a requirement to need a third child instance or would just the 2 be ok?

#

I suppose in a way an enemy is just a chest since when you loot them they are either dead or it's pickpocketing..

rain gate
#

Possibly, that's part of the design you'd need to think about. Is the inner workings of the inventory going to work effectively the exact same way as a chest as it would being on an NPC? If the answer is yes, then you probably don't need to.

mellow fractal
#

I still need to refactor a lot of this inventory system honestly.. and splitting up the player from the containers might be a blessing because I wanted to remove the slot based system and have it be weight based

#

there's already a system in place for # of inventory slots, and it's on a scrolling box so, would you just look for an open slot, and if there isn't one generate a new one and place the item in there?

rain gate
#

How you want to handle what your inventory is displaying or holding isn't really something I could help you with. That being said, this is also diverging from the original intent of the thread.

mellow fractal
#

fair enough. I'm going to sleep since it's like 8:30 in the morning and I've been awake since yesterday. I'll likely run into more issues setting up the whole GUID system for inventories so, I'll ask here when I do.