
tannertan36
Misplaced Lens Cap
styofa doing anything
"I'm Dorothy Gale from Kansas"

Kiana Khansmith
2025 on Tumblr: Trends That Defined the Year

❣ Chile in a Photography ❣
I'd rather be in outer space 🛸
Cosmic Funnies
Game of Thrones Daily
d e v o n
almost home
RMH

#extradirty

Andulka
Cosimo Galluzzi
dirt enthusiast
Sade Olutola

Origami Around

No title available

seen from Malaysia
seen from Chile
seen from United States

seen from United States

seen from Singapore

seen from United States

seen from United States

seen from Brazil
seen from United Kingdom
seen from Saudi Arabia

seen from United States

seen from Netherlands
seen from Brazil
seen from United States
seen from Peru
seen from United States
seen from United Kingdom

seen from United States
seen from United States
seen from United States
@mindshaftgames
Demons with Shotguns leaves Early Access April 25!
In an earlier update, I talked about the End of Times boss battle, showing off the current design and implementation. As I continued to develop it, I quickly came to realize the boss battle was falling into all of the bad boss battle tropes. Things like inverting spatial control by having the boss attack from behind, suddenly introducing all new game rules and being overly bullet spongy. Mainly though, the boss battle wasn't testing all of the skills and mechanics the player spent all this time learning and mastering. That's why I decided to scrap the original idea completely and come up with something new. The boss battle is now being designed to almost feel like a bot Versus match. The boss will attack, and most importantly defend itself, in the same ways that the player can. This is forcing the player to really master his shotgun & melee attacks, shield blocking and quick movement to avoid attacks. Here is some new concept art for the new boss. The Devil takes many forms!
And here's a sneak peak of what he looks like in-game.
All new boss artwork credit goes to Mike Stanton.
Demons with...Swords?
Time to give a development check-in, yeah? Work for the epic End of Times boss battle is fully underway!
This is just a glimpse into what's in store for the boss battle, but as you can see it involves a giant bad guy with big swords. We've actually decided to animate the boss a bit differently then all the other sprites in the game, which were done via frame animation (think a flipbook of still images played back really fast to give the illusion of movement). For the boss, we decided to do skeleton animation, using the excellent Spine software. Given the large size of the boss, this allows us to create new animations without having to pixel them by hand, which is extremely labor intensive. Instead, we can rig together all of the limbs of the boss and create animations by moving each limb (connected together via a skeleton of bones), frame by frame. Here's an attack animation being created in Spine.
The boss battle is going to take some time to develop and get something worthy of being pushed out to everyone, so bare with us as we go quiet for a few weeks! As always, please let us know of any bugs you may come across in the forums and we'll prioritize them. Same goes for any type of feedback on the current build.
Demons with Shotguns Trailer #3
Crushed & spike impalement. Ouch.
Jiffier gifs. share your gifs with the world on the fastest gif hosting platform. Yes to playback controls, No to size limits!
Finding Purpose in War
With the foundation of End of Times fully in place, I can start working on improving the enemy AI. To start, I'll be working on improving the pathfinding on enemies so that they can travel to a particular spot in a arena, rather then roam randomly. Currently, all enemy AI have a simple "bump and switch" algorithm defining how they move. What this means is, an enemy will roam in a particular direction until they detect a collision, or a ledge, in which case they'll simply turn around. While this is serviceable, and many arena shooters use this type of enemy AI, I'd like the player to face off against smarter, more worthy adversaries! To allow enemies to traverse a arena more fully (no more be containing to a single area/platform), I started to build a network of nodes throughout the arena. These nodes will tell enemies where they can go, and they even serve as jump pads, telling an enemy that they can jump and how high they need to jump.
Ignore the red numbers, those are enemy spawn points and not related to pathfinding. Instead we're interested in the yellow dots and lines connecting them. Currently, the lines don't do serve any purpose (they will soon, more on that later!). At this iteration, whenever an enemy collides with one of the yellow dots (our Nodes), it will tell the enemy three things, the speed at which they can continue to travel at (each node has a left speed and right speed value), and a value to let the enemy know they should jump, and by how much can they jump. At this point, the enemy doesn't have any goals or desires to travel to any particular node in the arena, they are still roaming somewhat aimlessly, but now the enemy can just jump around to other platforms and be steered in a particular direction. This is good a start! But we can do better. What if we want the enemy to travel to a particular node or object within the arena, say hunt our player? One way of achieving that is by simply telling the enemy which direction the goal is relative to themselves (is the object to my left, or right?). Thankfully, we can easily calculate that using vector dot product formula. Depending on the angle of the dot product, we'll know if the object is the left, or right, telling the enemy AI which direction to travel in.
In the GIF above, the enemy starts to travel towards the direction of the player once he has spawned, only to be treated to a buck shot. Poor Nomed. He had it coming though. All done! We have our enemy hunting a particular goal in a arena, using nodes to steer them in the right direction. Well, not quite. There's still two things we need to consider at this point. What if there are multiple objects the enemy could care about? How do we select which one is most desirable? And second, right now, there's nothing telling the enemy which path is best to travel. There's still no real pathfinding going on. Let's address the first issue, determining which object is most desirable to head towards. What if we could have our nodes rate their current desirability, based on several variables such as is if the player or a particular game object near by, and allow enemies select the most desirable node to travel to?
And that's exactly what I did! In the above GIF, the large yellow circles for each node is the area in which a node will check to see if there is any particular object they care about is near by (right now, just the player). The number within the circles is the nodes current desirability rating. Each nodes as a default desirability of 100. Once a player comes within range of the node, it will add 300 to it, for a total desirability rating of 400. When the player leaves the node area, it'll go back to 100. The enemy can now search through all the nodes and determine which one has the highest desirability rating, and thus is the most desirable to travel to. This lays a nice foundation to give enemies a system to more smartly traverse the arena and achieve a particular goal. We still haven't addressed our pathfinding requirement. At this point, enemies don't follow a particular path to a node, per say. They are still just moving left or right until a node tell them to jump (actually, they'll only jump if their current target node is above them), or their target node changes desirability and heads in that general direction. This does work well, but there are some edge cases where this breaks and a more robust system is need (in the GIF above, if the most desirable node is in the platforms above only reached by portals, the enemy doesn't know how to get there properly yet). More astute readers are probably screaming "A*! A*! A*!". That's probably going to be the next step in the system. So this is the current state of the enemy AI in Demons with Shotguns. The short term goal is to have smarter, more worthy enemies to face off against. The long term goal, possibly introducing bots into the Versus game modes. We'll see how things develop!
Build 0.2.5
This build contains significant changes to the End of Times enemy wave controller logic. Originally the wave controller was defined by hand designed wave definition files, but now the controller is completely randomized, with specific logic to make the randomization “smart”. This system will continually be tuned and balanced.
This build also introduce two more End of Times arenas, with arena unlocking progression; note the final arena (planned boss battle) is not yet complete and thus not unlockable at this point.
Summary of changes (EoT = End of Times, Vs = Versus, G = General):
EoT: Hell and Church End of Time arenas
EoT: Arena unlocking; Watertower Terror now needs to be unlocked, along with the other arenas
EoT: Save/Load system for arena unlocking progression, including Steam Cloud Save
EoT: Randomized enemy wave controller
EoT: Improved Nomed attack sound effects
EoT: Improved Hellhound AI
EoT: Number of player lives in End of Times is displayed above each player head
Vs: Player respawn time now customizable via the Match Settings menu; for design reasons 2 seconds is the lowest possible setting
EoT/Vs: Adjusted Sands of Time tarot card; time doesn’t slow down as much as previously
EoT/Vs: Adjusted Possessed tarot card; doesn’t auto fire, but instead just increases fire rate
EoT/Vs: Bug fix with holy water grenades colliding with lantern/lamp wires
EoT/Vs: Bug fix with cages, lanterns, lamps and hanging rocks to break with collision with any layer
G: Other miscellaneous bug fixes and improvements
G: Redesigned menu system, with improved usability; can now easily hold down button to scroll through multiple selections
Angel by www.milanjaram.com
Improved gibs on explosions :)
Made the backgrounds darker in the Hell arenas to increase foreground readability.
I NEEDS A HUG! HUG ME!! *poof*
Hellhound pounce.
Enemy Wave Controller
Demons with Shotguns features a 1 - 2 player local co-op game mode called End of Times, where players must fend off wave after wave of the Nephilim army in a single arena space. Demons with Shotguns is a competitive local multiplayer game first and foremost, but I always wanted to include some form of singleplayer so the game could be played alone when you didn’t have any friends around to battle it out for each others souls.
I want to share how I’ve setup the wave and enemy systems. The system makes it very easy to define waves and add new enemy types, isolating specific enemy behavior to their finite state machine states.
Before we dive in, let’s go over the game view. I started developing Demons with Shotguns in Unity before Unity announced their 2D API, so I’m using 2D Toolkit instead. 2D Toolkit has a built-in tile map editor that I use to build all of the game’s arenas. The End of Times game mode is isolated to a single Unity scene, with each different arena spaced out as a different tile map under a root StrangeIoC context gameobject.
The name of the root object will be used to select which wave definition file we parse (more on that later).
Each arena also has spawn points placed, both for players and enemies. A view script handles finding these spawn points and storing their reference in an array, and later passing that array to the wave controller.
The game defines which enemies to spawn in a wave, and how it controls the progression of waves. Originally, I assumed that having a system that would randomly select which enemy type to spawn at a random spawn point in the arena would suffice, but I quickly found out that to ensure the best experience, I really needed a way to define which specific enemies would spawn at which specific spawn point. It allows me to control the battle experience much more finely, ensuring a fun and diverse experience.
Currently, wave definitions are defined in simple text files. Here is an actual example for one of the Watertower Terror wave definitions.
Each line represents an entire wave of enemies. Each cell, delimited by the pipe character, represents a cycle in the current wave, defining the enemy type and its spawn location. So looking at the first line, we see that the game starts by spawning a Nomed at spawn location 0. The pipe delimiter indicates a single cycle, so the wave controller should wait till the current Nomed is killed before spawning the next Nomed at spawn location 1, and so forth. Once all enemies in wave 1 (line 1) are killed, the controller moves on to the next line, which has two Nomed enemies spawning at the same time.
I’ll forego describing how the game parses the wave definition file as it’s not particularly interesting. Just know that based on the properties of the GameSettings object, which is created and populated in the game’s main menu system, we determine the file path of the wave definition in the game’s resource folder to parse (all done by a expected convention). Since I want to include multiple wave definitions for each arena to add more variety, I will later add the ability to randomly choose a definition file to parse, but still specific for the arena in play.
Now that we know how waves are defined, let’s look at how the controller actually operates. Once the game mode startup sequence has finished, an EnemyWaveController class will getting setup, being passed an EnemyWaveModel that’s a simple POCO that wraps up the data necessary for running a wave; mainly a List of enemy spawn points and a List of Lists of Lists representing the parsed wave definition file, among other properties.
Here’s an abbreviated version of the controller class.
Our Update method runs three nested for loops (don’t panic, it’s not a performance bottleneck). Thinking back to the wave definition file, the outer for loop represents each line in the file. The first inner for loop represents a collection of enemy spawns, or the pipe delimited cells in a line, and the second inner for loop represents an individual enemy spawn.
These for loops may look ugly, but it’s very simple so let’s step through. The outer for loop will kick off, dispatch some UI feedback animations, yield for 2 seconds, and then enter another for loop to start spawning enemies in an individual cell. Once we have our EnemyType enum, we index into the spawnPoints array to determine the spawn point based on the index defined in the wave definitions file. This part requires some upfront knowledge and care, as you can easily get a IndexOutOfRangeException if the definitions file defines an index out of bounds, but we catch it and set a random spawn point if that were to ever happen.
With our EnemyType and spawnPoint, we dispatch a request to the enemy factory to actually spawn and setup the enemy. Once this has been completed for each enemy in the cell, we enter a while loop to yield every frame and check a GameStateModel property to determine if each enemy has been killed. If so, we move on to the next cell, and then eventually to the next line. This all repeats until we’ve reached the end of the definitions, and thus the player has defeated all the waves! In which, we dispatch a end game event.
So how are enemies setup and created in the enemy factory? I’m not telling till next post! Part 2 coming soon.
Who gave a Nomed a rocket launcher?! Who thought that was a good idea?!?!