17
\$\begingroup\$

I'm coding my game using a client-server model. When playing on singleplayer, the game starts a local server, and interacts with it just like a remote server (multiplayer). I have done this to avoid coding separate singleplayer and multiplayer code.

I have just started coding and have encountered a major problem. Currently I'm developing the game in Eclipse, having all the game classes organized into packages. Then, in my server code, I just use all the classes in the client packages.

The problem is, these client classes have variables that are specific to rendering, which obviously wouldn't be performed on a server.

Should I create modified versions of the client classes to use in the server? Or should I just modify the client classes with a boolean, to indicate if its the client/server using it. Are there any other options I have? I just had a thought about maybe using the server class as the core class, then extending it with rendering stuff?

\$\endgroup\$
3
  • \$\begingroup\$ Do you have pre-processor options? Like #ifdef CLIENT <some code> #endif. That's a simple way of having shared class files, which can be different between the server and client and share parts too. It's a bit messy though. \$\endgroup\$
    – William
    Commented Dec 6, 2011 at 6:10
  • \$\begingroup\$ I agree with MindWorX. Though conditional compilation is a pain in Java, there are solutions that should be considered. \$\endgroup\$ Commented Dec 7, 2011 at 10:56
  • 1
    \$\begingroup\$ Conditional compilation is a crude way of saying "I didn't put enough design time into my packages," in my opinion =) "A bit messy" usually translates into "What the heck does this do?" six months later when you re-read even your own code and is counter-productive for anything but throwaway prototypes. \$\endgroup\$ Commented Jul 7, 2012 at 15:50

3 Answers 3

25
\$\begingroup\$

You should prefer to keep your rendering code separate from your game logic, as they are separate concerns.

If you separate your rendering code from your client/server code, you get a couple of advantages:

  • Creating a dedicated server will be easier, as any code that renders will be in one place.
  • You can separate your update phase from your render phase, and run them at differing timesteps.
  • You can ensure your rendering code doesn't mutate game state, by using const, reducing bugs.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ +1 I can't agree with this sentiment more. Separating data modeling from rendered views of that model will let you cleanly do neat things like multiple windows that show different information, port the rendering to other platforms, add analysis and tweak your simulation for gameplay all without having to touch 90% of your code base. \$\endgroup\$ Commented Jul 7, 2012 at 15:45
5
\$\begingroup\$

I think you should cleanly separate client and server code. The server code and client code should not know about each other except for the functionality exposed with interfaces. The server is not supposed to know anything about rendering, just registering clients, tracking positions, time, etc. If you have cleanly separated concerns it is easier to maintain and further develop your game. Hope this helps a bit.

\$\endgroup\$
1
  • \$\begingroup\$ +1 I tend to agree with this. If the server is going to be running any clients, then it should do so as separate processes. \$\endgroup\$
    – Engineer
    Commented Dec 6, 2011 at 14:29
5
\$\begingroup\$

Separation of concerns FTW, as the others have said, but if your end-goal is to have separate client and server applications, you need to take it a step further. You need to determine what is client-specific, what is server-specific, and what is shared. For everything that is shared, separate it into classes of exclusively-shared code; client- or server-specific classes can then subclass or reference the shared classes as appropriate. Move the shared classes into a separate project, building a "shared library" JAR, and include that JAR in both the client and server projects.

This has a few advantages: it makes the separation of concerns crystal-clear to keep everything in separate projects; it assures you that client and server are starting with the same shared code (as long as they're using the same version of the shared JAR); and it makes it impossible to "accidentally" modify shared code without realizing it. If the shared code is in its own project, you'll know when you're editing anything in that project that you need to be aware of how the changes will effect both the client and the server.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .