how do i turn this simple game into multiplayer(2 players) game

so i made this simple 3D game from jmonkey3 tutorial, and i just learn about java socket recently. i understand how the client, and server works, how they send data using string type in chat application. but i dont know how to implement server client to this game. i dont know how do i send the data to the server(how to get the coordinate, since other simple 2d java network game that i’ve come across send coordinate x,y), what to update, and other thing like what should the server handle(rules?)…

about the multiplayer game that i had in mind:
basically 2 players shoot the ball(each player have one ball), into the middle of the spiral thing model… as simple as that, no counting for score, no timer, coz i just want the network part to work 1st, others can add later…

hope u guys can guide me.

heres the pic for better picture

the code


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jme3test.guligames_package;
 
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
//import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
//import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
//import com.jme3.math.Vector2f;
import com.jme3.scene.Geometry;
//import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;
//import com.jme3.texture.Texture.WrapMode;

//import com.jme3.animation.AnimChannel;
//import com.jme3.animation.AnimControl;
//import com.jme3.animation.AnimEventListener;
//import com.jme3.animation.LoopMode;
//import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
//import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.scene.Node;
/**
 * Example 12 - how to give objects physical properties so they bounce and fall.
 * @author base code by double1984, updated by zathras
 */

/**
 *
 * @author NURAINI
 */
public class guligames extends SimpleApplication{
  /** Prepare the Physics Application State (jBullet) */
  private BulletAppState bulletAppState;
  private RigidBodyControl landscape;
  private RigidBodyControl guliColli;
  private Spatial gulicourt;
  private Spatial guli;
  
  public static void main(String args[]) {
    guligames app = new guligames();
    app.start();
  }
  
  /** Prepare Materials */
  Material ball_mat;
 
  /** Prepare geometries and physical nodes for bricks and cannon balls. */
  private RigidBodyControl    ball_phy;
  private static final Sphere sphere;
 
  static {
    /** Initialize the cannon ball geometry */
    sphere = new Sphere(16, 16, 0.2f, true, false);
    sphere.setTextureMode(TextureMode.Projected);
  }
 
  @Override
  public void simpleInitApp() {
    // We re-use the flyby camera for rotation, while positioning is handled by physics
    viewPort.setBackgroundColor(new ColorRGBA(0f, 0f, 0f, 1f));
    
    /** Set up Physics Game */
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    //bulletAppState.getPhysicsSpace().enableDebug(assetManager);

    
    // Display a line of text with a default font
        guiNode.detachAllChildren();
        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
        BitmapText helloText = new BitmapText(guiFont, false);
        helloText.setSize(guiFont.getCharSet().getRenderedSize());
        helloText.setText("Soccer Game");
        helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
        guiNode.attachChild(helloText);
    
    // Load a model from test_data (OgreXML + material + texture)
        gulicourt = assetManager.loadModel("Models/guliplace/guliplace.mesh.xml");
        //Spatial fieldsoccer = assetManager.loadModel("Models/field/field.mesh.xml");        
        gulicourt.scale(4.0f, 4.0f, 4.0f);
        //ninja.rotate(-4.0f, -3.0f, 0.0f);
        //fieldsoccer.setLocalScale(1f);
        gulicourt.setLocalTranslation(2.0f, -0.5f, -2.0f);
    
    // We set up collision detection for the scene by creating a
    // compound collision shape and a static RigidBodyControl with mass zero.
    CollisionShape sceneShape =
            CollisionShapeFactory.createMeshShape((Node) gulicourt);
    landscape = new RigidBodyControl(sceneShape, 0);
    gulicourt.addControl(landscape);
    bulletAppState.getPhysicsSpace().add(landscape);
    rootNode.attachChild(gulicourt);
    
    // Load a model from test_data (OgreXML + material + texture)
        guli = assetManager.loadModel("Models/gelung2/gelung2.mesh.xml");
        //Spatial fieldsoccer = assetManager.loadModel("Models/field/field.mesh.xml");        
        guli.scale(4.0f, 4.0f, 4.0f);
        //guli.rotate(0.0f, 1.5f, 0.0f);
        //fieldsoccer.setLocalScale(1f);
        guli.setLocalTranslation(1.5f, 0.1f, -0.1f);
        CollisionShape keeperShape =
            CollisionShapeFactory.createMeshShape((Node) guli);
        guliColli = new RigidBodyControl(keeperShape, 0);
        guli.addControl(guliColli);
        bulletAppState.getPhysicsSpace().add(guliColli);
        rootNode.attachChild(guli);
                
        // You must add a light to make the model visible
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        rootNode.addLight(sun);
            
    /** Configure cam to look at scene */
    cam.setLocation(new Vector3f(2f, 6f, 8f));
    cam.lookAt(new Vector3f(1, 1, 0), Vector3f.UNIT_Y);
    /** Add InputManager action: Left click triggers shooting. */
    inputManager.addMapping("shoot", 
            new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
    inputManager.addListener(actionListener, "shoot");
    /** Initialize the scene, materials, and physics space */
    initMaterials();
    initCrossHairs();
  }
  
  /**
   * Every time the shoot action is triggered, a new cannon ball is produced.
   * The ball is set up to fly from the camera position in the camera direction.
   */
  private ActionListener actionListener = new ActionListener() {
    public void onAction(String name, boolean keyPressed, float tpf) {
      if (name.equals("shoot") && !keyPressed) {
        makeCannonBall();
      }
    }
  };
 
  /** Initialize the materials used in this scene. */
  public void initMaterials() { 
    ball_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    TextureKey key2 = new TextureKey("Models/guli/yellow.jpg");
    key2.setGenerateMips(true);
    Texture tex2 = assetManager.loadTexture(key2);
    ball_mat.setTexture("ColorMap", tex2);
  }
 
  /** This method creates one individual physical cannon ball.
   * By defaul, the ball is accelerated and flies
   * from the camera position in the camera direction.*/
   public void makeCannonBall() {
    /** Create a cannon ball geometry and attach to scene graph. */
    Geometry ball_geo = new Geometry("cannon ball", sphere);
    ball_geo.setMaterial(ball_mat);
    rootNode.attachChild(ball_geo);
    /** Position the cannon ball  */
    ball_geo.setLocalTranslation(cam.getLocation());
    /** Make the ball physcial with a mass > 0.0f */
    ball_phy = new RigidBodyControl(1f);
    /** Add physical ball to physics space. */
    ball_geo.addControl(ball_phy);
    bulletAppState.getPhysicsSpace().add(ball_phy);
    /** Accelerate the physcial ball to shoot it. */
    ball_phy.setLinearVelocity(cam.getDirection().mult(18));
  }
 
  /** A plus sign used as crosshairs to help the player with aiming.*/
  protected void initCrossHairs() {
    guiNode.detachAllChildren();
    guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
    BitmapText ch = new BitmapText(guiFont, false);
    ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
    ch.setText("+");        // fake crosshairs :)
    ch.setLocalTranslation( // center
      settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
      settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
    guiNode.attachChild(ch);
  }
}

I’m sorry to say this, but you should have been thinking about multiplayer from the start. All the physics should be done on the server. the client sends the server the player’s control state. the server sends back where each of the objects are, and their speed(for client side interpolation). then the client renders.