Friday, January 19, 2018

How can I design an effective game object interaction scheme with a component-based architecture?


This is a design question... I'm sure this could be generalized more, but I'm having a hard time with it. I am wondering about design for game object interactions - here is my example (2D puzzle-platformer).


Say the player is trying to progress through a level. There are many lights that can be pointed in different directions. Here is an example of how these light objects might interact...



  • One light projects a platform that allows the player to cross a gap

  • One light decreases the friction coefficients of anything it touches, another increases it

  • One light nulls the effects of all lights, which would make the platform disappear while that light is on and null the friction modifiers

  • Etc...


What is the best way to approach this problem when using a component architecture? Components for each major object seem obvious, as well as a clean way to define their effects on the environment. A class to "resolve" interaction (seems like that could become a mess quickly)? Some usage of the decorator pattern to create combined objects for those that are interacting at a given time? A data structure that lends itself to this?



Also, connecting audio to these interactions? It seems like connecting audio to the system would be just like connecting any other property, like visibility or player movement/collision.


Obviously as more components are added it would be nice if there was a robust system that could handle new ones with little modification, but I am not familiar with how to go about designing this.


Other Information: The engine I am using is an XNA engine called IceCream.



Answer



In an object oriented system, the only real answer to the question of what's the best way to do X is that you should just do it the most straight forward way you can think of to get something up and running, and then change it when an easier expression becomes apparent. Concerning yourself with choosing the right pattern before you've written any code is a good way to saddle yourself with the wrong answer from the get go; let all thoughts of patterns and components melt away and just follow these steps, starting from where you are today (assuming you have implemented a light component):



  1. Add code to the light component to project platforms. (Get this working.)

  2. Copy that component into a new component, remove the platform stuff and add code to decrease friction of appropriate objects. (Get this working, verify that #1 still works.)

  3. Copy that component into a new component, removing the "new" code and add stuff to disable the other components' effects. (Get this working, then verify that #1 and #2 still work.)



At this point, you will (probably) have a ton of duplicated code. Extract common code into functions or another class (maybe a base class) or whatever seems appropriate. Just because you started with a "light component" though doesn't mean that LightComponent is an appropriate base; it could be that whatever code made up the light component isn't really a "component" per se and maybe that will be best represented by a set of functions or even a separate class that is aggregated into your new components (as a member variable).


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...