-->

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.