It seems like yesterday was the end of September, and now it is the end of October! We’re sorry for the delay in posting. The good news is we have a lot to share!
We are excited to finally share the titular enemy, the Violets. This was one item that was mostly completed around the end of July, but had a few more polishing items to finish. Thus, we decided to wait to share in this post!
As mentioned 5 years ago in the about post, the Violets behavior is similar to the splitting and combining of the game agar.io. The Violets in their defensive form have no concept of good or evil. They have one task: to defend at all costs. Violets survival is completely based on feeding off of their enemy to grow bigger. The larger the Violet, the more health it has. The problem is, the bigger the Violet, the slower it moves. Thus, they attack when a threat is nearby by splitting off, thus getting smaller and can move quicker. When Violets take damage, they also shrink in size. Violets like to group together to swarm their enemy. When same sized Violets group together, they can combine to grow bigger (albeit being slow again, but having more health). The AI of the Violets makes them the deadliest of foes, similar to how
Metroids are for the Metroid series. The Violets pose a huge threat if they are not properly handled.
As the title of this posts insinuates, the Violets are completed functionally and artistically! Tony did a great job capturing what we were wanting in designing the Violets. Below are a few design concepts:
We ended up combining designs 1 and 2 which produced these designs, ordered from oldest to final:
As mentioned, the Violets have variety of sizes. Thus, we had to design all of the different animations around the many different sizes. We aren’t going to share all the different sizes or animations. However, we did want to share our first public screen capture, demonstrating the Violets in action:
I (Dan) make light work of destroying the Violets. But keep in mind, I have a lot of health here, with all the best weapons in the game! Playing the demo of the game will demonstrate just how deadly these Violets are!
Also at the cusp of the last post, we were working on getting a concept artist to design a few of our characters. It is our pleasure to introduce our newest team member, Corinne Schwallie. Corinne is a freelance concept artist based in Ohio with a few years of concepting passion projects. She has already brought a few of our characters to life so far (which we will be showcasing in a future post) and we’re excited to see what else she can bring to the table! We are excited for what her talents will do for the project.
Below are a few more items that can be picked up during the game:
We also decided that consumable healing food comes from Globs in this world. Below are those items:
Each of these “Gluits” are native to specific provinces in the world. For example, globs will drop Glushrooms in the swamp province.
Tutorial and Fog
We made some updates to what we’re calling the “tutorial border” as well as fog in the game:
One of the biggest updates we have done to the game in the month of October was updating our NPC‘s art. Though we haven’t done most of the main characters, we did create all of the “bit” characters. You maybe wondering “I know the team is making progress on the game, but making hundreds of animations for bit characters vs. the ratio that you have been creating enemies / etc., there is no-way!?” And you’d be right — except we didn’t create our bit characters the same way as everything else. We created a layering system.
We ended up creating an almost bare base, which then we can layer on hair, beards, and clothing. We created six bases: adult male, chubby adult male, adult female, chubby adult female, child male and child female. With these bases, we can palette swap skin tone. With the clothing layer, Tony drew these in such a way where each color distinguishes a part of clothing (e.g sleeves, chest, pants). We can then palette swap the clothing to make the character have many different variations of clothing types. Beards and hair had to be created distinctly for each type of hair / beard style. But, we can palette swap hair colors easily. With all of these different layering / body types / skin colors / hair colors / hair types / etc., we are able to make thousands of different variations for our bit characters.
Below is a screenshot with some of them:
In addition, we also updated the dialog for these characters to reflect the direction of the story as well as new game updates.
There have been some additional game mechanics the last couple of months, as well as some tweaks to existing systems.
The first is the ability to learn new combat skills. Before this, the player had essentially “all of the best combat skills” from the start. But we asked a main question: “what if we limited the amount of swings / thrusts a player can do?”. Which led into these questions: “How does that change the game? Will the game feel unbalanced or just feel ‘bad’?” Strangely, the game didn’t feel bad or unbalanced. In fact, it felt good to learn these “new skills”, and made progression feel all that more rewarding. In our opinion, it changed the game for the better. But, we had to figure out a way to “unlock” learning these moves.
Originally, before the real tutorial was implemented, the Dojo master “taught” the player a few of the moves / skills / etc. as the tutorial. Now, we have the Dojo master teach the player these new skills by trading in Skull Pendants (the icon shown above in the `New Items` section). These Skull Pendants can be obtained by clearing out forts of enemies. Essentially, the player is proving to the Dojo master the mastery of their skills and the Dojo master rewards the player by learning (or unlocking) the new skills.
The second update is better weapon assignment to our
Soldier enemies. Before, they were all randomly generated. Now, we can specify what type of weapon they carry. For those type of
Soldier enemies that are still random, we limited the amount of randomness based on the player’s inventory size for that type of weapon. For example, if the player has only two capacity for balanced weapons,
Soldier enemies that are of balanced weapons type can only have
Sword. However, if the player’s balanced weapons capacity increases to three,
Soldier enemies that are of balanced weapons type can randomly choose
What this helps with is the weapon merging mechanic. When we decreased the capacity, we noticed a lot of players not merging or picking up weapons because the weapons were all sorts of different. Now with enemies dropping more common weapons, the player is more easily able to merge their weapons. So essentially, the greater the capacity, the more available weapons that are out there randomly. We still can assign weapon assignment specifically to
Soldier enemies. So, we could still add weapons that aren’t in the random selection pool, giving some mystic / value to the player.
The third is overhauling our enemies hearing system. Before we started adding sound effects to the game, the way an enemy “heard” the player was by how fast the main character was moving. This had a lot of limitations, but worked for us very well early on in development. But with all the newly added sound effects, this system was severely outdated. Thus, we decided to overhaul the hearing system. The good news is the properties that the enemy determined if they “heard” the player moving was all reusable. For example, each enemy had a
hearDist property, which is how far an enemy can hear something. So if the player was moving so fast within the
hearDist property, then the enemy could hear the player.
When updating our hearing system, we wanted to replace “how fast the character is moving” with “what sounds are being played, where at and how loud”. “What sounds” are being played was relatively easy, we cached the sound until it is no longer playing. “Where at” was relatively easy as well. We keep track of the starting position when the sound is played. If the sound is attached to a moving object (like an arrow), we can get its current location as well. “How loud” was an interesting problem to solve for. We didn’t want to use the playback volume for a given sound effect, since that is relative to the human player / mixed with all the other sounds / music. Therefore, we assigned a “loudness” property to each sound effect using this hearing system. There are five thresholds: quiet, noise, normal, moderate, and loud. Quiet / noise sounds are like footsteps, Normal sounds are like speaking volume, Moderate / Loud sounds are like things breaking / explosions. With these relative volumes, we can not only make use of our
hearDist property on our enemies, but also “gate” quieter sounds for enemies with bad hearing. This system is very simple but also provides robust amounts of enemy configurations.
Other Notable Updates
One other feature we had mostly completed at the cusp of the last post was a cutscene / sequence system. In our minds, a cutscene is just a sequence of scripted events that should happen. Therefore, what was really at play was a sequence system. We wanted this sequence system to handle not only the aforementioned cutscene problem, but something like “when a block is moved onto a switch, pan the camera to the gate, show it unlocking, pan the camera back”.
Interestingly, Game Maker Studio just released a sequence creator as a feature (which is partially why we waited so long to implement this). However, there were some limitations of Game Maker’s sequence creator with our engine that we won’t get into here. Therefore, we rolled out our own solution.
To solve for this, we added to our global object a function called
addSequence that registers a callback, or a list of actions that should run. The instance that registers the function can then run that sequence when it is ready, or use another function called
runSequenceWhen that provides a logic callback. When that logic callback is true (e.g. “a block is on a switch”), the sequence will then run. There can be multiple sequences ran sequentially, as
addSequence takes a time delay of when the next sequence should run. In our above example, “pan the camera to the gate” takes some time to actually happen. We don’t want to run “show it unlocking” until a certain amount of time has passed for the camera to get to the gate (or we could use another
runSequenceWhen the camera is in position, but just illustrating a point). We also have a few other helper functions, like
sequenceHasRan, which checks to see if a given sequence has ran already, as well as
pauseSequenceWhen, which pauses a running sequence when a certain logic callback is true.
This system has a few other bells and whistles that the average reader probably won’t want us getting into the weeds of. But this sequence system is going to be the backbone of mainly other systems to come.
Below are the remaining notable updates:
- We found another issue with our
Playbacksystem for watching a player’s session / debugging. We found out that the audio system in Game Maker is asynchronous. Well, we knew it was asynchronous, but we didn’t realize it was affecting our recording / playback system until now. The Game Maker Studio functions audio_is_playing and even more specifically audio_sound_get_track_position are not guaranteed to be the same each playback (due to computers running different tasks on each playthrough). Therefore, we added functionality in our
Recorderto capture these values so that our
Playbackcan return these values as they were for a given session.
- We made some updates to our map generator. In our last post, we mentioned that we had begun building the real game world. Our old map was out-of-date, but we haven’t made updates to the map generator in a while. Therefore, we spent some time updating our map generator to account for all the different new things (e.g.
- We fixed some issues with our moveable blocks introduced in our last post. There was some snapping issues / moving through blocks if the player positioned themselves correctly (or incorrectly).
- Since we added a concept of moveable blocks, it only made sense to have these moveable blocks be pushed on a switch. We therefore made some adjustments to our gates to be able to go from an unlocked state back to a lock state (e.g. the block was on a switch, and now we moved the block off).
- September saw us fixing many, many TODOs. We had up to 110 TODO items. Yes, we’ve been a bit busy adding new features that we haven’t really refactored much. Now we’re down to about 45, the majority related to updating old sprites with new ones.
- We also have been doing a lot of play testing. This is because we are getting demos out to a few people to help with the future Kickstarter.
- Because we are going to start handing out the demos to people, we’ve begun making use of tagging / releases in Github (where our source code is hosted), for better tracking. We’re going to be creating minor releases from here on out. Along with this, we’ve been essentially committing to one branch this whole time. Now we are getting in better habits of making pull requests for our bugs / issues / features. This helps with tracking / searchability / tagging / releases as well.