My rocky transition from T2D to TGE... a little help
by Matt Troup · in Torque Game Engine · 10/13/2005 (5:09 pm) · 17 replies
Welp,
The world editor is a crazy magical tool.
However,
I got used to scripting-in my objects with T2D and then checking them out.
I'd just like to do something very simple:
1) Create a datablock
2) Instantiate the object
3) Give that object a Z velocity on keypress
There seems to be slight differences in the way datablocks are written and how you create an instance of your object between T2D and TGE. To the best of my ability, I've been able to see the format is something like:
Then to give that object a Z velocity I create the keybinds. So, when I hit the space bar I'll call:
Except, I don't know if there is a "setLinearVelocity" function in TGE. It seems to be T2D exclusive.
How should I change this to do what I'd like it to do?
The world editor is a crazy magical tool.
However,
I got used to scripting-in my objects with T2D and then checking them out.
I'd just like to do something very simple:
1) Create a datablock
2) Instantiate the object
3) Give that object a Z velocity on keypress
There seems to be slight differences in the way datablocks are written and how you create an instance of your object between T2D and TGE. To the best of my ability, I've been able to see the format is something like:
datablock myObject(insertName)
{
position = "x y z";
rotation = "1 0 0 0"; //should I use setTransform here? If you create an object in the world editor it doesn't use setTransform.
scale = "1 1 1";
shapeName = "~/data/shapes/myShape.dts";
};
$objectInstance = new TSStatic()
{
dataBlock = insertName;
}Then to give that object a Z velocity I create the keybinds. So, when I hit the space bar I'll call:
function sendObjectUp()
{
$objectInstance.setLinearVelocityZ( insertValueHere );
}Except, I don't know if there is a "setLinearVelocity" function in TGE. It seems to be T2D exclusive.
How should I change this to do what I'd like it to do?
About the author
#2
For player movement control, you'll want to look at the functions in default.keybinds.cs, and there is a particularly good resource on AI bots, I think if you search for "AIGuard" you should find some good links.
The transition is going to take some time, but be patient with yourself (and TGE!)--it's just that 3 dimensions do add quite a bit of complexity, and FPS style games (which is the genre you are basically working with in the demo/starter world) have a lot of pre-determined assumptions. It can take some time to get them all in your head :)
10/13/2005 (7:09 pm)
Mike is correct, there is a setVelocity, but it's not designed really for use in the way you are thinking. Most of the time if it is an object the player is going to control then you use the move manager system, and if it is some form of server side object/enemy, you will set up some form of AI...check out the "Getting Started" area of the tutorials, as well as some of the many resources here on AI, "bots", and the like.For player movement control, you'll want to look at the functions in default.keybinds.cs, and there is a particularly good resource on AI bots, I think if you search for "AIGuard" you should find some good links.
The transition is going to take some time, but be patient with yourself (and TGE!)--it's just that 3 dimensions do add quite a bit of complexity, and FPS style games (which is the genre you are basically working with in the demo/starter world) have a lot of pre-determined assumptions. It can take some time to get them all in your head :)
#3
10/13/2005 (7:12 pm)
And the FlyingVehicle updateForce code is an excellent example of how velocities should be handled in TGE/TSE... a very straightforward class in regards to physics, since it isn't constrained like the wheeled or hovervehicles in most places.
#4
10/13/2005 (7:13 pm)
Great follow-up Mike...making your player a FlyingVehicle will give you probably the least restricted (in terms of physics assumptions) object to play around with!
#5
I did go about writing this question a few ways, Stephen. I noticed those pre-determined assumptions right away, so I'm trying to strip down the tutorial.base as much as I can for what I'd like to make. I've seen quite a few people asking recently for "stripped down" versions of TGE to make it more user friendly. I believe part of this movement is because of the ease of use the community has seen with T2D. I really like that T2D starts with a blank slate... and a giant comment block in client.cs that says "add your custom code here" that lets you know when the computer is done setting up the smoke and mirrors and you can start coding your magic (it gives it a welcoming feeling). I'm also sure you guys at garage games thought about a "stripped down" version of TGE long before you released the engine. However, making those pre-determined assumptions in the engine upon release was probably a key point in moving your fanbase from FPS modders to customers and potential game publishees. After a certain amount of time, though, GG may want to consider releasing that stripped down model to bring in new talent (as more and more of these people will probably not be FPS/Adventure/RPG fans - I'm guessing). If they don't bring in new customers then they won't be receiving any potential "killer apps" because the current pool of game devs will be out of ideas (an overwhelming amount already "not worth looking at" according to Jeff Tunnel's latest .plan).
...after I typed that up a few different ways I realized Garage Games has already released a stripped down version of TGE... T2D! So, I quickly deleted what I wrote so nobody would be able to read it.
- Preaching to the choir, I know, but I just thought any constructive input would be welcome.
10/14/2005 (3:46 am)
Ah! Great. Thanks. I did go about writing this question a few ways, Stephen. I noticed those pre-determined assumptions right away, so I'm trying to strip down the tutorial.base as much as I can for what I'd like to make. I've seen quite a few people asking recently for "stripped down" versions of TGE to make it more user friendly. I believe part of this movement is because of the ease of use the community has seen with T2D. I really like that T2D starts with a blank slate... and a giant comment block in client.cs that says "add your custom code here" that lets you know when the computer is done setting up the smoke and mirrors and you can start coding your magic (it gives it a welcoming feeling). I'm also sure you guys at garage games thought about a "stripped down" version of TGE long before you released the engine. However, making those pre-determined assumptions in the engine upon release was probably a key point in moving your fanbase from FPS modders to customers and potential game publishees. After a certain amount of time, though, GG may want to consider releasing that stripped down model to bring in new talent (as more and more of these people will probably not be FPS/Adventure/RPG fans - I'm guessing). If they don't bring in new customers then they won't be receiving any potential "killer apps" because the current pool of game devs will be out of ideas (an overwhelming amount already "not worth looking at" according to Jeff Tunnel's latest .plan).
...after I typed that up a few different ways I realized Garage Games has already released a stripped down version of TGE... T2D! So, I quickly deleted what I wrote so nobody would be able to read it.
- Preaching to the choir, I know, but I just thought any constructive input would be welcome.
#6
I'm not getting anything... no object, no warnings in the console. I'm a bit baffled. I have the fear that after I place a "staticShape" in the world I won't be able to manipulate it (by the context of the name). Are there any non-static shape classes built into TGE? Nothing caught my eye in the class list docs. Player objects can move, so I imagine I can mimic one of those classes.
10/14/2005 (11:30 pm)
Well, still no dice. I've checked as many tutorials and docs as I could find and mimiced each one in their own way, and still no progress. Is there anything wrong with the following code:datablock StaticShapeData(myBox)
{
shapeName = "~/data/shapes/box.dts";
};
$objectInstance = new staticShape()
{
position = "18.8961 -410.782 156.5";
rotation = "1 0 0 0";
scale = "1 1 1";
datablock = myBox;
};I'm not getting anything... no object, no warnings in the console. I'm a bit baffled. I have the fear that after I place a "staticShape" in the world I won't be able to manipulate it (by the context of the name). Are there any non-static shape classes built into TGE? Nothing caught my eye in the class list docs. Player objects can move, so I imagine I can mimic one of those classes.
#7
Also, I can't recommend Ken Finney's book "3D Game Programming All in One" enough to anyone getting started with TGE...and seeing the transfer issues you are having, I would have to recommend it even more to someone coming from T2D.
Ironic to say, but you are almost making a point for T2D being too easy....or as I imply above, yet another selling point for Ken's book!
10/14/2005 (11:36 pm)
You may want to try playing around with the Item class.Also, I can't recommend Ken Finney's book "3D Game Programming All in One" enough to anyone getting started with TGE...and seeing the transfer issues you are having, I would have to recommend it even more to someone coming from T2D.
Ironic to say, but you are almost making a point for T2D being too easy....or as I imply above, yet another selling point for Ken's book!
#8
I think TGE is actually too restricted to it's FPS roots and isn't dynamic enough without having to tear into the engine quite a bit. This is in contrast to T2D which is simply a more dynamic game tool that assumes less than TGE.
When we're talking about making games the system cannot be 'easy' enough to interface with because the presentation, psychology, style, and still technical know how of making a game on the most abstract level is still astounding!
10/14/2005 (11:51 pm)
Quote:
T2D being too easy
I think TGE is actually too restricted to it's FPS roots and isn't dynamic enough without having to tear into the engine quite a bit. This is in contrast to T2D which is simply a more dynamic game tool that assumes less than TGE.
When we're talking about making games the system cannot be 'easy' enough to interface with because the presentation, psychology, style, and still technical know how of making a game on the most abstract level is still astounding!
#9
1) The object is there, but it's not being rendered
2) The object is hooked to the character object in some manner(so when I go look for it, it keeps being pushed away... haha).
The item is no longer hooked to the character object, but it still doesn't render.
I'll keep chipping away at it.
10/15/2005 (1:05 am)
I found two things that are giving me problems, and removed one obstacle. 1) The object is there, but it's not being rendered
2) The object is hooked to the character object in some manner(so when I go look for it, it keeps being pushed away... haha).
The item is no longer hooked to the character object, but it still doesn't render.
I'll keep chipping away at it.
#10
10/15/2005 (8:47 am)
I changed "shapeName" in my datablock to "shapeFile" and now I'm working fine. Thanks for the Item Class recommendation, Stephen. Everything is on the up and up.
#11
Anyone know how to fix this? Ultimately, I'd like to be able to move an object through space as I hold a button down - as I would move a character in a 2D platform game if I hold a directional button down.
I've taken the if(%val) out and tested a flagged call with no luck - just in case anyone first suggests that.
10/15/2005 (5:12 pm)
I've noticed there are only 3 arguments passed to a keybind in TGE unlike T2D where there are 4 arguments passed. If I press a key that calls a function, that function gets called twice - once (and only once!) when the key is depressed, and once when the key is released. I can make the function only call once by sticking an if(%val) at the top of the function, however I can't make the function continuously call if I hold the key down. Is this normal behaviour for a keybind in TGE? If I set a flag and call the function again from a bool the game exits (not crashes, but exits a la quit();). Anyone know how to fix this? Ultimately, I'd like to be able to move an object through space as I hold a button down - as I would move a character in a 2D platform game if I hold a directional button down.
I've taken the if(%val) out and tested a flagged call with no luck - just in case anyone first suggests that.
#12
10/15/2005 (7:00 pm)
Of course it is normal behaviour... it is called when the key is pressed, and once when it is depressed... you just need to write your game around it. It is really a pain with joysticks -- I had to write a client-side caching routine for that.
#13
10/15/2005 (7:26 pm)
Oh, boy. Thanks for the heads up. I dunno about that "of course it is" part - as it is certainly not the case in T2d, nor any game I'm familiar playing. If you can think of a game where the same action is called on both the up and down key action more power to you. Disagree to agree, heheh. Back to the drawing board!
#14
10/15/2005 (7:35 pm)
Torque's movement model is inherently different from how T2D games get moves from the player. IIRC, Melv basically integrated the capabilities of move keys (which allow for constant presses to have constant inputs), and the more "normal" keypresses into a single model in T2D.
#15
10/15/2005 (7:50 pm)
I'm hunting down those keypress files to see how he handled it for T2D (as well as the $mv functions in TGE). Thanks again, Stephen!
#16
You seem to be confusing bind and bindCmd.
ActionMap.bind() does call the function it is bound to on keypress and on keyrelease. It passes in as the first argument a 1 or a 0 that indicates whether or not it is a keypress or keyrelease.
For example say you have
This will call:
and set %val to a 1 on keypress and to 0 on keyrelease. As you can see in this example we use if (%val) to make sure that it is only doing something on keypress.
At first this does seem a little odd and unnecessary. Why is it set up this way? Take a look at:
This gives us the flexibility to have actions that will work only while a key is held down (for example freelooking around while driving a car or holding down a button for zoom and having it unzoom when you release). If bind was only called on keypress you would have to hit a button twice to have it undo something or to toggle out of a mode/state. See what I am getting at?
Now, there is also ActionMap.bindCmd(). This function allows you to bind two different functions to it. One that will get called on keypress and one that will get called on keyrelease. This is most likely what is being used in T2D and is leading to your confusion (since TGE and T2D share exactly the same input/binding code).
Here are some quick examples of bindCmd():
This one is calling editor.setEditor(WorldEditor); on the keypress of F2 and nothing (note the "" at the end) on keyrelease.
This one is calling nothing "" on keypress and toggleFullScreen(); on keyrelease. Why not on keypress? In this case no real reason beyond possibly wanting to make sure they aren't trying to give an input immediately after the engine tries to switch in or out of fullscreen. It doesn't make a big difference.
Unfortunately, there are any good examples in the stock scripts of a bindCmd() that calls one function on keypress and a different one on keyrelease but it easy to imagine someone wanting to split up some really complex function into two different ones to make it easier to read the code.
The other reason you might see someone favor bind() over bindCmd() or vice versa is the difference in how arguments are passed into each. With bindCmd() you can pass in the arguments separately like so:
*Keep in mind that the first argument passed in will be the keypress/keyrelease so "arg1" will actually be the second one.
With bindCmd() you have to "inline" the arguments you pass in like so:
*Note the \" escape characters.
Whether or not you use bind() or bindCmd() is largely a matter of personal choice since both can accomplish the same thing in different ways.
10/15/2005 (8:21 pm)
Matt,You seem to be confusing bind and bindCmd.
ActionMap.bind() does call the function it is bound to on keypress and on keyrelease. It passes in as the first argument a 1 or a 0 that indicates whether or not it is a keypress or keyrelease.
For example say you have
moveMap.bind(keyboard, "alt c", toggleCamera);
This will call:
function toggleCamera(%val)
{
if (%val)
commandToServer('ToggleCamera');
}and set %val to a 1 on keypress and to 0 on keyrelease. As you can see in this example we use if (%val) to make sure that it is only doing something on keypress.
At first this does seem a little odd and unnecessary. Why is it set up this way? Take a look at:
function toggleFreeLook( %val )
{
if ( %val )
$mvFreeLook = true;
else
$mvFreeLook = false;
}This gives us the flexibility to have actions that will work only while a key is held down (for example freelooking around while driving a car or holding down a button for zoom and having it unzoom when you release). If bind was only called on keypress you would have to hit a button twice to have it undo something or to toggle out of a mode/state. See what I am getting at?
Now, there is also ActionMap.bindCmd(). This function allows you to bind two different functions to it. One that will get called on keypress and one that will get called on keyrelease. This is most likely what is being used in T2D and is leading to your confusion (since TGE and T2D share exactly the same input/binding code).
Here are some quick examples of bindCmd():
EditorMap.bindCmd(keyboard, "f2", "editor.setEditor(WorldEditor);", "");
This one is calling editor.setEditor(WorldEditor); on the keypress of F2 and nothing (note the "" at the end) on keyrelease.
GlobalActionMap.bindCmd(keyboard, "alt enter", "", "toggleFullScreen();");
This one is calling nothing "" on keypress and toggleFullScreen(); on keyrelease. Why not on keypress? In this case no real reason beyond possibly wanting to make sure they aren't trying to give an input immediately after the engine tries to switch in or out of fullscreen. It doesn't make a big difference.
Unfortunately, there are any good examples in the stock scripts of a bindCmd() that calls one function on keypress and a different one on keyrelease but it easy to imagine someone wanting to split up some really complex function into two different ones to make it easier to read the code.
The other reason you might see someone favor bind() over bindCmd() or vice versa is the difference in how arguments are passed into each. With bindCmd() you can pass in the arguments separately like so:
GlobalActionMap.bind(keyboard, "alt p", myFunc, "arg1", "arg2", "arg3");
*Keep in mind that the first argument passed in will be the keypress/keyrelease so "arg1" will actually be the second one.
With bindCmd() you have to "inline" the arguments you pass in like so:
GlobalActionMap.bind(keyboard, "alt p", "myFunc(\"arg1\", \"arg2\", \"arg3\");", "");
*Note the \" escape characters.
Whether or not you use bind() or bindCmd() is largely a matter of personal choice since both can accomplish the same thing in different ways.
#17
10/15/2005 (8:41 pm)
Wait a minute, you're not allowed to fix my problem with something that already exists in the TGE source. Then us dopes can't complain! Heheh, I just figured out I could use a schedule/cancel schedule method, too, to get around the computer closing the program.... buuuuuuuut, I guess you're right *wink*. Really, I appreciate everything, and I'm glad you guys put up with our crap for the sake of our learning. Cheers.
Torque Owner Mike Kuklinski
datablock myObject(insertName)
{
shapeName = "~/data/shapes/myShape.dts";
};
$objectInstance = new TSStatic()
{
dataBlock = insertName;
position = "x y z";
rotation = "1 0 0 0"; //should I use setTransform here? If you create an object
in the world editor it doesn't use setTransform.
scale = "1 1 1";
};
now, you can use setTransform to position your objects when moving them... there isn't any setLinearVelocity, because TGE is Three-Space, not Two-Space... there is a setVelocity (iirc), which is X,Y,Z velocity.