The Violets, Concept Artist and NPCs

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!

The Violets

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:

Violet Design 1
Violet Design 1
Violet Design 2
Violet Design 2
Violet Design 3
Violet Design 3
Violet Design 4
Violet Design 4
Violet Design 5
Violet Design 5
Violet Design 6
Violet Design 6
Violet Design 7
Violet Design 7
Violet Design 8
Violet Design 8

We ended up combining designs 1 and 2 which produced these designs, ordered from oldest to final:

Merged Design
Merged Design
Polish Design
Polish Design
Final Design
Final Design

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!

Concept Artist

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.

New Items

Below are a few more items that can be picked up during the game:

Lantern
Lantern
Telescope
Telescope
Skull Pendant
Skull Pendant

We also decided that consumable healing food comes from Globs in this world.  Below are those items:

Glanana
Glanana
Glapple
Glapple
Gleach
Gleach
Glelon
Glelon
Glerries
Glerries
Glickly Glear (Working Name)
Glickly Glear (Working Name)
Gluffle
Gluffle
Glushroom
Glushroom
Gluts (Working Name)
Gluts (Working Name)

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:

Tutorial
Tutorial
Fog
Fog

NPC Updates

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:

New NPCs
New NPCs

In addition, we also updated the dialog for these characters to reflect the direction of the story as well as new game updates.

Game Design

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 Sword or Rapier.

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 Recorder / Playback system 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 Recorder to capture these values so that our Playback can 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. TileLayer system).
  • 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.

The Game Continues

After the disappointing month of March, we took some time to recalibrate once again.  After a long couple months of silence on our end, we are pleased to announce some long overdue updates.  On the name front, we can’t quite reveal this yet (per our lawyer), but we can at least share the good news that we’re still able to use Violets in some capacity!

Even though we had some time of recalibrating, we also can’t deny that the months of May and June have been busy for us outside of this project.  As you may know, a little game called The Legend of Zelda: Tears of the Kingdom came out.  Being that Tears of the Kingdom (TotK) is a direct sequel to The Legend of Zelda: Breath of the Wild, a game we took a lot of our original inspiration from, it was critical that we took the time necessary to play through and understand what the game was about.  Many choices, ideas, and game design moving forward (some which will be covered in this post) was definitely impacted by playing through Nintendo’s latest Zelda game.

Part of the recalibration effort these past couple of months was actually game planning / coming up with the tasks needed to be completed to make our game.  All of this planning, especially after TotK coming out was no accident.  We are certainly glad that it came out when it did.  Giving a review / our opinions of TotK is beyond the scope of this blog.  However, our biggest learning as it relates to this project is that there is a sense of traditional Zelda that is no longer present in Breath of the Wild (BotW) / TotK.  Perhaps we’ll touch on that topic at a later date.  For now though, let’s move on from high level talk and get into the updates!

Minotaur Updates

Since we last posted, we shared some Minotaur updates, and we have even more to share below:

Minotaur Balanced Swing Up
Minotaur Balanced Swing Up
Minotaur Balanced Swing Right
Minotaur Balanced Swing Right
Minotaur Heavy Swing Down
Minotaur Heavy Swing Down
Minotaur Heavy Swing Left
Minotaur Heavy Swing Left

The minotaur has extreme strength, and Tony did a great job capturing this with these swings!

Soldier

(Not to be confused with the enemy type Soldier).  Castle town contains soldiers that protect the royal family and the population from danger.  There’s also a special type of soldier that exists in the game to protect a special place (this is a bit vague, but this is the most we can explain for now without spoiling anything)!  We wanted to save time and not design two different types of soldiers.  Therefore, we made use of the palette swapper and made one version of the solider and swapped different colors to make two different types of soldiers out of one design.

Like anything new, we came up with a couple designs (in pairs) shown below:

Castle Soldier Design 1
Castle Soldier Design 1
Special Soldier Design 1
Special Soldier Design 1
Castle Soldier Design 2
Castle Soldier Design 2
Special Soldier Design 2
Special Soldier Design 2
Castle Soldier Design 3
Castle Soldier Design 3
Special Soldier Design 3
Special Soldier Design 3
Castle Soldier Design 4
Castle Soldier Design 4
Special Soldier Design 4
Special Soldier Design 4

We ultimately went with the last design and came up with this final version:

Castle Soldier
Castle Soldier
Special Soldier
Special Soldier

And we even have some walk and run cycles completed:

Castle Soldier Walk Down
Castle Soldier Walk Down
Special Soldier Walk Down
Special Soldier Walk Down
Castle Soldier Walk Left
Castle Soldier Walk Left
Special Soldier Walk Left
Special Soldier Walk Left
Castle Soldier Run Left
Castle Soldier Run Left
Special Soldier Run Left
Special Soldier Run Left
Castle Soldier Run Up
Castle Soldier Run Up
Special Soldier Run Up
Special Soldier Run Up

Yellow Enemy Variants

We decided that we needed another variation type that was on the medium difficulty side to help the pace / difficulty curve of the game.  Therefore, we added yellow enemy variants, shown below:

Glob Yellow
Glob Yellow
Ambush Yellow
Ambush Yellow
Knight Ghost Fire Yellow
Knight Ghost Fire Yellow
Knight Ghost Water Yellow
Knight Ghost Water Yellow
Knight Ghost Ice Yellow
Knight Ghost Ice Yellow
Orc Yellow
Orc Yellow
Reptile Yellow
Reptile Yellow
Minotaur Yellow
Minotaur Yellow

Other Art Updates

Below are a few screenshots of a few other new art assets, including updated glows, signs and icons, boulders, pots and moveable blocks!

Boulder and Glow Sizes
Boulder and Glow Sizes
Sign Post
Sign Post
House Icon
House Icon
Holding Pot
Holding Pot
Moveable Blocks
Moveable Blocks

Game Design

One of major items we have been working on the past month is nailing down the answer to the question “What is Violet”?  As mentioned in the introduction of this post, one of our learnings of playing the latest two Zelda entries was that the traditional Zelda experience is no longer present.  Therefore, we believe in order for this project to standout amongst the vast crowd of games is to separate ourselves as much as possible from the “modern” Zelda formula and really deliver on “the traditional Zelda experience”.  To us, this means many things.  But to summarize it succinctly, it would be a “simple, progression based, laser-focused scope”.

Over the past month, we’ve began thinking about the design of the game.  We’ve been brainstorming different collectibles, where they exist, why they are collected, etc.  We’ve been deciding what areas we want to build in the game, why they exist, what purpose they serve in the game, etc.  We’ve been thinking through what additional mechanics should be in the game, how they are obtained, for what reason do they serve, etc.  Basically, we’ve been determining the purpose of the game.  Originally the plan was to make this game a huge, 2D, open-world adventure.  After playing TotK, I (Dan) don’t think bigger is always better.  Therefore, we decided to get “laser-focused” on the areas we want to create and make sure these areas are full with fun, unique, and engaging content.

As discussed in our previous post, we pushed back the Kickstarter date.  Part of these past couple months was actually beginning to build out the actual world.  Before the events of the previous post, we were planning on making a Kickstarter demo that would throw away the world we’ve created.  In order to deliver the project in a timely manner, we decided it would be better to create part of the world for the demo, that would be refined as development continues.

Before our previous post, we were experimenting with the actual world and how big it was going to be.  The original world was going to be 18×18 sections (a section originally contained 6×6 zones and a zone was 480x480px).  We even started building castle town, which was going to be 2×2 sections large!  After realizing we needed to make this game smaller in scope, we ironically, we went back to the room size of the original Kickstarter demo, which was 9×9 sections.  However, we found that to be a bit small (mainly with the fact that houses / dungeons / caves / etc. are as big on the inside as they are on the outside (breaking a convention here)).  With the math involved, there wasn’t a divisible way to have an in-between size that encompassed 3×3 provinces (a province would contain n number of sections) with 81 sections that we were wanting.  However, a thought eventually popped into our heads of “what if we made the sections contain 8×8 zones”?  This made the original Kickstarter grid of 9×9 sections not feel as small anymore, while the world also didn’t feel too large either.  Essentially, making the sections contain 8×8 zones made our 9×9 section grid feel like an original 12×12 section grid (6×6 zones), but utilizing the 3×3 provinces that we wanted from a world building standpoint.

Concurrently with building out new sections, we’ve also been coming up with the scope for the game.  This has been a long and hard process.  Much of the reason why this has been hard is that determining what should be cut, and what should be kept is painful.  Up until now in my career, I (Dan) have always been on the other side of the conversation when it comes to cutting things.  It’s much easier to say “no” when it isn’t ultimately your product.  However, now being in the role of “the client”, it’s really hard to remove good ideas, for the sake of time and budget.  With that said, getting “laser-focused” on what we are building will ultimately be for the best of the game.  We’ve had a vision for the game (and honestly, we really haven’t strayed too far from this vision), but haven’t had any need for boundaries or rails up until this point.  But with time and money entering the picture, it’s very important to put into words what this definition of the game will be, and of course, sticking to it!

Coming up with the scope of the game has also been tedious.  We currently have notes and ideas in many different places.  We’ve had to do a lot of consolidating on our part!

One of the more tedious parts was determining what resources (items) we wanted.  We originally were planning on having many droppable resources with a few different inventories to organize them.  However, a common shared complaint in TotK, was the cluttered, and annoying to sort through inventory system.  Part of the problem in our opinion is that there is just too much stuff in that game.  Therefore, we decided to scale back what was collected and why.  For example, we were going to have resources in the game that served multiple purposes.  Instead, we decided to give a resource one purpose, which makes the game “simple” and “laser-focused”.  A good example of this is we decided to combine the Fire, Ice and Water Cores into one Element Ore that can be used as ammunition for the elemental rods.  We originally wanted the ability to have the Fire Core be used for Fire Rods, as well as other purposes.  But, cutting this idea in favor of removing extra clutter will help streamline the game.

Other Notable Updates

It’s been satisfying to start designing the game now that we have many of the game’s systems developed.  We still have a lot more design / work to do, but we’re getting closer each step of the way!  Below are a list of other updates we’ve worked on:

  • Since we have another year of development, we finished worked on the horse from a functionality standpoint, and it works great!  Now we hope we’ll have enough time to implement the art for the Kickstarter demo for the player to be able to ride horses!
  • We mentioned yellow enemy variants above.  With that addition came increasing the highest ranking from S to SS.  Now the ranking is as follows: F, E, D, C, B, A, S, SS.
  • As we were building new Castle Town, one thing we thought was “wouldn’t be cool if we could get on the roofs, jump off of them, etc.?”  So, we decided to implement that feature.  It required some updates to our tileLayer system, but it ended up being for the better.  For example, one thing we realized was house walls were acting much like cliffs!  Therefore, we refactored house tile layer into the cliffs, and cleaned up a bunch of unnecessary systems around that.

    Jumping Off Roof
    Jumping Off Roof
  • Along with our tileLayer system updates, we also added two other types of tiles: holes and shallow water.
  • We added a No Controller Dialog (to help the player know if their controller is connected):

    No Controller Dialog
    No Controller Dialog
  • We added a position editor to help us position weapons / items on the Living objects.  Before we were doing this manually by going into the art canvas, positioning the sprite there, and manually calculating the offset, and typing it into the code.  Now we have a debug in-game editor that does all of this and outputs a json file with this data:

    Debug Position Editor
    Debug Position Editor
  • You may have noticed that the HUD contains icons for the L / R Shoulder buttons now.  We decided to combine rods as a group of weapons (much like balanced or agile is its own group).  We also found that it was easier to not swapped the “Dpad pages” with the shoulder buttons.  Therefore, we assigned the rod / special weapon selection to the shoulder buttons.
  • We overhauled our buildings system (inside a house, cave, etc.).  In this post, we mentioned that buildings being as big on the outside as they are on the inside.  To make this work, the “inside” of a building exists in the same game room as the outside.  Therefore, we need a way to determine when a Interactable object is inside or outside.  The old way of making this work was to draw primitives that created tris (triangles), and these tris would create rectangles, or tiles that we could use to determine if something was inside.  Here’s a simple example:
    Primitive
    Primitive

    If you look closely at the red line, it makes two triangles, which form a rectangle.  Pretty neat.  But, what if we have a complicated building, or a cave system like below:

    Primitive
    Primitive

    This creates all the rectangles we need, but is an utter mess to maintain.  For example, as we were designing this cave system, we changed the layout multiple times, which required us to update this primitive.  We decided that this needed to be simplified.  Now, if we want to create a building, we basically lay down a tile overlay of what the boundaries should be:

    Building
    Building

    It’s quick to update and easy to maintain.  We had to write some code around how to actually interpret these tiles to create actual “insides”.  But now that this work is done, creating additional buildings, cave systems, etc. will be a breeze.

Conclusion

We recognize it’s been a while since our last post and we appreciate the patience!  We’re hoping we can share some bigger news in our next few posts.  You know… things like what the story is, the name of the game, what our characters name is, who the villain is, and some art of different things that we haven’t been able to share yet.  Stay tuned!

The Future of Violet Part Two

Last Year we shared our plans about Violet from a logistical front.  The TL;DR of our post was we’d be shooting for a Kickstarter in February 2024.  And unfortunately we have some bad news:

Our original, high level plan was to launch our Kickstarter in February 2024.  I (Dan) would continue working full time until January 2025 where we’d develop the game for two full years.  In 2027, we’d polish the game and release.  After meeting with the advisor, it was encouraged for us to set a lower target dollar amount, as well as to spend less time post Kickstarter developing the game.  With less budget and less time (the double whammy), we decided to postpone the Kickstarter.  Though we know we’d have a good demo / be ready by Kickstarter in 2024, my (Dan’s) gut was telling me to wait another year (2025) for personal financial reasons.

Above everything else, I (Dan) need to make sure my family is provided for.  And second, I want to make sure those involved on the project don’t have to worry about if / when they are getting paid.  This is a big risk and I need to make sure everyone involved can get through two years without my full time salary.  Of course this is disappointing, but I think the pros might be better in the long run (I always say slow and steady wins the race).  For one, this gives us another year of development / design / art, which should help reduce time post Kickstarter developing the game.  It also means we naturally wouldn’t need as much from a Kickstarter, making a lower target actually workable from a budget standpoint.  And obviously, one more year will make the demo even that much better.

From a logistic standpoint, the timeline stays the same, but we are just shifting the Kickstarter out a year.  The Violet team was graciously more than accepting with postponing the Kickstarter.

However, the “bad news bears” doesn’t stop there:

Shortly after we decided to push the Kickstarter out, our lawyer informed us that not only is Last Life Studios (the LLC I (Dan) am operating under) is trademarked, the game name of “Violet” is also already trademarked.  Essentially what this means is the name of the game is going to have change, as well as some of the branding we have developed (e.g. the website, violetthegame.com, our logo, etc.).

March has not been a good month for Violet.  It has really got me (Dan) discouraged.  Tony, our artist did give me a little encouragement and said “For what it’s worth, those are all normal setbacks. If it means anything, none of those have discouraged my faith in the project.”  The next couple of months will be a bit of a rebranding time, so we may go a bit silent as we try to figure out what to rename / rebrand too.

Setbacks yield pruning, and then growth.  Right now the pruning phase sucks.  But we believe the growth will be exponential.

The Game Begins

This is another one of those hodgepodge of updates posts.  However, we already named a post “A Hodgepodge of Updates”.  Therefore, we decided to name the post with one of the main new features we added in the last couple of months — the beginning of the game (i.e. the tutorial)!

I (Dan) hate tutorials in games.  I’m the type of gamer who just wants to play the game and figure things out on my own.  Therefore, we made the tutorial succinct and to the point (and there’s even a way to quit early if an experienced player knows how!).  We believe the tutorial shows the game loop well, while explaining the basics of the game.  The best thing to do is experience it for yourself!  Until then, a few screenshots will have to do:

Tutorial
Tutorial
Tutorial
Tutorial

Tutorial
Tutorial
Tutorial
Tutorial
Tutorial
Tutorial

A couple of other updates you may have noticed in the most recent build of the game:

  1. The minimap icons have been updated.
  2. We have a cave tileset, with a looping cave texture that repeats for those “out of bounds” areas (i.e. the void).
  3. We added a concept of gates and locks, which require unlocking by clearing out enemies, a key, or by some other means.
  4. We added hit effects (slashes) as well as changed the damage color an enemy takes.  This in turn means we removed the blood particle effect.
  5. We made the rounded corners in the UI for drawn shapes (i.e. programmatic art, like circles) more pixelated.  Game Maker apparently draws its shapes at screen resolution and not the surface resolution, which ended up taking a week of reworking fonts / code / etc.

We also added many UI sound effects to help the player know which buttons / inputs are being pressed / used!  Unfortunately, those are not observable with these screenshots.

Minotaur Updates

We made quite a bit of progress on the Minotaur these past couple of months.  Firstly, the Minotaur dying:

Minotaur Death Down
Minotaur Death Down
Minotaur Death Left
Minotaur Death Left

Next, we’ll showcase the Minotaur’s dash attack:

Minotaur Dash Left
Minotaur Dash Left
Minotaur Dash Up
Minotaur Dash Up

As usual, progress can create setbacks.  After we created our stun animations and tested with a few players, we realized the startup of both the dash attack (as seen above) and the stun animation were very similar, causing players to be confused whether the Minotaur was going to attack or be vulnerable.  I (Dan) personally don’t like in games when an enemies telegraphed animation is similar — especially in making split second decisions.  So, sympathetically, we decided to change all of our stun animations to correct this problem.  Below is an old version (which we’ll see how similar it is to the left dash attacks above):

Old Minotaur Stunned Left
Old Minotaur Stunned Left

And below is the current, updated Minotaur stunned animation:

Minotaur Stunned Left
Minotaur Stunned Left
Minotaur Stunned Down
Minotaur Stunned Down

Other Art Updates

While taking a break from the Minotaur, we also did a lot of color and effect updates.  We’ve mentioned some of these updates already (the slash effects).  Therefore, the rest of this section will show off the remaining updates:

Clouds and cloud colors

We removed the cloud effect particle and replaced it with our own “cloud particle”.  We won’t go into all the details of how the clouds work, but we will show off a few updated screenshots:

Single Cloud Sunny Day
Single Cloud Sunny Day
Cloudy Day
Cloudy Day
Cloudy Day Inside
Cloudy Day Inside

When it is sunny, clouds will cast a nice, dark blue shadow.  When it is cloudy, these colors become a mix between a nice dark blue and a cloudy gray.  Inside, we change the void color to be a mix between dark brown and cloudy gray.  That is a great segue into:

The Void Color

When we are inside a building, and we don’t have a texture, we will use a void color.  This color used to be black, but we decided to give it a little flavor, depending on the building.  For example, when we are inside a house, we get this nice dark brown:

Inside House Void Color
Inside House Void Color

As we saw above, when it is cloudy, we mix the two colors.  When it is night, we replace the void color with our night time dark blue:

Inside House Nighttime Void Color
Inside House Nighttime Void Color

This is a good segue into:

The Nighttime Color

Much like the void color, we were using black to represent night time.  However, we changed this color to be a dark blue as shown below:

Nighttime
Nighttime

The difference is night and day… or, comparatively between some of our other nighttime screenshots, more pleasant looking.

Removed the Fort Fog

Fort fog was one of those things we added very early in development with Violet to test being “inside a building”, before we actually had artwork for buildings.  Now that we have buildings and concepts of being inside / outside, we decided to remove the fort fog.  The difference is night and day:

Fort
Fort
Fort
Fort

Cliff Decor

Finally, we added some random decor to the cliffs to give it a little less of a pattern look:

Cliff Decor
Cliff Decor

Other Notable Updates

Unlike our two recent posts, there isn’t as much to share in detail within this section.  Below is our bulleted list:

  • Performance Increases.  These past few months have increased performance in our game dramatically.  We added a couple of optimizations as well as a few fixes.  For the first time in a while, I (Dan) feel proud to show off the game.
  • Slow Motion Debugging.  We came across a function game_set_speed that let’s us toggle the framerate at which the game is running.  Before, we’d change this value in the game settings if we needed to see if animations we’re running correctly / at the correct speeds / etc.  However, running at 2 frames per second made this very cumbersome to test.  With this find, we can toggle the framerate at the moment we need to!
  • Fix Playback Input.  With the updates to our path finding, we broke quite a bit with the input recorder / playback.  We finally got around to fixing this (again).  It was really cool to “watch” someone play through the tutorial without having to sit next to them!
  • Made Picking Up “A Too Heavy Object” Not as Punishable.  One thing that was frustrating me and other players was that if A were pressed to try to pick up a dropped item, and instead we were close enough to an enemy, we’d try to pick them up instead!  The game would not let the player move until the “too heavy” animation was done.  For really heavy enemies, this could last a couple of seconds, where the player would then get punished.  We made this so the player could “interrupt early” by simply moving during any “too heavy” animations.  That way if an accidental A press occurs, they won’t be punished by it.

Minotaur Updates

These past couple months have seen many art updates, font cleanup, stability fixes and performance increases.  We’re excited to showcase the highlights below.

Minotaur

At the beginning of 2023, we began coming up with a few designs for the newest member of the Soldier enemies, the Minotaur.  Tony, as always, comes up with several great designs that we then have to decide which fits best with the game, story, etc.  Below are a few of the initial designs:

Minotaur Design 1
Minotaur Design 1

 

Minotaur Design 2
Minotaur Design 2

 

Minotaur Design 3
Minotaur Design 3

 

Minotaur Design 4
Minotaur Design 4

Without going into all of our rationale, we decided to go with the head of the second design and the body of the first design.  This yielded the fifth design:

Minotaur Design 5
Minotaur Design 5

After some further tweaking, we ended up with our final design:

Minotaur
Minotaur

The Minotaur has more HP and strength compared to the Orc and the Reptile.  To illustrate this from a gameplay perspective, we decided to make the Minotaur significantly larger.  We originally went with 1.5 times larger, but that seemed a bit large comparatively.  We also tried 1.25 times larger, but that seemed a bit small.  Therefore, at about 1.33 times, the Minotaur stands tall at 42 pixels (our hero is 32 pixels for reference (~5’9″)).  We also wanted to showcase the strength with its intimidating walk cycle, as shown below:

Minotaur Walk Down
Minotaur Walk Down
Minotaur Walk Left
Minotaur Walk Left
Minotaur Walk Up
Minotaur Walk Up

Reptile Updates

December found us finishing up some Reptile animations with the bow and two-handed walk cycle.  However, as we were preparing the Minotaur, we had realized we forgot to do idle animations for the reptile.  Below are those animations:

Reptile Idle Down
Reptile Idle Down
Reptile Idle Left
Reptile Idle Left

Cliff Updates

We also decided to touch up the cliff walls a bit, as well as add a few palette updates for the cliffs in different biomes shown below:

Upper Mountains
Upper Mountains
Snow Mountains
Snow Mountains

Target Updates

We finally decided to give an overhaul to the targeting system, both artistically and functionally.  Functionally, we added a “pause” concept that would only change the targetable enemies every one second, or when the player made a selection.  Even though the computer could calculate accurately which targets were “next”, having them change so rapidly made it really hard for the player to choose.  This delay or pause concept really helps in selecting.

Visually, we added three states:

  1. Light blue bracket — the “next” target if we quickly let go of L-Trigger and press it again
  2. Yellow bracket — the current target we are locked on to
  3. Directional arrows — if we press the R-Stick in the direction of the arrow, that enemy will become the “next” target

Below is an illustration of what this looks like:

Orc Fight
Orc Fight

You may have also noticed in the above screenshots that we moved the HUD elements.  We haven’t officially decided if we like this, but moving these elements to the corners of the screen really helps with the vertical screen real-estate.

Font Updates

You might have noticed in the above screenshots that the font is much different than before.  We overhauled the font systems and used / touched up some elegant pixel art fonts, as showcased below:

Updated Font
Updated Font
Updated Font
Updated Font

Other Notable Updates

Path Finding Part Two

In our previous post, we explained our problems with the path finding / grid system native to Game Maker and our current solution of using our own grid system.  By using our own, faster grid system, we also had to use our own implementation of A*, which essentially made us break even with the performance gains (because Game Maker’s mp_grid_path function is impossibly fast).  However, we hinted at our backburner task of rolling out the path finding (A*)  on a different thread.  Game Maker Studio has the ability to pull in from external resources, and we finally got around to offloading the path finding in C++ as well as on a different thread (spoiler, this gave us extreme performance boosts).

I (Dan) finally had a few consecutive days off after Christmas where I was able to dedicate 100% of my time with no interruptions learning how to make external DLLs that Game Maker Studio could then import and make calls out too.  The journey was tough — and honestly, I thought it was going to take longer to figure out than it did.  Most of our learnings came from these forum posts / guides:

  1. https://forum.gamemaker.io/index.php?threads/getting-started-with-c-dll-extension-creation-in-eclipse.73728/
  2. https://forum.gamemaker.io/index.php?threads/asynchronous-c-dll-extension-creation-in-eclipse.74176/
  3. https://help.yoyogames.com/hc/en-us/articles/360015676137-How-To-Create-DLL-Extensions-For-Windows-Games

We ended up going with Visual Studio instead of Eclipse, mainly because we already had Visual Studio installed for Game Maker’s YYC compiler.  After about the first day, we had a simple “Hello World” program made where we were able to talk to Game Maker and back to the DLL.  Day 1 and 2 also saw us converting our A* from GML to C++.  I haven’t touched C++ since my college days, so it took a little bit of time to remember how good ole pointers work.  After about Day 2, the A* algorithm was able to compute within a main program within the DLL (meaning, it was converted successfully).

Day 3 was the trickiest as we had to convert our aforementioned grid system of the previous blog post to buffers.  The only way to send large amounts of data to a DLL is to send the memory address (pointer) of the buffer from Game Maker.  Therefore, we had to convert our ds_grids to buffers.  Even though this was a pain, buffers are not only faster in Game Maker, but the size in memory was about half, so we inadvertently gained some performance.  Day 3 also saw us learning how to use threading properly in C++.  Even though native C++ is faster than GML, it still didn’t really make since for us to spend all of these new CPU cycles sending to the DLL if we were still running the A* on the same / main thread as the game.  Therefore, we had to figure out how to implement C++ threads.

There were two threading libraries we looked at.  The first was pthread, which we ultimately scrapped as it is meant for Unix computers.  Though there are ways to make it work on Windows (the eclipse link / we had it kind of working at one point in Visual Studio by importing the pthread library, but eventually gave up) we finally went with thread, which seems like it is native to C++ now.  After a few hours of experimenting, we were able to get threads working within C++.

By the fourth day, we were able to successfully send the grid data to the DLL, create a thread, compute the A* path and send the path data back to Game Maker!  When I first got the logs of the path data in Game Maker, I screamed at the top of my lungs and scared my wife!  A few minutes later, we were able to convert that data so that our Soldier enemies could move again!  We also were able to figure out ways to cancel computations / threads in the DLL.  For example, if an Orc dies while computing its path, we no longer need to compute the path anymore, since its dead.

Seeing the fruits of this labor paid of majorly.  We’re even thinking of moving our boid enemies (Globs, Bats, Violets) so that the computation is also threaded / asynchronous, as we eventually want tens of Violets on screen.

“Asynchronous” Zones

If we recall from previous posts, as our hero / camera moves from one location to another, we load in zones that are slightly off screen the direction we are moving and unload zones that are slightly off screen in the opposite direction.  If the whole world was computing all at once, our game’s speed would crawl.  In the spirit of async, we decided to make our loading / unloading of zones “asynchronous”.  We put asynchronous in quotes because, unlike the aforementioned A* which is truly asynchronous, the loading and unloading of zones is spread (vs. done all at once) amongst several frames.  For example, if we need to load in 4 zones, and it has taken more than 500ms to do so, we tell that system “hey, you’re taking a long time.  Let’s continue loading the next frame”.  So, instead of loading 4 zones in 2000ms (remember, a frame should compute and draw in ~16000ms), we load 1 zone each frame for about 500ms.  Since these zones are slightly off screen, there is still no need to worry about a jarring “pop in” effect.  By offloading this task to several frames of the game, we are able to prevent stutter slow.

Other Stability Increases

We also improved the frame rate of the game by removing a few particle effects that we were planning on replacing anyway.  For example, blood was a particle effect that we don’t believe was getting removed properly.  Recently, if an enemy dies, its body remains until the player unloads the zone and then comes back to that zone a few minutes later.  However, if the player never returns back to the zone, the body and its particle system remained in memory until the game ended.  By removing the particle (we’re eventually going to create a system for handling dead bodies / other objects that linger around like this), this in turned freed up memory, which in turn, frees up the CPU.

We also improved the draw_container routine for the inventory.  All other draw_container calls cached the container that is being drawn, except the inventory screen.  This was mainly because refactoring this was going to take a bit of time and was easier to just leave alone.  However, keeping the inventory from redrawing the container each frame would create hundreds of structs per frame, which would cause memory to spike.  Game Maker’s automatic garbage would eventually clean this.  However, the amount of time garbage collection has taken on Game Maker’s part has become quite burdensome for Violet recently.  Essentially, there have been stutter slow downs, similar to the aforementioned loading / unloading of zones.  However, unlike loading / unloading of zones, we don’t control Game Maker’s automatic garbage collector.  Therefore, anything we can do to help avoid unnecessary structs / memory on our part we’ve noticed helps keep Game Maker’s garbage collector more stable.

Weapon Degrading / Capacity / Shards

On Christmas Eve, I (Dan) was playing an old build from 2019.  I was mainly doing this just to see how far the game had progressed.  While playing, I realized a mechanic that functioned differently than it does now.  When a weapon degraded, it only moved down by 1 damage point.  Though there was nothing in 2019 indicating that it had degraded, it was interesting to play the game with weapons that slowly degraded vs. now where degrades go down a full letter (therefore, like 20 damage points).  We began thinking “what if we degraded by a smaller amount”?

We decided to try this theory and liked this so much better.  Now, instead of a C ranked weapon dropping to a D, it goes from C to C-, C- to D+ and then D+ to D.  We feel this really helps with the damage output in mid-battle.  However, with degrading only going down by thirds, the amount of weapon shards (which can be used to increase weapon capacity) had not changed, being way more abundant.  We decided to decrease this, as well as decrease the amount hits it takes to degrade a weapon.  Therefore, the degrading happens more (but the damage output is not cut has bad), which yield more weapon shards (but not too abundant).  With these two new systems at play, we also decided to make starting inventory capacity for each type 2.  With more weapon shards, it becomes pretty easy to increase weapon capacity.  With the primary mechanic of merging degraded weapons together for better weapons, we feel like we’ve made better a really interesting game loop with the weapon system.

Horsing Around

It’s been a bit longer between posts than we were hoping for.  I (Dan) usually write these posts on the weekends.  But here in development land and in the real world, it has been pretty busy.  A couple of quick stories before we proceed:

  1. Two weekends ago, my computer started micro stuttering the game weirdly.  At first I thought it might have been something to do with my graphics card.  However, after some testing, it was concluded that my hard drive was starting to go bad.  More on this story later.
  2. We were able to show the game to some familiar faces who hadn’t seen the game in a couple years, as well as new faces who were seeing the game for the first time.  The feedback was amazing as, for the first time, we were able to see a lot of the game mechanics for others actually come together and work as intended.  This was really exciting as it reinvigorated us and reinforced that we have something good here!

The good news in the extra time between posts means there is a bit more to show!

Horse

The title of this post is two-fold.  First, there were several concepts and functionalities that we experimented, or, “horsed around” with.  Second, of course, the horse!

The prototype horse has been in the game for a couple of years now.  It’s hidden away in a barn and we usually don’t tell players about it and let them discover it on their own.  For those players that do discover the horse, they absolutely love it (even in its terrible, prototype state).  We decided to have Tony create a walk and gallop animation for us to test ideas and concepts out with.  Below are those animations:

Horse Walk Right
Horse Walk Right
Horse Walk Down
Horse Walk Down
Horse Gallop Right
Horse Gallop Right
Horse Gallop Up
Horse Gallop Up

The animations feel very good in the game.  However, one of the reasons we haven’t gone “full force” into the horse is of course the additions of all the new different kinds of animations we would need.  We had an idea to potentially save time by cropping out the bottom half of our hero’s animations and replace them with a sitting / riding animation.  However, this idea in practice is probably not going to end up working.  We’re still “horsing around” with ways to make animations go quickly as we know everyone loves the horse.  However, we still have a lot of other art / animations to get done before our Kickstarter goal and reworking current animations just to ride a horse may not be time best spent.

Riding Horse
Riding Horse

Reptile Updates

We also have a few more animations to share about our good friend (rather, enemy), the Reptile, that we introduced in our previous post:

Reptile Heavy Swing Down
Reptile Heavy Swing Down
Reptile Stun Left
Reptile Stun Left
Reptile Death Left
Reptile Death Left

Sound Effects

It’s been long overdue, but at the beginning of July, Noah Flack began replacing many of the old, crusty placeholder sound effects with some new, polished sound effects.  We started down the road of creating sound effects from scratch, but it seemed more feasible to use a library of sounds and update / alter them according to our needs.  The library we are using in their licensing agreement has a restriction of “redistributing” these sound effects elsewhere.  Though this post isn’t intended to be a place where we are redistributing sounds (as well as many of these are heavily modified and would be unrecognizable from the original source), we felt it would be safer not to showcase any of those sounds from that library.  However, we do have a couple of sound effects that we created from scratch.  Here are a few below:

Knight Ghost Hit

Knight Ghost Death

Raining Outside Perspective

Raining Inside Perspective

UI / UX Updates

There was a reason why we wanted to tell the stories at the beginning of the post that we did, and here is the first reason.  While watching folks play the game, we noticed a few reoccurring behaviors that needed to be addressed:

1. Players had a hard time seeing how much damage they were taking in the “heart bar” in the top left of the screen.  Though Violet’s iframes are intentionally small, we still found a way to communicate how much damage the player was taking by making an animation of the heart breaking.  The more damage / combo damage that happens, the longer the delay for the start heart animation to playback.

Losing Health
Losing Health

2. In the same vain, players had a hard time seeing how much health they recovered when eating a recovery item.  Now granted, we still don’t have an eating animation (which we plan to add).  However, adding a heart animation that shows the player how much health they’ve recovered should help with this problem.  The delay of the start of the animation works similarly to taking damage, in that the more health / combo health recovered will delay the start of the animation.

Gaining Health
Gaining Health

3. We’ve also observed many folks in the colder regions wonder why they began taking damage.  After the initial cold damage popup (which players may forget or ignore), there was no way of knowing why the player was taking damage other than seeing the temperature gauge down in the bottom right.  However, before these updates, the needle was very small and hard to see.  We’ve addressed this with a few things:

  • Made the needle bigger as well as change colors the closer it gets to the cold / warm zones
  • When taking cold damage, use a blue color instead of red
  • When taking heat damage, use a red color (like before)
  • When taking any other damage, use a violet color instead of red
  • When taking cold or heat damage, make the gauge turn colors and have a cold / heat animation playback
  • In cold / warm zones, shake the temperature gauge a little to grab the players attention
Freeze Damage
Freeze Damage
Burn Damage
Burn Damage

Doorframes

We ended up reworking doorframes a bit.  We noticed when going through a doorframe with a weapon that the weapon was drawn in the wrong layer.  This is because all we were doing to sell the illusion that our hero was going through a doorframe was turning the visible property on and off at the right times.  This was a bit hacky and we went back and redid the way this works so that doorframes / doorways are on the appropriate layer now:

Doorway In
Doorway In
Doorway Out
Doorway Out

Other Notable Updates

Path Finding

At the crux of our Soldier AI is Game Maker’s path finding algorithm.  In hindsight, Game Maker’s mp_grid_path function is impossibly fast (seriously, if anyone knows how this is implemented, hit us up) — which is unfortunate because our problem wasn’t with this function.  Game Maker has two requirements for creating paths:

  1. Grids, which is essentially “the world” made up of walls and not walls.
  2. The aforementioned mp_grid_path function, which takes a grid and generates a path, most likely using an extremely optimized version of the A* algorithm.

The problem we were encountering was the time it takes to create grids.  Though paths are extremely fast to compute, grids are on the slower side (perhaps Game Maker pre-optimizes the grids, which is why paths are so fast?  We’re still not sure).  We’ll explain why this is a problem soon, but we really need a solution from Game Maker described in this Reddit post.

The way Game Maker Studio encourages developers to use these functions is to create a “world grid” one time and be done.  For the average developer using Game Maker’s mp_grid_* functions, this would be more than adequate.  However, in our case, our world is huge and each enemy has a slightly unique grid.  We’ve still been able to make great use of these functions though by doing a few workarounds.

To get around these problems, each Soldier enemy would create their grid based on the “chunk” of the world they resided in, as well as a few trade secrets.  In the above link to the Reddit post, since there wasn’t a simple mp_grid_copy function, we were manually creating grids every time we needed them (smarter enemies would make a grid every 30 frames for example).  This was costly on the CPU.  We had several tricks to make this less intensive, such as offsetting each enemy to create their grid, essentially preventing multiple grids from being created on every frame.  But this trick can only go so far.

One other problem we were wanting to solve for is the built in path finding deals with points, where our enemies and their hitboxes are bigger than one pixel (essentially wanting clearance-based path finding).  It wasn’t a big deal until recently when we discovered our Centaur enemy, with its big hitboxes, kept running into the wall on a tight turn, and not able to clear it.  With this problem and all the other aforementioned problems, we decided to roll out our own grid and pathing implementation.

We knew we needed to update the path finding algorithm itself, but the first thing we focused on was creating fast grids.  Since we were able to roll out whatever solution we could build, we wanted to solve three things with our implementation of grids:

  1. Have a “master” grid that all enemy / etc. grids would inherit from.
  2. Only update enemy grids with necessary updates (i.e. only update when needed, don’t update everything every n frames).
  3. It needs to be fast.

It took many nights and weekends to solve for this, but the solution we came up with for grids is ten times as fast as Game Maker’s grids!

We even solved a bonus problem introduced by our layerDepth system:  instead of one grid per enemy, it was however many layerDepths there were per enemy.  We ended up solving this problem with our friend, binary!  Our grids represented a wall as 1 and a walkable tile as 0.  We could express walls in layerDepth 0 as simply 1 (0001).  In layerDepth 1, we would express walls as 2 (0010).  But, what if we had a wall in both layerDepth 0 and 1?  We could express walls as 3 (0011).  When we needed to know if a cell in a particular layerDepth had a wall, we could simply pull out the bits of a number and determine whether a wall was there or not.

Our last task was to actually implement our own variation of A* and clearance based path finding.  Rolling this out in pure Game Maker has actually been more of a hindrance than a help.  With the performance gains we’ve obtained from the grids, we’ve essentially lost that and then some with our implementation of A*.  This isn’t because our implementation is bad — it’s actually really clever all things considering.  It’s simply that GML is a language above C++, and the further we get from writing code in native 1‘s and 0‘s, the slower the code becomes.

We did implement one trick with our A* which essentially only computes an enemies path for 100ms for a given frame.  If it takes longer, we store the computations its made and move on until the next frame, where we continue from where we left off.  It’s essentially fake threading and is a good compromise for now.  At the very least, we “break even” with our net performance gains / losses from all of this.

Where do we go from here?  Well, one of the backburner tasks we’ve been wanting to implement is rolling out path finding on a different thread.  Game Maker Studio has the ability to pull in from external resources, and this is the next logical step for us.  Offloading the path finding in C++, as well as on a different thread is going to give us extreme performance boosts — especially with our Soldier AI being so integral to the game behind-the-scenes.

TileCompressedData

Another update we had to do was in regards to our build scripts.  Game Maker 2022.8 introduced TileCompressedData to the IDE, which increases build times by tenfold.  Before, Game Maker Studio did not compress tile data for rooms, which made the file size for larger rooms with many tiles in the megabytes.  When doing builds, Game Maker would do comparison with these rather large room files, taking additional time for each build.  So what’s the problem — this seems like a great thing?!  Well, our build scripts were built with the uncompressed tile data, so we had to account for that.  This was a weekend project, but we were able to reverse engineer how Game Maker Studio stores its TileCompressedData.  That code is available here in our GMS-Tasks helper project.

Recorder / Playback Input

I bet you’re still wondering about the juicy details of what happened to my computer’s hard drive and what caused the micro stuttering?  Well, if we recall back in December of 2020 we introduced a dev feature called “Playback Input” which lets us record all of the inputs we make and if something crashes, we can “playback” those inputs exactly to get the exact crash.  Well the way we were handling this was less than optimal.  The reason for this is not because we are incompetent, but at the time, Game Maker did not have a means of handling crashes.  For example, if the game crashed, there was no way to “save” our input recorder since there was no way of handling unexpected crashes.  Our hacky solution around this was to write out one file every frame of the game the input the player made.  That way if the game crashed, we were able to “glue” those files together to create one big file.

The problem is writing 60 files every second while the game plays for the past two years has been taxing on my hard drive.  Out-of-the blue one fine Saturday morning, our game finally had enough and began running terribly slow.  I didn’t realize at the time that the problem was the Input Recorder.  My brother-in-law was in town and as I was explaining the issue, he happened to noticed the SSD in task manager was maxing out at 100%.  Once I remembered we were writing those files every frame, I turned the setting off and the game played normally again.  After testing on my laptop, confirming no one else was having issues, and reinstalling Windows, that’s when I knew I was beginning to see a hardware failure.

Good news in all of this is I decided to buy the AMD Ryzen 5700x processor and the Corsair MP600 1TB M.2 drive.  The processor cuts build times IN HALF and I’ve seen about 20% increase in build times with the faster read times on the M.2 drive.  The other good news in all of this is unbeknownst to me, Game Maker Studio added the exception_unhandled_handler which lets us handle unexpected crashes gracefully.  This lets us, for example, save out our input recorder, as one, sane normal file!  All of that to say, we needed to update our Recorder Input to handle writing just one file and our Playback Input to read in this one file.  Hopefully we won’t have to worry about future drive issues now 😛

 

 

Reptile Updates

Since our last post, there were a lot of concurrent systems that got resolved that came together to form what felt like some of the most productive months in a while!  On top of that, we have quite a few animations to show off — mostly centered around the Reptile.  Without further ado, let’s get into it!

Reptile

The Reptile is another one of our soldier enemies. The Reptile has very fast, unpredictable movement.  Tony Wojnar has really captured the chaotic nature of this guy and it has been fun seeing it come to life.

Reptile Walk
Reptile Walk
Reptile Run
Reptile Run
Reptile Backflip
Reptile Backflip
Reptile Breath
Reptile Breath
Reptile Balanced
Reptile Balanced

Walking / Running Weapon Animations

The next major addition from our art department is walking / running weapon animations.  Actually, this was a joint effort between programming and art!  Currently there are 12 different types of walking animations for each soldier enemy, as well as our hero.  Plus, each of the aforementioned have four run animations and four stand frames.  Multiply this for each weapon type and the number of unique animations would spiral out of control real fast.  We ended up coming up with an idea where each weapon, for each direction, has a couple of reusable still frames to choose from.  Then, programmatically, we specify the exact frame and position for our enemies / hero.  We save on the number of assets, but we do have to tediously figure this out by hand.  Luckily, this is the type of work I like to do on vacation during travel / downtime, so this worked out perfectly.  Tony concepted out a few of these, so below are what we’d see in game programmatically:

Sword Run Animation
Sword Run Animation
Sword Walk Animation
Sword Walk Animation

We did run into a problem though.  One of the big things we’ve been conveying from a gameplay standpoint is the difference between balanced and agile / heavy weapons is the fact that balanced are one-handed weapons (that can be used with a shield) and agile / heavy weapons are two handed weapons (that cannot be used with a shield).  Unfortunately all of our current walking animations assumed one-handed animations.  We tried to “cheat” with an example animation below:

Mace Walk Test
Mace Walk Test

However, it didn’t quiet feel right.  We ended up resolving this by adding two-handed stand, walk and run animations.  Luckily we could reuse a lot of the base animations and change the positions of the hands to make holding a two-handed weapon work.  Below are a few examples of all of this coming together (again, positioning programmatically, these are just references):

Spear Walk
Spear Walk
Spear Walk
Spear Walk
Orc Spear Walk
Orc Spear Walk
Orc Spear Walk
Orc Spear Walk
Reptile Spear Walk
Reptile Spear Walk
Reptile Spear Run
Reptile Spear Run
Reptile Spear Run
Reptile Spear Run

Other Notable Updates

As mentioned at the beginning of the post, we’ve made a lot of progress / resolved a lot of work on concurrent systems that have been in development for several months now.  The biggest of which was the layerDepth system.  The layerDepth system was introduced back in 2019 when we added bridges.  The simplest way to convey this system is if we are standing on a bridge, layerDepth is most likely 1, and if we are supposed to be under the bridge, layerDepth is most likely 0.  As mentioned in the linked post back as early as 2019, this system worked well for the hero, but applying this to all objects ended up reworking a lot.

Now, we didn’t just work on this system for three years (which we hope is obvious by the other posts on our blog 🙂 ), but integrating with all of the other systems took a bit of work.  Not only that, but when we discovered that the collision system we built originally was not going to handle layerDepth very optimally, we decided to update other systems (e.g. which is one of the reasons the Tile Object was introduced, to help speed up the collision system).  We’ve been talking on an off about all of these systems for a while now, but the final frontier was making all of this work with enemies, weapons, and other interactable objects.

Some interactable objects were pretty easy to update while others (like our soldier enemy) were a bit more involved.  For example, we had to update the path finding algorithm to account for different layerDepths.  This took a bit of reworking, especially around the transitions areas, which we called rampTile. RampTiles used to be single individual tiles, but we ended up merging that with our Tile Object system for optimizations.  As a reminder, RampTiles are essentially the triggers for switching an object’s layerDepth.  So, for an enemy to find a point in a different layerDepth, the enemy first needs to find the nearest ramp to toggle the enemy’s layerDepth, then the enemy needs to find the best path to that ramp, and finally, the enemy needs to compute the best path to the target.  Whew!

That was a more complicated interaction to figure out.  Below are a few other interactions we had to update and fix to make the layerDepth system work:

  • Updating an enemy’s “seeing” and “hearing” logic (i.e. enemies can normally see targets in different layerDepth, unless the target is under a bridge, for example)
  • Determining how collisions should behave with different layerDepths / trigger points / RampTiles
  • Updating the Renderable system to draw objects correctly
  • Updating the Buildingable system to determine whether an enemy is inside / outside and accounting its layerDepth
  • If an enemy / hero is using a weapon or holding something, determining how that interaction accounts for layerDepth, as well as interacting with the Buildingable system

These bullet points are not an exhaustive list either! As you can see, there were A LOT of complicated systems converging!  Of course, we’re now play testing the game again and encountering some bugs / edge cases / minor issues (which is normal with a system as complex as this).  However, we’re extremely proud of how well it all came together!

Finally, here’s a list of some other important updates we’ve completed:

  • Sound Effects / Pitching
    • We are in the beginning stages of updating our old, crusty sound effects with some new ones.  With new sound effects came the need to pitch the base sound effect randomly when needed.  Therefore, we did two things:
      • Figured out how to take Game Maker Studio’s pitch functions and use them with industry terms, such as octaves, semitones and cents.
      • Added a string definition (for easier reading, not optimally performance-wise) to indicate how we want to randomize these (e.g. snd_SlashBalanced: "semitone:-1..1;1" would take the balanced sound effect and give us three pitches relative to the base, between -1 semitone and 1 semitone (0 would be no change, so really giving us two “new” pitches)).
  • Transitions of Regions
    • As an example, the transitions from the green grasslands to the lower mountains was a pretty hard line.  Now we’ve added some softer / smoother transitions into regions.  This will be expanded on once all of the art for backgrounds has been finalized, but that will be a long ways out.  Below are a couple of screenshots:
      Transition Example
      Transition Example

      Transition Example
      Transition Example
  • Updated Long Grass Tiles
    • We also updated the art for the long grass tiles.  Below are a couple of screenshots:

      Long Grass
      Long Grass
    • When cutting the grass tiles, there was no concept of changing the neighbor tiles to visually look correct.  This was quite the undertaking to understand how auto-tile systems work.  Before we actually understood it, we were hardcoding different values with this cheat-sheet:

      Auto Tile Indexes
      Auto Tile Indexes
    • However, we soon recognized a pattern.  We’ll try to keep this brief and simple, but it does deal with binary, so hold on to your seat!
      • The first tile from the cheatsheet, 255 in binary is 11111111.  This tile has 8 neighbors, because it is a full tile.  Each of the 1 represent a neighbor.  The last tile from the cheatsheet, 0 in binary is 00000000.  This tile has 0 neighbors, because it is an empty tile.  Each of the 0 represent a neighbor.
      • So, for example, if we wanted to represent a tile visually with a left neighbor only, 8 would be that number, and could be represented by 0001000.  Here is a visual:
        000
        1 0
        000
      • So, if we wanted to represent a tile visually, with a left and right neighbor, visually it would look like:
        000
        1 1
        000
        The binary string would be 00011000, which in our normal system would be the number 24.
  • Projectiles Shot Off Cliffs
    • For a while, we’ve had the ability to shoot projectiles / throw objects over cliffs.  However, with the introduction of the z, zPseudo, we were trying to figure out how the shadow should be drawn relative to going over a cliff.  We spent a couple of weeks playing with different approaches:
      • When the object landed, continue bouncing / falling off the cliff
      • Increasing the z when moving over a cliff top and then decreasing by the same amount after moving past another cliff top of the same height
    • We ended up settling on keeping everything the same, as the fake 3/4‘s perspective didn’t seem to make it feel off in anyway.  However, we added a new construct that when a projectile lands within the cliff, if something broke from the projectile (i.e. rock breaks and a treasure came out) that this treasure will fall to the bottom of the cliff.  That way, these types of things won’t get stuck in the cliffs for the player to never be able to collect.

A Hodgepodge of Updates

We’ve been trying to get away from the “Art Updates Part n” titles to be a bit more descriptive with our recent posts.  But this update could very well be a continuation of those parts with the hodgepodge of art and functionality that were updated the last couple of months.  They say the best way to explain is to show, not tell.  So without further ado, let’s show and not tell:

Updated Weapon Icons

When picking up a weapon, or seeing it in our inventory, a different graphic is represented than the graphic used for combat.  We’ve updated all the icons at 4 different resolutions: the smallest for the HUD, 1x for normal gameplay, 2x for the inventory and 3x for seeing the item in descriptive dialog page.  Our artist, Tony, had to draw out each of these essentially four times — it was a blast 😉  Below are a few of these icons at the highest resolution:

Sword Icon
Sword Icon
Spear Icon
Spear Icon
Axe Icon
Axe Icon
Fire Rod Icon
Fire Rod Icon
Long Bow Icon
Long Bow Icon
White Shield Icon
White Shield Icon
Ambush Dropping Icon
Ambush Dropping Icon
Weapon Shard Icon
Weapon Shard Icon
Extra Heart Icon
Extra Heart Icon
Violet Leaf Icon
Violet Leaf Icon

Docks and Bridges

Below are a couple of screenshots in the northern mountains with the newly updated bridge and docks graphics:

New Bridge
New Bridge
New Docks
New Docks

Bow and Arrow Animations

As simple as the bow an arrow animations look, there were quite a bit of updates from a functionality standpoint that we had do in order to pull all of this off in game.  In the Other Notable Updates section, we’ll go into more detail about all of that.  Below are a few animations for the hero and Orc:

Hero Bow Animation
Hero Bow Animation
Hero Walk With Bow Animation
Hero Walk With Bow Animation
Hero Run with Bow Animation
Hero Run with Bow Animation
Orc Bow Animation
Orc Bow Animation
Orc Walk with Bow Animation
Orc Walk with Bow Animation
Orc Run with Bow Animation
Orc Run with Bow Animation

Hero Stun and Death Animations

We also decided it was finally time to have our hero get hurt and die:

Hero Stun Right
Hero Stun Right
Hero Stun Up
Hero Stun Up
Hero Death
Hero Death

Pickup / Throw / Setback Down

We also added all the animations associated with picking up and throwing objects.  Similar to the bow and arrow, we also had to add walking animations for holding and running.  Below are a few updated animations:

Hero Pickup Throw Animation
Hero Pickup Throw Animation
Hero Pickup Setdown Animation
Hero Pickup Setdown Animation
Hero Walk Hold Animation
Hero Walk Hold Animation
Hero Hold Run Animation
Hero Hold Run Animation

Other Notable Updates

Last time we introduced a new system called Renderable, which in summary, gives us a better way of handling shadows and the z axis.  There’s been a lot of work behind-the-scenes on improving on / expanding this system further.  For example, we have added on to this system by giving objects a bouncing property.  There are a few updates that are not quite yet done, but it’s progressing well nonetheless.

We mentioned earlier in this post that there were updates we had to make for the bow to work properly.  For as long as the bow-and-arrow mechanic have been in the game, walking / running while holding the bow has always been a still image.  This worked fine for prototyping purposes.  Once the pull-back the bow string animation is complete, the object goes into a hold state of the bow until the arrow is released.  With our current system we can be in a stand, walking or running state while holding the bow, and the new animations work great!

However there was one problem with the current system — the pull-back of the bow string animation.  This animation is about a second long, which without moving the feet, made our hero seem like he was floating.  We did not want to remove the mechanic of being able to walk / run while equipping (i.e. the bow string animation), and we did not want to add a pull-back animation for each different combinations of walking / running directions we could do.  Therefore, we got creative with the animation and decided to shuffle the feet when doing the pull-back of the bow string animation.  This seemed to solve the problem for the most part, and works well with transitioning into the walk / run while holding bow animations!

The rest of the updates, including the updates to the bow animations, are pretty simple and can be summarized in a quick bulleted list:

  • We updated our soldier enemies to account for the new bow animations.  Mostly, we wanted to make sure that once a soldier enemy had committed to telegraphing which direction they were facing to shoot, that they couldn’t change directions until the animation had played out completely.
  • Speaking of telegraphing animations, we finally got around to updating the soldier enemy to telegraph its attacks.  This essentially amounts to pausing on a specific wind up frame for a given amount of time (easier enemies pause longer than harder enemies).
  • Last time we also mentioned how we allow the player to merge anywhere instead of going back to the town to merge weapons.  This new feature is great, but was definitely becoming a tedious chore after a while.  Therefore, by pressing a button in the inventory screen, we can simply “auto merge” our weapons to automatically rank them up!
  • Finally, we’ve had our hero be able to pickup and throw things for a while.  However, we also needed the ability to set objects back down without them breaking (so we can do the infamous set an object on a switch puzzle).  We updated the holdable system so that they can be setback down (as well as concurrently getting the animations to make this look right at the same time!).

The Future of Violet

It’s been a while since we shared our plans about Violet from a logistical front.  Obviously we’ve been making a lot of progress with art and functionality, but there’s been a lingering question: “when are we going to do Kickstarter”?  We haven’t revealed the when for a while in case what we shared was premature and then to go back with our tail between our legs.  However, in 2019 we wrote a post attempting to explain the current plan at that point in time, and we believe we’re long overdue to share an update.

This past year, Tony and I have been trying to shoot for a date of February 2023. Recently though, after realizing just how much art and animations we still need to do to make the demo “the best it can be”, we decided to move that back to an April 2023 window.  This gave me some time to reflect on what all need to actually get done before then.

Meanwhile, the adviser I met with back in 2019 just so happened to reach out to me to see how the game was coming.  It was crazy as I was considering reaching out as well to get some feedback and opinions.  We setup a time to meet and during that week of prep, I had this uneasy feeling about all the work that still needed to be done if attempting to do a Kickstarter by April, 2023.

There’s a long list of improvements, features, lore implementations, demo direction, among other things that need to be done.  If this project was a full time job, this list would be a piece of cake to complete.  However, this game is a project that I do on nights and weekends which makes this deadline seem daunting.  Therefore, I started having an uneasy feeling about the April 2023 deadline. As I was struggling with that uneasy feeling, I kept dreaming of the opportunity where I could do this project full time, as that has been the long term goal.  As the game and its systems continue to grow and become more complex, it gets harder to revisit those systems to fix bugs / make improvements / etc.  And I know that eventually, nights and weekends just won’t cut it.

Nevertheless, the adviser and I had our meeting.  The first half of the meeting was showing the progress of Violet since 2019, which if you have been following along, you’ll know it’s been night and day.  The second half of the meeting was to get some advice and opinions on what to do next on the logistical front.  The main information I was hoping to obtain was three things: “when is a good time to do a Kickstarter”, “what should I prioritize before then” and “what is a reasonable goal number to reach”.

The when to do a Kickstarter for the first question aligned with what I had originally thought:  sometime in the months of February – April.  “So far so good” I thought.  The advice I received for the second question wasn’t as daunting as I thought it would be.  There were several tips and tricks we could do to pull off a April 2023 window.  This had me excited as the fantasy was starting to become a reality.  However, when I had mentioned my goal amount versus the expectation, the actuality set in.

With the uneasy feeling I was already having about trying to meet the April 2023 window, and then the news about how much to money to statistically expect to receive, I unofficially decided to pivot from the April 2023 window.  This was not an easy decision, especially because doing this project full time is something I have been hoping to do for a while now.  However, even though the systems of the game continue to get more complex, I still am able to make progress during nights and weekends — even if it’s not at the pace I always want.

As I have been writing these posts, it’s been awesome to go back to previous posts whenever I feel discouraged to see the progress the game has made. Back in 2019 we wrote a post attempting to explain the current plan at that point in time.  I actually reread this post and this quote still can’t be more true:

…If the game became a “chore” or another “job” at this point in time, I would not have the motivation to fight for this project like I want to.  I do eventually want to make this something I do full time, but not by sacrificing myself mentally in the meantime.

The biggest thing, even now in 2022, is making sure that the game doesn’t become a chore or a job while I have a full time job.  If I knew pushing for a year meant getting to a point where I could do this full time, then I would definitely go for it.  However, pushing to get this game across a finish line to only receive a fraction of the amount I would really need to fund this project full time is not worth it to me.  And as it currently stands, I am able to fund different aspects of the game (art, sound, etc.) out of my own pocket, albeit at a much slower pace.

As I was accepting this decision, Nintendo announced that The Legend of Zelda: Breath of the Wild Sequel had been pushed back to spring 2023.  If the signs weren’t already clear to me to wait on doing a Kickstarter, this was the final confirmation I needed.  Even though Violet would “compete” in a much different way than one of the most anticipated AAA sequels by Nintendo, running a Kickstarter for a game with many similarities would be foolish, let alone, most likely getting absorbed by the hype surrounding Zelda.

So if not 2023, then when?  And if I can continue the fund the game out of my own pocket, why do a Kickstarter at all?  Those are very good questions and I am glad you asked. 😀

I do think it is wise in setting some “target date” as otherwise, iteration of Violet will go on forever.  At some point, we need to show the game to the general public to get some reception and feedback — and what better way to do it than a Kickstarter where we can hopefully get future fans invested in the project.  After all, we’re not just making this game for ourselves.  And we are not Nintendo, where we can drop a trailer, and that alone can drive buzz and hype for months.  Therefore, we are now targeting a date of February 2024.

Meanwhile, another two years “cooking in the oven” is a lot of time to make progress on the development front, as well as the art and sound.  With more of the game complete and polished, we’ll hopefully be in a better spot where that fractional amount can be doubled or maybe even tripled.  To summarize, here’s something from the same post in 2019:

…I think it is wise to continue being patient, and slowly building out concepts and features at a pace that is fun and rewarding, rather than something that feels like “work”.

Orc Updates

These past couple months we’ve been focusing on updating one of our soldier enemies, the Orc. The Orc is one of the more simpler soldier enemies in that it’s weaker, generally slower and its reaction time lacks.  It’s been fun seeing this guy come to life and we can’t wait to share some of the animations here:

Orc Idle
Orc Idle
Orc Walk
Orc Walk
Orc Walk Backwards
Orc Walk Backwards
Orc Stun
Orc Stun
Orc Run
Orc Run
Orc Death
Orc Death
Orc Heavy Swing
Orc Heavy Swing
Orc Balanced Swing
Orc Balanced Swing
Orc Agile Thrust
Orc Agile Thrust

Other Notable Updates

Renderable

In our previous post, we did not have a notable updates section, mainly because we were still in the middle of updating two major systems.  Both of these systems have to do with depth, or, where the object is drawn on the screen.  The default depth system in Game Maker Studio has served us well, but with the ever increasing complexity of the layer depth system, draw order gets blurry when dealing with transitions between on layer depth and another.  This link explains some of the same issues we’ve been running into.

We started down the road of implementing a z-tilt shader, similar to how this blog implements it.  However, we found a bug with rendering tiles.  As we continue to wait for the resolution, we simply decided to update the default depth system, as well as update different places where layer depth was being triggered.  For example, previously we were triggering the layer depth at the two openings of a bridge over water.  We decided to make all land and bridges over water layerDepth1 and all water and inside caves layerDepth0.

When we jump off a cliff and into water, we trigger layerDepth1 to layerDepth0 and simply multiply the depth by a negative room_height.  When entering a cave, there is a fade transition that sort of masks (or hides) the fact that there is a draw depth problem.  This solved most of the draw depth problems for now — though it won’t solve issues like stair transitions from a lower area to an upper area.  We still plan on using z-tilt in some way as that is really the only to solve for properly drawing objects with this complexity properly.

In the same vein, we’ve also been updating our drawing system (the pipeline to be more consistent) and shadow system, as well as adding a z axis.  z gets complicated when we’re in a 2D space.  What is z?  Where should it be drawn?  Where is the collision with respect to the visuals?  All of these things are very hard to get right, so most of the time, we don’t use z, but something we made up called zPseudo.

zPseudo keeps the current visuals and the collision at its normal y position.  Therefore, the purpose of zPseudo is to render the shadow zPseudo units down from the y position.  z on the other hand renders the shadow at the current y position and renders the image of the object z units up.  In 95% of our use cases, we found that using zPseudo was a better system for visuals and collisions.  For example, a bat that is flying uses zPseudo casting a shadow 32 pixels from y.  If the bat collides with a sword, it made more sense for the sword’s visual to overlap the bat’s visual, so that the bat would get hit.  The 2.5D perspective is very odd, but our brains believe it to be true!

This system was complicated to come up with, but it’s proven to be very useful in making all of the game use shadows, heights, z positioning consistently across the board.  For example, each projectile (arrow, fireball, ice particle, etc.) all implemented their own way of shadows.  Now they all inherited from the parent object, Renderable!  We were also able to therefore implement a consistent gravity function, giving objects a sense of falling or being dropped.  The possibilities are now endless of what we can do with this system!

Ranking System

That last section was complicated, so thanks for sticking through our ramblings!  The rest is straight forward and more fun “game” things!

Our weapon ranking system has been revamped!  We used to use letters EA, S, where E was low quality and A, S was best quality.  We now added the letter F as worst quality, and added +/- rankings for each letter grade as well (except for F and S)!  The reason for this was we found that merging weapons that were not the same letter grade was cumbersome.  Therefore, we added the ability to merge any letter grade.  We still have to merge the same weapon type though.

We also added the ability to merge anywhere instead of going back to the town to merge weapons.  We found merging anywhere to be more rewarding help the player continue to adventure.  With that said, we’ve had to update our merge system quite a bit.  Even though we’ve made some updates to our merge system, we still find it tedious after a while to merge many weapons and will probably implement some sort of “auto merge” system.

Finally, we didn’t want to leave our town’s blacksmith without a job, so we added the ability for our blacksmith to take weapon shards and expand inventory!  Weapon shards can be found when a weapon deranks.  This helps the player to not feel like using a good weapon is a bad thing because they’ll be able to use those shards to make further progress within the game!  Plus the higher the ranked weapon is, the more shards that will drop from a degraded weapon.  Plus, we can easily remerge our lower-ranked weapon back up!

Everything Else

  • In adding our Orc, we’ve updated our soldier enemy a bit to be smarter!  One thing we added was for the enemy to move out of the way of moving projectiles.  Smarter enemies are better at doing this than others.  We still have a lot of rework to do with the new animation updates to make the soldier enemy a bit more seamless.
  • We’ve merged the way our tile layer system handles the tiles so that each layer has three sub layers: the base, overlay and animated overlay.  For example, what we were once calling decor tiles is now in the animated overlay.  Paths on the grass tile would be in the overlay sub layer.  And of course, the grass tile would be in the base sub layer.
  • We noticed an issue when swinging our balanced weapons up that sometimes smaller enemies would not get hit if they were between the balanced weapon’s visual and the hero.  We fixed this so that the balanced weapon has a bit more collision below its normal visual.
  • We updated the targeting system to be a bit more accurate.  Plus, using the R-Stick to move between enemies should be a bit more intuitive and better to use.  Also, instead of using the “Ocarina of Time” triangles, we’ve resorted to a more simpler “triangle over the targets’ head”.
  • Finally, we added a system called “animation position” that let’s us move an object to a position based on the animation frame an instance is on.  For example, our Ambush’s protection can now more accurately be position on the Ambush’s head for each frame of the animation.