Sunday, August 23, 2015

architecture - How can I design lots of different attack types that can be combined?


I'm making a top down 2D game and I want to have a lot of different attack types. I'd like to make the attacks very flexible and combine-able the way The Binding of Isaac works. Here's a list of all the collectibles in the game. To find a good example, lets look at the Spoon Bender item.




Spoon Bender gives Isaac the ability to shoot homing tears.



If you look at the "synergies" section, you'll see it can be combined with other collectibles for interesting yet intuitive effects. For example, if it combines with The Inner Eye, it "Will enable Isaac to fire multiple homing shots at once". This makes sense, because The Inner Eye



Gives Isaac a triple shot



What's a good architecture to design things like this? Here's a brute force solution:


if not spoon bender and not the inner eye then ...
if spoon bender and not the inner eye then ...

if not spoon bender and the inner eye then ...
if spoon bender and the inner eye then ...

But that will get out of hand very fast. What's a better way to design a system like this?



Answer



You totally don't need to hand-code combinations. You can instead focus on the properties that each item gives you. For instance, Item A sets Projectile=Fireball,Targetting=Homing. Item B sets FireMode=ArcShot,Count=3. The ArcShot logic is responsible for sending out Count number of Projectile items in an arc.


These two items can be combined with any other items that modify these (or other) properties freely. If you add a new type of projectile it'll just automatically work with ArcShot, and if you add a new firing mode it'll automatically work with Fireball projectiles. Likewise, Targetting is a property that sets the controller for the projectiles while FireMode creates the projectiles, so they can be easily and trivially combined in any combination as makes sense.


You might also set of property dependencies and such. For instance, ArcShot requires that you have a provider of Projectile (which might just be the default). You might set priorities so that if you have two active items that both provide Projectile the code knows which one to use. Or you can provide UI to let the user select which projectile type to use, or simply require the player to unequip high-priority items he doesn't want, or use the most recent item, etc. You can further allow a system of incompatibilities, e.g. such that two items that both just modify Projectile cannot both be equipped simultaneously.


In general, when possible, prefer any kind of data-driven approach (or declarative) over procedural approaches (the big if-else messes) when it comes to the objects and such in your game. Higher-level generic logic that is configurable by simple data is much preferable over hard-coded lists of special-cased rules.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...