Monday, April 30, 2012

I Love Databases

I got the database to work.  I basically lifted the scripts I wrote for Unity3D and compiled them in Microsoft C#.  I dumped the Battlestar.dll file in the Unity3D asset folder, and Battlestar (the game) now accesses a database.  Bullets and missiles now load their information from the databse.  Here's the coding for the bullets.
First the class declaration (bullet.cs):

Now here's the BulletManager.cs that handles the loading and saving of data to and from the database:

Basically, the load and save routines are executed here along with the creation of the Bullet class structure.  The missile data routines are similar to the bullet routines.  The major difference being the number of fields.  It takes more data to define a missile (not only does it explode; it has AI parameters and the flight control script to guide it). 

I did complete a basic AI routine for missiles, and they do travel to target now.  However, there is an issue of collision detection.  Sometimes the missile appears to travel through a target; I am working on resolving this issue. 

In addition, I made the explosive force associated with bullets and missile do damage.  The old system was purely kinetic damage.  Now, the explosion checks for all craft in range and applies damage.  There is a linear falloff on damage based on range (craft further away will take less damage). 

Inspired by the bullet and missile spawn points, I added damage spawn points.  After a craft takes so much damage, a "I'm damaged" visual effect is activated randomly.  It's just a simple particle effect to simulate sparks flying from certain points of the craft.  Each effect is preloaded onto the plane and activated after taking damage. 

Current plans include finishing up the counter measure routines and then revisiting the user control setup.

Sunday, April 29, 2012

I Hate Databases!

After a full day messing with accessing databases in Unity3D, I have come to a troubling conclusion.  Databases and Unity3D don't mix well.  I think the main problem stems from Unity's need to dynamically generate code at every execution.  That means a routine to access a database will vary slightly every time the game is closed and reopened later.  Consequently, the "newly" generated code can't access data saved by a "previously" generated code.  This "feature" has given me a massive headache.

Since Unity will dynamically create code, the best bet to incorporate database routines into Unity is to create an external .dll file to handle database functions.  By building the database routines in Microsoft C#, the routines should be pretty "static" compared to the "dynamic" nature of Unity routines. 

To make this work, I'll generate a Battlestar namespace and .dll file.  It will contain various managers.  I'll have to build the stuff over time; so, Battlestar.dll will start with a BulletManager.  To access the database routines in Unity, the following code should work:

Load will be a defined procedure in BulletManager and will need a path name (which will reside in the ResourceManager; so, we won't have to figure it every time we need to access the database) and the bullet type.  Load, itself, will open the database at the path name and look for a bullet of the specified type.  vBulletData will be a variable designed to hold the bullet data retrieved the database.  After getting the data, it can be manipulated normally.

Missiles and Countermeasures will require a similar setup to load data into these commonly instantiated (created) game objects.  In addition, the future resource manager will utilize this concept.  The Battlestar.dll file will grow over time. 

Another major issues is data entry into the database.  Currenty, there is no way to easily create or maintain the database.  I'll have to create a database editor in Microsoft C# (using the Battlestar.dll) to access the database from a developer perspective.  This will allow the developers to add different styles of bullets the game.  Currently, the only type of bullet available is a "standard" type.  In the future, there are plans to add a "armor piercing", "high explosive" and other types.  The same thing goes for missiles and countermeasure.

I spent a majority of the last twenty years developing and deploying databases.  This is probably the first time that I abolutely hated databases.  Unity just created so many headaches and routines (at least in design) that have worked for me for over two decades just didn't cut it.  It just took forever to learn that the routines weren't flawed; it's just how Unity's setup causing issues.

Friday, April 27, 2012

Prototype 2.1

I finished with the controls for the next prototype.  I'll post both prototypes here for user comparison.  The AI input routines are not finised on the new version; however, I will hold off on designing them until I get some feed back.  I just don't see the use in creating them if nobody likes the new controls.

Here's the previous version:

These are the controls:
W and space - Accelerates and decelerates the ship
A and D - Rolls the ship
Q and E - Apply side thrusters
S and X - Apply up/down thrusters
Mouse Move - Turns the ship
Left Mouse Button - Fires primary (bullet) weapons
Right Mouse Button - Fires secondary (bullets) weapons
R - Releases countermeasure
V and B - Zooms and unzooms the dradis picture
Here's the new version:
Here are the new controls:

W and  X- Adds or subtracts thrust (1% of maximum thrust)
S - Sets thrust to zero (but retains forward momentum
A and D - Rolls the ship
<Space> - Activates inertial controls which stops the ship and reduces thrust to zero (over time)
Left Mouse Button - Fires primary (bullet) weapons
Right Mouse Button - Fires secondary (bullets) weapons
Mouse Move - Turns the ship
R - Releases countermeasure
V and B - Zooms and unzooms the dradis picture
These controls are either disabled or an extra option:
`, 1-9 and 0 - sets thrust to 0%, 10% - 90% or 100%
J  and L - Apply side thrusters (disabled on a viper - available on a Raptor)
I  and K - Apply up/down thrusters (disabled on a viper - available on a Raptor)
I tried to simplify things with mixed results.  W, S, X and <Space> (with A and D) are primarily things that are going to be used in combat.  The mouse buttons and R activate various weapon systems.  I left the zoom option in the game.  The directional thrusters are listed; however, they are disabled to the player.  I didn't take them out due to the possibility of including Raptor like craft into the game.  I added the ability to go directly to a thrust setting (`, 1-9, 0); however, the W, S and X setup are just as effective. 
So, play both prototypes and let me know which one works better.
As a side note, I included the Battlestar Minoa, a Hermes Class Destroyer, to the new prototype.  Its a model that I created from scratch.  It's untextured and does not have any script attached to it.  Also, I did not include any gun emplacements.  I'm holding off on that until I hash out my plans on capital ships. 
But, I made it myself...  What do you think?

Thursday, April 26, 2012

Prototype 2.0

I developed a "scene" similar to the tutorial #3 from the first prototype.  I'm posting it here for how the viper handles feedback.

Here are the controls:

W and space - Accelerates and decelerates the ship
A and D - Rolls the ship
Q and E - Apply side thrusters
S and X - Apply up/down thrusters
Mouse Move - Turns the ship
Left Mouse Button - Fires primary (bullet) weapons
Right Mouse Button - Fires secondary (bullets) weapons
R - Releases countermeasure
V and B - Zooms and unzooms the dradis picture

I plan on making some changes to the flying behavior.  In the next build, the ship will have a permanent forward thrust, and the user will control the thrust setting.  The ` and 1 - 0 keys will immediately apply 0 to 100% thrust for the ship's model (viper mk1 will have a max thrust of 15 while the mk2 will have a max thrust of 30).  The fuel consumption rate will depend on the how much thrust is applied at any given time.  In addition, the W key will increse thrust by 1% per frame, and the X key will decrease thrust by 1%.  The S key will set the thrust to 0% (like the ` key).  I will take out the side and up/down thrusters in the next build for fighter craft; however, the stuff will remain coded into the system.  Raptor and Raptor-like vehicles will be able to utilize these features.

When I get the next build done, I will post here in my blog.  Hopefully, someone will give good feedback between the two builds.

Wednesday, April 25, 2012

Flight Control Overview

I'm trying to get my prototype hosted on the web but have ran into some problems.  So I will cover the flight control script.  It's a rather long script and involved script that uses the player data and vehicle data scripts.

This script was originally from the Space Game Starter Toolkit created by ArenMook.  I have heavily modified the code to fit the game.  It is also unrecognizeable from its original format.
It starts out with the usual declarations and documentation:

At this point, I will point out that the variables in vehicle data are replicated here.  There is a very specific reason for this.  First, I plan on leaving vehicle data (and player data) relatively untouched by the mission.  These two data structures will represent the benchmark values for a fighter and do figure into calculations.  Second, declaring them as values allow me to directly manipulate them in this script without worrying about unforseen interactions.

The variable declarations are pretty run of the mill; however, we do use a couple of new declarations.  We set up a Listener for collisions, a List for collisions and make a public declaration for a GameObject.

The collision stuff is a hold over from the original code, and the game object declarations allow us to create (or instantiate) an explosion when the fighter is destroyed during gameplay.

The main section has many of the same type of statements in the data scripts.  We do create a reference to the vehicle data script here.  vInitialData = VehicleData.Find(vTrans) creates a reference to the VehicleData script attached to the fighter.  We don't change any values; we use it as a quicker way of accessing the "benchmark" data. 

At this point, there are calculation scripts.  Update() allows the user to control the ship (if it is own ship) and is a built in Unity script.  The LateUpdate() and FixedUpdate() are also built in scripts.  Update() executes every frame.  As long as your computer is not taxed, it is the quickest update script.  LateUpdate() only updates after the other update functions have completed execution, and FixedUpdate() updates at a fixed interval.  In the prototype, FixedUpdate() updates every 0.1 seconds.

The UpdateInput() is not a built in fuction; it is a user defined function.  I deleted the android app section for readability.  Basically, this function checks the mouse position against center screen and generates a turn force based on the offset.  In addition, it checks for inputs for right, up and forward momentum (left appears as a negative right and down appears as a negative up).  All of these inputs are placed parsed and placed into the manuevering variables (vTurn, vMove and vSmoothMove). 

The future AI routines will directly place values into vTurn, vMove and vSmoothMove via the defined methods.  The FixedUpdate() function actually executes manuevering based on what is in these variables by UpdateSteering() and UpdateTorque().

UpdateSteering() calculates the direaction and amount of force to apply to the craft.  Based on what was calculated into the vector variables for vMove and vSmoothMove, it will apply the appropriate force to the fighter.
UpdateTorque() handles the actual turning of the fighter.  It gets the values stored in vTurn and calculates what kind of angular velocity to apply to the fighter to make it turn.

DamageNavigation() applies damage to the ship's structure and navigation systems.  It is invoked in a special script called DamageControl.  The DamageControl script calculates the amount of force that impacted the ship and passes that value here via the DamageNavigation() script.  The ApplyDamage() script does the actual calculations, and the DestroyShip() function will destroy the ship (and create a nice explosion) if the structure falls below zero.

These two scripts are "flags" used by AI routines.  Basically, it just tells the AI routine if the ship's navigation systems are offline due to damage.
This actually a pretty long script.

Tuesday, April 24, 2012

HUD Completed and another Basic Overview

The HUD portion is completed for the this prototype. It's still in the basic stages; however, there is now a timer for locking target process and a gun reticle. The gun reticle grows in size when there is a mouse hit to the target. Here are some screen shots of the "final" HUD:

Ordinarily, I would cover this process by providing code; however, I am going to go over the vehicle data script in this blog. In addition, I will cover a portion of a dummy load script, at least, the portion on how to access the player data (from a previous blog) and the vehicle data scripts.

The vehicle data script is very similar in design to the player data script. Its purpose is to store the vehicle's (usually a fighter) capabilities for other scripts. This script is very important to the flight control, fire control and countermeasure scripts. It also provides "benchmark" (the fighter's capabilites when it is undamaged) to the damage calculation routines. This allows for incremental deterioration of the ship's combat capabities.

Like the player data script, it consists of local variables, a load and find function, and a bunch of methods to access the local variables.  So, we need to populate the player data and vehicle data scripts.  I did this through a dummy load script.  This script is a temporary script designed to load a player controlled viper with some default values.  In the future, its functions will be handled by a resource manager.  Here’s the script:

This script loads the player, vehicle, flight control, fire control, faction control and dradis control scripts; however, we’ll just look at the player and vehicle data.  The actual viper has a player and vehicle script attached to it, along with the dummy load script.  In order for a script to access another script, you have to create a reference to it.  The statement “PlayerData vPlayerData = PlayerData.Find(vShip)” and the similar statement for VehicleData create that reference.  (The variable “vShip” represents the viper model and was defined by the statement “Transform vShip = transform”.) 

With the reference, the vVehicleDAta variable has direct access to the “VehicleData” script attached to the viper.  Any changes made within the vVehicleData variable automatically update the script attached to the ship.  The first manipulation of the vVehicleData is done in the statement “vVehicle.Load(…)”.  If you look at the vehicle data script, the Load statement takes a bunch of strings and float values and places them into variables such as the main thrust and fuel capacity variables.  The statement before the vehicle load statement loads player data values into the PlayerData script. 

Other scripts are loaded in this dummy load script.  For example, the statement following the vehicle data load handles the loading of data into the flight control script.  The flight control script, unlike our two data scripts, actually manipulates the data.  We’ll look at that script in a future blog...

Sunday, April 22, 2012

The HUD Update

I completed most of the HUDControl script.  It now displays a dradis (radar picture), a scope (tells you if a target is directly ahead of you), two status pages (detailing combat and navigation stats), a custom mouse pointer and two targeting graphics to detail whether a target is in the process of being acquired or completely locked onto.  There two things that need to be added to the scripts: a time to acquire timer for targets under acquisition and a "where the bullet is going" reticle. 

This is a pretty complex script utilizing the flight control (for that navigation data), fire control (for combat data and targeting data), dradis control (for positioning and a list of game "engageable" objects) and faction control (to make sure you don't lock onto a friendly target).  In addition, I created two game objects (Lock Reticle and Target Reticle) with an associated script for each object to display whether a target being acquired or completely acquired by the targeting computer. 

After I create the last two features, I will be ready to move onto another script.  I do have an idea on how to implement the timer; however, I'm not sure how I want to implement the bullet reticle.  The timer could be completed two ways.  First, I could just add a text box object to the target box and update the timer in the box.  Second, I coud just change the mouse pointer into the timer.  I'm not sure which way to go; I'll have to think about it.  The bullet reticle is another story.  I'll have to think of ways to implement it...

Here are some screen shots:

No Target (just the mouse pointer)

Acquiring Target (and the float reticle)

Target Locked...

I do plan on improving the graphics; however, these procedures should work for the game.  

Saturday, April 21, 2012

The Basics

I'm about 3/5 of the through recreating the previous build's HUD in the HUDControl script and have completed the DradisControl (which replaces the HeatSource script) and FactionControl scripts.  I'll provide a better update on these scripts after I've completely recreated the original HUD. 

Per some requests, I will be covering the creation process for some of my "completed" scripts.  Completed is in quotes because I tend to add features to my scripts as the needed by other scripts. 

Why am I covering the creation of my scripts?  First, I know that there are some aspiring game designers out there that are just intimidated by the whole programming process.  Dr. Joseph suggested creating this blog to document the creation process of a game.  Second, some of my cohorts that have promised to help me develop this project need to know what I did and why I did it.

In this blog, I will cover the construction of the PlayerData class.  As a starting point for the project, I wanted a source of baseline data for both the pilot and his/her fighter. The PlayerData script holds data concerning the pilot and allow for other scripts to access this data.  Besides holding data, it really doesn't do anything else.  This simplicity make it a good starting point for describing how to create a basic class (a script that holds and manipulates data). 

Here's the PlayerData class:

For those of you in Dr. Joseph's class, the first thing you will notice is the documentation remarks at the beginning of the code stating the class purpose and declarations.  The class purpose, at least in my style of programming, acts like a focus document for the script.  A script should have a purpose and should not deviate from it. 

Why?  It's called modular design.  If I put all the data together, I have to add everything to a game object or nothing.  If it is modular; I can just add the components pertinent to the game object.  For example, I won't add AI routines to a player controlled craft.  By keeping things modular, you save memory and increase performance.  In addition, if you need to add something (to let's say to PilotData), you can just go into that module and add it with less chance of breaking other code.

The second part of my documentation deals with the declared variables and statements in the code.  A "+" and "-" sign denote whether that variable or statement is a public or private access.  Instead of searching your code for a statement, you should be able to get an idea of what exists in the class from your declaration documentation.  It makes writing other scripts much easier...

Public access statements can be accessed outside of the class.  For example, the statement FirstName(denoted with a "+") is publicly accessible.  Let's say I have a variable of the PlayerData type called vPlayerData.  If I type vPlayerData.FirstName = "Berton"; that will set the vFirstName variable to the value "Berton".  I'll go over declaring and accessing a user developed class in more detail in a future blog.

Private variables and statements are only accessible within the class itself.  Variables, as a general rule, should be local access only.  You should create a public statement that allows you to change the variable's value.  Some statements, like the CheckRank() statement, are only needed locally and should be restricted as necessary. 

So in my code, I have a bunch of privately accessible variables with a bunch of statements with public access to change those values.  I have a statement that is restricted to private access to check a rank input, and I have a public Load and Find statement.  Load allows the programmer to mass load a set of values into the appropriate fields.  It's a useful statement and should be in every data oriented class.  The Find() statement is essential in Unity3D.  Each script is attached to a game object (whether it is a viper, cylon raider or something else).  Most of the time, you have a game object but need to access a script attached to it.  The Find statement allows you retrieve the script.  I'll explain the usage of Load and Find when we get a script that utilizes it in a future blog.

So, that is the first class in a nutshell...

Friday, April 20, 2012

Missile Targetting Done (for the most part)

Missiles are now functional. The lock on process and launching process are complete. I added a "float" timer to the overall process. Basically, it takes ten seconds to lock a missile to target. Ordinarily, this requires the player to hold a "mouse over" of the target for the full ten seconds. The "float" timer allows the player to lose contact between the mouse pointer and target for a few seconds. Currently, three seconds is the amount of time a player can "float" a lock. The ten and three seconds rule will probably change after AI routines get developed, and I get a better picture of the speed and feel of the game.

There are two issues with the missile script. First, I have not developed a good method to inform the player of what is occurring in the locking process. Second, the missiles have no AI associated with them; they just travel in a straight line like a bullet. I want to put off dealing with AI routines for now, and concentrate on a user interface.

Currently, the player's viper if flyable; however, you have no idea of your speed, the amount of fuel remaining or the amount of damage sustained by your viper. You can fire bullets and missiles; however, you don't have any idea of how many bullets or missiles are left in inventory. There is no radar (or dradis as it is referred to in BSG).

 So, next up is the Heads Up Display. First, I want to replicate the general features in the older prototype. This includes a radar screen, a f-scope display (like a radar but more height oriented), a targetting camera and a display for fuel, fuel rate, structure, bullets, missiles and countermeasures. I'll use the general processes employed in the previous build and am not too worried about this prospect. I will create a new class called an identification manager to handle what the old "heatsource" class did in the older build. Instead of using Unity's built in tag system, I will be using a faction, type and size variables to help track objects. Size will be a new concept and will be used heavily in future AI routines. It's non-existence in the previous build really hampered creating a viable AI system.

In addition to previous build's HUD features, I will manipulating the mouse pointer and making it an integral part of the user interface. Instead of the standard mouse pointer, the pointer will be a target crosshair. When it mouses over a target, the pointer will change depending on circumstance. Mousing over a friendly (same faction) target will result in a change in mouse pointer. I'll have to come up with a pretty "you can't target this" picture. When mousing over a targettable object, the mouse pointer will disappear or become much smaller. A target recticle will be placed over the target. It will display the lock timer. If the mouse pointer leaves the target during this process, the mouse will change and the float timer will be displayed as part of the change. After obtaining a lock, a different target recticle will replace the "locking on" recticle.

Dealing with the mouse pointer and it's proposed features worries me some. It shouldn't be too hard; however, I can see a few issues that can make this potentially difficult. So, the plan of attack is to get the old features into the new build. After that, I will implement the mouse pointer features.

Once I get the graphical interface functional, I'll probably feel more comfortable releasing some images.

Thursday, April 19, 2012

Update on Missiles

I started to write the missile portion and came to the realization that I need to write a load up script.  Currently, the load process for all variables are located in the flight control class.  It was just easy to do it that way and put off the writing the load sequence.  It's limited in that it's catered towards the player's viper. 

I was using old models from the previous prototype; shooting them was fun.  Since there are significant differences between the new prototype and old prototype, the locking on sequence will not work with the old models.  I need to write two dummy load up scripts: one for the player's viper and the other for a cylon raider.  Once that is complete, I can actually create and test the missile portion of the fire control class. 

I did manage to get a raycast to work.  I can tell if the mouse pointer "hits" an object.  There was an issue with the "main camera"; however, someone on Unity Answers suggested using a publicly declared camera as a solution.  It worked out great. 

Also, I can identify the object being hit by the mouse.  That's just to let you know where I am in the process.  Faction data will be stored in the Player Data class which needs a proper load script at this point.  This prototype will feature a Resource Manager class that will handle the creation and loading of data for all objects.  I want have complete game objects (like a fully functional viper, cylon raider and at least one capital ship) before creating this script.

Wednesday, April 18, 2012

Firing Guns Work!

So, I successfully completed the script to fire guns, and it is fully functional.  I made a few improvements like creating a list of spawn points during start up and using the list during the firing procedures.  The previous prototype required that each spawn point be defined (via global variables) and each spawn location be included in the code.  The old flight control and fighter AI routines could only handle two bullet spawn points (pretty much one on each wing).  The new fire control script can handle any number of spawn points. 

Now that I got step one out of the way (see previous post).  I needed to sit down and map out the missile firing sequence.  Here's the basic process:

Step #1

The missile firing process requires the player to lock onto a target.  When a player mouses over an object, the game checks the faction of the object.  The lock on process won't function on members of the same faction which will involve a change cursor routine with a "Can't Lock" looking cursor. 

As long as the factions are not the same, the script will check for eligibility.  Basically, the target has to be within a certain range and firing cone (probably 30 degrees in front of your ship).  This will force a change to the mouse cursor with a "I'm locking onto to a target" looking cursor.

At which point, we need to check if the target is already being locked onto.  If the target is new, the scipt starts a timer process which will involve starting a 60 second timer and recording the target under acquisition.  If the target is already being acquired, then we just continue with the timer (and update the U/I with the countdown.

Once we get a lock, we place a permanent "locked on" cursor over the target and load the object into the missile target variable. 

This should complete the "locking on" process.

Step #2

After the lock on process, the player can fire a (or multiple) missiles at the target.  This can be accomplished by pressing the right click mouse button.  Once clicked, a class will check the missile firing timer (make sure that we're not firing missile too fast).  As long as everything is good, it will spawn a missile at the missile spawn point(s) and decrease the missile load by one.

I've already completed the variable declaraction section for the missiles.  Here's the documentation section with a list of variables, methods and procedures. 

Now I just need to create the code...

I did run into a problem getting the bullets to spawn correctly.  Unity3D has a great resource in Unity Answers.  Here's my question and answers: