Questions from the forum

Top  Previous  Next

Q: I am experiencing low frame rates with very large scenery in 3DGS. Could you tell me what techniques I should use in order to optimize the process of very large scenes in 3DGS?

A: Any game engine will slow down if it has to render many polygons at the same time. Fortunately, there are several solutions that can be applied successfully:

- Use LOD (level of detail) for models. Hide the entities completely if they are far away or invisible for the player.

- Create regions in Wed, and then enable / disable them depending on the area the player is in. As an example, if the player is outside a building, you can disable the rendering for all the objects inside that building.

- Don’t run any CPU-intensive functions or actions when they aren’t needed. As an example, don’t run your enemies’ pathfinding functions if the player is far away from them; a simple, much faster vec_dist instruction will do the job.

- Only use shadows for the entities that really need them.

 

 

Q: How would you assign an action from the script that you have created to an entity in Wed? I have copied the script inside the game folder, but I dont see it inside Weds “Resources” tab. Is there a tutorial for this?

A: Copying the newly created script inside the game folder is a good first step. Then, you need to include that script in your main script, the one that includes function main( ).

 

aum107_faq1

 

aum107_faq2

 

 

Q: I want to use 'inkey' to type a string to the screen and more importantly then save it to a txt file. This is explained in AUM 74 using a booker database as an illustration. When saving to a txt file AUM 74 gets into structs and pstring which I want to avoid; is there a simple way of saving the inkey data to a text file?

A: There you go:

 

STRING* input_str = "#50"; // allow the name to have up to 50 characters

 

TEXT* input_txt =

{

       pos_x = 10;

       pos_y = 50;

       string(input_str);

       flags = SHOW;

}

 

function name_input()

{

       var filehandle;

       inkey(input_str); // now let's input the name

       filehandle = file_open_write("name.txt"); // overwrite the existing name.txt file (if any)

       file_str_write(filehandle, input_str); // write the name that was input

       file_close(filehandle);

}

 

function name_startup()

{

       on_n = name_input; // press the "N" key to input the name

}

 

 

Q: I would like to have snow falling down from the sky, and when it collides with the ground I would like it to make a white pixel. Is it possible to do that?

A: Open the weather.c file inside Gamestudio’s samples folder; you will see a fully functional example.

 

aum107_faq4

 

 

Q: I am trying to make a dynamic loading level, with an entity that rotates while the level is loading and disappears after the level was loaded. I hope that this is possible.

A: Take a look at the fully functional snippet below:

 

var loading_percentage = 0;

 

STRING* test_wmb = "test.wmb";

 

ENTITY* rotating_model =

{

       x = 200; // tweak the x y z values until you set the desired position and size

       y = 0;

       z = 20;

       type = "n.mdl"; // use your own model name here

         layer = 20;

       flags2 = SHOW; // show the model

}

 

function rotate_entity(factor)

{

       rotating_model.pan += 1.2 * factor * time_step; // play with 1.2

       loading_percentage = factor;

}

 

void main()

{

       fps_max = 70;

       video_mode = 7; // run in 800x600 pixels

       video_depth = 32; // 32 bit mode

       video_screen = 1; // start in full screen mode

       on_level = rotate_entity;

       level_load (test_wmb);

       while (loading_percentage < 100) {wait (1);} // the level is loaded here

       rotating_model.flags2 &= ~SHOW; // so let's hide the rotating model

}

 

 

Q: I am trying to get a spear to appear in my player's hand and move and rotate with it, but it wasnt animated together with it. Is there any chance to do that and make it look nice?

A: Sure! You only need to get two (let’s call then) “gripping” vertices on player’s hand; then, you will be able to compute the proper spear direction and thus rotate it properly. 

 

VECTOR palm1, palm2, sword_direction;

 

STRING* sword_mdl = "sword.mdl";

 

function attach_sword()

{

       proc_mode = PROC_LATE;

       set (my, PASSABLE); // the sword shouldn't slow down the player

       while (you)

       {

               // get the vertex at the bottom of the palm in Med

               vec_for_vertex (palm1, you, 28);

               // get the vertex that separates the thumb and the pointer finger in Med

               vec_for_vertex (palm2, you, 9);

               // compute the vector that will be used by the sword

               vec_diff (sword_direction, palm2, palm1);

               // rotate the sword accordingly

               vec_to_angle (my.pan, sword_direction);

               // put the origin of the sword in the vertex that is placed at the bottom of the palm

               vec_set (my.x, palm1);

               wait (1);

       }

}

 

action spearman_action()

{

       var anim_percentage = 0;

       ent_create (sword_mdl, my.x, attach_sword); // attach the sword to the player

         while (1)

       {

               anim_percentage += 3 * time_step; // 3 = "walk" animation speed

               ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "walk" animation

               c_move (my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

               my.pan += 2 * time_step; // 2 sets the radius of the circle

               wait (1);

       }

}

 

aum107_faq3

 

 

Q: I have several entities that are parts of a single ship. How is it possible to treat them as a "single" entity (e.g. move and rotate the ship with all attached entities)?

A: There you go:

 

STRING* part1_mdl = "part1.mdl";

STRING* part2_mdl = "part2.mdl";

 

function attach_parts()

{

       proc_mode = PROC_LATE; // prevent shaking

       set (my, PASSABLE);

       while(you) // as long as the creator exists

       {

               vec_set(my.x,you.x);

               my.pan = you.pan;

               my.tilt = you.tilt;

               my.roll = you.roll;

               my.frame = you.frame;

               my.next_frame = you.next_frame;

               wait(1);

       }

       ent_remove(my);

}

 

action my_ship()

{

       ent_create(part1_mdl, nullvector, attach_parts); // attach two parts to the ship

       ent_create(part2_mdl, nullvector, attach_parts); // add as many extra parts as you need

         while (1) // rotate the ship in a circle

         {

            c_move (my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

            my.pan += 2 * time_step; // 2 sets the radius of the circle

            wait (1);

         }

}

 

 

Q: I'm trying to make a panel A with a button that (when clicked) will display panel B. Also, panel B will have a button that (when clicked) will display panel A, and so on. How do I do that?

A: Here’s a fully functional example:

 

BMAP* button_a1_pcx = "button_a1.pcx";

BMAP* button_a2_pcx = "button_a2.pcx";

BMAP* button_b1_pcx = "button_b1.pcx";

BMAP* button_b2_pcx = "button_b2.pcx";

 

BMAP* pointer_tga = "pointer.tga";

 

function show_panel_a();

function show_panel_b();

 

PANEL* panel_a =

{

       bmap = "panel_a.jpg";

       layer = 15;

       button(40, 10, button_a2_pcx, button_a1_pcx, button_a2_pcx, show_panel_b, NULL, NULL);

       flags = SHOW;

}

 

PANEL* panel_b =

{

       bmap = "panel_b.jpg";

       layer = 15;

       button(40, 10, button_b2_pcx, button_b1_pcx, button_b2_pcx, show_panel_a, NULL, NULL);

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function show_panel_a()

{

       set (panel_a, SHOW);

       reset (panel_b, SHOW);

}

 

function show_panel_b()

{

       set (panel_b, SHOW);

       reset (panel_a, SHOW);

}

 

 

Q: I have had 3DGS for awhile now but have never had the time to devote to a project until recently. Before I get started on any development I wanted to know if there are any tips anyone can give me to help me not lose my way and get distracted by little details. Should I be setting myself goals or making some kind of development plan or something? Really anything that you find helpful when you want to stay focused.

A: Very helpful thread (the same where this question came from):

 

http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=403123&gonew=1#UNREAD

 

Let me add my own two cents. One of my mentors says that none of us plans to fail, but most of us fail to plan, which leads us to the same result. You get an amazing game idea, and then you start working at it. Then, you hit a stumbling block or you get an even more amazing game idea, so you stop working at the new project. The process repeats over and over and you end up having several unfinished games.

 

Here are the three key things that will help you finish your projects, no matter if they are gaming-related or not.

 

a) Plan everything. Create a mind map that includes ALL the details, with a checkbox at the right side of each item, and then print it out. Tick the checkboxes as you complete each task. Basically, you need to create a comprehensive task list and follow it.

 

b) Work with small sized projects. If you really want to create a huge game, break it down into smaller, manageable projects. As an example, break down a MMORPG into AI, user interface, multiplayer, and so on. Then, create individual task lists that won’t scare you – there’s a reason why the top games were created using the work of hundreds of people.

 

You might not get rich by creating a smaller sized game, but you will definitely learn the fine art of completing projects, a very precious skill that will be of great help throughout your entire life. No matter the size of the project, make sure to schedule and execute all the tasks on the list as planned.

 

c) Avoid the distractions. Sure, it might be fun to play games or watch TV 4-5 hours a day, but it will be even more exciting to work at your own projects and see them progress. Do a Google search and learn to work using the Pomodoro technique; you’ll never get tired if you apply it.

 

 

Q: Is there an opposite for enable_scan, like disable_scan? If the answer is negative, how do I disable the scanning for a specific entity, which was sensitive to scanning initially?

A: Here’s a fully functional example:

 

BMAP* pointer_tga = "pointer.tga";

 

function i_am_scanned()

{

       if ((event_type == EVENT_SCAN) && (my.skill99 == 0))

       {

               my.pan += 3 * time_step; // rotate the entity for as long as the entity is scanned and skill99 isn't set to 1

       }

       if (event_type == EVENT_CLICK) // the entity was clicked? Then don't allow it to react to c_scan instructions anymore

               my.skill99 = 1;

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

action my_entity()

{

       my.emask |= (ENABLE_SCAN | ENABLE_CLICK); // the entity is sensitive to scanning initially

       my.event = i_am_scanned;

}

 

action players_code() // attach this action to your player model

{        

       var movement_speed = 20;

       VECTOR temp;

       player = my;

       while (1)

       {

               my.pan -= 7 * mouse_force.x * time_step;

               vec_set (temp.x, my.x);

               temp.z -= 10000;

               temp.z = 0;

               temp.x = movement_speed * (key_w - key_s) * time_step;

               temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step;

               c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE);

            c_scan(my.x, my.pan, vector(360, 90, 200), IGNORE_ME | SCAN_ENTS); // scan around the player, play with 200

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50;

               camera.pan = my.pan;

               camera.tilt += 5 * mouse_force.y * time_step;

               wait (1);

       }

}