2
\$\begingroup\$

I don't know a good way to implement single and multiplayer in a game without messing up the whole project structure.

Should I create separate classes for single and multiplayer entities or is there a clever programming pattern I can't find for this situation?

Let's make a simple example of my problem.

Let's say I want to make a pong clone with single and online multiplayer, how should I go about this? Make separate classes for both modes?

I read somewhere that the MVC pattern might be a good choice in this case but I'm not sure how to implement it correctly.

Should I create a Player data class and then multiple controller classes for example: PlayerControllerSingleplayer, AIController, PlayerControllerMultiplayerSelf, PlayerControllerMultiplayerOpponent.

And then a PlayerRenderer view class?

I've read some articles about mvc previously but still don't know really much about it or how to do it correctly in my case.

I will be using libgdx and probably kryonet for the networking if that might be important.

Thanks for every piece of advice in advance!

\$\endgroup\$

closed as off-topic by Josh Feb 5 '15 at 20:18

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about "how to get started," "what to learn next," or "which technology to use" are discussion-oriented questions which involve answers that are either based on opinion, or which are all equally valid. Those kinds of questions are outside the scope of this site. Visit our help center for more information." – Josh
If this question can be reworded to fit the rules in the help center, please edit the question.

2
\$\begingroup\$

The MVC pattern is indeed a good solution here. You would need three different controllers:

  • The LocalPlayerController which is sending commands to a paddle by listening to the local input devices. When you have multiple input devices (keyboard, mouse, gamepad...) it might be a good idea to further subclass it into the one it listens to. In any case, these class(es) should be used in both singleplayer and multiplayer, because it makes no difference for the control who you are playing against.
  • The AIController which analyzes the current game state and sends commands to an ai-controlled paddle.
  • The RemotePlayerController which listens to a network socket and interprets the incomming messages as commands to a paddle.

Regarding network output: This would not be another Controller, this would be another View. A view is not just something you see on the screen. It is any form of output representation of the model (the model in the context of game development would be the game state). It can be a graphical output on the screen or a data stream sent over the network. In this case the NetworkView would observe any paddles controlled by LocalPlayerControllers or AIControllers and translate their movement to the network.

\$\endgroup\$
1
\$\begingroup\$
  • A Singleplayer game is a Multiplayer game with one human player.
  • None-human players (often referred to as bots or AI), are a class or a group of classes that extends the base Player class. These classes compute the game state and output the moves the computer algorithm "considers" to be reasonable.

You could implement Multiplayer by itself and allow a player to run a solo server locally.

The "server" class accepts input from the Player class instances. Extend the player base class to implement AI controlled players (with different levels of difficulty). Remember that in online gaming (multiplayer or not), you need to compensate for the lag. You can still use the same code when gaming locally and latency free. Compensating for lag is a question in its own merit. The general idea is to consider when the actual input occurred and re-positioning the pong paddle in retrospective.

\$\endgroup\$
  • \$\begingroup\$ Do you mean "Server" figuratively as a class within the same program or are you talking about a separate server process to which the client process connects via IP even when the player wants to play single-player? That would be a very unusual solution. \$\endgroup\$ – Philipp Feb 5 '15 at 1:43
  • \$\begingroup\$ It's not "unusual", and even if it were, so what? \$\endgroup\$ – Volte Feb 5 '15 at 19:06
  • \$\begingroup\$ @Philipp I meant it as a class that is responsible for digesting user and ai activity, and maintaining the state of the game. The same class could be used inside the Singleplayer executable and the Multiplayer server executable. I referred to it as the "server" class because it the body of code responsible for accepting inputs from users and bots, deciding on a result and reporting back what is going on in the game. The communication between the server and the users could be "dependency injected", depending on the situation. \$\endgroup\$ – wolfdawn Feb 6 '15 at 12:36
0
\$\begingroup\$

My approach to this is to build the Multiplayer/Networking aspect of the game first.

After a bit (not much, really) upfront cost (of building the network capabilities) you're primed for building an AI/Director agent that connects via the same "API" (the network communication API you set up to get Multiplayer working) and sends commands and responds to events very similar to another human player.

Incase it wasn't obvious, this does not necessitate an internet connection for single player, as you can (and should) simply have the AI (in single player/campaign, of course) connect on the loopback/localhost/127.0.0.1 address.

It's a pretty clean solution that I'm happy with. It prevents having to duplicate work, or write shims and maintain two separate subsystems.

The loopback or localhost interface bypasses the NIC so there is no hardware overhead. It's a great way to maintain a robust API between your game and agents which sets a solid groundwork for further expansion and maintenance.

Enjoy!

\$\endgroup\$
  • \$\begingroup\$ Having a program connect to itself is quite odd. When the user is using a personal firewall, they will wonder why your game wants to open a server port. It might also be bad for performance to go the detour over the operating systems network stack instead of just calling the methods directly from inside the same application. \$\endgroup\$ – Philipp Feb 5 '15 at 1:38
  • \$\begingroup\$ This is not "odd"; it's a perfectly reasonable practice, and there isn't a significant overhead to it. The loopback or localhost interface bypasses the NIC so there is no hardware overhead. Furthermore, it's roughly the equivalent of connecting via a socket, which is a perfectly reasonable and prolific use-case. \$\endgroup\$ – Volte Feb 5 '15 at 19:10

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