Submarine Simulation



Thanks to the A6 Template Scripts that comes with the 3D GameStudio engine, you´ll see how easy it is to make a submarine simulation with no need of programming experience.




Submarine movement

1 Open the WED application.
1.1 Click File/Open, to open the pool level we used in the Sonar Interface section, the name that i suggested was AY_Level_01.

1.2 Open SED application and click File/Open, and search for the AY_Level_01.wdl script. It´s located on the same path as your level.


2.0 With the SED still open, click File/Open and search for movement.wdl script. You´ll probably find in this path C:/Program Files/GStudio6/template/movement.wdl in your computer.

2.1 The movement.wdl script is a wdl prefab script made by the Conitec© developers specially for us. This way we don´t need to worry about writing all the codes to deal with keyboard inputs and moving our entity in a correct way.

2.2 The code part in this script that interests us right now , is this:

////////////////////////////////////////////////////////////////////////
// User modifiable global skill definitions
// Duplicate them in your wdl script AFTER the include
// to give them new values
// NOTE: in most cases it is a good idea to make actor_scale == movement_scale
var movement_scale = 1.00; // used to scale the movement
var actor_scale = 1.00; // used to scale the size of actors

var gnd_fric = 0.5; // ground friction
var air_fric = 0.03; // air friction
var water_fric = 0.75; // water friction
var ang_fric = 0.6; // angular friction

var gravity = 6; // gravity force


2.3 After you find this part in the movement.wdl, you can notice that are a lot of predefined variables with initial values, that deals a lot of aspects in the movement of an entity.This way we can modify or add somethings we want too.


3.0 Now look for the move.wdl script, using the step 2.0 find the move.wdl and open it, then look for this code:

/////////////////////////////////////////////////////////////////////////
// Desc: player drive action
//
//]- Mod Date: 8/31/00 DCP
//]- Scale the player by vec_scale
//
// uses _WALKFRAMES, _RUNFRAMES, _WALKSOUND
ACTION player_drive
{
MY._MOVEMODE = _MODE_DRIVING;
MY._FORCE = 1.5;
MY._BANKING = 0.5;
MY.__SLOPES = ON;
MY.__TRIGGER = ON;

player_move();
}


3.1 This is the Action that simulates a player driving movement. We will be using that with some modifications for making the submarine movements.


4.0 Now that we have seen some of the useful codes we´ll be using, let´s come back to our main script and start adjusting things.

4.1 Go back to the AY_Level_01.wdl main script and add only this blue code that i highlighted here, location is right on top of your script:

path "F:\\Program Files\\GStudio6\\template_6\\sounds"; // Path to A6 template sound subdirectory
path "F:\\Program Files\\GStudio6\\template_6\\models"; // Path to A6 template model subdirectory
path "F:\\Program Files\\GStudio6\\template";
/////////////////////////////////////////////////////////////////

4.2 This way the engine will automatically look for the wdl prefabs in the correct folder of the gamestudio engine, make sure to write your own partition in it, like C:, E: or F: like my own example. Or you can copy the wdl prefabs from the ...//Tutorial_Conitec_Contest\AY_work_files\pool_demo folder.

4.3 After that, add this line in blue to your script, don´t write the " //etc... "commented code if you don´t want, since it´s just a commentary:

Everything after the " // " or between " /*...*/ " are comments that you can put in the script, as reminders so you can track your work between all your codes without loosing your mind, and even to pass informations for other programmers.
A whole line will be ignored after these " // " .

////////////////////////////////////////////////////////////////////////////
// Included files
include <gid01.wdl>; // global ids
include <display00.wdl>; // basic display settings
include <movement.wdl>; //includes the A6 template script for moving entity



4.4 With this line we tell the engine to include the prefab when building our main script, that is, when it builds our script, first it adds all the codes that are writen in the gid01.wdl, following this, it writes the display00.wdl script, then the entire code contained in the movement.wdl script, and only then it writes our own main code, the AY_Level_01.wdl.

4.5 Now you may wonder where i´m going to add the move.wdl script. Don´t worry, it´s already beeing included because in the movement.wdl script we have this lines of code in the bottom of the script:

// INCLUDED CODE (originally part of movement.wdl
include <move.wdl>;
include <camera.wdl>; // handle camera movement
include <animate.wdl>; // handle animation
include <input.wdl>; // handle user input (mouse, keyboard, joystick, ..)

4.6 This means that we´ll have all this wdl prefabs included before our main code, so we get all the durty work done by the prefabs, like a handler for the user input, an automatic first person camera, etc.


5.0 Now we need to make an action that will deal with all this codes. Write this action function in blue in the bottom of your script, and in the same position as shown:

action sub_simulate
{
player_drive();
wait(1);
}

on_anykey=rotate_scan;
/////////////////////////////////////////////////////////////////
//INCLUDE <debug.wdl>;

5.1 This will be the main action function for our entity, calling it sub_simulate, and between the signs " { } " we are calling the action player_drive function from the move.wdl script.

5.1.1 If you are using the same script file from the sonar interface tutorial, you probably have something like this code in it:
on_anykey=rotate_scan;
Don´t worry, we fix this later, live it that way for now.

5.2 Save your script, CTRL+S is just fine for saving it.
In WED we will need an entity to be our submarine. Since it´s going to be like first person all the time, so we won´t be seeing our player, we just need to put any kind of entity to serve our purposes and be the owner of the sub_simulate action.

5.3 in WED click Object/Load Entity... and search for the torpedo_skin.mdl model. After that, it´ll be added to our level.

5.4 With the torpedo model selected, right-click and choose properties.
5.5 In the Object Properties dialog, go to behaviour tab and click Choose Action button and in Choose Action list dialog select the action we created.

If you can´t find any action, just close the WED application and open it again to refresh the actions.


5.6 Build with update entities on and Run.
Now we see our action working in the entity, notice that when the game starts, the camera moves automatically to the entity position, like first person camera, and you are able to use the arrow keys to move yourself in the level.
These are the basic movements for a driving player from the wdl prefabs, now we can proceed to make it more like a submarine movement.




6.0 For resolving the gravity problem, remember that in the movement.wdl script we´ve seen some predefined variables, so we´ll overwrite them to fit our needs.

6.1 Back in SED, write this line in blue in your main script:
Right after the other variables from the sonar interface tutorial, if you have done that tutorial, or on top of the sub_simulate action is just fine.
Always keep your variables together on top of all your functions for ordenation reason. So you know where they are when you want to see them.

bmap scan_04=<Sonar_Scan_04.pcx>;
var switchgrav = 0.01;
var gravity=0;


6.2 What we did here was declare the same variable used from movement.wdl script, but now with an initial value of 0. If you remember, the movement.wdl script is going to be added on top of our main script with this variable gravity receiving a value of 6, since we are starting the variable again, it will be overwrited with the value we want, that is the 0 value for the gravity, this way if you, Save the script in SED and Build and Run in WED now, you´ll see that the entity will no longer drop all the way to the ground, and will stay floating with no gravity influence over it.

6.3 The switchgrav variable we created we´ll use now in a function, to help us to play with the gravity variable, so let´s see how to do that.

6.4 Write this function on top of the sub_simulate action and below the last variable, giving enough space to work on:

function switch_gravity
{
while(key_a)
{
gravity-=switchgrav;
wait(1);
}

while(key_z)
{
gravity+=switchgrav;
wait(1);
}

gravity=0;
}


6.5 This switch_gravity function will give us a way to emerge and submerge our submarine.
What´s it doing exactly:
Remembering that a function is just a block of code that executes something especific for us, we just need to worry about what is inside of it, which is:
One while loop that when the condition key_a is true, that is when we press the a key on the keyboard gives this variable a value of 1, which means true for the computer, otherwise is always 0.
So, now we know that when the a key is pressed and while it´s pressed will be functioning the code inside of the while, so it will be subtracting the switchgrav value(0.01) from the gravity value(0) value and assigning the resulting value to the gravity variable, which is just like making this kind of subtraction: gravity = gravity - switchgrav.
(gravity variable receives(=) gravity value minus(-) switchgrav value).
And wait 1 frame every time.

The other while loop will be true when the z key is pressed, and will be making this sume to the gravity variable:
(gravity variable receives(=) gravity value plus(+) switchgrav value).

After that, no matter what while the engine was in, the gravity variable will receive the value of 0, overwriting everything we did before, so it returns to the (floating) value and stops submerging or emerging:
gravity=0;
(gravity variable receives(=) value of 0).

6.6 Now we just need a way to make this function to be called every time. Write this code in blue inside of our main entity action:

action sub_simulate
{
player_drive();
on_anykey=switch_gravity;
wait(1);
}

6.7 Build and Run, and test this function pressing either a or z key on your keyboard.

6.8 If you´ve done the sonar interface tutorial, you remember that we assigned the rotate_scan function to the on_anykey variable to execute always when any key was pressed:

We ended with the problem of being called too many times mixing the image order.
And we have a new problem that this code is not working at all.

on_anykey=rotate_scan;


6.9 To resolve both problems:
6.9.1 Delete this code:

on_anykey=rotate_scan;

6.9.2 Write this code in blue in our sub_simulate action:

action sub_simulate
{
player_drive();
on_anykey=switch_gravity;
rotate_scan();
wait(1);
}

7.0 Save the script, Build and Run to see everything working now as it should.

7.1 The reason why we always call a function through on_anykey without parenthesis " ( ) ", is simple:

7.1.1
With this code:
on_anykey=rotate_scan;
It assigns the rotate_scan function to be executed.

7.1.2 This way:
on_anykey=rotate_scan( );
It not only executes the rotate_scan function, but also assigns the returning value, if any, to the on_anykey variable. Use this only when your function returns a value and you want to get that value back.


8.0 You may notice that our player is moving pretty fast for a submarine under water, because we are using no gravity influence, which makes our entity without any kind of friction influence, (ground friction). We can control using the predefined variable air_fric (air friction).

8.1 Write this code in blue in your main script:

var gravity=0;
var air_fric = 0.05;

8.2 If you remember from the movement.wdl, in step 2.2, this variable starts with a value of 0.03. Now we overwrited the air_fric variable with a value of 0.05. So it gets more difficult to move the entity.

8.3 Save your script, Build and Run to see the effect, try changing the value to see how it works.

9.0 If you notice that our entity player can pass through walls, staying half inside and half outside, that´s because the collision detection of our entity is not set properly.
To fix the problem, write this code in blue inside our main action:

action sub_simulate
{
my.narrow = OFF;
my.fat = ON;

player_drive();

9.1 This way we certify that the collision detection of our entity will be fat, used for entities bigger than 64 quants, and first we turned off the narrow hull used for entities smaller than 8 quants. We use the my reference always when we are inside of an action, this way we can refer directly to the entity owner of that action.


Now we have finished our submarine simulation. Try using other variables in the wdl prefabs, you´ll find a lot of interesting features.
I hope this tutorial completes the goal of making to you an easy entry to the world of 3D Game Studio.




Go To:
  1. Introduction
  2. Level Design
  3. Low Poly Modeling
  4. UV Mapping
  5. Submarine Interface
  6. Submarine Simulation




All Rights Reserved - 2004