Game Development Community

Cameras and Control Objects Confusion

by Eric Roberts · in Torque Game Engine · 06/03/2005 (2:01 pm) · 7 replies

Hi all,

I'm currently scripting my app from the ground up and now have stumbled for the past few days on a particular issue I find rather confusing. I'm trying to simply load a mission, and render it through a fixed viewpoint. No more no less.
It looks like from my console output I have sucessfully loaded a mission, GUI is set up, I just can't get it to render to my GameTSCtrl.
I called the common code scripts for createServer (singlePlayer), and set up a local connection
e.g.
createServer("SinglePlayer", "AAbase/data/missions/moon1.mis");
   %conn = new GameConnection(ServerConnection);
   %conn.connectLocal();

Now here's where I get horribly confused. How exactly does torque know where it's rendering from (or rather what orientation it's supposed to render at)? What defines the "camera" at which the world is viewed from? What exactly do I need to set up in "Game Connection"? Various examples from Ken Finney's book and the torque demo apps seem to use different methods.
Examples seem to indicate control objects. But what are they? Does it have to be a player object?

I tried to create a camera class and set that as my control object, but it failed.
This is the code that immediately follows the previous snippet
%camera = new Camera() {
      dataBlock = Observer;          
   }; 

   // Camera setup
  // %camera.setTransform(playerSpawnSphere.getTransform()); // where to put it
   %camera.setTransform("0 0 0 0 1 0 0");
   %conn.setControlObject(%camera);
   
   Canvas.setContent(playGui);

Also I get output that " 'Observer' is not a member of GameBaseData data block class" even though I've cut and paste the definition of the datablock from the demo app, and the script seems to have loaded fine.

As an extra bit of confusion I'm curious as to what the mCameraObject inside the Game Connection object is for. I saw someone experimenting with it in another thread, but it's still unclear as what it's used for? Could this be a solution to my problem (expose the get/set camera methods) ?

As you can probably tell right now I feel a little overwhelmed and a little lost, and I apologize for the length in advance. Please if there's a certain thread or resource that you think I may have missed that would help my understanding, kindly post a link.

Thanks for your time in advance,

- Eric

#1
06/03/2005 (2:10 pm)
You're almost right. You have to set the control object on the server's end of the connection - ie, ClientGroup.getObject(0) in this case. Setting it on the client end won't get you anywhere. :)
#2
06/03/2005 (3:10 pm)
First of all thank you very much for your speedy reply. :)

I think I've gained some insight into what my problem is! :) From what I gather I should be setting my control objects on the server side of the code, not the client. This makes sense.
I put this into my code:
function GameConnection::onClientEnterGame(%this)
{
   // Create a new camera object.
   %this.camera = new Camera() {
      dataBlock = Observer;
   };
   
   // Camera setup
  // %camera.setTransform(playerSpawnSphere.getTransform()); // where to put it
   %camera.setTransform("0 0 0 0 1 0 0");
   %conn.setControlObject(%this.camera);
   MissionCleanup.add( %this.camera );
}

This guarentees I'm creating the camera object on the server side and setting the control object on the server side. However, I'm still getting nothing rendered! Is there something else I'm missing?

And here's something else, the " 'Observer' is not a member of GameBaseData data block class " error dissapeared. Why is that?
However, does this mean I have to create my objects on the server side only? This seems like a silly question considering GUI objects are created on the client side (from what I believe).
The "playerSpawnSphere" (from the line commented out above) is a GUI defined object that fails to be created because " 'SpawnSphereMarker is not a member of GameBaseData data block class ". It seems like only objects created on the server can use datablocks? This isn't what I thought...

@Ben - the ClientGroup I'm wagering a guess is a global SimSet object holding all of the client objects? and getObject takes the index and returns the object at that index? What exactly resides at "0" and how did you know?
And examining the example code further I found a method called scopeToClient which seems to be a camera method (from onClientGame, %this.camera.scopeToClient(%this) is used).

Oh dear. Too many questions. It feels like I'm misunderstanding something fundamental to torque.

Again, thanks for your time in advance.

- Eric
#3
06/03/2005 (3:32 pm)
Actually, you've just about grasped it...yes, all "in game" objects should be created server side, and then ghosted (using the networking model) to the client. You've discovered all the basics, so here's just a short summary of the concept:

Torque actually runs both a client and a server in any game, including one that is single player. Responsibilities are loosely broken up like this:

CLIENT
--all rendering/audio output
--all GUI displays
--all user interface (move events)

SERVER
--game state management
---authoritative game object manager
---event processing
---networking/synchronization
--connection (clients) management
--other "authority based" requirements (persistence, accounts, etc.)

The main reason for this model is two fold:
A) Game security. The server will only broadcast information about game objects that the client currently observes, or is about to observe (the onCameraScopeQuery and scopeToClient calls you found). This keeps clients from having information about the game world they shouldn't, and avoids common hacking attempts.

B) Client synchronization for multi-player. Torque's network model is extremely powerful, and can maintain synchronization with as many clients as your infrastructure can handle. It does this by allowing the client and the server to communicate about each side's point of view regarding the current game state, which is authoritative on the server, and "ghosted" on the client(s).

So yes, you are very close to the understanding needed--just keep in mind that if something is "in the game world", it almost always should be created on the server side of the equation, and set to be ghosted to the client(s) as appropriate--which, at the scripting level, is handled for you.

Also, datablocks are transmitted to all clients at mission loading, so yes, they belong server side as well.
#4
06/03/2005 (5:57 pm)
Thank you again for your patience and your time. Your reply was greatly appreciated. I believe I have a much better grasp between server and client responsibilities, and their purposes.

On that note I would like to address the problem that I'm still having about " 'SpawnSphereMarker is not a member of GameBaseData data block class " which makes me think I'm having the same problem of trying to create an object that uses the SpawnSphereMarker datablock on the client (instead of first creating it on the server then ghosting it to the client). But the part that really kills me is that it's defined inside a .mis file that I load using createServer from the common modules. But I call createServer from the client (as does starter.fps)? And the object is being created on the client side? Starter.fps doesn't have this problem and it uses the same datablock in Stronghold.

But things I believe have gotten a little side tracked from what was some of the more original questions that caused me to post this thread. What exactly is a control object? What does it have to be? What can it be? What defines the "camera" view in which we see what we want rendered (and hopefully a little more specifically in script)?

And finally, since I'm still not rendering anything to my GameTSCtrl yet, and I'm still going back and forth between examples to see where the problem lies. So...
What steps am I missing? :)

Thanks again guys,

- Eric

- EDIT ---------------------------------
Turns out that MOST of my problems dealt with server/client issues ;). Thank you very much, I gained a sudden insight into "what has been wrong all of this time". I still am not exactly sure what a control object is but I think I have a better idea. I'm still working on getting something rendered, but I suddenly feel like I'm making progress, and as long as that's happening, that's a good thing ;). Thanks again.
- EDIT ---------------------------------
#5
06/04/2005 (1:39 pm)
The control object is the object that will recieve all keyboard inputs for processing. E.g. you could switch between a player object and a wheeledvehicle object using the setControlObject() command on the server side
#6
06/04/2005 (7:24 pm)
Thank you very much for clearing that up for me.
Would it also be correct to say it's the object in which you view the "mission" from?

Thanks a ton

- Eric
#7
06/07/2005 (5:13 am)
Try make your function like this:

function GameConnection::onClientEnterGame(%this)
{
   // Create a new camera object.
   %this.camera = new Camera() {
      dataBlock = Observer;
   };
   MissionCleanup.add( %this.camera );
   %this.camera.scopeToClient(%this);

   %this.setControlObject(%this.camera);

   // To place camera somewhere in the world:
   %this.camera.setTransform("0 0 300 1 0 0 0");
}

Make sure that the camera.cs file (from starter.fps) is executed, becuase that's where the Observer datablock is defined.