An adventure singleplayer game using multiple missions
by Carpenter Software · 11/22/2006 (9:29 am) · 4 comments
Multiple Missions?
Ever since I played the Game "Dungean Seige", I was impressed with their terrain. There is a certain topic about how "Gas Powered Games" accomplished it - www.drizzle.com/~scottb/gdc/continuous-world.htm. They call their terrain "The Continuous World".
I want to use TGE 1.4.2 to create an adventurous game but one mission (2048 world units by 2048 world units) is not large enough. I may not be able to create a continuous world similar to Dungean Seige but I may create a large world by loading screens (missions).
How to accomplish "An adventure singleplayer game using several missions" is the topic of this blog.
On the forum - Torque SDK Private Forums >> Terrain Discussions - read the following threads:
(1) Terrain Plan for TGE Click Here
(2) Mission Area Dimensions Click Here
(3) Porting Graphics from OpenGL buffer Click Here
(4) Can't get terraformer to work Click Here
(5) What's the purpose of emptySquares? Click Here
(6) What are the different files in the mission folder? Click Here
(7) Large Worlds? Click Here
The following subroutines only uses Torque Script (very simple).
Create a height map (source 3DGPAi1) using a large greyscale bitmap at the desired size in pixels. Divide this large bitmap into 256 by 256 pixels with overlaping of 64 pixels. Load the Bitmaps into the sub-directory named: example/creator/editor/heightScripts or example/creator/terrain_imports depending on what version 1.4.0 or 1.4.2 respectively. Then load each bitmap in the terrain into each mission with the appropriate map number. In the Mission Area, the Player can be transferred from one mission to another by a callback to player::onLeaveMissionArea (see subroutine below). The onLeaveMissionArea will be set within the 64 pixels overlap beyond the halfway mark of 32 pixels. Upon transition, the player will end up exactly at the same point of exit but at the opposite side; AND with a little manipulation, will set the player inside the missionArea on the other map. For example, when the player leaves map 10 going south to map 20, y = -768.2 on exit. Increment the map by 10 to give 20. Get the fraction of -768.2 and multiply by -2 to get 0.4. Add the result to -768.2 to get -767.8. Finally, change the sign to get 767.8 which is the north side of map 20 just within the missionArea. While being transferred, he is standing in the same geographic spot in the overlap from map 10 to map 20.
In terms of length, the conversion units are 1 pixel to 8 wu, when squareSize = 8 in the mission file under TerrainBlock(Terrain). When I am speaking in terms of either pixels or world units (wu), I mean the same thing as in the x and y plane of the bitmap or the world coordinates of TGE respectively. Thus world units "are related" to the dimensions used by the area of MissionArea; whereas the source 3DGPAi1 instead uses "meters" and does not convey clearly how pixels from the bitmap are related to "meters" (but does an excellent job in discussing how to set the greyscale (RGB) of the bitmap to the z-axis of the world coordinates in TGE). Therefore, to add it all together, a 256 pixels by 256 pixels greyscale bitmap will fill in a 2048 wu by 2048 wu terrain where the area of the missionArea is arbitrarily set equal to or less than this terrain size.
File: missionName10.mis
Remember that the maps overlap 64 pixels or 512 wu (25% of 2048 wu). So when leaving from one terrain to another, they look axactly alike. The missionArea is set at 32 pixels (256 wu) which is the halfway point in the overlap and that is where the value 768 wu comes from (see the area above under MissionArea). Thus when the player transfers from map 10 to map 20 he is in an identical geographic area of the overlap of both maps, so all transform coordinate values remain the same except either x or y.
The transition between missions (loading missions) needs improvements when using the screenShot function while using the loadingGUI.gui.
File: Player.cs
To test your math and understanding:
(1) If you used the same map arrangement (4 by 5 area) as indicated in the subroutine above, what size (pixels) greyscale bitmap would be needed to create 20 greyscale bitmaps (256 x 256 pixels) with 64 pixel overlaps!? Hint: The perimeter would not require an overlap.
(2) What dimensions would you set the location (x and y) and the height and width to the area of missionArea if you decided to use 32 pixels as the halfway point of your overlap? (Although the answer is posted, show your work.)
File: Game.cs
You may notice I have used a different value on the missionArea parameters than the ones discussed in the threads on the forum listed above. An overlap of 64 pixels (512 wu) gives 32 pixels (256 wu) on either side which is far enough to see ahead in the game.
One final note: remember to initialize the global variables....
What ever content is populated in the overlap of one mission has to be populated exactly the same way in the overlap of the other mission.
Have fun Torque-ing.
Edited 11-26-06
Ever since I played the Game "Dungean Seige", I was impressed with their terrain. There is a certain topic about how "Gas Powered Games" accomplished it - www.drizzle.com/~scottb/gdc/continuous-world.htm. They call their terrain "The Continuous World".
I want to use TGE 1.4.2 to create an adventurous game but one mission (2048 world units by 2048 world units) is not large enough. I may not be able to create a continuous world similar to Dungean Seige but I may create a large world by loading screens (missions).
How to accomplish "An adventure singleplayer game using several missions" is the topic of this blog.
On the forum - Torque SDK Private Forums >> Terrain Discussions - read the following threads:
(1) Terrain Plan for TGE Click Here
(2) Mission Area Dimensions Click Here
(3) Porting Graphics from OpenGL buffer Click Here
(4) Can't get terraformer to work Click Here
(5) What's the purpose of emptySquares? Click Here
(6) What are the different files in the mission folder? Click Here
(7) Large Worlds? Click Here
The following subroutines only uses Torque Script (very simple).
Create a height map (source 3DGPAi1) using a large greyscale bitmap at the desired size in pixels. Divide this large bitmap into 256 by 256 pixels with overlaping of 64 pixels. Load the Bitmaps into the sub-directory named: example/creator/editor/heightScripts or example/creator/terrain_imports depending on what version 1.4.0 or 1.4.2 respectively. Then load each bitmap in the terrain into each mission with the appropriate map number. In the Mission Area, the Player can be transferred from one mission to another by a callback to player::onLeaveMissionArea (see subroutine below). The onLeaveMissionArea will be set within the 64 pixels overlap beyond the halfway mark of 32 pixels. Upon transition, the player will end up exactly at the same point of exit but at the opposite side; AND with a little manipulation, will set the player inside the missionArea on the other map. For example, when the player leaves map 10 going south to map 20, y = -768.2 on exit. Increment the map by 10 to give 20. Get the fraction of -768.2 and multiply by -2 to get 0.4. Add the result to -768.2 to get -767.8. Finally, change the sign to get 767.8 which is the north side of map 20 just within the missionArea. While being transferred, he is standing in the same geographic spot in the overlap from map 10 to map 20.
In terms of length, the conversion units are 1 pixel to 8 wu, when squareSize = 8 in the mission file under TerrainBlock(Terrain). When I am speaking in terms of either pixels or world units (wu), I mean the same thing as in the x and y plane of the bitmap or the world coordinates of TGE respectively. Thus world units "are related" to the dimensions used by the area of MissionArea; whereas the source 3DGPAi1 instead uses "meters" and does not convey clearly how pixels from the bitmap are related to "meters" (but does an excellent job in discussing how to set the greyscale (RGB) of the bitmap to the z-axis of the world coordinates in TGE). Therefore, to add it all together, a 256 pixels by 256 pixels greyscale bitmap will fill in a 2048 wu by 2048 wu terrain where the area of the missionArea is arbitrarily set equal to or less than this terrain size.
File: missionName10.mis
new ScriptObject(MissionInfo) {
desc0 = "My adventure Game - map 10.";
name = "nameMap 10";
map = "10";
};
new MissionArea(MissionArea) {
canSaveDynamicFields = "1";
area = "-768 -768 1536 1536";
flightCeiling = "300";
flightCeilingRange = "20";
locked = "1";
}Remember that the maps overlap 64 pixels or 512 wu (25% of 2048 wu). So when leaving from one terrain to another, they look axactly alike. The missionArea is set at 32 pixels (256 wu) which is the halfway point in the overlap and that is where the value 768 wu comes from (see the area above under MissionArea). Thus when the player transfers from map 10 to map 20 he is in an identical geographic area of the overlap of both maps, so all transform coordinate values remain the same except either x or y.
The transition between missions (loading missions) needs improvements when using the screenShot function while using the loadingGUI.gui.
File: Player.cs
function Armor::onLeaveMissionArea(%this, %obj)
{
if (%obj.client.player == %obj)
{
// There may be 20 Maps (4 by 5 area)
// Each MissionInfo has map number
// 10 11 12 13 14
// 20 21 22 23 24
// 30 31 32 33 34
// 40 41 42 43 44
// The Outer perimeter prevents player from reaching missionArea
if (isObject(MissionInfo)) %map = MissionInfo.map;
echo("MissionInfo.map: " @ %map);
// Inform the client
%obj.client.onLeaveMissionArea();
// Make transistion between missions smooth
// $loadBitmap = "screenLoading";
// screenShot("screenLoading" @ ".png", "PNG");
%playerLocation = %obj.getTransform();
%x = getword(%playerLocation, 0);
%y = getword(%playerLocation, 1);
%z = getword(%playerLocation, 2);
%playerRotation = getwords(%playerLocation, 3, 6);
%flag = true;
// Heading North
if (%flag && (%y >= 768.0) && ((%x > -768.0) && (%x < 768.0)))
{
%deltaCrement = -10;
if ((%map + %deltaCrement) > 9)
{
%map = %map + %deltaCrement;
// %y outside missionArea
%fraction = (%y - 768.0) * 2.0;
// %y inside missionArea
%y = %y - %fraction;
// change sign
%y = %y * -1;
}
%flag = false;
}
// Heading South
if (%flag && (%y <= -768.0) && ((%x > -768.0) && (%x < 768.0)))
{
%deltaCrement = 10;
if ((%map + %deltaCrement) < 45)
{
%map = %map + %deltaCrement;
// %y outside missionArea
%fraction = (%y + 768.0) * -2.0;
// %y inside missionArea
%y = %y + %fraction;
// change sign
%y = %y * -1;
}
%flag = false;
}
// Heading East
if (%flag && (%x >= 768.0) && ((%y > -768.0) && (%y < 768.0)))
{
%deltaCrement = 1;
if (((%map + %deltaCrement) % 10) < 5)
{
%map = %map + %deltaCrement;
// %x outside missionArea
%fraction = (%x - 768.0) * 2.0;
// %x inside missionArea
%x = %x - %fraction;
// change sign
%x = %x * -1;
}
%flag = false;
}
// Heading West
if (%flag && (%x <= -768.0) && ((%y > -768.0) && (%y < 768.0)))
{
%deltaCrement = -1;
if (((%map + %deltaCrement) % 10) < 5)
{
%map = %map + %deltaCrement;
// %x outside missionArea
%fraction = (%x + 768.0) * -2.0;
// %x inside missionArea
%x = %x + %fraction;
// change sign
%x = %x * -1;
}
%flag = false;
}
// Perform loading
if (!%flag)
{
$uploadMission = "fileLocation/data/missionName" @ %map @ ".mis";
$gNewTransform = (%x SPC %y SPC %z SPC %playerRotation);
$spawnBool = true;
schedule(0, 0, "mapCycle");
}
}
}
function mapCycle()
{
schedule(100, 0, "mapCyclePause");
}
function mapCyclePause()
{
%search = $Server::MissionFileSpec;
for (%file = findFirstFile(%search); %file !$= ""; %file = findNextFile(%search)) {
if (%file $= $uploadMission) break;
}
loadMission(%file, false);
}To test your math and understanding:
(1) If you used the same map arrangement (4 by 5 area) as indicated in the subroutine above, what size (pixels) greyscale bitmap would be needed to create 20 greyscale bitmaps (256 x 256 pixels) with 64 pixel overlaps!? Hint: The perimeter would not require an overlap.
(2) What dimensions would you set the location (x and y) and the height and width to the area of missionArea if you decided to use 32 pixels as the halfway point of your overlap? (Although the answer is posted, show your work.)
File: Game.cs
function GameConnection::spawnPlayer(%this)
{
// Combination create player and drop him somewhere
if ($spawnBool) {
%this.createPlayer($gNewTransform);
$spawnBool = false;
}
else {
%spawnPoint = pickSpawnPoint();
%this.createPlayer(%spawnPoint);
}
}You may notice I have used a different value on the missionArea parameters than the ones discussed in the threads on the forum listed above. An overlap of 64 pixels (512 wu) gives 32 pixels (256 wu) on either side which is far enough to see ahead in the game.
One final note: remember to initialize the global variables....
Quote: Stefan Lundmark
The problem with large worlds is also that you have to populate it or produce content...It's both expensive and time consuming to produce....
What ever content is populated in the overlap of one mission has to be populated exactly the same way in the overlap of the other mission.
Have fun Torque-ing.
Edited 11-26-06
About the author
#2
Thanks
English Grammar not my cup of tea....
11/26/2006 (10:29 am)
It took several days to work on this blob to make it complete. This is my first plan. I have others but still doing research. I would like to update this blog in the near future but I need your comments. I am presently going on to other things but will come back to review any comments that may exist.Thanks
English Grammar not my cup of tea....
#3
12/15/2006 (7:06 am)
It's a neat idea, and congrats on doing some work towards getting it to work. I think that in the absence of paging terrains in TGE, this is a good alternative. Keep up the research!
#4
12/21/2006 (4:19 am)
Very interestings! Keep up the good work sir. 
Torque Owner Andrew Hull