The Pi Tri Game Making Experiment

The Pi Tri project is my first serious attempt at developing an independent game. Most of my programming experience was in making modifications in the Unreal engine using UnrealScript. I have done a little work in Blitz3D and, well, BASIC way back in the day. Pi Tri's code is mostly my creation, sometimes building on ideas picked up from other projects on the Internet (like how to find if two lines are intersecting in vector math, SCARY!). Pi Tri is written in the C# language and uses Direct3D to handle drawing graphics.

Pi Tri is a 2D overhead-view shooter. Ships are controlled with a forward/reverse/turn control scheme. The defining feature of Pi Tri is that these ships are custom-built from a variety of parts. The way the ship behaves depends on how the player constructs it.


An example ship I whipped up.

The name Pi Tri comes from Pi/3 radians, the equivalent of a 60 degree angle (and the size of each angle inside an equilateral triangle).

The initial inspiration for the game came from a toy that had rods and ball bearings that connected together with magnets. You never know where new ideas will come from.

The parts that can make up a ship

Ship parts are color coded to their use. Currently these colors have been put to use:
  • Gray = structural
  • Green = engines
  • Yellow = fast attack weapons
  • Red = heavy attack weapons
  • Blue = defense
Core: The heart of the craft. When making a new ship, this is always the first part placed.
Disc: Used to connect other parts together. Remember Tinker Toys? They're like those circular hub pieces. Parts connect at intervals of 15 degrees or pi/12 radians. This equates to 24 possible angles.
Rod: Basic connector piece
Booster: Propels the ship. They have settings to control when they fire. Using these options they can propel the ship forward or in reverse, and turn the ship by only firing engines on one side of the ship.
Blaster: Rapidly fires fast-moving but weaker shots.
Cannon: Fires heavier shots, but has lower rate of fire, and the shots are slower than the Blaster's.
Shield: Supposed to take less damage than other parts, but it's not yet implemented in code.

The previously mentioned parts are the most basic types. The plan is that parts are made of a formula of color-coded materials, and with the correct 'blueprint' the player can manufacture raw materials into new parts.

Working Features

Ship Builder
Updated 2/11/09

The Ship Builder is the part of the game that you build your craft. It's currently functional, allowing you to put various parts together to form a vehicle.

On the left is the parts inventory. On the top are options for a selected part of the ship, in this case a Booster Engine. The rest of the screen is the area for the ship under construction.

There’s also the Test Ship button in the corner that will throw your creation into a playable space to try it out.

Non-disc parts can be attached to Discs in 24 angles. To place one, select it from the inventory, then select a disc already on the ship, then rotate the mouse around the disc to get the piece in the desired angle.

Conversely, Discs can be placed on non-disc parts. To place one, select it from inventory. Corners where you can place a disc become highlighted. Just click on the highlighed spot you want and it will be placed.

Parts can't be placed to overlap each other, and for parts like weapons and engines, other parts can not be placed in their line of fire.

The red X in the top part of the screen allows the removal of a placed part. Parts can only be removed if they don't 'break' the ship, leaving any other part orphaned from the ship's core.


Delta Time game loop stepping
Game data is updated in steps. The Delta Time (DT) is how long it took the last step to run. By adjusting physics equations and timers by the DT, it allows the game-play to run at a reliable speed regardless of how fast the computer is able to process each step.


Input system
I based this input system on one I made in Blitz3D.

There is a key input array that contains an entry for each keyboard and mouse button. For each button there is a place to track its current state, and places for a “press” “hold” and “release” Input Event.

The base program tells the input system when a key has changed between being on or off.

Once each game loop, the input system updates the state of each key. If a key is in the press, hold, or release state, its entry in the array is checked, and if an Input Event is present for that particular state, the Event is sent to the next step.

Once all keys are checked, a list of the triggered Events is passed back to the main program.

The main program passes the Events on to other parts of the program (mainly the GUI and player control). These parts check if a certain Event name is present (for instance (“Fire”) in the list it got and then runs the appropriate code if it finds it.

Settings for the Input Events are saved in an .ini file and therefore can be hand edited.

The program can convert the mouse screen position to the game world, adjusting for camera position, angle, and zoom (this is currently used to select parts of the ship).
Graphics system

The graphics system displays sprites from the game world using Direct3D.

A basic GUI system including images, buttons, and text is working. The best example of the GUI system so far is the Ship Builder's GUI.


Camera
The camera code is based on one I made in an Unreal engine top-down game modification.

The camera follows the player’s ship. It can also be set to use different modes. In its normal mode, it has a bit of movement lag to make the camera feel a bit more fluid and natural.


Physics system
Updated 2/11/09

Basic physics are working, utilizing location, angle, velocity, spin, acceleration, and torque of each entity.

For collision detection, entities can use a collision map making up an outline of their shape, or a basic circle to define their physical form.

The post-collision physics are sort of working, I haven't quite got down how much things should spin from an impact, but they do bounce off each other.

I have learned a special lesson from Pi Tri: Programming collision stuff is BRUTAL.


Map files
Pi Tri can store information about a game level in a file and it can be loaded by the program. The maps are currently just a list of each Entity in the map and the properties of each one.

There is also a rudimentary level building utility, which can place a couple types of map pieces and then save the changes to file.


File Packager

A simple system of packaging image files into a single file is working. Textures can be loaded from within a package by using a ‘filename.texturename’ format. Currently there is only a method for batch packaging files from a command line, and there is no method to add, delete, or modify items in a package. The contents of a package can be displayed by running the packager with the package's filename after it (this can be achieved by dragging the package onto the executable in Windows Explorer).

Pi Tri is a creation of Jesse Schoch / Critical Systems Digital. All rights reserved.