DistributedNode

I was trying to activeSmoothing before the object was actually generated. I moved the call to after and not getting an error now. But still don’t have all the pieces to make it smooth yet. Do I need to manually start a task to do the smoothing or something? I thought this was handled by the DistributedSmoothNode. I’m doing trial and error.
After the avatar is generated I do:
self.avatar.activateSmoothing(True, False)
self.avatar.startSmooth()

At this point I am sending setX and setH updates when you press the direction. I’m not entirely sure all the methods that have to be called to get this running. Am I missing something? Do I need to manually send a sync request? I guess I’m going to have to look under the hood of this class to figure out what needs to happen. :confused:

Ok, after playing with this some. I am trying to call setSmXY(x,y) and it throws an error that x must be a float. After some investigation I found that it is passing ‘self’ as 2 parameters. So the x value which should be the number i’m passing in is instead of type avatar. Any thoughts on this?

The other methods work as they should which is very odd.

Alright, I have finally made some progress on this. I had to change my steerring method and take samples of the postion every 10 frames or so. I’ll post my updates on here once I refine the smoothing and such some more. The movement is a little bit jerky and the remote object kind of zig zags a little.

Edit: this is not doing any smoothing yet. I’m working on it

base.dc

from direct.distributed import DistributedObject
from direct.distributed import DistributedNode
from newServer import Movable, Avatar

typedef uint32 DoId;

import types;

dclass Movable {

	set_xyz(int16 x, int16 y, int16 z) required broadcast ram;
	set_hpr(int16 h, int16 p, int16 r) required broadcast ram;
	set_xyzhpr(int16 x, int16 y, int16 z, int16 h, int16 p, int16 r) required broadcast ram;

};

dclass Avatar : Movable {

	setName(string text) required broadcast;
	tellPlayer(string message) broadcast;
};

newServer.py

#############################################################################
## This sample program shows how to use a DistributedSmoothNode that shows ##
## up on multiple clients and is updated across the network without        ##
## dealing with low level sockets and datagrams hardly at all.  It also    ##
## does smoothing on remote clients as the name implies                    ##
## Feel free to make any suggestion/modifications                          ##
## Enjoy!                                                                  ##
##                                                                         ##
## -=Zanz=- May 2009                                                       ##
#############################################################################

import direct.directbase.DirectStart
from direct.showbase.ShowBaseGlobal import *
from direct.showbase.DirectObject import DirectObject
from direct.distributed.DistributedObject import *
from direct.distributed.DistributedSmoothNode import DistributedSmoothNode
from direct.distributed.ClientRepository import *
from direct.distributed.ServerRepository import *
from direct.gui.OnscreenText import OnscreenText
import sys

font = loader.loadFont("cmss12")

def addTitle(text):
	return OnscreenText(text=text, style=1, fg=(1,1,1,1), font = font,
	pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)

def addInstructions(pos, msg):
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1), font = font,
                        pos=(-1.3, pos), align=TextNode.ALeft, scale = .05)

# Our Movable class that can be inherited into subclasses such as the Avatar class
# to allow the subclass to be moved around as a DistributedSmoothNode
class Movable(DistributedSmoothNode):
	def __init__(self,cr):
		DistributedSmoothNode.__init__(self,cr)
		# you have to initialize NodePath.__init__() here because it is not called
		# in DistributedSmoothNode.__init__()
		NodePath.__init__(self, 'avatar')
	
	# all the required methods as defined in the base.dc file
	# note: for each method defined in the dc file that begins with
	# set needs a corresponding get method in the class definition
		
	def set_xyz(self,x,y,z):
		self.setSmPos(x,y,z)
		
	def get_xyz(self):
		return tuple((self.getX(),self.getY(),self.getZ()))

	def set_hpr(self,h,p,r):
		self.setSmHpr(h,p,r)

	def get_hpr(self):
		return tuple((self.getH(),self.getP(),self.getR()))

	def set_xyzhpr(self,x,y,z,h,p,r):
		self.setSmPosHpr(x,y,z,h,p,r)

	def get_xyzhpr(self):
		return tuple((self.getX(),self.getY(),self.getZ(),self.getH(),self.getP(),self.getR()))
		
class Avatar(Movable):
	def __init__(self,cr):
		Movable.__init__(self,cr)
		self.cr = cr
		self.name = "unknown"
		self.zone = 1
		s = loader.loadModel('smiley')
		s.reparentTo(self)
		self.reparentTo(render)
		self.readyToMove = 0

	# required fields as defined in the base.dc file
	def setName(self, name):
		self.name = name

	def getName(self):
		return self.name

	def tellPlayer(self, message):
		print "message from "+self.name+">"+message

class MyClientRepository(ClientRepository):
	def __init__(self,dcFileNames):
		ClientRepository.__init__(self, dcFileNames)

	# we need to delete the DistributedNode when the server tells us to
	def handleDelete(self,di):
		doId = di.getUint32()
		do = self.doId2do.get(doId)
		do.delete()

class Server(DirectObject.DirectObject):

	def __init__(self):
		self.serverRepository = ServerRepository(tcpPort=4400,udpPort=4400,dcFileNames=["base.dc"])
		print "Server Repository instantiated"

class Client(DirectObject.DirectObject):

	def __init__(self):
		self.clientRepository = MyClientRepository(dcFileNames=["base.dc"])
		#self.clientRepository.setVerbose(1)
		#self.clientRepository.notify.setDebug(0)
		self.host = "127.0.0.1"
		self.port = "4400"
		self.avatar = 0
		self.zone = 1
		self.sampleInterval = 8       # this is the how many frames between sending network updates
		self.sampleCounter = 0

	def connectToServer(self, host, port):
		if(self.clientRepository.isConnected()): return
		self.clientRepository.connect([URLSpec("http://"+host+":"+port)],
			self.connectSuccess,[],self.connectFail,[])

	def connectSuccess(self):
		print "Connected to server"
		base.taskMgr.add(self.tskMonitorConnection,"tskMonitorConnection")

	def connectFail(self):
		print "Connection to host failed"

	def move(self, task):
		toggle = 0;
		if(self.avatar == 0): return Task.cont
		# only send a network update every so often to not flood the wire
		# you can modify self.sampleInterval in __init__ above to change the sample rate
		if(self.sampleCounter >= self.sampleInterval):
			self.sampleCounter = 0
			# if connection is lost to the server stop all movement
			if(self.clientRepository.isConnected() == 0):
				return Task.done
			self.avatar.sendUpdate("set_xyzhpr",[self.avatar.getX(),self.avatar.getY(),self.avatar.getZ(),
				self.avatar.getH(),self.avatar.getP(),self.avatar.getR()])
		elapsed = globalClock.getDt()
		if (self.keyMap["cam-left"]!=0):
			self.avatar.setH(self.avatar, +(elapsed*120))
		if (self.keyMap["cam-right"]!=0):
			self.avatar.setH(self.avatar, -(elapsed*120))
		if (self.keyMap["forward"] !=0):
			self.avatar.setY(self.avatar, -(elapsed*25))
		if (self.keyMap["backward"] !=0):
			self.avatar.setY(self.avatar, +(elapsed*25))
		if (self.keyMap["up"] !=0):
			base.camera.setP(base.camera, +(elapsed*50))
		if (self.keyMap["down"] !=0):
			base.camera.setP(base.camera, -(elapsed*50))
		if (self.keyMap["oobe"] !=0):
			base.oobe()
			self.keyMap["oobe"] = 0
		if (self.keyMap["menu"] !=0):
			self.toggleMenu()
			self.keyMap["menu"] = 0;
		self.sampleCounter += 1
		return Task.cont

	def tskMonitorConnection(self, task):
		if(self.clientRepository.isConnected() == 0):
			print "Connection to server lost"
			return Task.done
		if(self.avatar == 0):
			if(self.clientRepository.haveCreateAuthority()):
				# this is the local avatar
				self.avatar = self.clientRepository.createWithRequired("Avatar",1)
				# turn on smoothing, but not prediction
				self.avatar.activateSmoothing(True,False)
				# start the smoothing task
				self.avatar.startSmooth()
				base.camera.setPos(0,-0.5,0.4)
				base.camera.reparentTo(self.avatar)
				base.camera.setH(180)
				taskMgr.add(self.move,"moveTask")
		return Task.cont

	def setZone(self, task):
		self.clientRepository.sendSetZoneMsg(self.zone)
		return Task.done


class World(DirectObject.DirectObject):

	def __init__(self):

		self.title = addTitle("DistributedSmoothNode Demo")
		self.inst1 = addInstructions(0.95, "[ESC]: Quit")
		self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Left")
		self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Right")
		self.inst4 = addInstructions(0.80, "[Up Arrow]: Move Forward")
		self.inst5 = addInstructions(0.75, "[Down Arrow]: Move Backwards")
		self.inst6 = addInstructions(0.70, "[a]: Look up")
		self.inst7 = addInstructions(0.65, "[z]: Look down")
		self.inst8 = addInstructions(0.60, "[o]: Toggle oobe")
		self.inst9 = addInstructions(0.55, "[s]: Start server")
		self.inst10= addInstructions(0.50, "[c]: Connect to server")

		self.oobe = 0

		self.myClient = Client()

		self.myClient.keyMap = {"forward":0, "backward":0, "cam-left":0, "cam-right":0,
			"up":0, "down":0, "oobe":0, "menu":0}

		self.accept("escape", sys.exit)
		self.acceptOnce("c", self.connectToServer)
		self.acceptOnce("s", self.startServer)
		self.accept("arrow_up", self.setKey, ["forward",1])
		self.accept("arrow_up-up", self.setKey, ["forward",0])
		self.accept("arrow_down", self.setKey, ["backward",1])
		self.accept("arrow_down-up", self.setKey, ["backward",0])
		self.accept("arrow_left", self.setKey, ["cam-left",1])
		self.accept("arrow_left-up", self.setKey, ["cam-left",0])
		self.accept("arrow_right", self.setKey, ["cam-right",1])
		self.accept("arrow_right-up", self.setKey, ["cam-right",0])
		self.accept("a", self.setKey, ["up",1])
		self.accept("a-up", self.setKey, ["up",0])
		self.accept("z", self.setKey, ["down",1])
		self.accept("z-up", self.setKey, ["down",0])
		self.accept("o",self.setOobe)	
		
		base.disableMouse()

	def setKey(self, key, value):
		self.myClient.keyMap[key] = value
	
	def connectToServer(self):
		self.myClient.connectToServer(self.myClient.host,self.myClient.port)
		# can't send this too soon or it gets lost so send it in the next frame
		base.taskMgr.doMethodLater(0,self.myClient.setZone,"setzone")

	def startServer(self):
		myServer = Server()

	def setOobe(self):
		base.oobe()

w = World()
run()

As you can see this uses the same steering method as the RR example. Enjoy!

-=Z=- :open_mouth:

I have realized I was not passing any timestamp data along with the updates. I am in the process of trying to get things synced now. I haven’t found the magical formula yet.

I am trying this. Does this look right?

			self.avatar.sendUpdate("set_xyzhpr",[self.avatar.getX(),self.avatar.getY(),self.avatar.getZ(),
				self.avatar.getH(),self.avatar.getP(),self.avatar.getR(),
				globalClockDelta.localToNetworkTime(globalClock.getRealTime())])

That’s the right idea, although you’ll probably need frame time instead of real time. And there is a convenience method called globalClockDelta.getFrameNetworkTime() which wraps up both function calls for you.

Just to muddy the situation even further, though, the sendUpdate() call you are trying to make is actually made automatically when you start the sendPosHpr task (by calling dsnode.startPosHprBroadcast()). The actual call to sendUpdate() is hard to find; it’s buried in C++ code in cDistributedSmoothNodeBase.cxx, presumably for efficiency’s sake when there are thousands of these things moving around at once.

You will be responsible for syncing the clocks between all of your clients and your server. This is also fairly complicated; it is discussed somewhat in the other thread regarding distributed smoothing.

David

When I enable sendPosHprBroadcast it sends me an error:
AssetError: No field named clearSmoothing in class Avatar

This is a method of DistributedNodeBase
Do I need to define this in the dc file?

Yes, it takes an int8 parameter (that has no meaning).

David

I’m getting a whole bunch of errors now:

Assertion failed: field != (DCField *)NULL at line 293 of direct/src/distributed
/cDistributedSmoothNodeBase.cxx
Assertion failed: _mode == M_pack || _mode == M_repack at line 245 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 177 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 177 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 177 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 177 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 177 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 177 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack || _mode == M_repack at line 194 of c:\p\p3d\p
anda3d-1.6.2\direct\src\dcparser\dcPacker.I
Assertion failed: _mode == M_pack at line 100 of c:\p\p3d\panda3d-1.6.2\direct\s
rc\dcparser\dcPacker.cxx
:distributed(warning): Unexpected pack error in DC file.
Traceback (most recent call last):
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 178, in tskMonitorCon
nection
    self.avatar.startPosHprBroadcast()
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNodeBase.py", line
94, in startPosHprBroadcast
    self.cnode.sendEverything()
AssertionError: field != (DCField *)NULL at line 293 of direct/src/distributed/c
DistributedSmoothNodeBase.cxx
:task(error): Exception occurred in PythonTask tskMonitorConnection
Traceback (most recent call last):
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 579,
in readerPollUntilEmpty
    while self.readerPollOnce():
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 584,
in readerPollOnce
    if self.checkDatagram():
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 178, in tskMonitorCon
nection
    self.avatar.startPosHprBroadcast()
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNodeBase.py", line
94, in startPosHprBroadcast
    self.cnode.sendEverything()
AssertionError: field != (DCField *)NULL at line 293 of direct/src/distributed/c
DistributedSmoothNodeBase.cxx
:task(error): Exception occurred in PythonTask readerPollTask
Traceback (most recent call last):
  File "newServer.py", line 249, in <module>
    w = World()
  File "newServer.py", line 208, in __init__
    self.myClient = Client()
  File "newServer.py", line 109, in __init__
    self.clientRepository = MyClientRepository(dcFileNames=["base.dc"])
  File "newServer.py", line 92, in __init__
    ClientRepository.__init__(self, dcFileNames)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 16, in __
init__
    ClientRepositoryBase.__init__(self, dcFileNames = dcFileNames)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepositoryBase.py", line 46, i
n __init__
    self.readDCFile(dcFileNames)
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 286,
in readDCFile
    self.importModule(dcImports, moduleName, importSymbols)
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 383,
in importModule
    module = __import__(moduleName, globals(), locals(), importSymbols)
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 250, in <module>
    run()
  File "c:\Panda3D-1.6.2\direct\showbase\ShowBase.py", line 2423, in run
    self.taskMgr.run()
  File "c:\Panda3D-1.6.2\direct\task\TaskNew.py", line 471, in run
    self.step()
  File "c:\Panda3D-1.6.2\direct\task\TaskNew.py", line 429, in step
    self.mgr.poll()
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 579,
in readerPollUntilEmpty
    while self.readerPollOnce():
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 584,
in readerPollOnce
    if self.checkDatagram():
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 178, in tskMonitorCon
nection
    self.avatar.startPosHprBroadcast()
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNodeBase.py", line
94, in startPosHprBroadcast
    self.cnode.sendEverything()
AssertionError: field != (DCField *)NULL at line 293 of direct/src/distributed/c
DistributedSmoothNodeBase.cxx

I don’t know what this means.

Here is my dc file:

from direct.distributed import DistributedObject
from direct.distributed.DistributedSmoothNode import DistributedSmoothNode
from newServer import Movable, Avatar

typedef uint32 DoId;

import types;

dclass Movable : DistributedSmoothNode {

	set_xyz(int16 x, int16 y, int16 z) required broadcast ram;
	set_hpr(int16 h, int16 p, int16 r) required broadcast ram;
	set_xyzhpr(int16 x, int16 y, int16 z, int16 h, int16 p, int16 r, int16 timestamp) required broadcast ram;


};

dclass Avatar : Movable {

	setName(string text) required broadcast;
	tellPlayer(string message) broadcast;

	clearSmoothing(int8 whatever) broadcast;

};

Hrm. In your dc file, there needs to be a definition of DistributedSmoothNode’s interfaces, and clearSmoothing is one of these. In fact, you need to define all of the fundamental dc interfaces. Truthfully, this fundamental dc file should be part of the public distribution, but I guess it didn’t make it in there. It should look something like this:

struct BarrierData {
  uint16 context;
  string name;
  uint32 avIds[];
};

// The most fundamental class
dclass DistributedObject {
  // These are used to support DistributedObjectAI.beginBarrier() and
  // the matching DistributedObject.doneBarrier().  If you don't call
  // these functions, you don't care about these distributed methods.
  // (Actually, you probably don't care anyway.)
  setBarrierData(BarrierData data[]) broadcast ram;
  setBarrierReady(uint16 context) airecv clsend;
};

dclass DistributedNode: DistributedObject {
  // if other than '', overrules setParent
  setParentStr(blob token) broadcast ram ownsend airecv;
  setParent(uint32 token) broadcast ram ownsend airecv;

  setX(int16 / 10) broadcast ram ownsend airecv;
  setY(int16 / 10) broadcast ram ownsend airecv;
  setZ(int16 / 10) broadcast ram ownsend airecv;
  setH(int16 % 360 / 10) broadcast ram ownsend airecv;
  setP(int16 % 360 / 10) broadcast ram ownsend airecv;
  setR(int16 % 360 / 10) broadcast ram ownsend airecv;

  setPos: setX, setY, setZ;
  setHpr: setH, setP, setR;
  setPosHpr: setX, setY, setZ, setH, setP, setR;
  setXY: setX, setY;
  setXZ: setX, setZ;
  setXYH: setX, setY, setH;
  setXYZH: setX, setY, setZ, setH;
};

dclass DistributedSmoothNode: DistributedNode {
  // Component set pos and hpr functions.

  setComponentL(uint64) broadcast ram ownsend airecv;
  setComponentX(int16 / 10) broadcast ram ownsend airecv;
  setComponentY(int16 / 10) broadcast ram ownsend airecv;
  setComponentZ(int16 / 10) broadcast ram ownsend airecv;
  setComponentH(int16 % 360 / 10) broadcast ram ownsend airecv;
  setComponentP(int16 % 360 / 10) broadcast ram ownsend airecv;
  setComponentR(int16 % 360 / 10) broadcast ram ownsend airecv;
  setComponentT(int16 timestamp) broadcast ram ownsend airecv;

  // Composite set pos and hpr functions.  These map to combinations
  // of one or more of the above components.  They all include
  // setComponentT(), which must be called last.
  setSmStop: setComponentT;
  setSmH: setComponentH, setComponentT;
  setSmZ: setComponentZ, setComponentT;
  setSmXY: setComponentX, setComponentY, setComponentT;
  setSmXZ: setComponentX, setComponentZ, setComponentT;
  setSmPos: setComponentX, setComponentY, setComponentZ, setComponentT;
  setSmHpr: setComponentH, setComponentP, setComponentR, setComponentT;
  setSmXYH: setComponentX, setComponentY, setComponentH, setComponentT;
  setSmXYZH: setComponentX, setComponentY, setComponentZ, setComponentH, setComponentT;
  setSmPosHpr: setComponentX, setComponentY, setComponentZ, setComponentH, setComponentP, setComponentR, setComponentT;
  // special update if L (being location, such as zoneId) changes, send everything, intended to
  // keep position and 'location' in sync
  setSmPosHprL: setComponentL, setComponentX, setComponentY, setComponentZ, setComponentH, setComponentP, setComponentR, setComponentT;

  clearSmoothing(int8 bogus) broadcast ownsend;

  suggestResync(uint32 avId, int16 timestampA, int16 timestampB, 
                int32 serverTimeSec, uint16 serverTimeUSec,
                uint16 / 100 uncertainty) ownrecv clsend;
  returnResync(uint32 avId, int16 timestampB, 
               int32 serverTimeSec, uint16 serverTimeUSec,
               uint16 / 100 uncertainty) ownrecv clsend;
};

drwr: I just don’t think many people in the panda community have used this system much so the need hasn’t really arrisen. Hopefully through this process we will reveal everything that needs to be addressed to make this work.

This is the same error I was getting when trying to manually send the update and convert the time:

Traceback (most recent call last):
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 579,
in readerPollUntilEmpty
    while self.readerPollOnce():
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 586,
in readerPollOnce
    self.handleDatagram(self.private__di)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 140, in h
andleDatagram
    self.handleGenerateWithRequired(di)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 170, in h
andleGenerateWithRequired
    distObj = self.generateWithRequiredFields(dclass, doId, di)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 210, in g
enerateWithRequiredFields
    distObj.updateRequiredFields(dclass, di)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedObject.py", line 334, in
updateRequiredFields
    dclass.receiveUpdateBroadcastRequired(self, di)
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 63, in set_xyzhpr
    self.setSmPosHpr(x,y,z,h,p,r,timestamp)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNode.py", line 265,
 in setSmPosHpr
    self.setComponentTLive(timestamp)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNode.py", line 351,
 in setComponentTLive
    local = globalClockDelta.networkToLocalTime(timestamp, now)
  File "c:\Panda3D-1.6.2\direct\distributed\ClockDelta.py", line 260, in network
ToLocalTime
    diff = self.__signExtend(networkTime - ntime)
  File "c:\Panda3D-1.6.2\direct\distributed\ClockDelta.py", line 329, in __signE
xtend
    r = ((networkTime+32768) & NetworkTimeMask) - 32768
TypeError: unsupported operand type(s) for &: 'float' and 'int'
:task(error): Exception occurred in PythonTask readerPollTask
Traceback (most recent call last):
  File "newServer.py", line 240, in <module>
    w = World()
  File "newServer.py", line 199, in __init__
    self.myClient = Client()
  File "newServer.py", line 109, in __init__
    self.clientRepository = MyClientRepository(dcFileNames=["base.dc"])
  File "newServer.py", line 92, in __init__
    ClientRepository.__init__(self, dcFileNames)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 16, in __
init__
    ClientRepositoryBase.__init__(self, dcFileNames = dcFileNames)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepositoryBase.py", line 46, i
n __init__
    self.readDCFile(dcFileNames)
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 286,
in readDCFile
    self.importModule(dcImports, moduleName, importSymbols)
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 383,
in importModule
    module = __import__(moduleName, globals(), locals(), importSymbols)
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 241, in <module>
    run()
  File "c:\Panda3D-1.6.2\direct\showbase\ShowBase.py", line 2423, in run
    self.taskMgr.run()
  File "c:\Panda3D-1.6.2\direct\task\TaskNew.py", line 471, in run
    self.step()
  File "c:\Panda3D-1.6.2\direct\task\TaskNew.py", line 429, in step
    self.mgr.poll()
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 579,
in readerPollUntilEmpty
    while self.readerPollOnce():
  File "c:\Panda3D-1.6.2\direct\distributed\ConnectionRepository.py", line 586,
in readerPollOnce
    self.handleDatagram(self.private__di)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 140, in h
andleDatagram
    self.handleGenerateWithRequired(di)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 170, in h
andleGenerateWithRequired
    distObj = self.generateWithRequiredFields(dclass, doId, di)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepository.py", line 210, in g
enerateWithRequiredFields
    distObj.updateRequiredFields(dclass, di)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedObject.py", line 334, in
updateRequiredFields
    dclass.receiveUpdateBroadcastRequired(self, di)
  File "C:\Panda3D-1.6.2\serverClient2\newServer.py", line 63, in set_xyzhpr
    self.setSmPosHpr(x,y,z,h,p,r,timestamp)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNode.py", line 265,
 in setSmPosHpr
    self.setComponentTLive(timestamp)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNode.py", line 351,
 in setComponentTLive
    local = globalClockDelta.networkToLocalTime(timestamp, now)
  File "c:\Panda3D-1.6.2\direct\distributed\ClockDelta.py", line 260, in network
ToLocalTime
    diff = self.__signExtend(networkTime - ntime)
  File "c:\Panda3D-1.6.2\direct\distributed\ClockDelta.py", line 329, in __signE
xtend
    r = ((networkTime+32768) & NetworkTimeMask) - 32768
TypeError: unsupported operand type(s) for &: 'float' and 'int'

I’m not sure what is happening here, because i put in some debug messages in ClockDelta to print out networkTime and it sure looks like an int to me. Not sure where the float is coming from.

Well, you can see in the traceback that it’s coming from your set_xyzhpr() method, which is passing a seventh parameter, timestamp, to setSmPosHpr(). That timestamp is probably a floating-point number, where it should be an integer.

Note that you can use Python’s pdb module to interactively walk through the stack after an exception has occurred, and inspect each variable’s value directly at the time of the crash. Very useful for researching problems like this.

David

Sometimes an error can stare you in the face and you don’t see it. lol
I appreciate all the personal responses. I know your time is spread amongst many things and appreciate the time to help me out with this. I’ve been struggling to makes sense of the dc file and what needs to go in there.

Believe me, I really appreciate your taking the time to study it and figure it out. :slight_smile:

David

How do you use this pdb module? I’m kind of new to python. I’m a java convert. :wink:

You should use it as a program, actually (like gdb).
google.com/search?q=pdb+tutorial+python

Do I need to create a DistributedObject to use as the root node for the avatars? If so, is anything special required? Currently the avatars have no parentId. Also it’s looking for a getGameDoId() method in the repository. Is there some special container that needs to be the root node?

in handleUpdateField
    self.__doUpdate(doId, di, ovUpdated)
  File "c:\Panda3D-1.6.2\direct\distributed\ClientRepositoryBase.py", line 567,
in __doUpdate
    do.dclass.receiveUpdate(do, di)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNode.py", line 269,
 in setSmPosHprL
    self.setComponentL(l)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedSmoothNode.py", line 305,
 in setComponentL
    self.setLocation(self.parentId,l)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedNode.py", line 49, in set
Location
    DistributedObject.DistributedObject.setLocation(self, parentId, zoneId)
  File "c:\Panda3D-1.6.2\direct\distributed\DistributedObject.py", line 484, in
setLocation
    self.cr.storeObjectLocation(self, parentId, zoneId)
  File "c:\Panda3D-1.6.2\direct\distributed\DoCollectionManager.py", line 347, i
n storeObjectLocation
    elif parentId not in (0, self.getGameDoId()):
AttributeError: 'MyClientRepository' object has no attribute 'getGameDoId'

I see something that might be related in one of the sample.dc files that pro-rsoft linked to in the source:

   63 dclass DistributedObjectHolder : DistributedObject {
   64   dropObject(AvatarObject object);
   65 
   66   // You can also have an array of structs.  This specifies a
   67   // fixed-length array of five elements.  This is slightly more
   68   // optimal than an array of unrestricted length, since the length
   69   // prefix need not be transmitted as part of the message.
   70   setObjectList(AvatarObject objectArray[5]);
   71 
   72   // In addition to fixed-length arrays and unbounded arrays, you can
   73   // specify a range for the valid size of the array:
   74   setRelatedObjects(AvatarObject relatedObjects[0, 3 - 5] = []);
   75 };

Is this something that is required to define these classes or is this for something else that happens behind the scenes in one of the base classes?

Hmm, it might be simplest just to take the required tag off of these fields (or remove them altogether from the dc file). These are more advanced and can be added back in on some later date when you’re ready for them and you actually need them.

David

I’m not sure I follow. The code I posted there is not in my dc file. Which fields are you referring to?

Ah, my bad. I thought that getGameDoId() was being called because of a required field called setGameDoId() in the dc file. But I see that’s not the case; it’s being called by some more complex chain within the python code itself.

I think what’s happening is that people here have added code to ClientRepositoryBase and related classes, which is part of a larger piece that is only fully implemented in the Disney version of ClientRepository et al. These developers didn’t realize they were breaking the public distribution version of ClientRepository. This is not surprising, since no one has been supporting the public distribution.

Perhaps it will be best if I take some effort myself to straighten out this mess. Give me a couple of days to take a look at it.

David