Game Development Community

CommandToServer and commandToClient

by gamer · in Torque Game Engine · 12/22/2006 (12:04 pm) · 16 replies

Is it true that you can only pass simple strings as arguments to client/server through these commands, you can pass any complex object(eg. a camera), correct?
thanks

#1
12/22/2006 (2:10 pm)
Yes and no -- when scripting, there is the appearance of being able to send pretty much any variable value (other than a TorqueScript array) as an argument. I think they all end up getting converted to strings as they were sent, though.

For example, you can pass the name of any GameBase-derived object as an argument, but those can be handled as strings. Once you get the name of an object, you can call methods on it, as if you had been sent the whole object.

At least that's how I've understood it. I may be wrong.
#2
12/22/2006 (2:54 pm)
But if the client and server are in on different machines, then when I use commandToclient to pass the id/name of a gamebase-derived object is useless to a client since that id does not exist on the client, right?
thanks
#3
12/22/2006 (3:03 pm)
No, I think it does exist on the client side if it's a GameBase subclass. I think that's what the whole ghosting thing is about. The actual data gets transmitted with the packUpdate, etc... methods.

I think. Anyway, it seems to work that way.
#4
12/22/2006 (3:15 pm)
I see, so in commandToClient(%client, %gameBaseObject), do I need to convert %gameBaseObject id its ghost id or something? or just commandToClient do that for me automatically.
#5
12/22/2006 (3:28 pm)
That's the part I'm always confused about.

I think, based on my own experience, that you only need to convert the id when you are dealing with an object received on the server from the client. I think that object ids sent from the server to the client are valid on the client inside the clientCmd handler function.

The experience I'm basing this on is using the Array resource to send a list of things from the server to the client. I just pass the array as an argument to commandToClient, and I can use the Array methods on what I receive (which 'echo' reveals is just an ID number) inside the matching clientCmd function.
#6
12/22/2006 (3:29 pm)
Ok I tried it something like this
commandToClient(%client, "test",%camera); //Camera class is GameBased
function clientCmdTest(%camera){
echo(%camera);
%camera.dump();
}

clientCmdTest does get a cameraId, but it doesn't reference any object.
#7
12/22/2006 (3:31 pm)
Were you doing that where the server and client are both on the same machine?
#8
12/22/2006 (3:37 pm)
Hmm...I do something similar with an Array instance, and it seems to be valid on the client side:

on the server
%array = new Array();
//...add stuff to it
commandToClient(%client,'UpdateInventory',%array);

on the client:
function clientCmdUpdateInventory(%array)
{
    //fill the inventory GUI with the items in the array
	IG_InventoryList.clear();
	%invCount = %array.count();
	for(%idx=0;%idx < %invCount;%idx++)
	{
		%invValue = %array.getValue(%idx);
		%invKey = %array.getKey(%idx);
		%invLine = %invKey TAB %invValue;
		IG_InventoryList.addRow(%idx,%invLine);
	}	

}

One issue I notice is that you are using the "test" parameter as a string, instead of as a tag. You might try using single quotes around it instead, though if that were the problem, I wouldn't expect your clientCmdTest handler to get called at all. Hmm...
#9
12/22/2006 (3:38 pm)
Yes, I did do it with both client and server on the same machine, but I didn't use globals to do it or anything. Wouldn't it work the same in each case this way? Good question.
#10
12/22/2006 (3:53 pm)
Here's a thread I found about this:
http://www.garagegames.com/mg/forums/result.thread.php?qt=27399

It looks like you might want to use 'resolveGhostID' on the client side to the get the client-side ID.

And I am going to have to go through my code and see if I need to add this to deal with multiplayer situations. I haven't run it on seperate machines very often.

on edit:
The script command is "resolveGhostID", not "resolveGhost".

Like this:
%clObj = ServerConnection.resolveGhostId(%srvObj);
#11
12/22/2006 (3:55 pm)
No, I think the reason it works in your case is because the id passed by cmdToClient exists only on server, but since your client and server are running in the same environment, this server object is accessible by your client in the clientCmdUpdateInventory. In fact all server objects and will be accessible by client and vice versa in your case.
I think cmdToClient(%client, 'UpdateInventory', %array) simplely pass %array as a number/string to the client. No object is actually transferred through the network.
#12
12/22/2006 (3:57 pm)
Here's another resource about this I just came across:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4852
#13
12/22/2006 (4:53 pm)
Thanks for the link! that's very helpful. some function names have changed since then, but it helped me understand the ghosting better. Server should sent ghostId to client in commandToClient, and client should resolveGhostId.

here's what I should do:
on server:
commandToClient(%client, 'acceptObservation',%client.getGhostId(%cl.getCameraObject())); //where %cl is another client

on client:
function clientCmdAcceptObservation(%tcamera){
   %cl=ServerConnection;
   %targetCamera=%cl.resolveGhostId(%tcamera);
}
#14
12/22/2006 (5:24 pm)
Well, that isn't working for me. When I call %clientConnection.getGhostID on the vehicle the player is currently mounted to, and a newly created Array object, it returns -1, and complains, "NetConnection::serverToGhostID - could not find specified object".

I wondered if there are scoping issues at play here, so I tried "%client.scopeToClient(%vehicle)" before I tried to get the ghost ID on the server, and still got -1 back from 'getGhostID' -- and the same complaint in the console log.

Well, it seems I have thoroughly confused myself in the process of responding to your question. :D
#15
12/23/2006 (3:58 pm)
Is your %clientConnection a server side object? it should be. and your Array Object needs to be a member of the %clientConnection... I think... try that and let me know if it works.
#16
12/23/2006 (7:00 pm)
Yes, it's doing it on the server side (I did it in a script function on GameConnection). I looked over the arrayobject.cc file again, and realized it was not designed to be ghosted anyway -- it's missing all the update methods.

Finally, after thinking about the implications of ghosting an array (if I wrote the appropriate methods), especially one that never changes after it's sent, I decided to just construct a string out of the array on the server side, and send that. I added this function to save time:
function Array::toString(%this)
{
    %retstring = "";
    %invCount = %this.count();
	for(%idx=0;%idx < %invCount;%idx++)
	{
		%key = %this.getKey(%idx);
		%value = %this.getValue(%idx);
		%retstring = %retstring @ %key TAB %value NL "";
	}	
    return %retstring;
}

Since, in actuality, I want the client-side array to be read-only anyway (it's for the inventory display), this seems like a more appropriate tactic all around.

As for why I can't seem to get a ghost ID on the server side for the vehicle the player is mounted in -- no idea. In that case also, though, I re-examined what I really needed, and since it was only the shape file path of vehicle the GUI (to be displayed in an objectView in the GUI), I changed it to just send that as a string.

Still confused, but now I have some workarounds for my confusion...