Object Driven Model Tutorial

From PX Documentation

Jump to: navigation, search

Contents

Introduction

In this section we will show how to use the Object Model family of NetDog functions to maintain synchronized object state between clients and servers.

Installing Objects

Both the client and server need to install the object type(s) which will be used.

For a server, it may look like:

   InstallObjectType(ObjectType::Player, sizeof(Player), "Player",
     &playerCreateObjectCallback, &playerCreateObjectValidationCallback, 
     &playerDeleteObjectCallback, &playerDeleteObjectValidationCallback, 
     &playerUpdateObjectCallback, &playerUpdateObjectValidationCallback);

Where we are defining a new object called Player. The server typically installs two types of callbacks--normal "event handler" type callbacks as well as validation callbacks. The event handler type callbacks are called every time an object-related event (create, delete, update) is received. The validation callbacks are called to allow the server to determine which clients, if any, should receive the create/delete/update event in question.

Similarly the client will install the object type as follows:

   NDInstallObjectType(ObjectType::Player, sizeof(Player), "Player", &playerCreateObjectCallback, NULL, &playerDeleteObjectCallback, NULL, &playerUpdateObjectCallback, NULL);

He must be installing the exact same object type and specify the same object size. The client does not have any validation callbacks because validation is not necessary for clients.

Then, the client and server must register the fields of the new object, in our case a Player object. The server and client must call these functions in exactly the same manner. The only exception is that they may differ in whether they install a callback. If installed, it's fine for the behavior of the callback to differ between server and client.

   NDRegisterField(ObjectType::Player, PlayerField::ownerID, NDObjectFieldType::tInt, sizeof(int), 0, 0, NULL, "ownerID");
   NDRegisterField(ObjectType::Player, PlayerField::pos, NDObjectFieldType::tFloat, sizeof(float), sizeof(int), 0, &playerPosChangeCB, "pos");

Where our player has a unique identifier called ownerID, and a certain position associated with it.

Clients then have some extra work to create their objects.

First, the session must be started by the server. If the flag NDConnFlags::startImmediately is set on the server, it should start automatically.

   // Wait for our conn to be active
   while (!NDConnIsStarted(connID)){
     NDEventLoop();
     NDSleepMS(10); // 10ms
  }

Then, the server must assign our unique ownerID which identifies us on the network.

   ourOwnerID = NDConnGetLocalOwnerID(connID);

At this point we can create a new object! We do this by simply instantiating one on the client side, and letting the server know we want it created. For our example,

   Player p;
   p.ownerID = ourOwnerID;
   p.pos = 2.5f; // Our starting position
   int res = NDCreateObject(ObjectType::Player, &p);
   // Wait for our player to be created
   while (!NDObjectIDEqual(ourObjectID, NDObjectIDDefault)){
      NDEventLoop();
      NDSleepMS(10); // 10ms
   }


This will create a player with an initial position and have a unique identifier (the same as our ownerID) to be used later.

Manipulating Objects

Now that we have the object created, an object will need to be updated during system use. This is simply done by modifying the object locally then to tell the system to update the object globally. This is done as follows:

   float newPos = p->pos + (float)NDRandom(3) - 1.0f; // Randomly move +/- 1 (or not move at all (though we still send the move event just for kicks))
   dbg0("Moving from oldPos[%.2f] to newPos[%.2f]\n", p->pos, newPos);
   p->pos = newPos;
   //Updates object on system
   NDBeginObjectUpdate();
   NDUpdateObjectField(ourObjectID, PlayerField::pos);
   NDEndObjectUpdate();

Deleting Objects

Deleting objects is simple!

   NDDeleteObject(ourObjectID);

Which will delete the object with the object with unique identifier ourObjectID.

Other Tutorials

  1. Server tutorial
  2. Irrlicht Client tutorial