Game Development Community

W-key acclerate handler

by Tim Hutcheson · in Torque Game Engine · 06/08/2005 (10:22 am) · 19 replies

Can anyone point me to the c++ code that handles the press of the 'w' key which accelerates the character?

#1
06/08/2005 (10:25 am)
It generates a move... that move is handled in Player::processtick ... or rather, it is directly handled in updatemove ... which is interpolated in updatepos

EDIT: A caution... its not friendly in there. Make sure you at least back things up and be prepared toget frustrated.

What you trying to do anyways ?
#2
06/08/2005 (10:32 am)
Hi, Chris. Player::ProcessTick is where I'm adding some code driven by a socket to move the player. I'm investigating simple movement right now but notice that the animation sequences are not working doing it this way.

When you say 'generates a move', where does the Move structure get filled in? I've been studying the code in AIPlayer::getAIMove(Move *movePtr) as a reference.

Thanks
#3
06/08/2005 (10:35 am)
Well, I am not exactly sure. I thought it was done in default.bind.cs methods for some reason, but Im not entirely sure...

It doesnt really matter where the move is populated...

UpdateMove is where you need to look... Mind you that is a generalization since I dont know exactly what you are trying to do. If you tell me a little about what you are trying to change I can help you more.
#4
06/08/2005 (10:56 am)
For a test, I'm just trying to replace the keyboard w,a,s,d keys with a little socket handler that reproduces the effect (disregarding the key-down, key-up issues for the moment).
#5
06/08/2005 (11:02 am)
@Tim: As Chris mentioned, let's take a quick step back and figure out what you are trying to do here.

For example:
Quote:
Player::ProcessTick is where I'm adding some code driven by a socket to move the player.

--This is very, very much not the way to be handling move events to the server. Mousemove and Input events are processed as part of the network layer, if you open up GameInterface.h/cc you'll see a list of the basic NetEvents that are transmitted to and from a client.
#6
06/08/2005 (11:48 am)
@Stephen: With all due repect, let's take a quick step back to the question. I prefaced everything I said with the admonition that this is just a little test code created in the process of exploring some sort of socket interface, for whatever reason I might have. And so, I mentioned I was jamming a little code into the processTick as a point of study (because Chris brought it up). Which led me to the question, how does the 'w' key get processed in the first place? I can make the player move around from the with my test code (which I agree is a dumb bit of moving around), but how does the whole sequence of events play out from the time one presses the w-key until the player begins accelerating? A fair amount of searching from the point where the 'w' key is bound to 'accelerate' failed to connect all the dots for me. Hence the question, "Can anyone point me to the c++ code that handles the press of the 'w' key which accelerates the character?"
#7
06/08/2005 (11:52 am)
@Tim - Have your questions all been answered then ? and if so, can you maybe speal about the whole string of events from the time the w key is pressed, to the time it hits the processTick() ?
#8
06/08/2005 (12:07 pm)
@Chris: ??? Hard to tell if your post was in reponse to my last, but I haven't any answers yet for what happens when the w-key is pressed. I mean it's obvious what happens but just how is it hooked together programatically, causing the animations sequences to play for running etc. as the motion is performed. Sorry if I can't seem to express the question better.
#9
06/08/2005 (12:34 pm)
@Tim:
Quote:
With all due repect, let's take a quick step back to the question. I prefaced everything I said with the admonition that this is just a little test code created in the process of exploring some sort of socket interface, for whatever reason I might have.

Not trying to be rude here, but no you didn't--at least not in this thread! And with the way this thread progressed, it appeared that you were trying to modify how the command event system works, by wiring it directly to the Player class, which isn't a good idea.

To answer your specific, first post question (which evolved quickly):
Look at ActionMap.cc/h in /engine/sim for the very specifics of the ActionMap code. Here is a rough breakdown of how things happen (at a -very- high level):

--Player issues a key press/mouse event.
--OS passes that to the engine platform layer.
--Engine defines it as an appropriate event type on the client side, and checks to see if it's in an action/move map table.
--An appropriate netEvent is created for the type, and network delivered to the server side.
--Server side processes the netEvent, and passes it to the simulation for event handling.
--event is processed within the simulation, and modifies the appropriate objects within the simulation.

There is also a fair rundown of the initial connection sequence for TGE from a client to the server located Here...while it doesn't talk about post-connection sequences, it does point you to pretty much the exact same code in many files.
#10
06/08/2005 (12:53 pm)
@Stephen: I'll take a look at the the link you provided and see if I can figure it out from there.
#11
06/08/2005 (1:10 pm)
@Stephen: Read your resource (have read it before) and what I am interested in determining is what happens AFTER the last line in your resource.

Quote:We are now connected, and "in game"!

Somwhere the clients keystroke 'w' is interpreted or package up and sent to the server and a Move structure is filled in for Player::processTick() to act on. And within that context, the objects animation sequence is selected (run, sidestep, etc) and initiated. I'm just trying to find out how that happens.
#12
06/08/2005 (1:13 pm)
Right..and that's the summary I gave above. All of the net event processing happens in the same files (and many of the same functions) that are mentioned in the Connection Sequence Overview, with the addition of the ActionMap.cc processing client side.
#13
06/08/2005 (2:21 pm)
@Stephen: Something still missing here in the picture. I spent an hour breakpointing in ActionMap.cc (and related files) and can trap the 'w' key action but trying to reveal from there how the event eventually results in the acceleration of the player, with animations playing, is far from obvious. Breakpoints and stepping are not up to the task of determining this due to the event driven and networked nature of the problem so I abandon that approach for now. What's needed is more detailed knowledge of the system and I can't seem to find that. But thanks for trying.
#14
06/08/2005 (2:40 pm)
That sets the move structure, I imagine... and it sets the acceleration and velocity and position in updatemove and updatepos in the player class... That is where the animation is determiend...
#15
06/08/2005 (3:57 pm)
Ok, ignoring the OS level handling, things start at:

client/scripts/defaults.bind.cs: moveMap.bind( keyboard, w, moveforward );

in the same file, moveforward is defined:

function moveforward(%val)
{
   $mvForwardAction = %val;
}

What this does is assign the value passed by the OS to the global client side script variable $mvForwardAction.

Now, buried deep in engine/game/gameConnectionMoves.cc, we have:

Con::addVariable("mvForwardAction", TypeF32, &mForwardAction);

What this does is tie the $mvForwardAction script variable to the address space of the MoveManger::mForwardAction variable. Ok, hold that thought.

The MoveManager is responsible for coordinating the server and the client's move event states across a (potentially latency ridden) connection. It has a large amount of logic that tracks which move the client thinks it's on, which one the server knows it's on, and how to synchronize the two. Understanding how this logic works isn't required for this level of discussion, just know that the states are kept in synch over the network with a bit of tracking logic.

Now, back to our variable: every single tick, all of the appropriate movement variables are packed up and delivered to the server. Since the server is aware of the control object that has been assigned to that client, it applies these variables directly to that object (processing of course to make sure it makes sense, etc.). The move is pulled off the connection in GameConnection::GetNextMove, which is where the values are parsed into a specific move, added to the move event queue for processing as appropriate.

Now finally, take a look at void Player::processTick(const Move* move), specifically the parameter that is sent in: note that it's a move! This is where the simulation handles the move events themselves--moves are sent in as part of the call to processTick().

Disclaimer: this isn't an area of expertise for me, but I did just get a quick and dirty lecture from Ben G. about how this works at the important discussion level. Any inaccuracies are mine, not his!
#16
06/08/2005 (7:13 pm)
I follow all of that and thanks for the detailed explanation of the MoveManager functionality. When I was poking around with the move structure in the processTick routine, it was not obvious how the move is coordinated with the player animation or how the animation is initiated in the sequence you described above. Can you share (or anyone) a little insight about that?
#17
06/08/2005 (7:33 pm)
With regard to the animation initiation, I figured that out when I noticed the ActionAnimationList initialization and the use of the actionList array. So maybe I'm beginning to see how this works, the correct animation is produced simply as a function of which direction the player is moving...
#18
06/09/2005 (6:17 am)
Ok, I figured this move and acceleration thing out, at least well enough. There is no place other than in Player::processTick that generates acceleration of the player or fills in the move structure related to this other than the setting of, for example, the move.y term in moveForward() to indicate forward or backward as +1.0 or -1.0. Similarly, I suppose for left and right with the move.x term.

I found that integration to provide velocity is performed within Player::updatePos as long as move.y is 1.0, for example to accelerate, and then is decellerated when move.y is 0.0. And so on. And I see how the actionList array selects and sychronizes the animation based on the type or direction of movement.

I think I get it. Thanks both Chris and Stephen who took the time to explain some of this. To resolve it I started putting console printf's in updatePos and worked my way backward, looking at the console window after pressing the w key for a moment.

So should I want to do such a dumb thing as putting a backdoor socket control directly into player and vehicle objects, I think I know how to do it now.
#19
06/09/2005 (9:31 am)
Take a look at setActionThread and pickActionThread as well--both of those deal with what animation actually gets played based on your interaction with the terrain (both velocity and contact). Keep in mind that the animations are all blended, so there is a LOT of interaction in there.