If for some reason this will not load for you, you can play the game here also:
Recent community posts
The game is released!
I scrambled really hard the last couple days fixing all of the small issues I could find. Today I built the End Game screen (giving you a bonus to your meta resources if you win, etc) and built two of the tutorial systems for the game. The first is a menu that pops up at the very start of the game, explaining the basic concepts. The second is a help menu that can be found in the game menu. Each of these is just a few pages long. Tutorials are not exactly my strong point, but when I am not under such a time crunch I will try to add one that guides the player more gently.
Play the game here:
And play my other games here:
I've added the last of the gameplay features to the game this week. I had to cut the skills out of the game for now (things like Destroy, Uncover the map, etc) because there it is too much to implement in too short of a time. Even if I could get the foundation for them implemented, I fear that I could never get it debugged and balanced before the deadline. I replaced the Skills with upgrades for the Big Alien, which were much easier to implement since they are very similar to the upgrades for the Small Alien that were already implemented.
I added the fourth faction to the game, the Builders. I was not sure that I would be able to finish them, but I decided to make them pacifists, so I didn't need to write all of the code to allow their ships to attack and be attacked. They simply spawn a ship when they have enough resources, and that ship captures the target planet in one shot.
The cool thing about the Builders is that they produce Relics while they control a planet. You can destroy them early in order to prevent them growing too big to manage, but if you wait to wipe them out, you will gain lots more relics. The Fighter faction also sometimes attacks them, so the player may want to defend them to farm more relics. Relics are used to purchase upgrades for the Big Aliens.
Manual Save And Loading
I'm not sure if anyone else uses this approach, but I always like to write methods to manually save the data necessary to recreate the game state. I know that it is possible to use libraries for easier serialization, but the resulting file sizes are much larger. Also, when you write methods to save only the essential information to file, you often find problems in the structure or design of your code that will be beneficial to solve, and become necessary to solve in order to save and recreate the game objects.
Here is an example of how I do this, with the Star class.
First, I write a method that returns a string that contains all of the information necessary to recreate a Star.
The BZStringTools class contains some members and methods that make it easier to save things in strings. The lineDelimiter (an "=" string) is used to separate the larger parts of the data, while the delimiter (a "-" string) is used to separate the larger parts into their smaller parts.
When I need to save, the save() method of the MainGame class is called. It calls the saveStars() method, and writes out all of the information to a file.
Here is the contents of that file:
Then when loading, the MainGame class calls the loadStars() method, which loads up the file, splits the contents, and recreates the stars.
When loading, the MainGame calls this static factory method of the Star class:
The unfortunate consequence of doing things this way is that I need to know what the order of the string elements will be (the order they were appended in the getSaveString() method). Any small mistake will result in errors in parsing and crashes.
After parsing the string, a special constructor is called that is only used when loading Stars:
And that's it! I still need to write methods for about 60% of the game, but everything will follow this same basic pattern. Saving is not super important for my game, but I would still like to allow the player to save and continue.
Took a couple days off, but today I put in some time working on the last bits of core gameplay that I have planned for the game jam release.
Unfortunately I was absolutely right that my approach was bad when it came to the ships in the game. Today I added the Big Alien and the Trader Cruiser ships. The idea behind the Big Alien is that it is the ranged ship for the aliens faction. The Trader Cruiser is the attack ship for the traders faction. In addition to adding these ships, I also had to add to the AI for the Fighter Ship and the Alien ships in order to make them able to attack the new ships.
What I faced here was a combinatorial explosion of methods. Because I did not succeed in making this part of the game generic, I needed to program a method for each possible outcome. Therefore, I needed methods for alienAttackedTraderCruiser, bigAlienShotTraderCruiser, fighterShotBigAlien, fighterShotTraderCruiser, etc etc for every possible combination of things that was now possible due to the new ships.
This was pretty much a nightmare, and took a few hours of my time to finish coding and testing. I'm sure that some kind of entity component system would have helped clean up this code dramatically, but I will have to go back through the code and rewrite it after the game jam is complete. I'm not totally sure yet how I would wire things up, because some of these methods are actually very different from each other. For example, some ships have health that is depleted first before they are destroyed, and different sounds, animations, and images are used depending on who is shooting and who is dying.
I decided to finish things in the inefficient way because I knew that I did not have enough time to rewrite everything with a better design. Everything in programming is a trade off, and there are always a million different ways to do things, so I think in this case I think it is forgivable. I still feed bad, though.
I have a laundry list of things left to complete before I will be happy with the game. I need a tutorial and help system, I need to finish adding the universe features and give them proper names, I need to add a save system for the game, and I need to polish up some of the existing elements. Crunch time!
Just a small update today!
I had a major breakthrough last night and this morning regarding the win conditions of the game. I decided that the player could earn special currency for kills, and could spend it on upgrades for their speed, range, health, etc. There can also be a second currency that is gained when the player captures a special planet with an artifact on it. The second currency could be spent on skills that could be activated on a cooldown to give the player a big advantage.
These upgrades, skills, and currencies would carry over from game to game, so the player would get stronger each game, whether they win or lose. They could get a bonus to the currency gained in a game if they completely wipe out all of their opponents.
However if they kill the neutral Traders, they will accrue negative karma points, and those will be kept track of too. Then if I ever implement leaderboards or something like that, the negative karma points could be counted against their score. Alternatively, the negative karma points could affect something in game such as the appearance of the aliens or reactions from the neutral races.
Here is a screenshot of the menu. I have not yet implemented the skills, but the upgrades are implemented and working:
After the last post I spent some time actually Playing the game, rather than just watching the AIs play it. It didn't take long to discover two major flaws with the game that needed to be fixed immediately.
The flag system that I have talked about in earlier posts was designed to make it so that the game is easily playable on mobile. I didn't want the user to have to click and drag on the screen to select units, then drag to a destination for them to move, and then click again. Furthermore I did not want to give the user full control over the units. Instead I wanted them to have an AI and have their own "feel" and "personality". Unfortunately, when I first tried playing a full game, I was constantly placing the wrong flag on the map. A partial fix to this problem was to make it so that when a flag is activated, it is removed from the array and inserted at the front of it. This way, when the game searches for the first active flag, it will find the one that has just been reactivated. This gives the flags a more natural and usable feel. If I have time, I am going to add another system where the player can click and drag on one of the flags in order to move it around, so that they can fine tune its position.
Another major problem with the gameplay was that as the game progresses, a huge number of aliens needs to be purchased to use up all of the player resources. Hundreds and hundreds of clicks are required in order to spend it all. To combat this problem, I changed the purchase button into a check box, and when the check box is checked, units will be purchased automatically. This allows the player to focus on something other than tapping the Buy Alien button a million times per game.
During the more prolonged gameplay sessions, I noticed some moments where the rendering froze completely, meaning that calculations were being done in the game model that were blocking the graphics thread. I decided to do some profiling so that I could discover the root cause of the problem.
I switched Eclipse to the JVM view and tried that to do some profiling directly in the IDE, but I could not figure out how to get the CPU profiling to work. I did get some useful results though:
Lots and lots of SequenceActions, and as I watched, the count continued to increase and never decrease.
I wanted CPU profiling, so I downloaded and installed VisualVM. It didn't take very long to get things working, but you have to make sure to click the Settings button and add the appropriate classes to the profiler or it won't work:
After getting it set up, I got down to some profiling and found some interesting results. Here was the memory usage:
So I confirmed that there were tons of SequenceActions that were not being freed/disposed/garbage collected.
I spent some time writing some code to fix this problem, adding Pools for the SequenceAction objects and Runnables that I needed for the 5 or so SequenceActions I was using in my game. Unfortunately, this did not affect performance at all.
It was then that I realized that I was using a bad hack to disable the fog of war so that I could watch the AI at the early stages of the game. The hack was to simply not add the Images to the stage. Commenting out that one line removed the fog of war without me having to change anything else. Unfortunately, because I did not change anything else, I was still adding the actions to the fog images when they needed to fade in or out based on where the player's ships were. Adding the images to the stage again fixed the memory problem:
Not much left here to worry about.
Now I moved on to the CPU profiling. Here are the total times:
And here are the self times (self time is the amount of time that the program spends inside of that specific method):
It turned out that the revealFog method was a real hog, and calculateDistance was a pretty poor performer too. I looked and saw that I was doing a bounds check to determine whether the point for a given alien ship was inside of a fog image. I changed this to a distance check to try to improve performance, and then I found out something very important. I was using Math.hypot() to calculate the distances almost everywhere in the game, and Math.hypot() has very bad performance when compared to simply using a square root to calculate the distance. I changed everything to use the square root method instead, and here were the results:
The results can be a bit hard to interpret, but the bottom line is that moving away from Math.hypot() has increased the speed of a bunch of methods. The test is not a perfect example, because the amount of times that isNearby gets called depends on the number of ships in the scene. I am still trying to figure out how to reduce these calls, but I'm not sure how to do it yet. At this point, performance might be good enough without further changes. I will probably revert to the bounds checking method to double check my results.
Well, today has been a pretty productive day for me. I was able to implement the code that allows the Alien ships and Fighter ships to attack the Traders, as well as the code for the Alien ships to attack the Fighter Colony ships. The player has a check box on the screen that allows them to turn trader killing on and off. I also added game speeds to the game and to the in game menu. While testing the new interactions between ships, I added those labels beneath the Small and Big Alien purchase buttons so that I could keep track of how many ships were present in the game. Those will not be in the final version.
While writing the code for the various ship interactions, I realized that I have coded things in a pretty bad way. I have to have a method in the game model for each different action, so there is one method for alienAttacksTrader, alienAttacksColony, fighterAttacksAlien, and so on. Along the way I tried to change these into something more generic, but it did not work out.
This is one of those times where writing this code took very little time, but extending it to add new ships to the game will be very difficult as a result. I think that this is one of those types of games where an ECS system would be very beneficial. Unfortunately I do not have time to rewrite everything, and I am not familiar enough with implementing ECS to accomplish it. Luckily, I only have two more types of ships to implement (Big Aliens, and Trader Cruisers) so having a few redundant methods is really not a big deal.
After setting up the foundation for the three factions AIs, and establishing all of the base components of the game (ships for each faction, and a way for each faction to capture planets and gain resources), I went back to polishing some UI related elements of the game.
Enable/Disable Sound and Music
I wanted to make it so that sound and music can be enabled and disabled. This may seem straightforward at first, but there are some edge cases that complicate things somewhat.
First of all, I believe it is important to have sound disabled by default in the HTML build, because someone browsing to your website is definitely not expecting music and sounds to start blaring out of their speakers. To deal with this I added some checks for whether the current ApplicationType is WebGL, and if so, I disable all sounds at the start.
Second, I wanted to make sure that player settings were saved between sessions in the non HTML versions of the game. If a player disables the sound or music, the odds are very good that they want those settings to stay without having to set them every time they play the game. To accomplish this, I implemented a UserData class that saves the version number and the settings for sound and music to a text file, and a UserData object is created from that text file each time the game runs.
For the player to control the aliens they place flags on the map and the aliens move to them. There are three of these flags, and when the player places one the last one previously placed is moved to the new location. From the beginning I wanted to implement a way to enable and disable these flags so that the player could have 1 or 2 flags instead of 3 if they wanted to.
It took quite a bit of bug fixing but I finally got this implemented. The biggest problem was that when a flag was moved, I was removing it from the array and adding it to the end of the array so that the first flag in the array was always the last one placed. Unfortunately, for simplicity I was using an integer when the flag button was pressed, so when the flag was removed from the array and added to the end the buttons on the screen did not match the indexes of the flags in the array. So I had to change the way I was doing things.
Here is a short gif of the flag system in action:
The flag buttons are implemented with a custom CheckBox object that pairs a CheckBox and an Image together in a Stack which is then added to the relevant Table.
Today I really wanted to dive into the major chunk of gameplay that still needs to be completed, but I didn't have time. Instead, I added some more polish to the game. I added a pause button, and I made sure to make it so that the player can issue commands while the game is paused. This way when things get really crazy in the late game they can pause and issue orders, and then unpause and watch things unfold. If this was not possible then the AI would have a huge advantage.
I also added colors for the flags so that it is easier to tell which one is which. Unfortunately the colors are still not perfect so I probably need to make a greyscale version of the flag animation so that they look better when colorized.
I added colors to the different homeworlds as well so that there is some kind of visual indicator of which planet is the homeworld for each faction. I would like to have a unique image for each homeworld, but I don't believe I will have time to do this.
There is lots left to do, and the game jam is more than halfway over! I still have to implement the Big alien, the Trader cruiser attack ship, AIs for them, and changes to the player AIs to account for the new ships. Next, I need to implement interactions between the ships that do not have them. Currently, the Trader ships and Fighter colonies are ignored by everything. Finally I need to implement a way for the player to determine whether or not they will attack the traders, and a penalty for attacking them (since they are neutral bystanders). Implementing all of this and then working out the bugs is going to take a while.In terms of UI and game polish stuff, there isn't too much left to do (famous last words). I have all the art and sound assets I need, so anything else added would just be bonus, and there will probably not be time for that. I need to add a save game system, but that is more time consuming than challenging. My plan is to simply save out a text file that contains just the information needed to reconstitute the objects of the game state. I might need to have more than one of these files for each save, just for simplicities sake, but I am not sure yet. Finally, I need to add a tutorial and help system to the game. Tutorials are always a rough spot for strategy games, so I am not sure that I will be able to craft a good one with limited time, but I'm definitely going to try.
I'm also planning to make a lengthy gameplay video soon to show off the gameplay :)
Sorry that I have not posted an update in a few days I've been steadily working on different parts of the game, and I will make some posts today about the work that I have done.
The first major change to the game was to add Trader Ships and Fighter Colony Ships, as well as AI for the Trader and Fighter factions so that they would know what to do with them. After that, I played some test games to see how the balance would play out.
Testing games this way takes forever, because each iteration you must start the game from scratch to see how it plays out with new values for ship costs and things like that. To deal with this, I added an AI for the Alien player, the faction that is currently designed for the human player. I had to create a somewhat complex algorithm for that AI in order to have it properly choose which flag to move when placing new flags on the map, but it seems to work pretty well.
Here is a screenshot of the 3 AIs battling it out:
The Trader Ships are the long lines of ships moving between almost every planet on the map. When they move from planet to planet, they perform trade actions which add money to the Trader player.
The shorter lines in the top right corner are the Fighter Colony ships. They must move colonists to a target planet, and then move back to their homeworld to refill the ship with colonists.
The red splotches in the bottom left corner of the map are the aliens. Their "fighter" ship is also able to capture star systems by eating them when in close range.
With all of this in place, I was able to set the speed of the game really high and let the AIs battle it out to see how the game plays and what kind of things are likely to happen during the course of a game. Based on the results, I can tweak the balance of the factions.
Last night I added music and sounds to the game. I've found that adding polish to a game as you go along really helps to keep you motivated. I found some nice free music online, and I created the sound effects using sfxr: http://www.drpetter.se/project_sfxr.html My process for creating the sound effects is pretty much randomly creating new sound effects and then twiddling with the bars, moving them small amounts until it starts to sound like something acceptable.
In the past when dealing with sound, it was always the last thing added to a project and this resulted in some bad spaghetti code. This time I approached it from an object oriented angle, and created some sound classes that seem to work really well.
The first thing I did was create an enum that has a type for each of the sounds:
I always load all of the assets for the game in the top level Game class, including sounds and textures. So in that class I created a Map<SoundType, Sound>, and I created a Sound object for every SoundType and added it to the Map.
At this point. you could call a sound just by grabbing it from that Map and doing sound.play(), but instead I created a SoundPlayer class to make things a little easier:
Now I play sounds by calling libGDXGame.soundPlayer.playSound(SoundType.soundTypeToPlay). This way, I can enable or disable sound effects all in one place, and I could easily extend this to have a user adjustable volume level.
This morning I worked on creating the Player classes for the game. This will allow me to create AI players for each of the three factions (Aliens, Fighters, Traders) that handle the high level actions that are similar to those that a human may take when playing the game. These are asymmetrical factions, so it will be a little bit difficult to transition to a game where the player can play as any of the three factions, but I am not going to worry about that right now. For now, the player is hard coded as the Aliens faction.
I wanted to work on the AIs after that, both for the Players and also for the individual units of the game. I got sidetracked however implementing a parallax background for the stars.
I implemented this using three layers of textures, each of them represented by a matrix of my custom ParallaxSprite class. That class has members for the Texture, x position, y position, width, and height. At first I went down the wrong path, trying to use the camera movement to move the texture positions. It turned out that there was a much easier way to do it, which I found here in the libGDX tests https://github.com/libgdx/libgdx/blob/master/tests...
This way, I did not have to couple things together as much. Unfortunately, I still had to add the ParallaxCamera as a member of the CameraPanner class. I wanted to have two CameraPanner classes working together, but when I added a second CameraPanner to the input handler, it prevented the previous one from working. So instead I add the ParallaxCamera to the CameraPanner class and pan both cameras at the same time.
After quite a bit of prototyping and testing out ideas, I am ready to name my game jam entry and nail down the basic gameplay concepts. I also have a working title screen.
You Are The Aliens
Game ConceptMajesty-esque RTS where you purchase units and place flags on the universe map to direct the aliens.
- Explore a unique galaxy each game.
- Fight against the fighter squadrons of the evil aliens.
- Decide whether to leave the neutral aliens and their trade ships in peace, or destroy them to increase your power.
Today I added a couple of major things to the game to enhance the feeling of exploration for the player.
First, I added the concept of UniverseFeatures to the universe generator. A UniverseFeature has a Circle and a UniverseFeatureType. Before the stars are generated, a number of UniverseFeatures are created. There are checks to make sure that these features do not overlap or extend beyond the edge of the game world. These features are things like Nebulas, Galactic Cores, Spiral Arms, etc.
If a particular point is inside of the Circle of one of the UniverseFeatures, it is part of the UniverseFeature and has the associated UniverseFeatureType. This can be used for many things, but currently the UniverseFeatureType is primarily used for determining the star density of a point.
When creating stars, the UniverseGenerator will now check whether a random point is inside of one of the Circles of the UniverseFeatures that are created first. If not, a default star density is used, otherwise the star density of the UniverseFeatureType will be used. The UniverseGenerator then checks the stars that have already been created, and if one of those stars is within the distance of the star density, it will be discarded.
When the GameScene is created, an image can be added to represent these UniverseFeatures, and the name of that feature is also added. Here is an example of a nebula feature:
Later, these features will have semi randomly generated names to increase their uniqueness for the player.
Fog Of War
The other major feature that I added is the Fog of War. I have previously tried to add this to a game using squares, but this time I created the fog out of overlapping circle textures. I think the result is a little bit better. As the player explores the map, the fog is usually permanently removed. However, one of the UniverseFeatures is called a Dark Zone, and if the point of the FogImage is inside of a Dark Zone, the fog returns and must be uncovered again.
Just implemented the gdx-ai StateMachine in my code. Feels much cleaner! Here is my github repo if you want to check out what I have done https://github.com/bazola/spacey-life/tree/add-gdx...
Setting it up is pretty simple. After you import gdx-ai into your project, you initialize the StateMachine class like this:
Then you update it each tick like this:
Here is the entire AlienState enum, which is the key thing that controls the flow of the logic for the AI:
Another very busy day for me, but I will have some real time tomorrow to dive into the AI stuff. Right now, when the aliens are close to a star, they will move over to it and start eating it! This is the eating animation:
I've got the GameScreen created, and all of the resources are loaded in the LibGDXGame class. All of the basic camera panning, zooming, and touch stuff is implemented.
I've got Universe creation up and running, currently randomly placing stars as long as they are not too close to other stars.
I've added an animation for the simple alien.
Hey all, indy developer bazola here!
I have one game released with libGDX called VoxelCity. I'm working on a few other prototypes. I'm a huge fan of libGDX, and I'm very excited to participate in this game jam. It is my first game jam ever, but with how fast it is to put together prototypes with libGDX, I'm sure I can come up with something fun to play!