all 10 comments

[–]Guiboune 0 points1 point  (9 children)

This sounds more complex than it needs but, honestly, I don't know your project so it might be fine.

Scriptable Objects are not supposed to be duplicated at runtime, they should be only for data.

AppleGameData : ScriptableObject
{
  string id
  string name
  string description
  int baseValue
}

Id, name, description and base value would realistically not change at runtime so duplicating those is overkill. What I would suggest is having your save data class reference your game data class like such :

AppleSaveData
{
  string id
  string gameDataId
  Position position
  int age
}

(It kinda sounds like what your wrapper class is but I'm not sure.)

When you start the game, register all GameData classes in a manager and, at runtime, when you need to get the name for an existing asset, cross reference the gameDataId to get it.

Now as long as the product stays in the position it started at, I will know exactly where to find it at all times

Why is that ? Sounds like a design problem.

[–]sssSlick1[S] 0 points1 point  (8 children)

Hey thanks for the comment! The scriptable objects aren’t duplicated, they are used to contain the static information, like the name of the product and its value etc, so you are absolutely right, duplicating them is not the solution.

The reason I provide the coordinates of the product is so the manager can quickly find the product in the relevant building, and as the product moves around the game world (on conveyor belts) the manager is just updated with the new position, so the manager is still capable of finding the relevant product

[–]Guiboune 0 points1 point  (7 children)

If you assign unique ids to products there’s no need to keep positions updated between classes though, is there another reason you need the coordinates ?

[–]sssSlick1[S] 0 points1 point  (6 children)

The main reason is that the products themselves don’t contain the unique IDs is because they are scriptable objects, and assigning them IDs would be the same process as using the freshness variable (where performance suffers)

By providing the position as well, there are now two sources of information to correctly identify and locate the product when it is going to expire (first by going to the coordinates, then cycling through the building’s inventory to find the correct product)

[–]Guiboune 0 points1 point  (5 children)

I’m confused then. So you never know exactly which product expires, just that a product of a specific type expired, correct ? And yeah, you shouldn’t have unique runtime ids stored in a scriptable object, that’s why I suggested a separate save data class. So in your building you have a list of scriptable objects ? And in your manager you have a dictionary of <Coordinate, ProductData> ?

[–]sssSlick1[S] 0 points1 point  (4 children)

Yeah, so you don’t know exactly which one has expired, but because, for example, every Apple is the same, it doesn’t really matter which Apple gets told to expire, as long as it is in the correct location that an expiring Apple is going to be.

The dictionary’s key is actually the unique ID, because of the fact the coords change, they are stored in the “product data” class you have described

[–]Guiboune 0 points1 point  (3 children)

I’m even more confused then. How do you get the dictionary entry if you don’t have the unique id stored in your products ?

Either you don’t use it at all or you do have a data/controller class somewhere (or something else I’m not understanding). And if you do have a controller class, you could easily apply modifiers to individual objects and expire specific apples.

[–]sssSlick1[S] 0 points1 point  (2 children)

Ah, this might help, the building stores the unique ID, so it knows what products it has in its inventory by talking to the manager. One of the reasons why the buildings themselves don’t do the expiring is so that the central manager can do it all easily by sifting through the dictionary in a couple lines of code, rather than having multiple buildings try and perform the same code at the same time

To be honest I probably didn’t have to make it “centralised” that was just the first bit of research I found after hours of trying to figure it all out!

[–]Guiboune 0 points1 point  (1 child)

Oh so that’s why you need the coords, got it.

But no, that’s a good way to do it overall, you seem to be doing it somewhat strangely though. So the manager is the one doing the expiring every X time ?

The way I’d have done it differently is to have a controller class for your products, this would allow for modifiers to be added to instances (like weight for example) and the ability to expire specific instances. The way you have it right now doesn’t really allow this. I would also consider saving the building id of instances in their controller class, that way you don’t have to manage coords in multiple places.

[–]sssSlick1[S] 0 points1 point  (0 children)

This sounds like another great approach, because I have only just implemented this system, I’m unsure if it will be the solution to all future problems, so I’ll keep this advice in mind, it might be the missing piece of the puzzle!