Best Pattern for Spatial Creation

Pardon me if this is not the best place to post these general questions on JME development, but these are not “problems” per se but more of a discussion on the best approach for game implementation.

My first in a long series of questions for the experienced game programmers out there is <span style=“text-decoration:underline;”>what is the best pattern for Spatial creation in the context of JME?</span>

I am slowly building a RTS game which obviously revolves around the creation of numerous “units” which Spatial will group together the underlying Geometry and the Controls. I want to implement my unit creation in the most flexible creation pattern possible, potentially supporting 3rd party “unit” creation and integration.

Are a series of Builder pattern classes preferred? Simple Factory pattern classes?

Well this is a way complex question that depends greatly on the style of programming and game.

Generally it’s always a very good idea to have the game logic independent of any rendering stuff.

Here are some examples of where I’ve been heading: (Hopefully the code formatting works!)

[java]
// SpatialFactory interface
public interface SpatialFactory {
public Spatial buildSpatial();
}

// AbstractEntityFactory builds Spatial by combining Geometry and Controls
public abstract class AbstractEntityFactory implements SpatialFactory {

protected static WorldSystem worldSystem;

public static void setWorldSystem(WorldSystem worldSystem) {
    AbstractEntityFactory.worldSystem = worldSystem;
}

public Spatial buildSpatial() {
    Spatial spatial = this.buildGeometry();
    List&lt;Control&gt; controls = this.buildControls(spatial);
    for (Control c : controls) {
        spatial.addControl(c);
    }
    return spatial;
}

protected abstract Spatial buildGeometry();

protected abstract List&lt;Control&gt; buildControls(Spatial spatial);

}

// HoverTank (prob should be called HoverTankFactory) is the concrete Unit factory instance
public class HoverTank extends AbstractEntityFactory {

private String model = "Models/HoverTank/Tank2.mesh.xml";
private RenderQueue.ShadowMode shadowMode = RenderQueue.ShadowMode.CastAndReceive;
private Vector3f localTranslation = new Vector3f(-140, 40, -23);
private Quaternion localRotation = new Quaternion(new float[]{0, 0.01f, 0});
private Integer physicsMass = 1500;
private Integer physicsCollistionGroup = PhysicsCollisionObject.COLLISION_GROUP_02;

@Override
protected Spatial buildGeometry() {
    Spatial hoverTank = worldSystem.getAssetManager().loadModel(model);
    hoverTank.setShadowMode(shadowMode);
    hoverTank.setLocalTranslation(localTranslation);
    hoverTank.setLocalRotation(localRotation);
    return hoverTank;
}

@Override
protected List&lt;Control&gt; buildControls(Spatial spatial) {
    List&lt;Control&gt; controls = new ArrayList&lt;Control&gt;();

    EventListenerControl eventListenerControl = new EventListenerControl();
    controls.add(eventListenerControl);

    ShootControl shooter = new ShootControl(worldSystem);
    controls.add(shooter);

    CollisionShape colShape = CollisionShapeFactory.createDynamicMeshShape(spatial);
    PhysicsHoverControl hoverControl = new PhysicsHoverControl(colShape, physicsMass);
    hoverControl.setCollisionGroup(physicsCollistionGroup);
    controls.add(hoverControl);
    return controls;
}

/**
 * @return the model
 */
public String getModel() {
    return model;
}

/**
 * @param model the model to set
 */
public void setModel(String model) {
    this.model = model;
}

/**
 * @return the shadowMode
 */
public RenderQueue.ShadowMode getShadowMode() {
    return shadowMode;
}

/**
 * @param shadowMode the shadowMode to set
 */
public void setShadowMode(RenderQueue.ShadowMode shadowMode) {
    this.shadowMode = shadowMode;
}

/**
 * @return the localTranslation
 */
public Vector3f getLocalTranslation() {
    return localTranslation;
}

/**
 * @param localTranslation the localTranslation to set
 */
public void setLocalTranslation(Vector3f localTranslation) {
    this.localTranslation = localTranslation;
}

/**
 * @return the localRotation
 */
public Quaternion getLocalRotation() {
    return localRotation;
}

/**
 * @param localRotation the localRotation to set
 */
public void setLocalRotation(Quaternion localRotation) {
    this.localRotation = localRotation;
}

/**
 * @return the physicsMass
 */
public Integer getPhysicsMass() {
    return physicsMass;
}

/**
 * @param physicsMass the physicsMass to set
 */
public void setPhysicsMass(Integer physicsMass) {
    this.physicsMass = physicsMass;
}

/**
 * @return the physicsCollistionGroup
 */
public Integer getPhysicsCollistionGroup() {
    return physicsCollistionGroup;
}

/**
 * @param physicsCollistionGroup the physicsCollistionGroup to set
 */
public void setPhysicsCollistionGroup(Integer physicsCollistionGroup) {
    this.physicsCollistionGroup = physicsCollistionGroup;
}

}

// LightHoverTank is simply a variation of a standard “HoverTank”
public class LightHoverTank extends HoverTank {

@Override
public Spatial buildSpatial() {
    super.setPhysicsMass(5);
    return super.buildSpatial();
}

}
[/java]

It kind of started as a Factory pattern and is starting to look more like the Builder pattern with the getters/setters. I started to think today that a fluent API might be good idea. Thoughts?

Fluent APIs are very hard to get right in Java.

I suspect you will be happier with simpler. Factories are certainly simpler and I suspect in most cases your factories will have a set of useful defaults and you won’t have to worry about that. I mean, I assume you are trying to make a game and not a game creation framework. That’s an important decision to make, really. I think many game developers forget that they are writing a game as the engineering mind wants to pull us towards massively general reusable systems. Note that this tends to be the opposite of actually “getting stuff done”.

Says me who wanted to write a simple hover bike game and now has a procedural tree editor published, is about to start open sourcing the terrain engine, and still is no closer to actually having a game. :wink:

@pspeed said: Fluent APIs are very hard to get right in Java.

That is what I hear and see. It seems more complicated than I want at this point.

@pspeed said: I suspect you will be happier with simpler. Factories are certainly simpler and I suspect in most cases your factories will have a set of useful defaults and you won't have to worry about that. I mean, I assume you are trying to make a game and not a game creation framework. That's an important decision to make, really. I think many game developers forget that they are writing a game as the engineering mind wants to pull us towards massively general reusable systems. Note that this tends to be the opposite of actually "getting stuff done".

Says me who wanted to write a simple hover bike game and now has a procedural tree editor published, is about to start open sourcing the terrain engine, and still is no closer to actually having a game. :wink:

I’m trying to decide that at this point. As a newcomer to game development in general, I just want to get it done. However as a seasoned developer overall, I’m drawn towards the idea of architecture and frameworks and other such lofty things.

In all honesty, the thought of an RTS “game creation framework” built on top of jME3 has crossed my mind.

I agree,

says me, who wanted a simple space game, and now wrote a own ES, networking, and after 6 years actually have a spaceship that can fly around !!1!

@Empire Phoenix said: I agree,

says me, who wanted a simple space game, and now wrote a own ES, networking, and after 6 years actually have a spaceship that can fly around !!1!

And yet, I think you’ve accomplished so much more! :wink:

Note: if you are really set on something really general and builder-like… then just go full bore and add groovy scripting to your application. Configure your spatials with groovy then and avoid a lot of boiler plate headaches.

@pspeed said: Note: if you are really set on something really general and builder-like... then just go full bore and add groovy scripting to your application. Configure your spatials with groovy then and avoid a lot of boiler plate headaches.

I had considered scripting. I used UnrealScript back in the day for some mods and had a good experience with it. I noticed that there is some discussion of Groovy integration on the wiki, but it is a little hard to follow. Is there some examples somewhere?

Well yes basically doing that game stuff (from way before jme) has lead me to where I am in life :slight_smile:

Anyway back to the topic, what might help you is something like annovention, that allows you to search for tagged classes, and register them properly.
(Spring framework can do the same and more, but I find it overkill for games)

That way you can do some more flexibility.

https://code.google.com/p/annovention/

@grghost said: I had considered scripting. I used UnrealScript back in the day for some mods and had a good experience with it. I noticed that there is some discussion of Groovy integration on the wiki, but it is a little hard to follow. Is there some examples somewhere?

Groovy integration isn’t really that hard… which may be why examples are lacking, I don’t know.

I mean, literally the code is as simple as (presuming groovy-all.jar is in your project dependencies):
[java]
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName(“groovy”);
Bindings bindings = engine.createBindings();
bindings.put( “myObject”, someObject );
engine.eval(“println myObject”);
[/java]

Where ‘bindings’ is where you put the stuff you want to expose to the script. eval() can be passed a Reader or a String or whatever.

That’s all part of standard Java:
http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html

Groovy is nice because it has some built in boiler-plate for passing parameters as maps and stuff. So even if you didn’t want to implement a full builder pattern, in groovy you could do something like:
[java]
myFactory = new DudeFactory(name:“John”, hitPoints:123, etc…)
[/java]

That would automatically call setName, setHitPoints, etc. during object instantiation.

i create a Factory/Manager App State for each type of piece in my game. (actors app state, scenery app state, decals app state. etc);

the app state handls all the stuff like pause/unpause, starting/ending the simulation, screen resizing, global quality settings, etc etc for the spatials it controls. If your game uses a seperate model outside of the scene graph, youd use this app state to read the model and do the appropriate spawning/despawning of spatials and moving them around and stuff like that.

just one way to do it.

@icamefromspace said: i create a Factory/Manager App State for each type of piece in my game. (actors app state, scenery app state, decals app state. etc);

the app state hands all the stuff like pause/unpause, starting/ending the simulation, screen resizing, global quality settings, etc etc for the spatials it controls. If your game uses a seperate model outside of the scene graph, youd use this app state to read the model and do the appropriate spawning/despawning of spatials and moving them around and stuff like that.

just one way to do it.

Yeah, “state crazy” is the only way to be. :slight_smile: Take a look at the main class for the SimArboreal tree editor:
https://code.google.com/p/simsilica-tools/source/browse/trunk/SimArboreal-Editor/src/main/com/simsilica/arboreal/TreeEditor.java

All of the magic is in the constructor:
[java]
public TreeEditor() {
super(new StatsAppState(), new DebugKeysAppState(),
new BuilderState(1, 1),
new MovementState(),
new DebugHudState(),
new TreeOptionsState(),
new LightingState(),
new GroundState(),
new SkyState(),
new AvatarState(),
new TreeParametersState(),
new ForestGridState(),
new AtlasGeneratorState(),
new FileActionsState(),
new PostProcessorState(),
new ScreenshotAppState("", System.currentTimeMillis()));
}
[/java]

@Empire Phoenix said: Anyway back to the topic, what might help you is something like annovention, that allows you to search for tagged classes, and register them properly. (Spring framework can do the same and more, but I find it overkill for games)

That way you can do some more flexibility.

https://code.google.com/p/annovention/

That is something I hadn’t considered. I use Spring a lot on other non-game projects and I was thinking about implementing a game server using it. I suppose it could be used on the client as long as all of its automagic doesn’t get in the way. For that reason, something like annovention sounds very interesting…

@pspeed said: Groovy integration isn't really that hard... which may be why examples are lacking, I don't know.

I mean, literally the code is as simple as (presuming groovy-all.jar is in your project dependencies):
[java]
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName(“groovy”);
Bindings bindings = engine.createBindings();
bindings.put( “myObject”, someObject );
engine.eval(“println myObject”);
[/java]

Where ‘bindings’ is where you put the stuff you want to expose to the script. eval() can be passed a Reader or a String or whatever.

That’s all part of standard Java:
http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html

Groovy is nice because it has some built in boiler-plate for passing parameters as maps and stuff. So even if you didn’t want to implement a full builder pattern, in groovy you could do something like:
[java]
myFactory = new DudeFactory(name:“John”, hitPoints:123, etc…)
[/java]

That would automatically call setName, setHitPoints, etc. during object instantiation.

I guess I never really looked at it using common sense. That might be a good way to go, but I’m not sure what it would really buy me over Java itself. Maybe unit properties defined in XML would be something better… as long as we are dealing with a fixed set of behaviors (controls).

@icamefromspace said: i create a Factory/Manager App State for each type of piece in my game. (actors app state, scenery app state, decals app state. etc);

the app state handls all the stuff like pause/unpause, starting/ending the simulation, screen resizing, global quality settings, etc etc for the spatials it controls. If your game uses a seperate model outside of the scene graph, youd use this app state to read the model and do the appropriate spawning/despawning of spatials and moving them around and stuff like that.

just one way to do it.

I am doing that for certain classes of entities so far, however as the list of core “units” in an RTS game grows, all of those app states could become expensive.

On another note, I fully agree with and embrace the composite “entity” model where behaviors and data converge into the entity. While this departs from standard OOP inheritance, I foresee my concrete “builder” mechanism would probably follow inheritance in at least some way (see example above).

I really appreciate the feedback, you all have given me a lot to consider! =D

Always favor composition over inheritance.

An aside: XML is such an ugly ugly format over the more elegant alternatives. You could use groovy for your config files and then have the flexibility to do more than just define some properties if you needed to… plus the syntax will be 1000x more expressive and you won’t spend your life typing greater-than and less-than symbols. Even json would be a huge improvement over XML.