Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Although this is a gamedev project, the question is about general OOP practices,

ID: 643493 • Letter: A

Question

Although this is a gamedev project, the question is about general OOP practices, so I believe it goes here. Here's the problem: (note: I will call any equivalent of real-world physical objects "entities" from now on; e.g. a rock in the game is an entity)

A specific class:

class Character
{
public/private CharacterInventory Inventory;
public/private CharacterStats Stats;
public/private CharacterEquipment Equipment;
}
Inventory functionality is self-contained in the CharacterInventory class. Same goes for stats. My aim is to make each character in my game a self-manageable entity. What do I mean by this? To put it plainly, I want to design the base Character class so that in the end I get an object that reacts in its entirety even when the smallest change occurs, in any of its components. To make things clearer, here's an example: when an item that changes the strength of the character gets equipped, the CharacterEquipment component of Character gets updated. At the same time, the Character will call the Stats object to change the strength attribute.

I've thought about doing this using events. Character subscribes to Equipment's OnEquip event, and in its handler, tells the Stats component do do its job. I believe this is an elegant enough solution; my issue however lies somewhere else.

I've got two ways in which I can update the character's inventory. First, by making the inventory (and any other component) private and providing a public method inside of Character, that does the work of calling the appropriate update method in the inventory. Like so:

Character chara = new Character();
chara.AddItemToInventory(SomeItem);
The 2nd way is by making the components public and accessing them like:

Character chara = new Character();
chara.Inventory.AddItem(SomeItem);
To me, both ways seem roughly equivalent in terms of readability. But the 2nd way seems like it's breaking the whole "self-manageable" idea. Basically, I'm invading the "private" space of the character. By going with the 2nd way, I can hook to the inventory events from some other place, but then again, this breaks the main idea even further. However, going the 1st way, I get the impression of writing duplicated code; even though it's not! I think the impression is given to me by the fact that Character.AddItemToInventory(...) and CharacterInventory.AddItem(...) share enough naming similarities to suggest duplicated code.

To be sincere, I'd go the first way, even though it seems to me like an extra layer of code. Then again, to make the character a self-manageable object, an extra layer of security is essential. But I'd like to hear from people more experienced than me. Are there any advantages to the 2nd way? Any severe disadvantages? I just can't get over the impression that I'm writing extra, unnecessary code.

Explanation / Answer

Are there any advantages to the 2nd way?

Absolutely, you're not repeating yourself. AddToInventory is just going to call Inventory.Add anyways. Worse, it is going to also know enough of the item to have to dispatch to the different things that care about it.

A better approach is to create your stats class with input as to where it can find modifiers. In the inventory, in skills you might've picked, etc. When someone asks for the character's Strength, it can aggregate the modifiers to provide a result.

Abstracting that well is near-impossible. Program design tends to be thorny with games in that regard since so many things can impact others depending on context. Focus on getting something working good-enough; your goal after all isn't making a great design - it's getting a game done.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote