I have a player inventory that holds items. These items have stats that can be modified, and other items that you can attach to them, etc; each one is a unique instance. On save game, I want to save everything in the inventory so it’s the same on load. Since every item is unique, I thought each should be a RefCounted, not a Resource. But every tutorial out there seems to make items as resources. I’m just wondering if I should make them Resources instead.
It seems easier to make new items with Resources in certain cases. Like if you have a generic Weapon class, and all Weapons have the same stats, making new ones with Resources seems like it makes sense. But say I want a new kind of Weapon that has unique properties, and it’s a very specific weapon. Ex: I want to make “RocketLauncher” and give it a unique stat called “rocket_size” or something. It doesn’t seem possible to use a generic WeaponData resource to make a RocketLauncher anymore. But there would also be no need to make a whole new Resource just for that one unique weapon type, right? So it seems like it makes more sense to just make a RefCounted called RocketLauncher instead which inherits from Weapon and give it the functionality it needs directly in the script.
And yes, I was thinking Nodes or Scenes would be overkill for items in my game (they don’t need to actually exist in-world, they just need to be attached to a character who uses their “use” function), so I’m using RefCounted. But it kind of sucks that I lose out on the power of quickly creating new items in the inspector if I’m making all my items purely in RefCounted classes. I was just wondering if what I was doing made sense.
Make it a Resource. The only draw back for you would be that Resources take slightly more memory than RefCounted, but unless you have actual performance issues, you shouldn’t worry about that.
Then you have all the benefits that come with Resources, the main one being able to view and edit it directly in the Editor.
Difference between a Resource and RefCounted is not that big as between a Resource and a Node.
Check this post out, it’s really insightful.
Huh. I guess I have no reason to worry about that if my game is really simple then, thank you! I think I’ll use Resources!
Though I still have the issue of what to do with more specific items… how does that work with Resources? Do you just inherit the Resource anyway to make a new type of Resource?
I apologize, as this might be derailing from the main topic of the thread a bit, but to give an example specific to my game:
I have an inheritance system that goes Item → Weapon. All Weapons have some basic properties like damage. Weapons are used to instantiate scenes for different attacks.
But, not all Weapons instantiate the same type of Node. It’s not like Guns producing Bullets. It’s more like Weapons producing either Bullets, summoning some kind of entity, or instantiating a scene that plays some kind of melee attack animation. Since each Weapon needs to know what kind of scene it instantiates, I figure I would have to make a new class for each type of scene.
But I don’t think I could just inherit Weapon into only three types. The reason being, I also want to mix and match different properties somehow. I have no idea how to do this, but I want to do something like:
Weapon A makes bullets and has a “penetration” property it passes to the bullets
Weapon B summons entities and has a “duration” property it passes to the entities
Weapon B makes entities that shoot bullets. So it needs both a “penetration” property and a “duration” property that it passes to the entities, and the entities pass “penetration” to their bullets.
I want to attach items to weapons to improve their stats. So how would such an item know what weapons it is allowed to attach to?
Wouldn’t I be forced to make a whole new class that inherits from Weapon to make each weapon in the game? What would the purpose of Resources be then if I’m making weapons with unique properties? Or is there some way to get it all to work with one generic Weapon Resource, or only a few…?
Put all possible properties into the weapon resource class and use as needed. You can simply use values to exclude. If you have duration for example, use it if its values is positive. Otherwise, it does not apply. Etc. It’s much simpler that way than inventing and managing inheritance chains.
If you suspect you might have clusters of properties that’ll end up unused, you can have sub resources that host them, and reference such sub resources from your main resource. This will give you modularity. But first do everything flat in a single resource class, and then extract afterwards if groups of properties start to look like candidates for extraction.
I’ll repeat what I already said in our previous exchange: minimze inheritance. Don’t let it be your primary tool to solve problems or build systems. It may seem elegant in theory but it often falls apart in practice. It’s a trap.
Consider all other options before going for inheritance.
Hmm. Well, I just wanted it for the inventory so I could just have an array of Items, so Weapons would count. I’d have to make an exception otherwise. Makes for simpler and easier code, no?
Unless you’re saying to just have Weapon, then give that an ItemData property, then somehow the inventory would… I don’t know what it would do, haha.
Though, I guess I can totally just put all the possible properties in Weapon and use as needed. That makes sense to me! I actually thought to do that, but worried if it was… wasteful? Open for bugs somehow? If weapons that don’t need a duration had one. But I guess I just make sure not to use it if it’s negative or something.
I will just do it in a flat class first and see if any clusters of properties appear later, then!
(Referencing our previous exchanges, this is actually basically exactly what I did the first time I made the game. I was under the impression that this was messy, I guess. Maybe it doesn’t need fixing after all.)
Consider this. Are you using booleans anywhere in your project? You probably do. Booleans are implemented as integers yet they store only a single bit of information. The remaining 63 bits are “wasted”. You’re producing 6300% waste by using booleans.
So if you care so much about waste at the level of bytes, you should pack groups of 64 bools as bit flags into integers. Looks a bit absurd, doesn’t it? Well it’s pretty much the same as worrying about unused properties.
Haha, you’re totally right. Thank you. I need to stop worrying about that stuff.
So if I want the inventory to hold items, and if I think weapons should be a kind of item, should I still avoid inheritance there? Or are you saying it’s better to give weapons a reference to an item data resource and then have the inventory deal with both items and weapons separately?
Depends on what shared functionality you need at the level of items. If it’s just so they can be stored in a typed array then I personally wouldn’t use it. I’d simply use an untyped array.
But if there’s some shared functionality and/or you’d prefer to use a typed array, then it’s perfectly fine to have a base class. As always: I’d suggest making some other item classes beside weapon, and see if there’s actually an overlapping functionality that’d warrant a base class. Never premeditate, always extract
Thank you for dealing with my overthinking rants lately, haha. You’ve helped me simplify things a lot. I will do my best to move forward without too much premeditation!