Game Development Community

T2D first experiences and issues

by Michael Cordner · in Torque Game Builder · 07/15/2005 (3:13 am) · 16 replies

Hello everyone,

So I've spent a couple of days so far playing with T2D and trying to get a handle on how it does things. What I'm trying to do at the moment is move some of our data from our proprietary engine into torque, and get it to replicate some of the functionality that existed in our engine to see what happens. I thought I might as well relate my experiences so far as a total torque noob rather than just ask a couple of terse questions :)

Before I get going, I have to say something (hopefully constructive) about the number one frustration I'm facing with T2D: the documentation. The docs provided are terse, (the detailed reference is good, but there's little information about how a real game hangs together) and I keep having to hunt around the garage games site, sometimes with no luck, to find information on specific topics. Usually when I think I have found something of use via the search facility, (such as detail on torquescript or the torque core,) I get a page telling me I can't see it because I haven't paid for the main torque engine. This is unbelievably frustrating, and I'd go as far as to say that the documentation could be a potential show stopper at this stage for a lot of commercial enterprises. As we all know, developers don't usually have a lot of time to spend evaluating a new technology, and any impediment to learning a technology is going to weigh heavily against any possibility of using it. I understand this is an 'early adopter' release, but to be honest at this stage I'd rather see better and more detailed documentation (or at least better access to what's there) than more engine features in the next release.

Anyhow, I just had to get that out. hope I haven't offended anyone yet :)

The design of our game is based on the concept of 'rooms'. A room is simply a location, and it's a multiple-screen area (limiting it to three 100x75 world units screen widths for now) that scrolls left and right as the main character moves. My first tasks, (and I haven't really gone any further yet) were as follows:

1) Get an animated character walking left and right
2) Get a scrolling, multi screen background in place
3) Get the character walk synchronised with the background.

After reading the available section on torque script in detail, I did the initial torque setup and figured out where to start putting code. I originally tried to create a new 'minimal' project, but kept getting confusing engine crashes when trying to run it. At that stage though, it was probably more due to my lack of understanding than T2D itself. I probably could have got it working with some more effort, but eventually I decided on the path of least resistance and just started modifying the code in the examples/T2D directory.

Getting a character to walk was simple enough. I cut and paste code from a FAQ I came across on the site that did exactly that. Then I had to substitute some of our own data for the stick figure. This was fairly straightforward, as all of our animations are in flash. I merely exported an animation sprite movie of a cartoon chicken as a series of PNGs, then used a command line tool I found on the resource section of the site to turn them into a single celled strip. A few changes to the animation datablocks, and the chicken was walking left and right in response to key-presses, looking sharp, and smooth against a white background. (I assume T2D is using FSAA by default?). I changed the resolution a few times, and was impressed with the appropriate changes in quality, despite the fact that the source image is a raster based bitmap. Impressive.

#1
07/15/2005 (3:13 am)
Next, the background. I used the simple fxBackgroundScroller2D (sic?) class to try and get something up and scrolling. It seemed fine at first, but for some reason failed to work at all under direct 3d. After verifying this on two machines and doing some more reading, it seemed a tiled background was the better way to go, especially since we'd like to have several layers of parallax scrolling on our backgrounds.

I took a sample background and found a utility to split a screen into a block of 12 256x256 tiles, and used the tile editor to 'paint' the entire three-screen width area. This went painlessly enough, though I think I'm going to need to write something to automate the process of splitting tiles.

Like the chicken, the background loaded map loaded painlessly, and after struggling with some understanding of tile layer vs panning positions, I was able to get it scrolling back and forth. Originally, I had been panning the map layer as opposed to moving it, and couldn't figure out why it's position within the world was remaining constant. After some hunting around I found it was preferable to move the entire layer rather than pan it, as it makes synchronization with the walk easier.

The next step was to stop moving the chicken, but simply display the animation of him walking while scrolling the background behind him. Easy enough. Then, after figuring out how world limits work, I was able to bound the background to a certain area, the net effect being that it stops scrolling when it reaches either side. Getting the precise coordinates for the world limit-bounding box was a matter of simple arithmetic, as everything, world view, tiles, and background, are kept at a 3:2 aspect ratio.

The next point lost me several hours, and I still haven't figured out how to handle it properly. I now have a character that remains at 0,0 while the background scrolls around behind it. The background stops scrolling in either direction at the appropriate point. However, the character keeps moving at 0,0 when a world limit is hit in either direction. What I would like to do is give the illusion of the character keeping on going when the background hits its world limit. i.e, when the background is at a limit, and the character is still supposed to be walking left, the character leaves it's 0,0 anchor and actually moves left. When the character comes back to the right as far as the 0,0 point, it becomes anchored again, and the background again starts to move.

I've tried a few things, but to no avail so far. I've set up a callback when the world of the background is reached at either end, which sets a flag saying 'stop moving the background, now move the character'... but I'm having issues getting it to trigger asynchronously.. that is, the change doesn't occur until I release the 'left' key, and hit it again. On the return trip, when walking back to the right, same issue.

I think the root of the problem is that I need to know precisely when the character reaches 0,0 and at that point set a flag as to whether I should be moving the background or the character. I'm not to interested in collisions per-se within the game, as it's not an action platformer (more of a hotspotter). What I need, (I think, anyhow) is a reliable way of triggering a callback when the character is at 0,0 but again, I'm not sure. The issue would be trivial if there were a traditional main loop in the game, but the callback based nature of T2D is making me wonder whether it's possible. T2D seems very tailored for physics based shooters (lots of collision callbacks).

And that's where I am so far. So far, T2D looks good but I'm obviously still struggling with how it all works. Does anyone have any experience with a similar issue to the one I'm having?
#2
07/15/2005 (12:25 pm)
When confronting scrolling logic, I tend to feel that moving the background around the character is always the wrong way to go. It makes it hard to know where the character really is in the world, and you have to move other entities around the character, rather than getting all of this automatically. Looking at it from as realistic a perspective, the background is not scrolling. The camera is simply moving, and therefore what is visible changes. So, in real-world terms (not screen space), the character moves from the left side of the world to the right side, and a camera follows the character.

As such, what I would suggest is doing exactly that. The camera should follow a specific character; there's even code in T2D to mount a camera to a SceneObject. Then, you should set up something that runs every frame to test to see if the camera attempts to move to an invalid position. Like off the side of the map. In which case you can clamp the position of the camera to within these extents.

To do the clamping, I think you can set something on the camera to prevent it from moving beyond a specific rectangular region of the world.

As for the documentation issue (in terms of being locked out of docs we should have and need), I wholely agree. Unfortunately, GG doesn't. And I have my suspicions as to why.

What I think it comes down to is pretty simple. T2D specifically is based on the TorqueScript scripting language. The way most people use T2D means that, when they release their game, anyone buying it effectively now has the T2D engine. If they knew the TScript interface, they could easily create anything from it. Therefore, the TScript interface must be a secret.

I imagine TGE works in a similar way, though perhaps not as script friendly. The script interface can do many things, and released TGE-based games means that the engine is available for anyone to use. The only thing that gets people to pay for the TGE/T2D licence is to learn what the script functions and interfaces are. Of course, you get source code too, which is a bonus, but it isn't entirely necessary depending on what kind of game you're making.

Because of that, the TScript interface from TGE must be kept a closely guarded secret. Only those who have licenses should be provided with it, as it contractually obligates them to keep it relatively secret. Because of this need for secrecy, and because we don't have TGE licenses, we are forbidden from accessing documentation that would be inhierently valuable to us as T2D programmers.

GG has made some noise in the past about something that they call the "Torque Developers Network". They're supposed to have been working on it, but nothing has actaully come of it. As I understood it, it was to be a Wiki of sorts for Torque documentation, that would separate the TGE docs into Torque Core documentation and TGE-specific docs.
#3
07/15/2005 (12:35 pm)
@Michael: Thank you for sharing your progress and thoughts, hopefully later I can dig up what you need specifically and help clear up some problems...

if you haven't seen them, here is a tutorial pack I made for T2D, hope it helps.
#4
07/15/2005 (12:42 pm)
I personally think that GG has a lot (too many?) of things going on, and their resources are streched a wee-bit too far to keep everyone perfectly happy.

But as "Early adopters" this is what we must live with. Personally, I love the early adopter stuff, as it gave me a little nitch to play with that I will hopefully manage to profit on, though I know if I was making a game (like most everyone wants) I might have other feelings out of this.

Also, another possible explanation is that there are going to be significant changes to the engine, so they dont want to 'waste' time on doc'ing something that will be changing.

-------------

As for the TorqueScript exploiting.. there are various ways to mitigate this. A some-what simple way would be to issue Torque Purchasers a private key signed by GG. Then run a dev tool that will create a 'manifest' file containing a hash of the TorqueScript files, and have it signed by the Developers Private key. Then when the Torque engine loads, it first validates that the TorqueScript files have been signed by an authorized Torque Developer. Anything not signed wont be allowed to run "Torque" functionality.

This takes about 1 day1 of dev time to implement in C#, so I'm assuming that a savvy C++ dev can do it in a 1-3 day timeframe.
#5
07/15/2005 (1:11 pm)
I agree with Smaug that the easiest way would seem to have the player move through the world instead of the opposite...

Quote:To do the clamping, I think you can set something on the camera to prevent it from moving beyond a specific rectangular region of the world.

Hes absolutely correct... this command is attached to SceneWindow2D

setViewLimitOn();

you can mout the camera to the player like this

sceneWindow2D.mount($player);
#6
07/15/2005 (1:41 pm)
Thank you all very much for the responses and the insights, (though I seem to have touched a nerve with the documentation). Before seeing your responses, I managed to get it all more or less working via the onSceneDisplay callback, but for some reason I get the feeling that isn't the best way of doing things, (seems to break the entire callback based paradigm, and potentially introduce overhead to each frame rendering).

I'll have a go at mounting the camera... I can definitely see the benefit, and it may be possible to add some physics to it to create a more fluid delay kind of effect rather than having the character rigidly attached to the centre of the screen.

I'll let you know how it goes.

Thanks again
#7
07/15/2005 (1:46 pm)
You can pass moutn th efollowing from the reference

Quote:(fxSceneObject2D, [offsetX / offsetY], [mountForce], [trackRotation?], [sendToMount?], [ownedByMount?] , [inheritAttributes?])

mountForce will be the one that gives the mounting a delay :)

I'm sorry if I came accross harsh, just wanted to ensure that you didn't get a skewed view of the documentation. Smaug seems to know his OpenGL well and can be very productive but has always spoken with a slant against Torque Script and Documenation (obviously hes a bit biased)...

If you have any further questions feel free to ask :)
#8
07/15/2005 (1:59 pm)
Also you can pass "setViewLimitOn()" these paramaters (from the T2D Reference pdf)

Quote:(minX / minY / maxX / maxY)
#9
07/15/2005 (2:04 pm)
Another quick one...

I don't actually want him at 0,0 on screen, more like at 0,15

$circleGuy.setPosition("0 15");

Logically, I want the camera to remain at a y value of 0 while following the character, so I blunder away with:

sceneWindow2D.mount($circleGuy, "0 -15");

which sounds great in theory, but in reality moves the camera off somewhere into lower earth orbit.. I play around with the values, and find that:

sceneWindow2D.mount($circleGuy, "0 -1.68");

does something similar to what I want, but with extra white space at the top and bottom... the only thing I can think of is that the camera is rotating rather than translating, and the sprite polys are being billboarded in a perspective projection or something, but that doesn't seem to make a lot of sense, as I had kind of assumed the rendering perspective is a parallel one. what is actually going on here?
#10
07/15/2005 (2:10 pm)
The default grid should be like this

www.razedskyz.com/games/torque/tutorials/T2D/t2dgrid.jpg
did you change any of the camera view settings ?
#11
07/15/2005 (2:16 pm)
Camera settings are:
sceneWindow2D.setCurrentCameraPosition( "0 0 100 75" );

I kinda assumed this was the ideal, cause it gives the standard 4/3 aspect ratio, from -37.5 to 37.5 y, -50 to 50
#12
07/15/2005 (8:15 pm)
Hmm... Just thinking a bit here, but maybe setting it up like this will help based on your initial camera settings:

Ok, put your little char where you wanted him:
$circleGuy.setPosition("0 15");

Use this to keep the camera from leaving a certain area:
sceneWindow2D.setViewLimitOn("-50 -36 250 36");
(I based the numbers on how you said you had your levels set up, 3 screens wide = 300 and your initial camera shows from (-50, -36) to (50 36) ) Overall I've found that little setViewLimitOn() to be one VERY usefull function. Makes setting up cameras for scrolling levels a snap.

Then mount the camera to the player:
sceneWindow2D.mount($player);

I use a similar system in the few little scrolling demos I've made.
#13
07/15/2005 (8:37 pm)
Currious, why did t2d decide on a coordinate system with the origin in the middle of the screen, instead of in the upper left?
#14
07/15/2005 (9:40 pm)
The origin is user definable via script. Personaly I pefer setting my levels up so that the top left corner is (0, 0) You can do that too by using:

sceneWindow2D.setCurrentCameraPosition("50 36 100 72");

I also tend to base my world units on my tile-size(usualy I go with a 32x24 tile screen out of habit, and set my camera width to a multiple of 32 and my camera height to a multple of 24)

As to why the t2d default has the origin in the center, only Melv knows for sure :) Probably a personal preference of his.
#15
07/16/2005 (2:59 am)
There's also the alternative ".setCurrentCameraArea()" which specifies the top/left coord as well as the width/height, which some people prefer. As to why I defaulted the origin in the center, well it was a personal preference and probably not the best call as it has caused a little confusion but in the end, it makes no difference where the origin is if the camera is moving. If it's stationary in a game then it's at least familiar to have the origin at the top-left.

The main reason for the centered origin was to highlight that the coordinates are not camera coordinates but world-coordinates and the default was to have the center of the world (origin) displayed in the center of the screen. That was the thought anyway.

We'll possibly change this in the next release to something that's more familiar so it doesn't cause any more confusion.

More documentation will help a bundle as well. :)

- Melv.
#16
07/16/2005 (4:22 am)
Thanks everyone for their help and suggestions. The functionality is now absolutely perfect... via the following:

//4:3 aspect ratio

sceneWindow2D.setCurrentCameraPosition( "0 0 100 75" );
.
//mainlayer is a 12x3 map layer made up of 25x25 tiles
$mainLayer.setTileSize( "25 25");
.
$circleGuy.setPosition("0 15");
.
//restrict circle guy's walking to the defined layer... 
//callback stops the animation when the bound is hit
$circleGuy.setWorldLimit(CLAMP, "-150 -1000 150 1000", true);
.
//mount camera to centre of circleguy, and apply
//a bit of physics so the tracking appears more natural
sceneWindow2D.mount($circleGuy, "0 0", 1.5); 
.
//ensure camera never leaves y axis, and stops 
//before it can pan off of the background
sceneWindow2D.setViewLimitOn("-150 0 150 0");

Works beautifully with a few lines of code now that I know how to use all the components... now I'm VERY impressed with T2D.
:) I'd imagine it's not difficult to abstract this away to handle different sized rooms.

The next thing I want to do is add a few parallax layers, scrolling at different rates.. I'll have to have a think about that.

Personally, I don't mind the origin being at 0,0, but the fact that Y goes downwards as opposed to upwards had me a bit disoriented as I'm very used to OpenGL. Ah well, makes no difference in the end, so long as it's consistent within T2D.