Setting up a basic game engine

Hi.

I've been poking with game engines for a while now. I've been using Java, and I would like to make some small games. I've been using JMonkey 3 for quite some time, but I am not really sure how to set up the code in the correct way.
So the problem is that I would like to write the game mechanic regardless of the graphic engine itself.
What I need are some classes that will interface with the engine itself, but also act as data storage for saving and modeling levels.
I've already wrote a small game in such a way, but I am not happy with it, it got too complex.
JME has its own classes for storing objects, such as solids. But when writing the game mechanics I don't want to directly interface with jme-s solid class, or any other class from jme, what I want is to have a set of classes that will interface with the game engine, so that I can save the status of those classes, or in future games synchronize them with a server, so that I can have a multiplayer game.

The first time I went to do something like that I used only 2D graphics, and I wrote some code that directly manipulated opengl-s functions, so I could easily implement such a system, and in the end I got that game working over multiplayer, and have friends join.
But now when I have JMonkey, I can't go poke inside the engine code.

 So this is how an example of game mechanic should  look like in such a system:

Object box=new Object(BOX_MODEL,x,y,z, rx, ry, rz); //Spawns the box


box.addItem(new Item(Soldering_iron)); //adds something into it


box.setSpeed(10,0,5); //sets the box flying

 


On the other way, I should also be able to serialize that box instance, and save it to a disk, or even send it over a tcp link to a game server.

But the problem is, that the Object class must not contain any specific stuff regarding the 3D game engine, because if it does, if the other side or game session tries to load such an object, it would load references that have nothing to do with the current session.

In my previous attempt I have everything doubled, and a class in the middle that acted as a bridge synchronisig the data in the Object class, and the engine itself, and that was a really complicated and messy solution.

So how do I set up the Object class, or any other interface class like that toward JMonkey, or any other engine so that I can have those features, and yet have a nice and clean implementation?

Any ideas suggestions?

 

 

 

 

 

 

 

This is worth the read. I read it as it came out and from what I can remember after skimming it, its still very much relevant. The architecture is more important in a lot of ways (for programmers) than the technology. 

Without knowing your exact design I cannot give you specifics on how to solve your problem, but I can give you a few tips about doing some of what you want to do in Java.  First, you pretty much have answered your own question with regards to how to solve the problem of having your code not directly interact with a specific gaming engine.  You will need to create a layer of abstraction between the game engine and the code that uses it.  Then your code will interact with the abstraction layer rather than directly with the engine.

You do this by creating a class hierarchy for your interactions and wrap the specific engine logic within implementation classes.  You can either use direct inheritance or a set of Interfaces, which ever makes the most sense for your design.  Depending on what you need to manipulate and store, you might want to also use generics in conjunction with your abstraction layer, this may lead to a cleaner implementation.

Your other problem of serializing data to a file or between a client and server can be solved by marking your objects' platform specific data members as transient.  

E.g.,

class SynchBox implements Serializable{

    //You must declare a serialVersionUID in any class that implements Serializable otherwise future version incompatibility can arise

    private static final long serialVersionUID = 918943L;

    private final String sameLocalRemoteValue;

    private transient SystemSpecificValues mySystem;

…..

}

The transient keyword is used to denote fields that should not be part of the serialization process.  The problem is when these objects are deserialized the transient values will be null, so you will have to provide implementation for the readObject method.  This is a little different from overriding methods for a parent class or a normal interface.  In Java the Serializable interface is a marking interface and has no methods to implement.  Implementing Serializable gives a cue to the JVM that the serialization related methods for a given Object instance will be used, of which readObject is one.  The readObject method is called during the deserialization process, and can be used to fill in values for transient fields.

I will give a simple example below.  This example just sets the above transient field to an object instance, you can certainly abstract this to provide a readObject value for both the client and server:

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException{

        ois.defaultReadObject();

        this.mySystem = new ServerSpecificValues();    

    }

There is also a writeObject method that can be overridden if you need to perform some action on an object prior to serializing it.

A word of caution about serialization, it can introduce some potential security issues into your code.  See Items 74-76 in Josh Bloch's Effective Java for details.  

Serialization is a must when you have to send Objects over the wire or persist them to a file or database, but just be sure you understand the implications of serialization.

 

Thanks a lot.
I still have to give it some thought on how exactly I am going to approach this problem.

If anyone else has other Ideas, please post them.