Scope confusion
by John Klima · in Torque Game Engine · 06/08/2005 (12:03 am) · 7 replies
Hi all,
pounding away here, got what i'm sure is a totally briliant question that i'm sure has a stupid answer. wait, other way around. actually, it's more of a hypothetical question which should help to resolve my confusion re scope and object access
okay, i'm using the advanced camera w/ tutorial.base. in my default.bind.cs, in toggleFirstPerson() lets say i want to do something like this:
%client.camera.setTransform(%client.player.getEyeTransform());
in toggleFirstPerson() i don't have %client as a param. so how the heck do i get at my player (or any other object in the scene) if it is not expressly passed as a parameter from somewhere else where it is in scope?
in other words, where's the scenegraph, how do i recurse it, how can i make everyone in the game drop dead when i press the "K" key (hypothetical :).
lemme know if my question doesn't make sense (as that might be the problem in the first place).
thanks!
j
pounding away here, got what i'm sure is a totally briliant question that i'm sure has a stupid answer. wait, other way around. actually, it's more of a hypothetical question which should help to resolve my confusion re scope and object access
okay, i'm using the advanced camera w/ tutorial.base. in my default.bind.cs, in toggleFirstPerson() lets say i want to do something like this:
%client.camera.setTransform(%client.player.getEyeTransform());
in toggleFirstPerson() i don't have %client as a param. so how the heck do i get at my player (or any other object in the scene) if it is not expressly passed as a parameter from somewhere else where it is in scope?
in other words, where's the scenegraph, how do i recurse it, how can i make everyone in the game drop dead when i press the "K" key (hypothetical :).
lemme know if my question doesn't make sense (as that might be the problem in the first place).
thanks!
j
#2
If the code isn't 100% correct, its because I am at work, and I couldn't look it up to just make sure. If you want to see the methods you can call from the clientGroup object, just type the command clientGroup.dump(); in the torque console.
06/08/2005 (10:20 am)
Well if you just want to arbitrarily get clients, check out "clientGroup". If i am not mistaken it would go something like this:for(%c=0;%c<clientGroup.getCount();%c++)
{
clientGroup.getObject(%c).kill();
}If the code isn't 100% correct, its because I am at work, and I couldn't look it up to just make sure. If you want to see the methods you can call from the clientGroup object, just type the command clientGroup.dump(); in the torque console.
#3
06/08/2005 (10:23 am)
Just keep in mind that clientGroup is server side, not on each of the individual clients. In his original question, he wanted to affect a server side object (%client), on the client side--which means that you have to network it, as the second poster pointed out a technique for.
#4
both suggestions clarify some things. of course both answers add some to the confusion as well - thankfully without sacrificing productivity in the short term, i can continue w/ my mucking about.
so taking my "kill all" question, what does zepp's "clientGroup is server side, not on each of the individual clients" mean in practical terms? if i were to "kill all" in the clientGroup, does this result in unexpected behavior on some of the clients?
lets take a more benign and realistic example. perhaps a player triggers some area effect spell that shrinks all other players in range to half their original size. normally i'd have a spell class and an onCast callback that iterates all player geometry in a globally available scenegraph, finds those in range, and sets their scale to .5
would i use the clientGroup, check distance from each to the triggering player, and set all in range to half scale, or is their a more integrated way of doing such a thing? does the trigger happen on the client side and then the effect proliferate to the server, or does the whole thing transpire on the server? does the client handle only device input and final display?
lets take another realistic example. lets say an NPC wants to get to the other side of the road, but there is a big old bombed out 18 wheeler in the way. i've handled this in the past with an NPC "future ghost" that has an onCollide() callback that is fired prior to the real bot actually colliding. when the future collision is detected, i grab the collided geom, get it's bounding box, find the corner points, and plot a path around the obstacle by evaluating each corner point's distance to the NPC's goal point. very lightweight pathfinding. so given torque, how would i approach this problem?
just trying to get a grip on where things happen, and more important, why.
i've read tons of the docs and tutorials, and at this point, until that magic click occurs, the more i read the more confused i get. my problem is that as a programmer i have been accoustomed to handling just about everything myself, short of the actual rendering. is there a big old hierarchical diagram in the docs somewhere that i have yet to stumble across, that indicates what is accessable and from where?
answers to any of the above most welcome!! lemme know if i should bust this up into multiple posts.
j
06/08/2005 (12:55 pm)
Thanks all,both suggestions clarify some things. of course both answers add some to the confusion as well - thankfully without sacrificing productivity in the short term, i can continue w/ my mucking about.
so taking my "kill all" question, what does zepp's "clientGroup is server side, not on each of the individual clients" mean in practical terms? if i were to "kill all" in the clientGroup, does this result in unexpected behavior on some of the clients?
lets take a more benign and realistic example. perhaps a player triggers some area effect spell that shrinks all other players in range to half their original size. normally i'd have a spell class and an onCast callback that iterates all player geometry in a globally available scenegraph, finds those in range, and sets their scale to .5
would i use the clientGroup, check distance from each to the triggering player, and set all in range to half scale, or is their a more integrated way of doing such a thing? does the trigger happen on the client side and then the effect proliferate to the server, or does the whole thing transpire on the server? does the client handle only device input and final display?
lets take another realistic example. lets say an NPC wants to get to the other side of the road, but there is a big old bombed out 18 wheeler in the way. i've handled this in the past with an NPC "future ghost" that has an onCollide() callback that is fired prior to the real bot actually colliding. when the future collision is detected, i grab the collided geom, get it's bounding box, find the corner points, and plot a path around the obstacle by evaluating each corner point's distance to the NPC's goal point. very lightweight pathfinding. so given torque, how would i approach this problem?
just trying to get a grip on where things happen, and more important, why.
i've read tons of the docs and tutorials, and at this point, until that magic click occurs, the more i read the more confused i get. my problem is that as a programmer i have been accoustomed to handling just about everything myself, short of the actual rendering. is there a big old hierarchical diagram in the docs somewhere that i have yet to stumble across, that indicates what is accessable and from where?
answers to any of the above most welcome!! lemme know if i should bust this up into multiple posts.
j
#5
In general, nothing but rendering, movement input, and audio happens on the client side of the equation. Everything else is done on the server. You may want to dig in to the networking concepts, specifically how (and why) objects are ghosted, how scoping works, and related concepts to get over the hump in understanding how things work.
One reference that I personally find useful is the object hierarchy list that is generated from dOxygen. You can look at the stock 1.3 version here, or you can also generated your own dOxygen output locally. A good place to start would be the beginning, so if you start at ConObject and go down in the inheritence chain, you can see what is added at each level, and why.
06/08/2005 (2:20 pm)
For your "ae" example, you'll want to look at the use of containerRadiusSearch(), which is I think demo'ed in crossbow.cs. It basically does what you want--looks for objects within a certain radius of a world point.In general, nothing but rendering, movement input, and audio happens on the client side of the equation. Everything else is done on the server. You may want to dig in to the networking concepts, specifically how (and why) objects are ghosted, how scoping works, and related concepts to get over the hump in understanding how things work.
One reference that I personally find useful is the object hierarchy list that is generated from dOxygen. You can look at the stock 1.3 version here, or you can also generated your own dOxygen output locally. A good place to start would be the beginning, so if you start at ConObject and go down in the inheritence chain, you can see what is added at each level, and why.
#6
06/08/2005 (6:03 pm)
On the client-side you can use LocalClientConnection as your "%client" variable. It is also handy to be able to get at LocalClientConnction.player (your Player) and LocalClientConnection.camera (the initially created camera).
#7
this opens things up a bit. for some reason i had not stumbled upon the class hierarchy diagrams, they help quite a bit.
j
06/08/2005 (7:14 pm)
Thanks guys,this opens things up a bit. for some reason i had not stumbled upon the class hierarchy diagrams, they help quite a bit.
j
Torque Owner Walter Yoon
So something like this would be your modified toggleFirstPerson() function in default.bind.cs:
function toggleFirstPerson(%val) { if (%val) { $firstPerson = !$firstPerson; commandToServer('NewServerCommand'); } }and you'd need to add this function to commands.cs:
function serverCmdNewServerCommand(%client) { //put in whatever you need to do here. }