Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In my gameclient I have the following classes(compontents): Game, GameScreen, GameWorld, Player.

They are structured like this: Game has two GameScreens: MenuScreen and MainScreen. MenuScreen has an instance of GameWorld. GameWorld has an instance of Player.

Now I wanted to add a multiplayer mode to my game. For this I have a class "NetworkConnection". For the problem keep in mind that this class needs to access individual objects in the game world, as well as vice-versa. Meaning that individual objects (as a simple example the player) need to send messages to the class. It could look like this for example:

networkConnection.SendPlayerPositionUpdate(x, y, playerID);
  • The problem

Where do I put my NetworkConnection?

I thought about adding it to "Game" because it is a part of the game (duh). But when I want the player to tell its position to the server I have to do this:

(Inside the player class)
world.screen.game.networkConnection.SendPositionUpdate(...);

The otherway around (when messages are being received from the server)

(Inside the network class)
game.currentScreen.world.player.SetHealthPoints(receivedHealth);

Where should I place NetworkConnection? Should I make NetworkConnection a global singelton ?

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

If you are using a language with both Reflection and Eventing like C# or Java, you can use a combination of the two to achieve some decoupling between the game and the network. I wrote about how I implemented this in C# at length here: http://jcpmcdonald.com/index.php/80-blog/91-networking All of the code is open-source too if you want/need to look.

To summarize: Your game entities (like your player) will have events that will communicate changes of state to anyone or anything that cares to listen (locally). These events are for things like moving, health changes, death, and any other game-related events you may have. Each of these events will have its own EventArgs class that it uses. Hidden inside the EventArgs, I have coded all of the information to reflectively replicate this event on an other client (read the linked article to see).

Now for the fun part. When an entity is created, my networking class looks at the entity through reflection and starts listening to all of the events that need to be replicated over the network. When one of these events is triggered, the network class picks it up, unwraps the reflection information that I have placed in the event, then send that off to the interested party(s). On the receiving side, I open the packet, read the reflection information, and invoke the method.

Using this method, my network knows as little as possible about the game, and the game knows almost nothing about the network.

share|improve this answer
    
This sounds awesome. I already knew about reflection and events, but it didn't occur to me to use those techniques the way you described it. But are there any noteworthy performance issues when using reflection that way? –  Felheart Oct 30 '11 at 4:39
    
@Felheart I have not had any performance issues yet, and because of this, I haven't done any optimizations. There are ways to make it more efficient by using less reflection, but at the cost of more maintenance (like sending a method # instead, then using a list to call the right one). I receive the messages in a thread, so I can do some pre-processing there before adding it to a thread-safe queue for the game's thread to use. If the threads are on different cores, it should be fine. Here is an article I found on reflection's performance msdn.microsoft.com/en-us/magazine/cc163759.aspx –  John McDonald Oct 30 '11 at 14:26
add comment

You could have PlayerNetworkComponent extending NetworkComponent and a NetworkManager singleton that has a GameWorld and list of NetworkComponents. Then in your game loop, you'd call Update() on your NetworkManager. You'd register a PlayerNetworkComponent where you create your Player.

In NetworkManager.Update(), you'd call NetworkComponent.Update() on all of your components, and then in PlayerNetworkComponent, you might get the NetworkConnection for the PlayerNetworkComponent and use that to send the Player information.

This would fit nicely into a component-based architecture.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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