-->

main-navbar

Saturday, August 1, 2015

The Gameplay

There is not much explaining what the actual gameplay will be like, its been a sort of a vague "build space ships and blow up the enemies" sort of thing. I drew up some plans outlining what the gameplay would be like:

You play as an Artificial Intelligence, recently reawakened in a derelict craft on an abandoned asteroid. The asteroid is one among many orbiting an extremely dense planet and contains rich metals that have attracted other artificial intelligence's. These other AI's are fighting over the resources, and have split into several factions. They are technologically advanced and have established strong footholds. You also have some advanced technology, specifically: a micro factory, capable of manufacturing extremely fast. This is your greatest asset, as it allows you to turn resources into firepower faster then any of the other factions, you will need it too, as you start out the weakest of all the factions. Each faction each has their own unique technology, though none as advantageous as the micro factory. 

Note: Image is not to scale

When you destroy an enemy ship, it breaks up into parts; which you can recycle, or attach onto your own ship. It is possible to learn the blueprint of the captured parts; which you can use to replicate captured technology. The enemy can do the same, this forces you to protect any ships which have your micro factory attached, creating a reward vrs risk scenario. Reward, because you can expand your fleet faster, risk, because if the enemy were to capture your micro factory while already ahead technologically, you would be hard pressed to survive.
some asteroids and fragments

Some things to note: The placement of the asteroids will most likely be procedural, to keep things fresh. Also, everything will be simulated at once; while you are mining metal somewhere on one side of the planet, an AI could be building a warship on the other side.

Since the game currently has multiplayer support, it should also be possible to have co-op games, or free for all games.

That about sums up the plan, comments can be posted here or on the forums: Forums thread

Saturday, June 6, 2015

Button Sounds

For code example, skip to the middle.

The new user interface tools in unity 4.6 and 5 are good...but not for programmers, or when you want to have complex interfaces, with a lot of code generated buttons for example. In my project, I decided to go for a mix: I used the new user interface tools for simple things, like main menu buttons and affects, and used the legacy GUI system for more complex things like hidden or context generated menus.

Using the new ui tools, it is very easy to setup the sounds that play when you mouse over or click a button. Even better, with the prefab system, you can make a default button prefab that has all the sounds and affects already setup, and easily reuse it wherever you need to.

The legacy ui, however, is a little more difficult. Setting up the ui skin is quite tedious, but it is worth it in the long run, especially if you have a lot of code generated ui. I wrote a blog post a while back detailing how to do this with half decent results.

Adding sounds to the legacy GUI system:

There are two main sounds most ui's have: a sound to play when the mouse clicks on a button, and a sound for when the mouse hovers over something. The first is easy, Just call the code to play the sound when GUI.Button returns true. It feels a little inefficient though, having to add that code for every single button. And what if you want to change it? Now you have to go through all the buttons, and change the code inside each. While there are programming patterns that make doing this easier, there is a better way.

The second main sound that ui's have, is the sound that plays when the mouse hovers over a button. One problem: there is no built in way for you to detect if the mouse is hovering over a button! There are several workarounds though, using google turns up several solutions: here, here and here. One solution is to add rects everywhere and detect if the mouse position is inside the rect. The other solutions use the GUI.tooltip.

I like the GUI.tooltip solution, its way less messy then having to spawn a rect for each button. The GUI.tooltip is a litle tricky though, For one, you have to have it unly update during repaint events, like:

if(Event.current.type == EventType.Repaint){
} 
 

In addition, you have to make it only play the sound once when the mouse is over the gui 
element, and play again when the element changes. The code ends up getting a little messy, but in the end, it works very well.

This is my code:

Variables:









//the previous tooltip
var prev: String = "";

//is the mouse button being pressed?
var pressed: boolean = false;

//the tooltip
var hoverButton: String  = "";





Inside OnGUI:





//Play a sound if we mouseover something
hoverButton = GUI.tooltip;
if(Event.current.type == EventType.Repaint){ if(hoverButton != ""){ if(Input.GetMouseButton(0) || Input.GetMouseButton(1)){ if(!pressed){ PlayMyButtonPressedSound(); } pressed = true; } else{ pressed = false; } if(hoverButton != prev){ PlayMyButtonHoverSound(); } }
 prev = hoverButton;
}




Just make sure each ui element has a GUIContent with the correct parameters, and each tooltip for each button has to be different. So for example:






if (GUI.Button(SomeRect, GUIContent ("Text displayed on the button", "Unique Tooltip")){
 DoSomething();
}

Sunday, May 24, 2015

The Flightcontroller

Flying in 3d space with Newtonian physics is tricky. With modular space craft, the center of mass can shift at any time, but even worse, if the object is not symmetrical, then forces generate hard to predict rotational accelerations. On top of this, any force applied will cause the ship to move....and keep moving, until another force slows it down. These are all things the user would have to take into account when building a ship, and set each engines output and keybinding accordingly, or else the ship would be completely uncontrollable,

The goal of the flight controller is to handle all this in background. It does this through several methods and techniques that together work to make the controls easy to use and user friendly, no matter the ship configuration (Though some designs work better then others).
The flight controller consists of two main parts.

The first part: Give it a target force and torque, and have it fire the engines accordingly.

You may have many engines, but you can only go in one direction at a time. Its follows then, that it would be useful to find how much power to give each engine, to go in a particular direction. This sounds simple, but turns out to be extraordinarily difficult to program. However, this can be modeled as a linear program, and there are linear program solvers that have already done the hard part for you. For those interested, the solver I used is lp_solve, and the linear program used is on math_exchange.

To format the problem as a linear program, you need to set each engine throttle as a variable. You also need to calculate the force and torque each individual engine would exert on the spacecraft. You then simply plug these into the solver, along with a target force and torque, and the linear program solver returns the throttles each engine needs to be set too.

This gets further complicated by one thing: When rotating, torque is not equal to angular acceleration*mass. In 3d space, if you apply a torque on something, the resulting angular acceleration depends on the distribution of that mass, that's why if your spinning on a chair, and you pull your arms in, you spin faster, its also why if you rotate something, its better if its symetrical. The distribution of mass of a 3d object relative to a pivot point, is commonly represented as something called an Inertia Tensor. An inertia tensor is a 3x3 matrix, and by doing some math operations involving it and target angular acceleration, we can get the torque required to produce the given angular acceleration.

Using the above, we can feed the flight controller a target angular acceleration, and target force, and the flight controller will fire the engines to produce it as closely as it can. The problem now is to figure out which angular acceleration and force we want to produce.

The second part: finding a target angular acceleration and force.

Before this part can be solved, we need to consider how the player expects the controls to work. In most cases, you aim with the mouse, and use the arrow keys to move. So, given a direction (from the user aiming the mouse), the ships current direction (ie: which way it is looking), we need to find a force/torque to rotate the ship to point in the desired direction. For moving around, we need to, given a target movement direction, move in that direction, by producing a force in that direction.

Finding the target force is the easiest part. Simply map each arrow key to a vector which points in the expected direction. So "w" would be mapped to a forward vector, pressing it would call the flight controller with this vector*maximum_force as the force vector. The flight controller would then accelerate in the given direction.

Finding the target angular acceleration, to rotate from one direction to another is a bit more complex. I used a PD controller to solve this part. Essentially, the pd controller takes the angle between the desired direction and the current direction, and the current angular velocity, and returns an angular acceleration to try and minimize the errors. It takes into account the maximum angular acceleration and two tuning constants as well. The constants are for tweaking how much the controller responds to the error in angular velocity and the angle error.

That's the flight controller for the most part. It sounds simple enough explaining it like this, but the flight controller has been the toughest part of this project out of the 4 years since I came up with idea. Now that its working quite well, I can work on the things that wouldn't be possible without it. Specifically: gameplay elements, AI etc.









Wednesday, April 29, 2015

How it started.

Around 2010? Idk, it was a while ago...but around this time I found this cool game called battleships forever, if you havent hear of it, well, google is your friend. Battleships forever is a space ship game based on ships put together section by section, that can fight other ships. I really liked the game, but it lacked many features...no multiplayer, no way of testing your ship against opponents in realtime..., the dev had disappeared, and there was only so much you could do. So I wanted to try making something better.

Summer 2011, I had this idea, what if, I made a game that was 3d, and you could make ships out of 3d components? How would that work? Thoughts aflood with these new ideas, I began drawing pictures of modular spaceships, and planning how it would all work.

At this time I had never programmed before (well, using an actual programming language, I had programmed with programming blocks, in the blender game engine before), but a friend introduced me to unity3d. Intrigued by the possibilities of the engine, I made a few code experiments, by following tutorials, and discoverd that programming wasn't that hard after all.

With the tool, and the idea, I began work on the project that's been eating up all my freetime since that summer in 2011. (well, almost all, I still play games once in a while!). In the first few months I had a crappy module put togther thing, that let you place modules onto each other. The code sucked,(it was my first coded program after all), so i ended up starting from scratch with the new knowledge I had gained. This next time I finished around the end of 2012/early 2013. The code was somewhat better, so i was able to get much farther before the codebase was spagettified from inexperience. I had a simple ship builder, (that had many limitations), that lets you place modules, and a separate scene that allowed for loading your creations and simulating them with unitys physics engine. It...worked, but it was very limited. Adding new modules was complicated, the graphics were, not that great. Even worse, the codebase looked like, well, a mess. I had learned so much though, I believed I knew how to redo it without spagettifieing the code base, and I really, really wanted to finish the game and make it good. So I started fresh, copied what I could, and began again.

Two years later, I have something, I think, that is almost ready to be shared with the world. There are still bugs, still lots of features to add, but the codebase is clean, the graphics are good, the engine supports construction even  while your being shot at mid battle, (though not sure if that should be included in the game), and I think most of the time consuming huge features are in. (It even has basic multiplayer support! well, sortof, still needs a ui, lobbies, etc. But the codebase itself supports everything in multiplayer!).

So, thats my story, right now I am working on features, and a website, I hope to have the site finished before the summer so I can start building a community and getting alpha testers. Oh, and the name on the blog is not the final name for the game, still thinking of one actually (if you have any ideas, i'm all ears!).

Sunday, March 22, 2015

Vector styled graphics

Its been a while since I last posted a blog post, but I have still been working on this project. To give the game a much better feel I decided to work on the graphics.

Since I am good at modeling 3d objects, but rather terrible at texturing them, I decided to write a script to generate a texture map. The script generates an edge highlight map, it essentially darkens any areas close to a sharp edge, based on the distance to the edge. Its also possible to change how sensitive it is to edges. ie: at 10, it will only count an edge as sharp if the angle between the normal's of its faces is greater then 10 degrees. Below you can see an example:

I also wrote a shader. The shader takes the information in the edge and draws a solid color, depending on the distance to the edge. This allows it to produce a "thick" edge highlight affect, such as the image below:

Below, an image of a simple spaceship using the script and shader:

As you can see, there are some artifacts, this is due to some defects in the script, and aliasing. After fixing the script and adding antiailiasing+bloom for the glow, we get a much cleaner look:

Its still a bit tricky with depth perception at this point, so I made the shader a surface shader, by combining unity5's new lighting model, and the previous edge highlight shader. This makes it affected by lights and produces a nice affect:

Whats really cool about the script though, is that it works for any 3d model, so that means the only bottleneck for adding new modules is how fast I can model one and import it into unity. This is really exciting because It gives the project a unique look, and it makes it possible to have lots of modules.


Saturday, October 11, 2014

Flight Controller Logic

Over the summer, I worked on the flight controller. The purpose of the flight controller is to make it easy for any ordinary human or AI to fly an unbalanced spaceship in a game with simulated physics. In space, the laws of inertia become very significant, as anything put in motion will tend to stay in motion. The flight controller would do two things: compensate for inertia so that the craft is easier to control, and allow an unbalanced spaceship to fly straight.

The first step I took, was to try and create an algorithm that would take take a direction/torque as an input, and would accelerate the assembly in said direction/rotation. I figured once I had this, the rest would be relatively easy.

The current way the algorithm works is as follows:

  1. The force and torque vectors each engine will exert on the assembly are calculated and stored.
  2. These force/torque vectors are then grouped together to form 6 dimensional vectors, one for each engine.
  3. These vectors are then transferred into a matrix class as column vectors.
  4. An additional target column vector is added to the far right of the matrix, this is the "target acceleration" input vector.
  5. An algorithm puts the matrix into reduced row form using Gaussian elimination. (if you think of the matrix as a system of equations, it essentially solves for the unknowns)
  6. The last column vector in the matrix now has a list of values. Essentially these are the ratios of the engines to each other required to accelerate in the input vector's direction.
  7. These values are then scaled to create the maximum thrust possible and the enignes are turned on.
While the algorithm technically works, there are some flaws:
  1. It does not take into account the fact that engines cannot fire in reverse, so some of the output values can be negative depending on the input and the engines available. This results in engines firing backwards.
  2. This solution works for only 6 engines exactly, and usually only if their force/torque vectors are linearly independent (ie only one engine for each direction).

So far I have found a partial workaround for the second flaw. If the number of engines is fewer then 6, multiplying the target vector and the original matrix of force/torque values by the transpose of the original matrix creates a matrix with as many solutions as you have engines. This can then be solved to get ratio values that will fire the engines with a resultant force/torque as close as possible to the input target force/torque vector.



Friday, May 9, 2014

Video Demo

Finally found some time to make a short demo video, by comparison to that last one I think its coming out very well!

Basically the video shows a few things:

  • The new graphics/art all that good stuff
  • Camera tracking
  • Camera rotation tracking
  • The current input system
  • Engine functionality
  • Laser effects
  • Toggling in and out of edit mode
  • Selecting different assemblies
  • How hard it is to fly

The camera rotation tracking basically rotates the camera as if it was parented to the selected assembly, the location tracking does the same except minus the rotating part. The cool thing about the rotation tracking part is that you can still orbit the assembly normally with the mouse while it is rotating.

It is currently very difficult to control a built ship, part of this is because the only way to rotate the ship is by using engines, which are too powerful except for large assemblies/ships. The other reason is because of the physics, once you start rotating or increasing the speed, rotational and directional inertia takes over and you continue spinning/moving until there is a counter force or torque.

To solve the first issue with rotation, I will likely add some RCS thrusters (basically thrusters for small changes in momentum or rotation) and a reaction wheel (magic science devise used to exert a rotational force on an object, for the science behind it, here)
.
The second issue is a little more difficult, but the basic principle behind it is to have a flight computer that tells the engines to slow the ship down after you accelerate, or slows the rotation down after you rotate. The computer would use available engines, and would be able to increase or decrease the thrust on each one as needed. In this way non symmetrical ships would be flyable. Using the flight computer, the ship would move more like people are used too regarding simpler games, while still using physics. The computer of course would be optional for those who want direct control. I plan to make it so both the flight computer and direct control can be used at the same time.


Thursday, April 17, 2014

Update

 I have been working on the multiplayer aspect of the game for quite a bit, as a result, most of the infrastructure for  it is now in place. As it is right now it is playable, however there are a few things missing, mainly client side prediction. So if you go too fast, the client receives positional update information that is to old, this causes your ship to jump backwards and jitter a lot when you are going fast.

The camera control has been much improved, now the camera will track to the center of mass of your assembly, and in addition there is a key that will toggle rotation tracking. Rotation tracking just causes the camera to rotate with the assembly if the assembly rotates. 

Below are some screen shots showing some significant graphics updates, a bit of the logic system, and the laser module:



Friday, February 28, 2014

Physics Multiplayer

Its been a while since I posted anything here, been very busy, both in college and working on this project. While I have been working on the project quite a bit, I haven't updated this blog much. Much has been changed, its practically a playable demo at this point.

Multiplayer, has been the most recent feature I have been trying to implement. Adding multiplayer to a game like this is very challenging for several reasons:
  1. This game is physics based.
  2. It has to be as lag free as possible for direct user feedback
That's it. 

Only problem is, those two things generally don't go together, especially when using unitys physics, here is why:

In most multiplayer games, you have a server and a client, the server runs the official version of the game, and the client runs a similar version that the server updates to be in sync with the server. Even with a very good internet connection, the delay between sending information to a server and receiving the resulting update of the simulation can range from .2-.4 seconds. Say if you press the space key to jump, the signal is sent from your computer to the server in .1-.2 seconds. The server receives the signal, tells your player to jump, then sends the updated position back to the client. So it takes .2-.4 seconds for your command to appear on the clients display.

To fix this delay, client side prediction can be used, how this works, is your player moves  immediately after receiving a command, and sends the command to the server. The server then sends its results back to the player. However, this data from the server cannot be used to update the player, its .2-.4 seconds old. The server is constantly sending out its idea of where the player should be. So if this old data is used to correct the players position, then client side prediction will be pretty much invalidated.
To Compensate for this, the data the server sends can be "checked" with what the players position was in the past. If the two don't match closely enough, then an extrapolation is made of where the player would be assuming the two did match. The player is then moved there.
The server also has to update the other players, since each of them also has a simulation of the world. The flowchart above shows roughly how this would work.

One of the problems with client side prediction though, is you need to predict something based off of old information. With unitys physics, you cannot do this. Unitys physics cannot "rewind" or "resimulate" nor "predict" any part of the physics system. That why making a physics multiplayer is very challenging, especially when using unity.

To get around this problem, you could simulate some data yourself, you would have to have your own simple physics engine essentially. What my project will do, is use a custom rigidbody system that supports "predicting" where it will be in the future. Unfortunately, it will not be possible to check collisions, so those will have to be handled server side, which will likely result in lag glitches during a collision.

This being a space ship game though, there should be few enough collisions that this should not be a problem.


Saturday, December 21, 2013

The Action System

Been very busy during the college semester. Getting used to college, then trying to keep up, has left little room for this project. However, finals are now over and I have nearly a month off, so time to get some more stuff done.

This past week and in my spare time over the semester I have been working on the action system. In an earlier post I described the action system as a relationship between the user, the assembly, and the actions that the assembly is capable of executing through its modules. When I went to implement this, I discovered it would not be as simple as it first appeared. 

The action system was going to be broken into three parts: the easy to use simple logic system (this would allow direct designation of keys to specific actions), the logic/node editor (this would allow for very complex programming without the user writing any code), and the code editor (just like it sounds, you have to write code to program stuff). 

The first part, the easy to use logic system, was going to be implemented as fast and easy as possible while still allowing for expansion. Then later on, when more of the game functionality was added, the second part would be implemented, which would allow the complex node/logic editing in addition to the simple keybinding. The two are unfortunately inseparable. In order to implement the first part, the second part (or at least the underlying infrastructure) must exist first. 

So this past week, and in my spare time over the semester, I have been working on the underlying infrastructure for the node editor. If you are familiar with programming, you can see how a node editor can be used to do logic. Each node in the editor will be broken into as many as three different parts: an input, an activator, and an action. The input is some sort of trigger or change, so you could use a variable change as well as a keyboard press as an input. Each input can be connected to one or more activators. As well, each activator can be connected to one or more inputs. The purpose of the activator is to handle the inputs and activate actions based on them. Each activator can also connect to one or more actions. The action is simply a link to a premade function within the code of a module. Anything passed to the action upon its activation, will also be sent to its target function. This target function can also be an input, so upon its activation it can trigger another activator. This depends on the actual code inside the action function, but it allows for some very complex behaviors.
Each input/activator/action together makes a node. The user will be able to use these nodes to create the desired behavior.


The above system has been mostly implemented so far, with the exception of passing in or handling values, saving and loading the logic, and actual nodes. It works well for simple things like a keypress. One of the reasons that actions have to activate a target (predetermined) function on the module, instead actual in game functions that are required for the game to function is this: it limits the user to within the modules actual capabilities. ie: You cannot do something with the module unless it has been programmed to be able to do that. In this way you can controll the spacecraft however you like; your only limitation is its limitations. This makes sense, you wouldn't want someone changing, their max health, or making themselves indestructible, or other hacks.


Saturday, October 19, 2013

A word on Quaternions and doing complex rotations - Solution

In my older post on Quaternions, I described a problem, but failed to show the solution. Someone commented on that, so I felt inclined to do a full post describing the solution. This post is mostly code, and what it does, just a warning to those reading.

The problem was as follows:
How do you align the faces of two objects that are facing different directions on objects facing diferent directions?

Note the setup here; a side is one of the faces that are being oriented, the gameObject is the object the side is apart of. A side has its own custom class with information about it(where it is relative to the object, its orientation, its number of geometric sides, etc).

Step 1 - Create a rotation variable that you are going to manipulate. Assign it to the gameObjects current rotation:

var rot: Quaternion = gameObject.transform.rotation; 

Step 2 - Create a function that will manipulate the rotation to point it toward the target direction, how I did it is shown below:

function GetLookRot(side: Side, rotation: Quaternion){
var rot: Quaternion;
if(rotation == null) rot = gameObject.transform.rotation;
//assigns rotation for manipulation
else rot = rotation;
//the location of the side relative to the center of the 
//object, which is the same thing as a vector that starts 
//at 0,0,0 and passes through the location of the side.
var fromLocalDir: Vector3 = (location);
//target global location (of the target side)
var target: Vector3;
//this basically finds the vector that starts at the 
//target gameobjects center and passes through the target 
//sides center, all in global coordinates
target = (side.gameObject.transform.rotation
*(-side.location))
+gameObject.transform.position;
//takes the global vector described above and makes its 
//position local, its rotation is kept global.
var toGlobalDir: Vector3 = target 
- gameObject.transform.position;
//updates the first vector by modifying it from local 
//rotation to global rotation, while still keeping its 
//local position.
var fromGlobalDir: Vector3 = rot * fromLocalDir; 
//so now we have two vectors, the first points in the 
//current direction the side is pointing, and the second 
//points in the opposite direction the target side is 
//pointing, because we want the sides to face each other, 
//rather then simply point in the same direction.
//after that we get a rotation using unity's 
//FromToRotation to get a Quaternion that describes the 
//rotation of going from the first direction to the second 
//direction, this rotation is then combined with the 
//gameobjects current orientation, by multiplying, to get a 
//rotation that points the current side to be facing the 
//target side.
return Quaternion.FromToRotation(fromGlobalDir, toGlobalDir) 
* rot; 
}



Step 3 - The next function assumes that the sides are parallel, this takes them and aligns their sides. Because it handles rotations, the sides do not actually have to be parallel at yet, just the rotation you feed this function would have to put them parallel. This step is a bit more complicated....

 //returns a rotation that would rotate so the face is aligned 
//(ie: so all the vertexes of both sides are at same pos)
//with the target face, rotates along the normal axis of the 
//side. rotates current, or if given rotation, rotates that, 
//target rotation is given through the passed side
function GetAxisRot(side: Side, rotation: Quaternion){
var rot: Quaternion;
if(rotation == null) rot = gameObject.transform.rotation;
//assigns rotation for manipulation
else rot = rotation;
//def axis is a vector that originates at the center of the 
//side and passes through a vertex on the side. This is 
//used to represent the sides rotation around the y axis
//if the side was in a horizontal position
var direction: Vector3 = (rot*(defAxis));
//this is an array that will be used to hold the diferent
//possible vectors.
var targets: Vector3[] = new Vector3[side.polySides];
//sets the array of axies
for(i = 0; i < polySides; i++){
if (i == 0) targets[i] = side.gameObject.transform.rotation*(side.defAxis);
else{
targets[i] = side.gameObject.transform.rotation*(Quaternion.AngleAxis((360/side.polySides)*i, side.location) * (side.defAxis));
}
//shows each axis for visualization
Debug.DrawRay(side.gameObject.transform.position, targets[i], Color.red);
}
//shows each axis for visualization
Debug.DrawRay(gameObject.transform.position, direction, Color.red);
//the angle between the closest direction of available directions to target,     //and the target
var angle1: float = 360;
//the angle difernce between the direction that comes before the above and the   //target
var angle2: float = 360;
//the angle diference between target direction and current direction in +-       //degrees
var angle: float;
//assigns the above
var j: int;
for(i = 0; i < polySides; i++){
if (i == 0) j = polySides-1;
else j = i-1;
if(angle1 > Vector3.Angle(direction, targets[i])) {
angle1 = Vector3.Angle(direction, targets[i]); 
angle2 = Vector3.Angle(direction, targets[j]);
}
}
if(angle2 < 360/polySides) angle = -angle1;
else angle = angle1;
//applies final rotation
var finalRot: Quaternion = rot*(Quaternion.AngleAxis(angle, location));

return finalRot;
}

Step 4 - Once you have both functions you run them like this:

var rot: Quaternion = gameObject.transform.rotation; rot = GetLookRot(side, rot); rot = GetAxisRot(side, rot); return rot;

And that is how I did it, hopefully this can be of some use to someone :)

Saturday, August 24, 2013

Actions

Been really busy the past few weeks, so haven't had much to show for the time. With college classes about to start in two weeks the available time is only going to decrease. However, I did manage to create and partially implement the action system.

What this system does, is handle module actions. This will be integrated into how the AI runs, how the user controls and configures input, and will basically give a framework for handling each modules actions. For example, an engine type module would have actions for controlling the engine. The actions for such a module would be something like: Activate, Deactivate, Set Power, etc. So to get such an engine configured, you could assign say, the spacebar, to Activate the engine when pressed, and Deactivate the engine when released.

The system works by storing a list of the modules actions in the module itself. An action in this system is a custom class that has an activate function, and a constructor. The constructor assigns the target of the action, so when the action is "activated" it calls the targeted function. in addition the constructor assigns a description and a name for the action, so that the user knows exactly what the action does. All the actions are assigned at start of the runtime to their parent module, and made available to all objects that have access to the module. The assembly itself will be the main object activating these actions, and assigning inputs to activate specific actions. These inputs will be stored on the assembly itself so that individual sets of controls can be isolated. (ie: the user controls one assembly, and an ai controls another. Their actions dont activate each other because they are assigned to separate assemblies) Basically the assembly will act as the distribution hub for all of its modules actions. Eventually it will be possible to create custom actions which would set off multiple others, sort of like programming.

With this system, it would be possible to practically let the user program the ship as they would a robot. One of the cool things about this, is a user could create a control system and share it with others who just want to fly the ship, and skip the whole configuring aspect. Or even better, a user could create their own AI. These are some of the major end goals. However, for the moment a simple "this key/button activates this action" sort of thing will be created, until after some sort of release. More complex layers of possible programming will be possible later on.

There are still some fine details to work out, like accessing module variables, but for now I hope just to be able to get a ship that is completely configured by the user.

Saturday, August 3, 2013

Project Update

The demo video I released last week showed some of the features and capabilities of the editor. This past week I have been cleaning up code and adding a few more essential elements to the infrastructure of the program. I also made it possible to select one or more modules and delete the selected modules.

The last part was the most difficult; not so much the selection system as the deletion system. Normally deleting things would be very easy; but it this case it was not because of the assembly system. With the assembly system, each group of modules that are connected to each other form an assembly. The problem is; how do you handle the deletion of a module that is the only piece holding two halves of the assembly together? Somehow I had to get the assembly to update its internal list of which modules were a part of it and in addition I also had to split the assembly into two individual assemblies. This is what was the really tricky part.

Eventually I came up with an algorithm that worked; but it took a while. Basically the algorithm starts with the first module in the list of modules on the assembly. It takes this module and scans through all of the modules directly or indirectly connected to it. Then the assembly removes these modules from a copy of its internal module array, adds them to a list of groups of modules as a group, then repeats until no more modules are left in the copy of the internal list of modules. After this the first newly created group is assigned to the assembly and for every remaining group a new assembly is created and assigned the contents of that particular group.

Anyways that's what I spent most of the week working on. Next will be adding the input/module properties stuff. This will allow the engine to actually fire, and also will allow the user to make control systems so they can build and fly a ship. This will involve a gui on the right side of the screen as well as some serious infrastructure to handle it all.

Saturday, July 27, 2013

Editor Demo

Not just some text and a few pictures. Here is a basic version of the editor running. Its not ready for any kind of public testing yet, but I did make a video demo showing off a few of the things that are/almost done.
The demo shows a number of things:
-The basics of how building ships/assemblies will work
-The current GUI
-Saving and loading



As I add content to the program, I will periodically release a video demo. Once I think its bug-free and content rich enough, I will release a limited alpha.
Let me know what you think in the comments!

Saturday, July 20, 2013

What this project is about.

After reading through all my previous blog posts, I realized I still had yet to explain in depth what this project is!

There are two core goals for this project:
-To create an environment that can be used to create and test complex dynamic AI's.
-To create a game environment that gives the user the most freedom in terms of control over their own abilities in the game.

In order for the first of these goals to be met, there needs to be a well developed core infrastructure to the game. In other words, the environment has to be tried and true before development of an AI can begin.

The second goal, is a bit more ambiguous. To explain it a little bit clearer: what I want to do, is allow the user to create and experience what it is like building and designing assemblies for use in space. My goal is to have it to such a level, that you could design your own missile, carry it with your ship, and fire it. My goal is to allow the user to create a ship that can do things it was never meant to do, like disassembling mid flight to avoid an anti matter missile, or split your ship into two and control both ships as if they were one. My goal is to allow the user to create their own AI ship if they so desire. These are the things I want to allow the user to do, and in a (somewhat) realistic fashion. Your ship wont fly because it just does; it will fly because you installed antimatter reactors directly next to thrust vectored engines. It will shoot because you attached some huge capacitors next to your customized high power feed laser. I would like it even possible to have multiple people controlling the same ship, star treck style.

These goals are a bit ambitious, you may say: "okay that's cool, but how are you going to do all that?" and I say: "one step at a time".

The first steps involved concept art (mostly in my graph paper notebook) and background planning; ie how to allow the user to do these things.

I came up with idea of using "modules" to build the ship out of. Modules are great because they are stand alone, can be used in complex configurations, and they can allow complex behaviors. As of now they all connect with triangular sides, but the code is in place for any kind of polygon to be used as a connection side; as long as it connects to a side of the same type.

The different kinds of modules that could be used:
-Engines
-Power Generators
-Laser Weapons
-Shield Generators
-Shield Emitters
And anything else that ends up being cool

I also plan on each module to have customization options, like the ability to balance how much power goes into the wavelength of the laser, and how much into the amount of photons fired. The goal is to have as much customization as possible while still keeping things balanced. Also, i would like to make it possible to place things on top of the modules, that are not actually modules. More like accessories. This would let you coat everything with armor, or attach antenna and other sensors in various places on the ship.

So that's the goal of this project. Now, anyone have an idea for a name? I originally called it polyhedra wars because many of the modules I had in place resembled polyhedra (ie octahedrons, tetrahedrons etc). But modules are not all going to look that way, many are going to have their "insides" shown. Anyway, let me know what you think in the comments.

Concept ship design, its hard to draw polyhedra by hand!

Thursday, July 18, 2013

Unity GUI - Graphics

There are two parts to making a GUI in unity; the graphics and the programming. These two parts mix a bit, but when I say graphics here, I mean the GUI skin. Unity's GUI system is a bit tricky to work with, and making your own customized skin can be a bit daunting. I realized that the default unity GUI wouldn't work, not even for testing, because all its controls are translucent and very dark. Most of the time in space, there are really dark colors. The default unity GUI tends to become nearly invisible against this kind of backdrop, and that's when I realized that I would need to make my own. If you want to see the results, skip to the bottom.

Note: before you go ahead and make a full blown GUI skin; make sure none of the ones on the asset store will do. There are a lot of decent skins for $5, and even some nice free ones. I neglected to do this, and as a result spent a lot of time making my own skin when it may not have been necessary, though it was an interesting experience.

Once you have come to the conclusion that the unity skin, the free skins, and the non-free skins are not options, then that's when you make your own. Before you even get started though, draw it out on paper, preferably graph paper. You do this so that when you finish making the skin, you don't go back and realize that 30+ images need to be redone. This also helps prevent redoing a simple image 20 times to get it just  right. Once you got a good idea of your skin down on paper, you can get started with the computer stuff.

One thing that needs to be taken into account, is how unity handles images. I spent 2 hours trying to figure out why my "crisp clean images" were all blurry before I realized the import setting : "texture type" of each image had to be set to GUI. The other settings can also be important depending on your image type. Its not usually to hard to figure out settings that work, the important part is making sure texture type is set to GUI.



The filter mode handles how the image is stretched. Point just scales the pixel, biliniar is good for textures with gradients, triliniar does something with mippixels. All this info is available in detail at the Unity Texture 2D documentation page found here.
After all the import settings are taken care of, the next step is to setup a test script that shows off all the GUI elements that you plan on using. I followed the tutorial here, which has a nice little script for this purpose, though it doesn't use all the elements (I made this; it has all the elements. The code is a bit messy but its only for visual testing). The tutorial also shows how unity handles stretching of textures at different places to make small textures seamlessly scaleable. The tutorial doesn't cover everything but its good for an introduction. After finishing it, its not that hard to just follow the same pattern of making images with the right borders, then changing the border setting in the skin to make it fit right.

Some elements do not follow the same pattern though and need a bit more work to get working. Notably is the toggle. When you make the toggle, make sure that you leave a section of pixels to the right for whatever you want stretched beneath the toggle text. Usually this is just blank alpha.

<-- That bit of white to the right is alpha used by the toggle text.

When making a skin, its also good to have the default textures available for reference, they can be downloaded from the asset store for free, and also on the unity forums here.

For scroll bar buttons, you need to make sure the fixed width and height are set above zero; otherwise they will not show up in your skin. Only do this if you actually want them to show up.


After finishing the last GUI texture, its a bit satisfying to see a nice GUI when you are done. I will not say its easy, but it can be rewarding to make your own custom skin. Below are some pics:



















I ended up making two versions, a translucent version, and a solid version. The translucent skin looks like a better fit, so I will likely go with that one. Making the skin translucent isn't that hard, especially for flat styled skins. You simply take each solid texture, copy the solid color, adjust the alpha value to about half (I used 125 on 0-255 scale), use a paint bucket tool on replace mode where you took the color from, then save the image. If by any chance you don't want to make your own, and you really like this skin, its on the asset store here.

That about concludes making a unity GUI skin, next comes the programming. This was more of a list of common pitfalls, or at least ones I fell into, then a GUI tutorial. There are lots of tutorials on youtube and in many other places, so don't just go by this if you decide to make your own skin.

Saturday, July 13, 2013

Planning a project and parsing texts

In my experience it is always best to work on the part of the project you are least confident in your ability to finish. The reason being that you do not want to finish everything else and find that you are, indeed, incapable of completing that particular part. While working on all my projects I have kept this in mind. There are other benefits as well; if you are capable of finishing that part, and you do finish it, then you got the hardest part done first. In addition, this helps keep you encouraged throughout the projects completion because every step brings you much closer. It could be argued that it makes it harder because starting with the hardest part is discouraging. But it will have to be faced at one point or another anyway.

This way of working on projects is best used when you already have experience, because otherwise your project is mostly a learning experience and may not be finished. Working on the toughest part of a project without at least some experience, can be much more daunting, and also much more discouraging.

The reason I bring this up, is because working on my project by using this strategy has lead to some interesting decisions. For instance, the next part of my project was going to involve the gui, so I planned it out by drawing what I wanted it to look like when it was done, and how I wanted it to function. Next I planned the lower level stuff, like how It was going to have that functionality in the first place. And finally, when all that planning was done, I looked at what was the most important and what was most difficult and worked on the next step that most balanced these two.

The gui that I planned was entirely for the ship editor aspect of the game. This aspect is what I consider the most important because it is what makes my game unique, and as a result is what I want the most polished. Since everything else is in place it is also the last step before there can be another release, so it makes sense to work on the ship editor part next.

The gui's layout has parts you can select to build with on the left, and on the right of the screen is the interface for configuring controls or activation keys. Now, because the editor is such an integral part of the game, it will be able to be accessed during flight, allowing real time editing of the ship. The user will be able to switch back and forth between the editor and the flight modes even during a battle, though during a battle would be dangerous.

At default the windows will pop out when the user hovers the mouse at that edge of the window. This makes it easy to access what you need and get the display out of the way quickly. In addition, there will be a toggle that when toggled, will keep the window out even when the mouse is not hovering over the window. Each icon represents a module that can be placed on the ship, or as I like to call it, assembly; because it may not necessarily be a ship that is being built. The list of modules also has a list of tabs at the top, to help categorize the modules.

This gui is nice and all, but I also needed as convenient a place as possible to store the available modules in the unity project. I also wanted something that was easily changeable and even moddable in the future. At the time I decided this, my unity project was in dire need of "housecleaning", it had many unorganized files and resources that were not even being used. I figured it best to start a new project and import what I needed as I went. After this was done, I got to the modding/module organization system.

The system works like this: in the project and build, there will be a folder with a list of .module files. The files can be in sub-folders and really in any order as long as they are in the modules folder. When the game is started, all these module files will be parsed for their contents. Each module file contains a list of all the aspects of the module, and in the future, references to texture and mesh files. In the meantime prefabs already in the built project will be referenced. Any of the .module files can be edited by a text editor, or new ones can be added. Parsing these files appeared the most difficult, as a result, that is what I worked on next.

First I planned out the syntax of each module, then I did a ton of research on the String class in the msdn libraries. For fellow unity developers; msdn is the place to go for all lower level code references. I also looked up how to parse a string in google; this provided a few handy results like: reading a text file line by line, and one method of text parsing. These weren't the only results, but they were the most useful. Anyway, how you parse a file mostly depends on the layout and syntax of it. So for my .module file I decided to read each line one at a time using the method described in the first link. Then I split each line along the = sign using String.Split. Properties on the left side were used to describe where to put the value described on the left. In some cases there were values that were compound. Take for example the custom Side type, it has a position, rotation, name, and variable for the number of sides(polygon sides, not Side type objects). (This is used to describe how to handle the connection sides in the game, ie what connects two objects together) For this type, I declared Side, followed by { and all the variables followed by a }. The text parser, when it read "side" would go into a corutine, reading all the lines until it got to the }. Then the parser would resume its normal operations.

The main task of the parser is to produce a list of modules that the gui can list as icons and the user can place as modules. In addition, only modules loaded this way are used to load a save game, or a saved assembly.

Now...time for that gui.


Saturday, July 6, 2013

A word on Quaternions and doing complex rotations

Its been some time since I last made a post here. Not for lack of working, but rather of lack of something to post. For the past several months I have been working quite a bit in Unity3d on Quaternions.

I will talk about that below; the first point is that I haven't made many posts here. To keep whoever bothers following this blog on my project interested and up to date, I will write a blog post (to the best of my ability; post is still not guaranteed) every Saturday with some info on what has been worked on/ updated etc. And for those that even that is not enough, I plan on making a twitter account with daily updates on progress. Now as a warning to those who wish to read on, below is a rant/very long post on quaternions which some may find fascinating and others boring.

Quaternions are what unity uses to describe rotations. Unity also has something called eulerangles, which  has the more easily interpreted 0-360 notation that we are used to using for rotations. The main reason unity uses quaternions as the underlying way of calculating an objects rotation though, is because quaternions don't suffer from something called gimbal lock. The major disadvantage of quaternions, is that their representation is very complex, so much so in fact that quaternions are best simply referred to as variables instead of their individual values. For a mathematical explanation of quaternions, here is a good explanation that might give you a little bit of an idea of what the values actually mean. However, the explanation went a bit over my head, and the variable method of representation is sufficient.

My problem with quaternions started when I tried to do something a bit complex, and all at once. The idea was to add a hook function for rotating one side of a module to be facing another side of another module.  So I setup something simple for selecting the sides that needed to face each other. I set it up so all that was needed was the new rotation to rotate too.

Each object stores its side as a rotation and position relative too the center of the module it is on. This greatly reduces lag from object creation and destruction compared to when I had an entire GameObject representing each side, but it added a complication; instead of rotating one module to be facing another, I had to rotate one rotation of a modules side to be facing another rotation of another modules side.

In the below example side one is selected to rotate facing side 3, and the goal was to rotate it so it looked like side 2; both sides plains are parallel, and the corners of the modules are aligned.
My first solution to get a rotation that would rotate in this way was to try rotating all at once, and i came up with this line of code:  

gameObject.transform.rotation*Quaternion.Euler(orbit))*(Quaternion.Inverse(Quaternion.Euler(side.orbit+Vector3(0, 0, 180)))
note: orbit is the sides relative rotation in euler angles to the module it is on. Quaternion.Euler converts it to a quaternion.

This line is the result from hours of trial and error and was by no means the most efficient time I spent. However, it still worked to provide the desired rotation. I am honestly still not entirely sure why it works, but it does, so I was fine with it. That is, until I tried to rotate the resulting rotation. 

At some point I realized I needed to rotate the returned rotation, the reason being that if you connect modules into a "loop" where there are connections connecting in a loop pattern, the assembly will destroy itself. In the example below the red shows the "loop" that would be created. The blue shows the corner of the side that would rotate toward the other corner of the other triangle if the above line of code was used to provide the target rotation.
If a joint is added with this rotation as the target, then the assembly literally flies apart. So as a solution I attempted to use the angle axis function to rotate the resulting rotation in a way that would return the correct target rotation. Only problem was, using the angle axis function seriously messed up the rotation; it rotated on some arbitrary axis as a result of the original rotation calculations. I spent a long time attempting to rectify this, but nothing worked and I was forced to attempt a different approach.

I was back to square one and I did what I should have done from the start: rotate in steps. Eventually I came up with a rotation that would align the faces of the two objects, which was really a modified LookAt function. From there I was able to use angle axis to rotate the previous rotation to the final rotation. This resulted in the desired rotation of the modules.

To sum up: Do quaternion rotations in steps; it will save you a LOT of trouble, and will certainly not cause you to learn a million things about quaternions you never needed to know.
note: the last part of the above sentence is not guaranteed not to occur. 

Edit: The details (with the actual code) on how this was solved can be found here.