Thursday, February 22, 2018

Order Matters

Shortly after the previous blog post I began socializing the test build with some friends, several of whom are experienced video game spaceship designers (if that actually means anything).  This initial version required the player to create the interior of the ship first, then design the outside around it.  Despite their experience they found it incredibly frustrating to produce anything more than a box-ship when designing from the inside out.  Even I, the person who programmed it, admitted to having some difficulties.

This style of design was difficult for a number of reasons, not the least of which was that people find it very difficult to think about shape when they're only presented with 2D slices.  Estimating weapon coverage and maneuvering thruster placement was next to impossible.

So of course I told my play testers they were wrong and kept forging ahead.

No, what I did instead of spend about two months re-writing the hull designer to work in the reverse order which turned out to be much more intuitive.  Players now design the exterior of the ship first and place their interiors inside that shell.  To be honest, I had taken inspiration for the inside-out style of design from Shores of Hazeron, but given how obtuse just about everything in that game is I really should have known this would be a losing proposition.

The best news: people now tell me they are actually having fun with testing, and have even reported firing up the game on their own just to play around with it.  So without further ado, here are some example builds.






The next milestone is a few usability improvements to the designer, including the ability to save and load multiple ships instead of always using the same file.  After that, it's time to leave well-enough alone and move on to turning these ship models into usable RTS units.

Saturday, December 9, 2017

Ship Building Demo




I spent today ironing out some "final" bugs in the ship builder and re-building the demo ship from the ground up.  I now have an alpha build of the editor which I sent to a few friends, so it'll be interesting to see what they come up with.

The next step is baking this construction model into a real, functional strategy game unit.

Tuesday, December 5, 2017

Resource Networks


One of the core mantras I really want to come across in this game is the 6 P's (proper preparation prevents piss-poor performance).  Players who think through the design of their ship will always win versus players who slap a lot of guns on a box and hope for the best.  One of the most important factors in how a ship will perform in combat will be how well it can withstand damage.

Unlike most voxel-based games, damage to blocks will not necessarily make them disappear (this will only happen where a specific DR for the block is beat, mostly from very heavy weapons).  When the exterior blocks take hits, they will have a probability of causing damage to interior blocks.  This damage can include starting fires, bursting pipes, severing data links, causing atmosphere leaks, etc.  For example, if the communication link between CIC and a gun is severed, that gun will need to switch to local control (which will incur penalties).

This suggests that there are pipes to burst and conduits to break.  In order to provide the player the ability to build redundancy into their design (e.g. so a single hit to the wrong place won't knock out power to half the ship) I had to implement a system of piping and wiring.  This system is called Resource Networks

Foreground: Water pump (left), Fuel pump (right)
Background: Circuit breaker (left), Reactor (right)

In the images you can see a simple version of an engine room with its various connections.  These include fuel and water tanks, engines, a reactor loop (reactor, steam turbines, condenser), and pumps.

Every resource system tile (4 per regular tile) can have a conduit traveling through it in 2 of 3 directions (e.g. if a pipe it going lengthwise and widthwise, nothing can go vertically).  Certain types of conduits can also jump others on the same level, as you can see in the very center of the top image where the grey power cable goes through the red pipe.  I haven't implemented specific geometry to illustrate this jump yet, so right now they just clip through each other.

Equipment can have Resource Connections at positions in the grid.  These are divided into Sources, Sinks, and Storage.  Every tick sources output a resource into the net, and sinks consume that resource.  If there is more demand than supply, connections become starved and the block may stop functioning.  Special types of sinks with the "CanPull" flag set can also draw from storages.  A pump, for example, is implemented as a can-pull sink and a source, allow equipment connected to the output to receive resources stored in tanks they wouldn't be able to pull themselves.

Monday, November 27, 2017

New Beginnings

It's been more than four years since I've had a project worth posting about on here.  Previously this blog was dedicated to progress on my own game engine.  Game engines are cool, but I'm more interested in making games.

Over the past two months I've been laying the groundwork for a new game project, and I finally have some progress worth presenting.  Most of that time has been spent creating extensible and generic components for building ships (compartments, machinery, exterior hull, etc) and an interface for putting them together.

So what do the first results look like?

Example Frigate Exterior
Interior Deck Layout
This game is a space strategy game with some twists.  I grew up playing games like Homeworld, and I loved the real-time strategy combined with the three dimensional battlefield (and of course, the spaceships).  But something has always bugged me about strategy games, and it is the fact that a gigantic space battlecruiser and an infantryman are treated exactly the same way: they are a singular unit which has x hitpoints before it dies.

I might be biased but ships are far, far more than a singular unit.  They're complex machines operated by hundreds of people.  In this game you can command your ship in a traditional RTS sense, but you can also go inside and give crewmembers orders to, for example, patch some damage or fight a fire.  I want the player to be able to see the chaos inside of a heavily damaged ship, and try to task their (surviving) crewmembers with repairs to keep the ship fighting a few moments longer.

Ships are comprised of compartments which have equipment such as engines, pumps, or terminals inside them.  This equipment is connected together with piping and wiring to form resource networks which allow them to function, such as providing power to blocks which need it.  The exterior hull is built in a Space Engineers style around the interior.

Battles will take place between small numbers of ships (2-3 per player) due to their complexity, with long time-to-kill for an individual ship.  As ships take damage, equipment will be damaged and resource connections broken necessitating repairs.  Fires can also be started, and will spread if not fought quickly.  If an exterior block has taken too much damage it can be destroyed completely, possibly opening a compartment to space.

One thing I am absolutely adamant about is that there will be no point where a ship loses all of its health and spontaneously ceases to exist.  As long as there is a single living crewman and functional equipment on the ship, it can still be selected and given orders (whether it can carry out those orders is another matter).

So join me on this journey into making the most micro-manage-y spaceship RTS ever.

Tuesday, August 13, 2013

Let's Talk About Planets


It's been a while since I've posted anything, but I certainly have not been idle.  In fact, the reason I haven't posted anything is because I have been so busy!  Usually I get an hour or two every night when I'm back from work/gym to work on this project, and writing blog posts is time consuming.  So usually I get coding instead of blogging, but I don't want to neglect this thing too much.

Sit back, this'll be a long one.

Up until recently, all of my terrestrial planets have been featureless, uniform spheres.  You could land on them, but you couldn't really go sightseeing.  Not so anymore.

I've always been a fan of building up concepts from the bottom, so if we're going to talk about planets the first thing we need to talk about is spherical quadtrees.  Each planet has six faces, which we'll call 'front', 'back', 'left', 'right', 'up', and 'down'.  Initially, each one of these faces is a flat grid of 32x32 vertices.  But planets are not square, so by normalizing the position vector of each vertex we end up with a unit sphere.  Moving these vertices along their normals by the equitorial radius gives us a sphere the size of the planet.

Each of these faces is the root node of a quad tree.  Each quad tree is capable of dynamically subdiving to provide higher levels of detail.  The reasons for this being necessary should be obvious, but I will state them anyway: it would require gigabytes of memory to store all of the vertices necessary to render a planet at a meaningful resolution (say, 5 meters between vertices).  Also, the majority of this fidelity cannot be appreciated when it is on a distant mountain, or from a ship looking down from orbit.  This method reduces the load on the GPU considerably, and consumes much less uncessary memory.

Every level down on the tree covers one quarter of the area of the parent, meaning we can represent more detail with the same group of 1024 vertices.  These subdivision continues until we reach a desired level of fidelity (based on a certain distance between vertices), at which point the node becomes a leaf.  Terrain leaves have collision meshes, and can be stood on.  In order to minimize physics complexity, only active pages (with objects directly above them) and their immediate neighbors have collision meshes.

The SphericalQuadTree class features a series of utilities for finding neighboring tiles given a direction of movement.  These utilities use a series of lookup tables to find the appropriate neighbor, and they even work across the "face" border.  Constructing these lookup tables took a while, and in order to get it right I actually had to make a paper cube that represented the 6 faces of the planet and label it.

With that stuff out of the way, we can talk about terrain generation.

Every planet has a terrain type and a seed value.  From there, we can generate the terrain for the entire planet.  This is done with an interface called the Landscaper, which has several different subclasses for different terrain types.  Every time a new vertex is created in a terrain page it calls a method on the Landscaper and then adds that to the equitorial radius, moving it up or pushing it down.

To do all of the generating I am using libnoise, an awesome open-source coherent noise generation library.

The first important thing to realize is that when I say "type" I don't mean things like plains and mountains.  The terrain type defines what type of planet it is.  Currently I am working on the simplest, called "Barren", to figure out what works and what doesn't.  After that is done, I will implement the others using the techniques from Barren.

Here's an example of what I've got so far (with vertices colored based on altitude):





And here are the currently-planned terrain types:

Barren

These planets are geologically dead (if they were ever very active at all).  Picture these planets looking a lot like the Moon.  They'll usually have rough mountainous areas and relatively flat maria produced by lava flows.  These types of planets will never have an atmosphere, and because of this will usually be heavily cratered.

Irregular

These aren't really planets so much as large captured asteroids.  Mimas is an example of what I'm going for here: a large, oddly shaped ball of rock.  Most of the geological features here will be cracks and craters in the surface.

Magmatic

"Lava" planets are generally young planets which haven't cooled down after their formation.  The Earth was probably like this for the first few million years of its existence.  The surface of these planets mostly appears to be "continents" of cooled magma seperated by gaping fissues of red.  Glowing rivers of lava can be easily seen from orbit.  These planets may or may not have an atmosphere, which would mostly be sulfur and other products of volcanic activity.

Ice

On the exact opposite end of the spectrum are ice planets.  Enceladus and Europa are great examples of these types of planets.  These planets will feature hilly white wastes, sprinkled with craters.  Enceladus also has interesting fractures on the surface caused by tidal stresses from the primary.  Some researchers suggest that Europa may have a sub-surface ocean.  I'm not sure if I'll be able to do something like this, but it could theoretically be modeled with some kind of terrain shell (I will have to think about this).  These planets may or may not have atmospheres.

Martian

I couldn't think of a great name for these, but basically they are relatively-habitable planets with terrain that was shaped by things like wind, dust storms, and glacier movement.  Rivers may appear on these planets, though the liquid is long gone.

Terran

Finally, the gems of the galaxy.  These are what the players are really hunting for if they want their best chance at survival.  These planets are much like Earth, with diverse geological regions and liquid water.  This will be the most difficult terrain generator to implement, and most likely the slowest because of the large number of noise modules needed to generate interesting terrain.

One of the things I want to add on to the basic terrain generation is the placement of monolothic features such as cataclysmic craters and giant mountains a la Olympus Mons.  I'm not sure how I can integrate this with the noise modules, but I will probably have to end up extending libnoise in order to do it.

Also, I mentioned atmospheres in several posts above.  I have a very rudimentary framework in place for atmospheres, but currently they are not actually implemented.  In terms of their actual generation, I'll save that for another post when I actually have something concrete done for it.

Once the actual generation of the physical terrain is complete, I'll be moving on to coloring them.  I have been thinking a lot about how to accomplish the texturing itself.  The planet terrain has a unique vertex class and its own set of pixel and vertex shaders, so I have a lot of freedom to try any methods I want without altering how anything else in the engine is rendered.

One of the first ideas to cross my mind was to do it all procedurally on the GPU, but I quickly decided that it would be too difficult to produce realistic results with only the data available to the GPU.

The idea I am leaning most heavily towards involves several steps.  I won't go into much detail until I actually have something implemented, but here is a rough overview.  First, we take the output of the noise modules determining things like terrian type and "biome" type.  Next, we also need to take into account the angle between the surface normal and the up-vector at that location on the planet (because this changes, the planet is round!) so that we don't get things like grass growing on the side of a cliff.  Once we have some information about the type of ground this vertex represents, we can blend together a palette of available ground textures to get the desired result.

Hopefully soon I'll have some more progress pictures for the different planet types (without textures).  Until then, onward and upward.

Tuesday, March 26, 2013

Starfield Builder (Iteration 2)

As part of the directx 11 port, I've finally revisited the starfield generator.  There isn't much new in this version, as it was mostly just porting dx9 to 11, but it finally draws textures on the quads for the stars, and colorizes them to match the actual star color.


The colors are very subtle, but still noticeable.  I'd rather have them that way, to be honest, instead of being obnoxiously in-your-face.

A simple re-write, but the results look much better!

Thursday, March 14, 2013

Ring Systems (Part 1)

I think it's pretty safe to say that Saturn's rings are one of the coolest things in the solar system (or at least one of the prettiest).  I've been wanting to give more love to rings for a while.  When I originally implemented them I was having quite a bit of stenciling problems (zbuffering doesn't work at these scales), and dropped them after I got them barely rendering.  Now that I've been slowly rebuilding every part of the engine to work with DirectX 11 I've come back around to gas giants.  Instead of doing the jovian shader immediately, I decided I really wanted to get rings right first (rationalizing to myself that they applied to all types of planets, and was thus a bigger step than just one specific type).

 The formation of ring systems isn't well understood, so I had to take a somewhat less-than-scientific approach to generating my own.  To over-simplify it, rings are basically a collection of particles inside of a planet's Roche Limit, meaning that the gravity of the primary is too strong inside that limit to allow them to coalesce into a planet.  I did a bit of reading on what we know about Saturn's rings and tried to nail down a way that they could be generated programmatically.  For a first iteration, I'm pleased with the results.

Structure


The Voyager probes were the first to discover that Saturn's rings were more complex than just the two main rings we could make out at our distance.  In reality, they are comprised of hundreds of thousands of tiny ringlets.  It's generally theorized that the structure of ring systems is closely tied to the moons orbiting the planet that hosts the rings.  The interaction of the gravity of the moons and planet with the ring particles creates "divisions" in the rings.  Moons that produce this effect are called "shepherd moons". 

To create the major structures I'm using a Weibull distribution modified by a portion of the number of moons the planet has.  There is a minimum value, so there is still some variety even if the planet has no moons.  "Major structures" includes rings and divisions.  By taking the modulus of the iterator in each loop I can alternate between divisions and rings.  An Inverse Gamma distribution is used to determine structure thickness, with the scale argument for divisions being smaller than rings.  Each structure is then written to the texture, with the alpha value varied using Perlin Noise to keep them from appearing as one solid color.

Here are some examples (each ring is given a random color to make them distinct during development):

Rainbow Rings!



There will be more on composition in a minute, but for now just know that each ring will have a general color.  To break up that homogeneity I added "minor structures", which are a randomly generated number of 1-texel wide rings roughly uniformly distributed throughout the major rings to add some flair.  Right now they're just green to make them stand out:



Composition & Color


Saturn's rings are comprised primarily of water-ice, with fragments of rock, dust, and minerals providing most of the color.  Right now all of the colors seen here are only for testing purposes.  Even though they look awesome, I don't want clown planets sprinkled around the galaxy.

This won't be implemented until much later, but the appearance of rings will eventually be determined by the composition of the planet they orbit.  The reason this feature is on hold for a while is because I have yet to figure out a good way to smear elements around the solar system with interesting distribution.  Before I can determine which elements will be present in the rings (and thus, which colors) I will need to determine the composition of the planet.

In general, lighter elements tend to be pushed into the outer solar system during stellar ignition (which is why all our outer planets are gas giants).  This is because when a star finally ignites the sudden burst of solar wind pushes the lighter elements away faster, leaving the silicates and heavy elements to form rocky planets.

Once I've finally managed to determine the composition of the planet I can take that and color the rings.  Right now I'm thinking that the more abundant materials of the planet will form the major rings, and the rarer and often brighter elements will provide the hint of variety in the minor rings.

Other Cool Stuff (in the future)


Eventually, I'll need to give the rings some real mass so that when you fly through them you don't realize it's really just a textured triangle ring.  Saturn's rings are made of particles ranging from a few centimeters to ten or more meters.  In terms of thickness, they range from a few meters to almost a kilometer.  In order to get this thickness, the shader will have to do a few things.  The first will be to fade away the texture nearest to the camera so there is a hole (in much the same way that you can't see the fog closest to you).  In order to fill that hole in the texture, I'll have to render dust specks in the field of view.  For more substantial particles, I haven't made up my mind on how to implement those.  Creating unique geometry on the fly for dozen or even hundreds of meter-sized asteroids seems like it would be a strain, even using geometry shaders.  Voxels may be the answer here, but I haven't yet implemented a sparse oct-tree renderer as it would be quite a task.

But I can dream.