How to use multiple SyncObjectManager's to build different remote Objects?

Hi, im building my game on the flagrushnetworking example. I have ran into some troubles and have few questions:


  1. Besides the flagrush bike, I have a box that moves up when mouse is clicked. The client builds this remote object  not as a box but as a flagrush bike instead.







    I did use a custom SyncObjectManager.


public class SimpleSyncObjectManager implements SyncObjectManager{
   
    private Box playerBox;
    private Node scene;
 
    public void setScene(Node scene){
        this.scene = scene;
    }
   
    public Object create(SynchronizeCreateMessage scm){
        System.out.println("CREATING PLAYER!");
        return BuildPlayer();
    }
   
    public boolean remove(SynchronizeRemoveMessage srm, Object obj){
        System.out.println("DESTROYING PLAYER!");
        return removeRemotePlayer((Box)obj);
    }
   
    public Box BuildPlayer(){
        playerBox = new Box("PlayerBox",new Vector3f(0,0,0), new Vector3f(2,4,2));
        playerBox.setModelBound(new BoundingBox());
        playerBox.updateModelBound();
       
        //Shouldn't be here
        updateScene();
       
        return playerBox;
    }
   
    private boolean removeRemotePlayer(Box player){
        return player.removeFromParent();
    }
   
    public void updateScene(){
        scene.attachChild(playerBox);
        scene.updateRenderState();
    }
   
}



And added it to clientSyncManager in the client program.


      SynchronizationManager clientSyncManager = new SynchronizationManager(client, controller);
      clientSyncManager.addSyncObjectManager(this);  //the TestClient class extends Test class which in turn extends the SyncObjectManager
      SimpleSyncObjectManager ssom = new SimpleSyncObjectManager();
      clientSyncManager.addSyncObjectManager(ssom);



The same create is probably called for both objects so that the box is not built to the client side.


How can I make it so that my box is built to the client?



You need to extend JMEGraphicalController and override:


public SynchronizeMessage createSynchronizationMessage(Spatial spatial)



So that it changes the SynchronizeMessage created depending on the Spatial passed in. You can create your own extension of SynchronizeMessage (extending Synchronize3DMessage for jME) that provides additional parameters to determine what type of object to create.

Tx for the reply, but i still dont get it. I don't understand what the Synhcronize3DMessage and JMEGraphicalController have got to do with building different objects to jme scene since Synchronize3DMessage only holds the info about position and rotation. As I understand the graphical-controller just points the message position and rotation to the spatials position and rotation and vice-versa.



In my case is the createSynchronizationMessage(Spatial spatial) called (for the box) from the server side and

applySynchronizationMessage(SynchronizeMessage message, Spatial spatial) called from the client side?

Where are these methods called from?



My box's location and rotation is syncronized but just the wrong graphical object is created to the scene from the client side.



Is there any example You could point me to, where different objects are syncronized?

Do I just need 1 SynchronizationManager in a server/client and multiple SyncObjectManagers?

Do I need multiple GraphicalControllers or is just 1 enough if I only need to sync position and rotation?

Ok, i think I'm starting to get it tx to some other thread where:


public class BasicSyncManager implements SyncObjectManager
{
   //synchronized objects
   private ArrayList<VehicleNode> vehicles;
   private Vector<Weapon> weapons;

   public Object create(SynchronizeCreateMessage scm)
   {
      if(scm instanceof SynchronizeCreatePlayerMessage){
         System.out.println("Create Player Message");
         VehicleNode vehicle = new VehicleNode(1,1,1);
         vehicle.setModelBound(new BoundingBox());
         vehicle.updateModelBound();
         scene.attachChild(vehicle);   
         vehicle.updateGeometricState(0, true);
         vehicle.updateRenderState();
         return vehicle;
      }
      
      if(scm instanceof SynchronizeCreateWeaponMessage){
         System.out.println("Create Weapon Message");
         
         SynchronizeCreateWeaponMessage message = (SynchronizeCreateWeaponMessage)scm;
         
         
            Weapon weapon = new Weapon();
//line causing the prob--->   weapons.add(weapon);
            weapon.setModelBound(new BoundingSphere());
            weapon.updateModelBound();
            scene.attachChild(weapon);   
            weapon.updateGeometricState(0, true);
            weapon.updateRenderState();
         
         return weapon;
      }
      
      return null;
   }

   public boolean remove(SynchronizeRemoveMessage srm, Object obj)
   {
      System.out.println("Remove Message");
      System.out.println(obj.getClass());
      System.out.println(obj.toString());
//      if(obj instanceof Weapon){
//         return weapons.firstElement().removeFromParent();
//      }
      
      return false;
   }

}




So if I would have SynchronizeCreateWeaponMessage and SynchronizeCreatePlayerMessage classes, then would this approach be right?

Yes, that's right…sorry for leading you down the slightly incorrect path…though I wrote it, it has been a long time since I've touched JGN 2.0, so I'll blame that for my mistaken advice. :-p



You can also use the same methodology to override the apply method to add additional functionality if you need to do more than positional synchronization.  However, in many cases you may just want to create a custom message and send it for things that are not going to be changing every update.

Hei, that's ok at least you pointed me to some direction and thanx to you, I got my issue solved. I now have the box built in server and client and it's synchronized.



However, in many cases you may just want to create a custom message and send it for things that are not going to be changing every update.


How to I do that, can you point me to some jgn test?

Look at the samples for JGN…that's one of the core features of JGN.

OMG, it's so simple, I can just use sendToPlayer(T message, short playerId) and I just actually was able to use it :).