Multiplayer game structure questions

I’ve started to write a simple client/server based multiplayer game using a DistributedSmoothNode for each player (very nice system, by the way). This is really my first serious endeavor into multiplayer games and I’m a little unsure of myself as I encounter certain issues.

My first issue is the terrain. I’ve created a client-side GeoMipTerrain (again, this is awesome) and I wondered, should the terrain actually be client-side? or does this enable cheating too easily?
If the terrain should not be client-side, is there any value/detriment to making it a DistributedSmoothNode over a DistributedNode?

My second, more noobish question has to do with the camera. I have created a system where the mouse wheel changes the zoom of the camera, moving mouse left/right/fwd/back orbits around the player. All of this code is within the client.py World class, along with the terrain creation code and all character movement etc.
This file is getting pretty long and I wonder how other people divide their code up into separate .py files. Do you put the camera controls in, say, camera.py and terrain in terrain.py?

Thanks in advance for the help.
[/code]

What’s so bad about cheating?
“Cheatability” is often considered bad by game devs, but for players, they’re a feature.
Only if playing against other real playrs cheating can get annoying, but consider this:
To change something within the game someone has to really dive into it. So you’d have at least one real fan :slight_smile:

You can’t realy protect yourself 100% against unfairness. What you can do is controlling the data coming from the client and kick/ban players who tell you they’ve moved much faster than usual or they’re in a place that is unreachable by default.
Some might try to change some numbers in the RAM. There are some general purpose cheating programs around, but you can protect your game from that by double checking all data. In worst case on the server AND on the client machine. Or you could try a software specialized on locking RAM for programs other than your game. I believe punk buster does that and it’s the most popular, I think.

For the second question. Having all code in one file becomes quite hard to maintain and hard to reuse (speaking of modularity). Logically splitting our files often helps a lot. How you split them depends much on your plan. For example, there are people handling as much as possible as plugins. Means you load a module, call a method there like activate(opts) or eventually call some stuff on a plugin manager. Others use managers for groups as in “all cars in the scene share a single texture-, sound- and instance manager”. Even others manage their game using scenes or scenarios where they initialize classes from other files and keep references to these.

It’s up to you, in the end. Questions you should ask yourself are: how many abstraction layers do I want/need, what logical groups can I make, how could i reuse most of the code (also for other projects, maybe) and how do I want to manage the scenes (by a central point where everything comes together or maybe by many self-contained modules).

Hope I could help you at least a bit.

Since my previous answer was a bit blurry, here’s my favorite coding style regarding panda:

All user input is handled by single, pluggable “control states”, which are basically all DirectObjects. Each one only accepts the keys it’s concerned about, translates them into action requests (a simple python set) and translates those into function calls. Inside the tasks, methods from other files are used. Beside DirectObject all of these also inherit from a class that registers them, looks for overlapping keybindungs and implements activate() and deactivate().

Assets like people or vehicles can’t be that self-contained, so they need to be more interactive. Only thing they do handle themselvespretty much is only loading and assigning defaults like sound, animations and a node under a suiting parent. Watch for ordered hierarchy for scenery. It’s way eaier to call city.removeNode() than looping over a list or filtering the scene graph for single things. If you keep irder on your files, filtering the scene graph never should be necessary.

Some classes make use of the above, others are used by the above. My views.py, for example holds a few classes. each for a different state of interaction. There is one class that handles all camera related stuff when flying an airplane and another when walking around in third person. Wach of those is most often a finite state machine at its own (since the camera can only be on one place at the same time).

Finally, where it all comes together are scenario classes. Again, every scenario is a state in a FSM. In each single scenario I can load scenery and control states by oneliners. I haven’t yet found out if it’s the best idea to keep all instances as attributes of that particular scenario or if it might not be better to have a few self-contained classes for not so interactive parts. E.g. “self.sky = BlueSky()” vs “skymodule.setSky(“bluesky”)”.
The second (kind of manager) might make for an easier cleanup as you don’t work on a local reference:
“self.sky.destroy()” vs “skymodule.cleanUp()”