The Trick I Used to Make Combat Fun! | Devlog

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Oh no. I accidentally created  a Newton’s Cradle of Skellies.  Howdy! And welcome to Game Endeavor.  Where I make devlogs with an emphasis   on game design and technique. I’m developing an open world RPG   where you’ll meet lovable characters, explore  dark and treacherous dungeons, and build a base   to stash your precious cheese. One of the more  difficult tasks that I’ve ever come across as   a developer is how to handle enemy movement in a  way that’s convincing and engaging for the player.  This is especially difficult because there are a  lot of factors to consider such as what direction   they should move towards to reach their goal.  What entities are nearby so they don’t clump   up together into a hyperdense singuskellety.  The nearby environment and everything else   around them, and even once they have figured  out how they should move, they need to do so   smoothly so that they don’t jitter around like  me after a long night of binge coding and coffee.  Even though combat isn’t the primary focus  of my game, not nearly as much as exploration   and the roleplaying. I still want it to  be enjoyable, because it is what builds   tension and keeps the player engaged as they  explore the world and uncovers its secrets.  If you look into AI movement, then one of  the first things you may encounter is what’s   known as boids and steering behaviors.  This is not what I’m using to be clear,   but it is where I started and is what helped me to  develop the technique that I am currently using.  Steering behaviors are where you combine  simple actions such as move to this point,   keep away from these points, and move in  the same direction as these other points.   On their own these behaviors are very simple and  unimpressive. But when combined and tweaked in   specific ways, they create something that I was  quite stunned by when I first encountered them.  But after implementing this some time ago in a  prototype for another game, I quickly noticed   some major flaws with the system. The biggest  glaring one being how opposing vectors can cancel   each other out to cause pretty silly situations  where the AI needs to run away from the player,   but there’s a wall immediately opposite to  them. So they just stand there completely   dumbfounded by the existence of this wall as  they wait for their slowly impending doom.  Ideally you would want them to realize that  they have other options available to them,   such as stepping ever so slightly to the side  and continuing along that path for a bit.   But since there’s only one vector that  has complete control over how they move,   they just sit there barely moving if at all.  I searched for a while about how I could  improve this, or alternatives to AI movement   and found a context based steering behavior  that inspired what I am currently using.   This is very similar to the behavior that I  mentioned before, except it keeps a record of how   desirable different directions are and chooses the  preferred direction that it can actually perform.  For example, say I set down a carrot for  Truffles to snack upon, odds are he’s going to   move directly towards the carrot. That would be  the obvious choice. But hold on there Truffles,   not so fast. He could, in theory, step off to the  side for a bit, make a big half circle around the   carrot, and then go in for the snack. It would  be rather silly, yes. But it’s still an option.  So to help truffles evaluate the different  directions that he could take, I’m storing   his options as weights that he can check and  pick the most desirable path in the event that   some of his options may be limited. To help me  visualize these weights as I’m developing the   movement systems, and help you visualize them  while binging these devlogs and subliminally   clicking little blue thumbs, I have created a  gizmo that can draw what the AI is thinking.  Each line represents a direction that  they are considering. Green lines showing   a desire to move towards that direction  with longer lines being most desirable,   and red lines meaning that they have  absolutely no desire to move in that direction.  So as you can see, when one direction  becomes obstructed then the AI will pick   the next best option and move in that direction  instead. In order for the AI to determine this,   I need to tell it how likely a direction is to  produce a desired result. I’m using a dot product   here between the direction being considered and a  vector that the entity would like to move towards.  For those unaware, dot product is a very useful  thing that will return the cosine value of   the angle between two normalized vectors. This  value will be 1 in the direction of the normal,   -1 in the opposite direction,  and 0 perpendicular to it.   When normalized between 0 and 1, you get a  scale of how desirable that direction is.   The AI is using this to decide  which direction it should move.  This is great for moving towards a specific  location. I can simply take the highest   unobstructed weight and move in that direction.  But the true power of this system comes when you   start shaping the weights and combining them  to perform even more interesting behaviors.  Skellies making a beeline for you is one way to  prototype a simple combat system. It is what I   have used so far and it served its purpose as a  placeholder, but it’s not nearly as engaging as it   could be. A much more interesting behavior would  be for the skellies to move in and out of combat,   strafe around their target, all  while keeping a safe distance.  I have one set of weights that will move  towards their target as normal, but as they   get closer to their target, the value of these  weights are lessened so that other behaviors   can take over. So I’m weighting the weights. Once they are within range to start strafing   around the character, I apply a shaping function  to the dot product that favors sideways movement   instead of forward and backwards. This causes them  to start circling around their target. Except,   oh no… I accidentally created a Newton’s  cradle of skellies. I had to offset their   following distance a bit otherwise they  start making perfect circles around their   target and bouncing off of each other. A big issue that I’ve had with this system   though is tweaking the movement to eliminate a  lot of jitteriness that I’ve been noticing due   to entities rapidly changing their direction  back and forth. This is because I was having   them move directly away from any nearby  entities and so they would get caught up   in this tug-o-war of pushing each other in  an attempt to get to their desired target.  I fixed this by also applying a shaping  function to their separation logic   so that instead of trying to move  directly away from the nearest enemy,   they would prefer to do so at a bit of an angle. When you combine this smarter form of movement   with the overall tweaks to the skelly’s combat  state machine, you get a very fun enemy to fight   that even I spend my free time spawning a few  in for a quick session. And when I had a tester   play this, they spent over an hour just fighting  a handful of skellies and sprouts over and over.  Combat wasn’t the only enemy behavior to receive a  massive improvement though. One of the main design   pillars for my game is immersion, having things  feel natural and convincing. And something I’ve   been wanting to improve for a while now is  the wandering logic for my enemies. Before   now it has been a placeholder just so they’re not  standing in one place when I record these devlogs.  The logic was that they would pick a random point  somewhere around their spawnpoint and move towards   it. If they were near the point or it became  obstructed within a short distance then they would   pick another point and start moving towards it. This is decent enough but it feels very erratic   and unnatural. The AI changes direction  sporadically and to me it feels a little off.   Rather than picking a random point to  move towards, I would rather have them   meander about. Gradually changing their  direction, but remaining near their spawn   point so that they don’t wander off too far. To have them wander about, I’m having them   move in a direction, but over time this direction  will gradually sway left and right which causes   the entity to start changing direction. I’m using  OpenSimplex noise here to adjust the direction.  There are a few benefits to using it here. Namely  that the randomization it produces is smooth which   gives the wandering a more natural feel to it.  But more importantly the values of OpenSimplex   noise tend to be more heavily weighted towards 0,  which means that if done right the entity isn’t   going to spend too much time changing direction.  Instead it will move straight for periods of time,   and then every so often it’ll start changing its  direction but then start pulling back towards 0,   which causes it to again move mostly straight. To keep them near their spawn point,   I’m weighing their wandering direction back  towards their spawn point whenever they start   getting too far away from it. This causes them  to gradually start turning around until they’re   no longer moving away from the spawn point. To keep this looking smooth and natural,   this isn’t a hard transition though. The weighting  starts to take effect at a pretty short distance   from their spawn point, currently at about  a 2 tile radius. But it’s weighted based on   how far they are from the spawn point, so  it’s much less effective until they start   getting further and further away. But since  it’s smoothed out over that distance, it can   be difficult to tell where that point is, so to  me it feels much more natural and convincing.  After I added these movement tweaks and ai  improvements, I started experimenting with   a faction system for NPC targeting, I ended up  making it so that enemies could target each other,   which surprisingly enough led to this interesting  battle royale behavior with the enemies. I didn’t   expect this to look nearly as amazing  as it did with no additional tweaking,   but this was an aha moment for me. If I can  flip a switch and make NPCs fight each other,   and have it look this amazing. Then I think I’m  going to lean a whole lot more into the pet taming   and raising system that I have planned next. If you want to join me as I work on this,   then I’ve been streaming development nearly  every day on my Discord, there’s a link in the   description to join our community. It has been  a fantastic way to interact with everyone as   we do everything from adding in new mechanics,  drawing art, or just playing games together.   We also got our first fanart of the spirit  skelly which is absolutely adorable, as well   as the two new NPCs that we designed during  the Tuesday streams. It’s always a treat when   sco_otr draws along with me during these. Thanks  for watching, and I’ll see you in the next one!
Info
Channel: Game Endeavor
Views: 1,650,622
Rating: undefined out of 5
Keywords: Game Endeavor, GameEndeavor, Godot, Godot Engine, Godot Game Engine, 2D Game, Game Creation, gamedev, Indie, Indie Development, Programming, Scripting, dream game, developing a game, devlog, development log, indie dev, pixel art, rpg, action rpg, adventure rpg, godot game engine, godot engine, godot, indie game devlog, indie devlog, game devlog, game development, 2d rpg devlog, rpg games, indie games, 2d game devlog, game dev log godot, devlog godot
Id: 6BrZryMz-ac
Channel Id: undefined
Length: 8min 12sec (492 seconds)
Published: Thu Dec 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.