4
\$\begingroup\$

Is it possible to make network independent components that allow networking details to be specified externally?

For example, if I have a "Follow" script that follows a game object, it would need to do certain actions on the server and certain actions on the client. However, these things can change based on the network architecture. Single player games would not even need to consider what runs where. That makes perfect sense, except why should a component as general as "Follow" need to be different across different types of game?

I've tried creating a base component class that figures out how to call each method based on options set in the editor, but that failed due to RPC names needing to be different across all components attached to one game object. Not to mention it was messy. I've tried abstracting method calls to figure out how they should be called, but that doesn't solve the problem of WHICH methods should be network invoked.

I really don't want to build this into the components themselves, even though it might be the easiest / most obvious solution. That would destroy their portability across projects.

\$\endgroup\$
  • 1
    \$\begingroup\$ So you want to create a generic network handler that will parse generic commands to be handled by generic classes across multiple platforms?... \$\endgroup\$ – Tom 'Blue' Piddock Dec 8 '14 at 12:41
  • \$\begingroup\$ Need a little more clarification on what you mean by networking details specified externally. Are you talking about externally specified configuration parameters or externally specified code? The parameters is relatively easy where you probably want an interface that queries a configuration server for the parameters to be used during runtime. External specified code is going to be a lot more difficult. \$\endgroup\$ – RightHandedMonkey Dec 11 '14 at 13:08
  • \$\begingroup\$ @RightHandedMonkey I actually had the editor in mind. So, for each method, I oculd tick boxes or whatever saying which method is called where. \$\endgroup\$ – Ben Dec 11 '14 at 19:30
  • 3
    \$\begingroup\$ I wouldn't recommend that, although it's technically possible. You might use the editor to choose a method to handle a particular event, such as a button click. But for non-trivial behavior you should separate the components. One big component which does different things depending on editor settings is a bad idea for the reasons in my answer. Your configuration should be used for minor or non-functional changes in behavior. i.e. You might have a button on your lawnmower to change the speed of the blade, but you shouldn't have a button that turns it into a toaster. \$\endgroup\$ – betitall Dec 11 '14 at 21:51
7
+500
\$\begingroup\$

It sounds like your intuition is correct and the components should be separate. However, I would look for better abstractions. For example, you say:

"a base component class that figures out how to call each method"

Putting Unity aside, this is something of a design anti-pattern (in OOP). You'll wind up with messy classes that don't have a clear purpose and do too broad a variety of things (violate Single Responsibility). You will also have a base class that has knowledge of the more specific derived classes (the inverse of what you want). Instead, try to break the functionality into logical parts and use those as class boundaries. Here's an arbitrary example of classes you might create:

  • FollowBehavior - keeps one object at a given proximity to another object
  • FollowNavigator - determines which coordinates an object should move to when following (consumed by FollowBehavior)
  • NavigationClient - Sends requests to a server to move an object from one set of coordinates to another (optional)
  • NavigationPredictor - used to smooth the rendering on the client by anticipating acknowledgements from the server. Helps avoid server lag.

You can see that each class is responsible for a very specific task. They are also modular. e.g. You might keep the general follow behavior, but "plug in" a new FollowNavigator for a new experience. Hope that helps.

\$\endgroup\$
  • \$\begingroup\$ I'll mark this as the answer before the expiry date. I'm just going to let others have a chance at an even better answer. Thanks for the answers and comments. \$\endgroup\$ – Ben Dec 12 '14 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.