Help Support the Baja Engine! Donate to Breezeway Studios!
Your First Game XSI

Search:

First, throw a party!


The Baja Engine staff recommends throwing a party before starting a project.

Making your first game


This tutorial will go through all the steps to make a simple game with the Baja Engine.

Creating a new Project and Scene in Softimage


Open up Softimage XSI. The go to file>Project Manager. Then, select "New Project..." and give your project a name and store it somewhere on your hard drive. Then Click "New Scene".



Netview


This step is optional. This tutorial can be viewed within softimage in the netview viewport. Just click the menu item on the top left of a viewport (where it says top,front,right or camera) and choose netview. Enter bajaengine.com in the address bar.

Building our Level


Now we have a blank canvas in front of us. Exciting! Softimage will open by default to 4 viewports that show us our scene from the top, front, right and the camera.

Our game will consist of a few simple rooms. Start by adding a cube (Get>Primitive>Polygon Mesh>Cube on the left bar). Then click on the 'S' under 'transform' in the panel on the right. (Both of these have been highlight in the image below.)



'S' stands for 'scale' - this will allow us to resize the cube so that it looks more like a wall. Just click one of the red, green, or blue scaling handles in the viewports to resize the cube. Scale can also be enabled with the 'x' key. If the 'shift' key is held down when you scale, all axes will be scaled the same amount, so that you object will get bigger but won't be distorted.

Next, click the 'T' under 'transform' on the right. This allows us to move the cube into position. The transform tool can also be enabled with the 'v' key.

The 'R' button allows you to rotate your cube. Rotate mode can also be enabled with the 'c' key. If the 'shift' key is held down when you rotate an object, it will lock the rotation to 45 degree increments.

Note the scale of your scene! A handy reference point is to add the default character (Get>Primitive>Model>Body - Man). The default script that we will write later assumes that your scene was designed so that it was in scale with the default character - if you make it a different scale you may need to tweak some of the variables in the script.

At some point, you will probably want to move the viewports around. Two tools that accomplish this are the Zoom tool and the Navigate tool. To activate the Zoom tool press the 'z' key on your keyboard. The left mouse button moves the viewport around, and the middle and right mouse buttons zoom. Do not use the zoom tool on a 3d viewport! The Zoom controls will change the FOV of your camera, which makes stuff look weird. Instead, use the Navigate tool, activated by pressing 's'. The left mouse button moves the scene around, the middle mouse button pans, and the right mouse buttons rotates the view in 3d. The 'navigate' tool orbits around a center - if the camera is panned very close to the center, then naviagation will break down. If you get stuck where you can't move with the navigate tool, try panning out (middle mouse button). If you want to move the camera to examine a different part of your scene, use the left mouse button (move) mode instead of the middle mouse button (pan) mode.

In softimage, tools like the navigate and zoom tool can be used temporarily by pressing and holding down their keyboard key; to active them permanently, tap the key quickly.

Also, at some point you may need to select another object. To do this, press the space bar to enter selection mode. Then, click on the object you want to manipulate.

Proceed to make more cubes (and whatever objects you want) until you have constructed a scene that is made up of two rooms with a hallway between them.

To focus a viewport on a single object, tap the 'f' key; to focus the viewport on all the objects in your scene, tap the 'a' key.

To delete a cube, select on of the cubes and press the 'delete' key on your keyboard.

To duplicate a cube (make an exact copy of it), select it and press ctrl-d.

Below is an example scene, with a few extra crazy cones and spheres thrown in for good taste! Note: The scene that we are constructing has a lot of unessential polygons that will not show up on screen in our game (the ends of the cubes, etc). In a real game, we would delete them, but for this tutorial it's fine.



Now is probably a good time to save your scene (File>Save). This tutorial assumes that you named your scene 'myfirstgame' (the name will be used later).

Adding Textures


Now we have our geometry in place, but our room is very boring because nothing has a texture on it!

Select an object that you want to apply a texture to. Then, click Get>Material>Phong on the left panel.


This will open up the Phong properties box. Now we want to attach a diffuse (ie, base color) texture to the material. Click the plug icon next to Diffuse - Color and choose 'Image' from the menu.



Now we want to select an image file to use as a texture. Click the 'new' button near the top of the property page and choose "New From File..." and select an image. By default, Softimage looks in the Pictures subdirectory of your project. This is a convenient place to store textures, but the file can come from elsewhere too. Later, if you want to reuse this image, select it from the drop down box at the top - do not add it again, as this will add another extra reference to the texture, which can be annoying. Note: the size of all texture images must be Powers of Two due to hardware limitations in graphics cards, and the image must be a bmp.



Now we need to add a texture projection. A texture projection maps our 3d vertices to a 2d picture. We are going to choose a cubic projection because all of our geometry is made of cubes. Just choose Texture Projection>New>Cubic from inside the properties box.



Next, we need to make a small detour. By default, the cubic projection in Softimage will not work well with lightmaps (explained later...). Click the 'edit' button right next to the 'new' button that we clicked earlier to edit the settings of the texture projection. This will open up a huge properties dialog. Down near the bottom, there is a tab called 'Layout'. Click this. Then click on the picture circled in red in the image below. Note: this fix is only needed for cubic projections, all other projections are fine.



Previewing your Textures in Softimage


You will probably want to see what your texture objects look like. In the top right of each viewport, there it says 'Wireframe'; click this and change it to 'Textured Decal'. There are a lot of other options for viewing modes - Textured Decal shows your textures without lighting, Textured shows it with lighting, shaded draws your geometry as solid object, etc.



Texture Repeats


You will probably notice that some of your textures are out of proportion. To fix this, you need to make your textures repeat. You need to have Tiled Textures for this to look right.

First, select the object that you want to adjust the texture repeats on. Then, open up the 'Render Tree' view. Do this by selecting the menu at the top left of one of the viewports, where it says 'Camera' or 'Top'. Select 'Render Tree'. You may need to click the 'refresh' button at the top of the render tree view for your object's material to show up. Note: the render tree is also where you implement nifty shader effects. See Shaders.



Now, double click on the node called 'Image'. This will bring up the properties box for our image node, where we can set the texture repeats.

To bring up the Texture repeat controls, click the 'Advanced' tab. It will look like this:



The first slider is repeats in the 'u' or 'x' direction, the second is in the 'v' or 'y' direction, and the third in the 'w' or 'z' direction. 2D textures don't have a z direction, so the third bar does nothing. Set one of the viewports to 'Textured Decal' mode and adjust the repeat controls until all your objects look correct.

The UV Editor


Texture projections (which map the 3d vertex to the 2d texture) are also referred to as UV maps. Sometimes the default projections won't work for your object and you have to edit the UV maps manually; this is called UV mapping. Discussing all of the elements of UV mapping is beyond the scope of this tutorial. As you progress to more complicated models and levels, however, you will need to learn about this. The main considerations are removing all overlaps (because this messes up lightmap generation), setting up your maps so that they use as much of the texture data as possible, preventing seam, and keeping the scale of the texture consistant. There are UV mapping tutorials in the 'Where to Go from Here' section below.

You can bring up the UV editor in Softimage by clicking one of the menus at the top of a viewport and choosing 'Texture Editor'. It will change your viewport to the UV editor:



The Explorer View


A useful way of viewing your scene as it gets bigger is the 'Explorer' view. The explorer lists all of your objects and their properties.

You can open the explorer by clicking the 'top','right',etc menu dropdown that is at the top left of each viewport. The explorer will show a list of many different types of objects, but you probably want to see your scene's geometry. To show the geometry, click the dropdown menu in the top left of the explorer box and choose "Scene Root". This is probably the default mode, but it may have been changed.

If, at some point in this tutorial, you need to open a properties box again, you can do it with the explorer find the object you need to change properties on, and click the [+] next to its name. Double click on the property node you want to edit. All properties attached to the object can be opened like this.

It looks like this:


Previewing our Level in the Engine


Now the we have our level built and textured, we are ready to preview it in the game engine! First, we need to export our level to the engine's level format.

Exporting: XSI Foundation


Note: if you're using the Mod Tool, skip this section and look at the next one.

First, if you added the default man character, delete it. It uses a texture format that won't work with the engine, and it's ugly.

In XSI foundation, is is really easy to export to a LML: just choose 'D - Developer Build' from the Baja menu at the top of your screen. If the menu isn't there, make sure you installed everything right. See Installation.



Exporting: XSI Mod Tool


Note: if you're using XSI Foundation, you can skip this section.

First, if you added the default man character, delete it. It uses a texture format that won't work with the engine, and it's ugly.

Next, export your scene to a dotXSI file, File>Export>dotXSI. Make sure that format is set to ASCII and 'Polygon Type' is set to 'Triangles'! Save the file in a subdirectory called 'myfirstgame' of your working directory. In the default install, this file would be located at C:/Program Files/Baja Engine {edition}/work/myfirstgame/myfirstgame.xsi. The subdirectory will not exist yet, you will have to create it.

Now we need to convert this dotXSI file to an LML. Open up the Command Prompt, and set the working directory to your tools directory. If you don't know how to do this, see Using the Command Line. Then type this command:

Code

xsiconvert --developer ../work/myfirstgame.xsi ../work/myfirstgame/myfirstgame.lml


For much more detailed information on the converter, see xsiconvert.

Creating A Simple Dummy Script


You need to give the engine instructions about what it should do by providing it a script written in Lua. For now, we will just create a dummy script that loads the level and lets us move around it with the default camera mode.

First, open up notepad.exe (Start>Programs>Accessories>Notepad) or anther text editor.

If you are not familiar with Lua scripting, you can just copy and paste this codeblock into your text editor and not worry about what it means. We'll discuss how scripting works later and in Lua Basics.

Code

function main()        --called when the engine starts
        mouse.visible=false        --hide the mouse
        camera.fly=true        --don't worry about collisions yet
        level.load('myfirstgame/myfirstgame.lml')        --load our level
end


Then, save the file. For convenience, and to follow this tutorial, it should be saved in the engine's working directory. By default, this is located at C:/Program Files/Baja Engine {edition}/work/. Save the file as 'myfirstgame.lua'.

Creating a Launcher: Windows


On Windows, the engine is started with your script as an argument so that it knows what to do. We can make it easy to start the developer version of the engine with our script by creating a bat file.

Open Notepad. Paste this in the file:
Code

..\tools\engineDeveloper.exe myfirstgame.lua


Save this as myfirstgame.bat in the engine's working directory, located at C:/Program Files/Baja Engine {edition}/work/myfirstgame.bat.

Creating a Launcher: Mac


If you are running windows, skip this section.

There are instructions about how to launch the engine on the mac in the Distributing tutorial.

Run your game!


Now, Open up the engine's working directory (C:/Program Files/Baja Engine {edition}/work/) in explorer and double click myfirstgame.bat. Your game will start, it will look something like this:



If, for some reason, your level didn't run, you will need to look at the log file. Open C:/Program Files/Baja Engine {edition}/work/logs/main.log in notepad. Usually, the only problem that you will encounter is incompatible textures.

Adding Lights


We exported our level and have looked at it in the engine! But, everything is ugly. There is no lightning; we need to add lightmaps.

Switch back to XSI.

First, of course, we need to add lights. Go Get>Light>Point, and then move the light so that it is in the center of one of your rooms. In one of your 3d viewports, use the navigate ('s') tool to look at the room. Then, press 'q', and drag a box around your scene. This will bring up a render preview.

Note: by default, Softimage includes a light in your scene. If you don't want to have this extra light, open up the explorer view and delete it.



Now, we are going to tweak the light. Select the light an press alt-enter to bring up the light's properties box. First, you will want to enable shadows, by clicking the checkbox to the right of 'Enabled' under 'Shadows'. Next, we will want to set up a light falloff. Set 'Mode' to linear and click the box to the right of 'Light Falloff'. Then set 'End Falloff' to something like 80. Set umbra to something like 0.25 - umbra is the amound that shadows obscure the light. Your shadow probably won't be too visible in the engine if you leave it at the default 0.75 setting. You can also change the color if you want to.



Tip: if you want soft shadows instead of hard shadows, a quick way to make them is to use the 'Shadow Map' option in your light's properties box. Click the 'Shadow Map' tab, click 'Use Shadow Map' and then click 'Use Shadow Map in Region' and 'Use Shadow Map in All Passes'. Adjust the 'Softness' and 'Resolution' parameters until you like them.



Proceed to add however many lights you want. Note that adding more lights will affect your lightmap render times, but won't affect the speed the engine runs.

Adding Lightmaps (Foundation)


Note: if you are using the Mod Tool, skip the section and move on to the next one.

Now we need to export our lighting to the engine. First, select one of the objects that you want lit. Then choose Get>Property>Render Map to add a render map to it.



The Render Map properties dialog will pop up. From here, you can tweak the size of the rendered map. Try to keep the size as small as possible without compromising quality; smaller sizes will fit into the limited graphics card memory better. Also, be sure to select your correct texture projection in the menu next to 'UV'. See XSI Tips for some tips about render maps.



Now, you need to actually render you maps. You do this in the Baja menu. Select the object(s) that you want to render lightmaps for. Then go 'Baja>Ls - Build Selection Lightmaps'.



Now the you have rendered your lightmaps, export your level again, using the instructions above. Then run it with the bat file and see how it looks!

Adding Lightmaps (Mod Tool)


Note: if you are using Foundation, skip this section (unless you want to know how to use Baja's built in lightmap renderer).

The Mod Tool doesn't have a built in lightmap render, so we need to export our lights to the engine and use its lightmap renderer.

Select you light, then click the 'Palette' button at the bottom left of your screen. Click the 'P' button. If it isn't there, make sure you followed the Installation tutorial correctly. The properties box will come up. Click the box next to 'static'. Tag all of the lights you want to export and disable the 'static' option in their properties box. For more information, see Properties.

Now, export your level again and convert it, using the instructions above. Then run the engine with the bat file. Bring up the editor by pressing the tilde (~) key. Select the object you want to add a lightmap to by clicking on it with the mouse. You can set the size of the lightmap by adjusting the size at the bottom of the screen. Try to keep the size as small as possible without compromising quality, to save texture memory space. Then, click the lightmap button (the bottom one on the left). A lightmap will be renderered and displayed.

If you run myfirstgame.bat again, your lightmaps will be gone! You will have to convert your scene to a LML again using xsiconvert for it to pick up the lightmaps and store them permanently.

Note: the Baja lightmap renderer may not be identical to the Softimage renderer; you may need to tweak your light's settings either in Softimage or from the Script Console.

See Editor for more information on the editor.



Our Lit Game


Your game should now look something like this:



Collision


Ok, now our level is looking decent; let's turn it into a game.

First, we need to make our camera collide with the walls of our room instead of fly through them. To do this we need to create a collision object.

Go to Get>Primitive>Polygon Mesh>Grid. In the box that comes up, set subdivision in the U and V to 1. Now, move and scale our grid so that it is a little smaller than your first room and right above the floor. Go into edge mode (click the edge button at the top right of the screen) and select all the edges (ctrl-a). Then, duplicate the edges (ctrl-d) and use the translate tool (the 't' at the right of the screen) to move the duplicated edges up to the top of your walls. You should now have something that looks like this:



Now we are going to extend this to your second room. Make sure your collision obect is still selected. Switch to polygon mode by pressing the 'u' key and click on the polygon that is on the side with the hallway. Then, right click on the shaded polygon and choose 'Extrude along Axis'. Now use the translate tool to move the selected polygon towards your hallway. You will also need to use the scale tool to make it the same size as the hallway. Continue to extrude and translate polygons until you have created the collision object for your two rooms.

Make sure that your collision object isn't too close to your walls - if it's too close, then the camera will be able to see through the walls when it gets near them.

Your object should look something like this:


Note: with collision objects, it is important that the Normals are always pointing in towards the area where the camera will be. If you followed the directions in the paragraph exactly, you shouldn't have problems with this, but you may run into it when you make your own game later. To see if your normals are correct, click the icon that looks like an eye at the top of a viewport and choose 'normals'. The blue lines should be pointing in where the camera will be.

Now the we have our object created we need to inform the engine that it should collide with this object. To do this, we need to tag the object with properties. Select your collision object. Make sure you are in object selection mode (press space). If you're using Foundation, go to the Baja menu and click 'Baja>P - Add Properties'. If you're using the Mod Tool, select the object, click the 'Palettes' button on the bottom left of your screen, and then click the 'P' button.

The properties box will open. Click the box next to 'collide' to enable collision with this object.



Now we need to hide our collision geometry - we don't want it to show up on screen in our game. Select the collision geometry and then press 'h' to hide it. If you want to edit it later, find it in the explorer view and select it and press 'h' again.

For more information, see Properties.

Setting a Start Point


Now that we have our collision geometry ready, we need to put the camera somewhere where it won't fall through the floor. We'll do this by adding a Null and using its position to place our camera.

Go to Get>Primitive>Null. Then press alt-enter to bring up its properties box. Change its name to 'start', then close the box. Move the null to somewhere in your first room, and place it well above the floor.

Next, we need to tell the engine that we want our null to be accessible to the script. Tag the null with a properties box (see the instructions above). Uncheck the checkbox next to the 'static' button, to tell the engine to make this null accessible to our script.

Now, we need to add code to our myfirstgame.lua script to put the camera at the start point.

Add this code inside the main() function, right under 'level.load' but before 'end':
Code

camera.pos.x=obj.start.pos.x
camera.pos.y=obj.start.pos.y
camera.pos.z=obj.start.pos.z


Also, enable collision in your script by changing this line:
Code

camera.fly=true


to this:
Code

camera.fly=false


Now, go ahead and export and preview your game again, to see if the collisions are working correctly. If you fall through the floor, you probably didn't put your 'start' null high enough off the ground.

Adding some simple gameplay


Now we are going to add simple gameplay to our game: we're going to add a door between the rooms that opens and closes.

First, create a cube and fit it between the first room and the hallway. When this cube's properties box opens, name it 'door'. use the instructions in this tutorial to texture it and add a lightmap to it.

Next, add a second cube: this will serve as our collision object. When this cube's properties box opens, name it 'doorCollide'. The second cube should be a bigger than the first cube big enough that it will cover the door even when it is open. You don't need to texture this cube because it will be invisible.

Then, we need to set the center of the 'door' object. By default, Softimage puts the center of each object in the middle of it; but, when a door turns, it turns on a hinge at the end of it instead of at the middle. To move the center, click the 'Center' button on the top right of the screen. This will bring up a small white dot that is the center of your object. You don't need to do this to the collide object.

Switch to a top view. Use the translate handles to move the dot to where you want your hinge to be.

Here's an example:


Now we need to mark both door objects as nonstatic, so that we can alter them when the user clicks on them in our script. Add a properties box to each using the instructions above, and unclick the box next to 'static'.

We also need to assign the 'door' object an action, so that our script knows when it is clicked. Type 'myDoor' in the box next to action in its properties box.

The model for our door is ready to go! You can go ahead and export it to a LML. Now we need to write the script.

First, add this code to the bottom of the script, outside of any other functions. This will handle the event that is triggered when the user clicks on the door.
Code

swingDoor=false        --a variable we'll use to indicate that the door should open
function myDoor(event)
        if event=='mouseLDown' then        --if the event was a mousedown event
                swingDoor=true
        end
end


See Object Events for more information.

We need to add a 'perframe' function to our script. The 'perframe' function is called every frame. It is used for animating objects and other things like that. We will use it to open the door.

This codeblock assumes that you door's y rotation when it is closed is '0' and '-90' when it is open. If you door's y rotation is different (you can check in softimage on the panel to the right) then you will need to change the 'doorClosed' and 'doorOpen' variables. Copy this at the bottom of your script:
Code

doorClosed=0
doorOpen=-90
function perframe()
        if swingDoor and obj.door.rot.y>doorOpen and doorOpen<doorClosed then
                obj.door.rot.y=obj.door.rot.y-time*2 -- rotate our door a little each frame
                if obj.door.rot.y<=doorOpen then -- if our door is at the end position
                        obj.doorCollide.collide=false        --allow player through the door
                end
        end

        if swingDoor and obj.door.rot.y<doorOpen and doorOpen>doorClosed then
                obj.door.rot.y=obj.door.rot.y+time*2 -- rotate our door a little each frame
                if obj.door.rot.y>=doorOpen then -- if our door is at the end position
                        obj.doorCollide.collide=false        --allow player through the door
                end
        end

        -- The next four lines are explained later
        obj.mousepanel.pos.x=engine.window.size.x/2
        obj.mousepanel.pos.y=-engine.window.size.y/2
        engine.picker.pos.x=engine.window.size.x/2
        engine.picker.pos.y=-engine.window.size.y/2
end


Next, we need to configure the picker, which will send mouseclicks to the object. Add this to the bottom of the main() function:
Code

engine.picker.on=true
engine.picker.draw="nonstatic"
engine.picker.scale.x=10
engine.picker.scale.y=10
engine.picker.clip.near=0
engine.picker.clip.far=20

obj.doorCollide.visible=false         --not picker related; hides the collide object
obj.doorCollide.collide=true        --mark the door as a collider


Finally, we need to make a mouse panel, so that the user knows that they can click on stuff. For this tutorial, you can just copy the Techdemo mouse (C:/Program Files/Baja Engine {edition}/work/techdemo/mouse.tga) to your working directory (C:/Program Files/Baja Engine {edition}/work/techdemo/mouse.tga). Then, add this code to the bottom of the main() function:
Code

level.add{type='panel',name='mousepanel'}
obj.mousepanel:load('myfirstgame/mouse.tga')


Adding sound


You will want to add a soundtrack to your game. First, you will need to add a wav or ogg sound file to your game's working directory. For now, you can take the Techdemo's background music (C:/Program Files/Baja Engine {edition}/work/techdemo/houseLoop.ogg) and copy it into your working directory (C:/Program Files/Baja Engine {edition}/work/myfirstgame/houseLoop.ogg). Note: in the viewer edition, this will be a wav file instead of an ogg file.

To load and play the file, add this code to the main() function, right under the camera code:
Code

music=audio.load('myfirstgame/houseLoop.ogg')
music:play()


For more information, see audio and AudioSource.

Where to go from here


After you have completed your first simple game, you will want to consult the rest of the documentation to learn how to create your game. Some good articles to read after this one are Lua Basics,Cutscenes,and GUIs. You can also take a look at how the Techdemo is put together.

If you want to share the simple game here with others, see the Distributing tutorial.

To learn more about XSI, EdHarriss.com has a lot of excellent tutorials.