Want some thoughts about creating smaller weapon classes from a big weapon ScriptableObject

Hello! I have been developing my first game so I am kind of new to game programming architecture. Anyways, I basically already created an end game weapon. It contains everything that I want. It contains weapon damage, parry windows, parry damage, throw damage, throw range, and much more.

Here’s some additional info about this class

  1. It’s a scriptable object, so I can easily edit it from editor
  2. It implements various interfaces such as IWeapon, IParryable, IThrowable
  3. When it implements these interfaces, it has to implement various methods such as getBaseDamage(), getThrowRange(), getParryDamage(), getPastParryWindow() etc

Here’s the part where I am having some trouble with

  1. Assuming not every weapon will implement all the interfaces (and only some of them), how can I reuse the variables defined in the original scriptable object, and create a second scriptable object with SOME of those variables? it doesn’t have to retain the information but I just don’t wanna type same variable names over and over again

One bad solution that came into my mind was creating new classes that implements interfaces normally but copy paste the variables to save time. Clearly I am not great at architecture.

Another solution that I can think of was copy all these Parryable variables into a ParryableValues data structure and simply declare it in each one of the IParryable-implemented classes. Remove all the methods from IParryable interface such as getParryPastWindow(), getParryDamage() and just replace it with getParryableValues() method which returns configured ParryableValues from ScriptableObject

In retrospect I didn’t think about this system well enough, I even came up with the second solution while typing this post lol. That might solve my issue but I’ll have to refactor some code so I am wondering if there are any better solutions. Thanks a lot :smile:

This seems like a good example of “inheritance vs composition” to me. If you google for this you will find plenty of articles that dig into that topic. Here is my own short take on it with Unity examples.

  • Oh nice, I get to use my meme again :smile:

While writing your post you already realized that you can extract some DATA. The next step would be to extract LOGIC too and try to compose your weapon logic of multiple reusable objects. In the end it often comes down to how interdependent (entangled) your logic is.

However, don’t overdo it.

This is also where opinions may differ. Some will argue that while your are still prototyping you should focus on finding the fun and not necessarily architecture. Others will tell you that separating into reusable objects is the key, even while prototyping. Though, it is cumbersome in the beginning and a bit impractical at times.

My rule of thumb: Extract only what has not changed for a couple of code iterations. Everything else is probablity still changing too frequently. Exception: You already know it will be a separate logic. But then, why have you not started it in a new class? :wink:

My advice: Think about what parts you need to reuse because they are part of multiple weapons. Extract those and leave the rest in your weapon class. Start by extracting just one. See how it goes. Then proceed.

One thing I am pretty confident about is that you should not try to solve this with inheritance alone. It is a dead end.

If you want to know how deep this “composition” rabbit hole goes: Don’t fear the Monad.

Thanks for the advice, I will relook at my code in the morning and see what kind of common logic I can extract along with the data and also read more about inheritance vs composition :smile: