Project Good Robot 12: Feedback Channels

By Shamus
on Sep 11, 2013
Filed under:
Good Robot

Games are a young medium, and we’re still inventing (or appropriating) nomenclature for it. Ludonarrative Dissonance, Kinesthetics, skinner box, gamification, consolification, boss fight, quicktime event, RPG, difficulty curve, level scaling, HOTs and DOTs, raid, crowd control, pay-to-win, force feedback. Twenty years ago these terms either didn’t exist, or they meant something else to the average person. Some of these terms came from the audience, and some of them came from game designers, but they all arose out of a need to talk about a thing that didn’t have a name yet.

One concept I’ve needed a word for is the way games use multiple audio / visual cues to let you know that a thing happened. The term I’ve settled into was “feedback channels”. But lots of people have run into this concept long before I showed up, and they already had their own terms. These two guys call it “juice” or making a game “juicy”:


Link (YouTube)

Actually, “Feedback Channels” and “Juice” might not be the exact same concept. I think of it in terms of making specific events in the game have as many possible routes of player feedback as possible, while these guys are more talking about making the game as a whole have more stimulation. But it’s very nearly the same idea, and I’m sure there are a hundred other developers with their own name for the concept.

An example:

gr12_borderlands2.jpg

Let’s say you’re playing some kind of shootin’ game of the first-person variety. You pull the trigger to make the gun do what it does. How many different ways does the game let you know what happened?

  1. Boom! The gun makes a gunshot sound.
  2. The player’s view is kicked slightly upward to simulate recoil.
  3. The weapon itself jerks backwards/upwards to further sell the notion of recoil.
  4. Perhaps the mechanism of the gun moves somehow. The barrel spins, the character’s hands pump the shotgun, a bolt slides, etc. Some sort of animation to show that this is a machine with moving parts.
  5. The spent round or shell casing is ejected from the firearm.
  6. There’s a muzzle flash / puff of particle smoke from the barrel.
  7. If the bullet hits a flat surface, then the game slaps a bullet decal (a picture of a bullet hole) onto it.
  8. The struck object will give off a puff of particles depending on what it’s made of: Concrete dust, splinters, blood, etc.
  9. If the bullet hits a physics object, the object will be knocked around by the force of the impact. It might shatter entirely.
  10. If the bullet hits an enemy, they will usually jerk backwards, flinch, etc.
  11. There’s a sound from whatever was hit: Shattering sound, a metal ping, cry of pain, etc.
  12. The bullet impact makes a sound, although it’s usually lost in the roar of the gunshot.

The game has about a dozen or so different channels it uses to convey the action. And keep in mind we’re mostly just talking about cosmetic stuff. This is in contrast to the mechanical stuff like your ammo count going down, the enemy hitpoints dropping, your aiming reticle expanding as you lose accuracy, etc. (The view kick is an example of an effect that falls into both categories.) You could remove all of these effects aside from the view kick and the game would play exactly the same. It would be mechanically identical, but it would feel incredibly numb, muted, or distant. When people say the guns in a game feel “weak”, I suspect they’re often not talking about mechanical stopping power but about the lack of key feedback channels.

Now think about how many other actions there are and all the feedback channels we have for them. How many cosmetic ways does a game have to let you know you’ve been shot? That an explosion happened nearby? That you’ve hit the ground after falling or jumping? That you’re running?

One of the things I wanted to mess around with in this project was coming up with as many feedback channels as I could.

Note that the game runs at 60fps and this animation runs at 10. A lot is lost in the transition.

This is an interesting exercise. It’s also pretty rewarding from a code standpoint. Adding cosmetic systems is easy because they don’t have a lot of interplay. I can make the game rewarding and visually interesting by adding effects to the scene without worrying that I’m going to break the AI, mess up the controls, or unbalance the game.

When I kill a robot I’ve got:

  1. It’s hard to see in the animation because the bullets I’m using are practically particle clouds themselves, but when you kill a robot a cluster of sparks fly out the back of the robot as if you were blowing its robo-brains out.
  2. The lights on the robot go out, turning it into a pure black silhouette.
  3. The robot falls.
  4. When it hits the ground it breaks into a cluster of debris particles. (Which also doesn’t show up in the animation above. Did I break that without noticing, or is it just lost in this low-framerate animation?)
  5. The robot might have a bit of spin on it, like a billiard ball. If you’re to the left of the robot and your shots grazed the top of its head then it will spin away from you. (Clockwise.) If you hit its base then it will tumble counter-clockwise. If you hit it center-mass then it falls straight down with no spin.
  6. While falling, it leaves a trail of black smoke.
  7. It makes some kind of death sound when you kill it, then an exploding sound when it hits the ground.

#5 was interesting to implement. It seemed simple in my head. I mean, I just look at the position of the impact and use it to create spin:

Zonk.

But hang on. Hitting the robot like this should create a clockwise spin. But hitting in the exact same spot from above should produce counter-clockwise spin. That means that… um…

I spend a couple of minutes staring at the screen. This is a simple problem. Or at least, I’m pretty sure it is. I’m willing to bet it’s not more than a couple of lines of code. But I can’t picture it. I know intuitively which way an object should spin based on the point of impact, but I don’t know how to express it. Like, if you asked me to explain why an object spins a particular way I’d result to pointing at the impact in illustrative ways. That doesn’t translate into c++.

Deep breath.

Okay, we’ve got at least two important bits of information. There’s the angle of the impact, and there’s the angle from the point impact to the center of gravity. (Which -in our hilariously primitive little 2D world – is just the center of the robot’s rectangle.)

Ummmm. Wait. It’s just like… You’ve gotta take the angle of… something. And calculate… something else?

I don’t know how to put these pieces of information to use. As a way of visualizing the problem I just take the difference between the two and… what? I guess I’ll just take that number and apply it to the spin of the robot when it dies. Then I’ll shoot a few down and see if that helps me picture the problem.

(Minutes later.)

Oh. That was actually the solution. Take the difference and apply it as spin. It works perfectly.

This is actually kind of disappointing. It’s like that feeling when you’re just screwing around in Portal because you’re stuck and you end up accidentally solving the puzzle. You’re robbed of that delightful “Eureka!” moment.

Ah well. It works.

Enjoyed this post? Please share!


A Hundred!17117 comments. Quick! Add another to see if this message changes!

From the Archives:

  1. Lanthanide says:

    Completely unrelated to Good Robot, but here’s a commercial procedural city generator: http://www.computerworld.com.au/article/525998/tech_behind_man_steel_metropolis_coming_developer_near/

    • ET says:

      Hell yes! Hopefully with this tool, big studios can spend a less on polygons, and more on aesthetic and narrative.

      • Winfield says:

        I doubt it. We’ve already got people so jaded that they gripe when they see SpeedTree on the back of a box because SpeedTree is so “samey.” It’ll take maybe three games using a drop-in procedural city generator before it starts causing game reviewers to ding games that use it and users to bitch about how “samey” games that use the city generator are.

        Then procedural content will catch on and every studio will blow thousands of hours writing their own procedural city engine for each game. This may be how Skynet begins.

  2. Scerro says:

    Ah, that’s where my statics/dynamics class would actually come in handy. Sure, I may be an EE with a focus on image processing/programming, but I guess those classes I took were useful.

    It was pretty obvious to me how to approach the situation. I think. It’s hard to be sure unless you’re in the situation.

    Where exactly ARE you applying the difference vector? At the point of impact? I’m looking at it and as long as you apply a vector to create a moment you’re going to get spin somehow. You could just as easily have gotten the wrong sign and have it spun the other way. So many possibilities! It’s impossible to tell whether you’re doing it “correctly” at least physics-wise.

    • MrGuy says:

      Very true. However, from the point of view of a game, if it looks “correct,” then it’s correct. Humans have certain strong intuitions about physics, much of which is pretty good. People can tell if things look “wrong.”

      There are some things where “game correct” actually means “physics incorrect,” and it’s actually better to get the physics “wrong” because the proper physics doesn’t match people’s intuition about physics. For example, people are not great at intuiting certain 3D angular momentum conservation effects. Trying to model them fully will actually make the game feel wrong.

  3. Piflik says:

    Would #5 not simply be the cross product between the projectile’s velocity and the position of the impact relative to the robot’s center of mass?

    • Abnaxis says:

      That’s what I was thinking too. X1*Y2-X2*Y1 will give you a signed number you could use for spin.

      Now I just need to sit here and think really hard for which one works better, for a physics and a looks standpoint…

      • Zukhramm says:

        I’m not really sure what Shamus means by “applying the difference to the rotation”, but assuming it’s the absolute value it seems that method looses a way to easily determine the direction of the rotation. It gives a decent speed though. The cross product gives both a more correct speed, as well as an easily accessible direction.

      • Peachfuzz says:

        You’re almost there, you just need to change to polar coordinates, say (x1,x2) becomes (rx,qx) [sorry, q should be theta, but I have no idea if you can do Greek letters in these comments] where rx = (x1^2 + x2^2)^2, sin(qx) = x2/rx, cos(qx) = x1/rx, and so on. Running the same calculation you have above, you get x1*y2 – x2*y1 = rx*ry*sin(qy-qx).

        To adapt the old engineer’s joke: assume a spherical robot. Then the force of the bullet (rx) and radius where the hit occurs (ry) are constant. So, all that changes between different shots are the angles qx and qy. Shamus’s calculation (taking the difference between the angles) works because it approximates the sine term for small angles. It will give too-large rotations for larger angles, especially when the shot is close to being straight on, but it mostly works and it’s faster than calculating the sine.

        • Zukhramm says:

          You don’t need to change to polar coordinates. In fact, what taking the cross-product is essentially doing is finding the theta-component of bullet’s velocity.

          • Peachfuzz says:

            You’re right. If you’re starting from the vectors, doing the cross-product is quicker than calculating the angle. That’s what I get for trying to do math before having any caffeine. So, ignore the last sentence in my comment.

            • Abnaxis says:

              One of the fun things about science is that coordinates are virtually always a matter of convenience, though a lot of times “convenience” translates into “able to run the calculations before the heat-death of the sun”.

              If you’re switching to polar coordinates and it doesn’t make the math cleaner, you probably shouldn’t be switching to polar coordinates.

      • Abnaxis says:

        Holy crap I’m an idiot.

        Yeah, doing the cross product it the physics-correct way of doing it, because it’s r x F. Wiki ref.

        I didn’t even need to think of it that hard, I just needed to get on the road where I couldn’t write first :p

        • topazwolf says:

          The really core reason that Shamus is using a simple difference is that, in his game, bullets do not have a true force (F) assigned to them. From a uniform perspective this is a simple and intuitive way of doing it since the only factors involved are the angle at which it hits and the offset to the center of the robot.

          However, if Shamus was to decide that bullets should have a standard force of impact value then he could use his difference to find the direction of spin and then use a subset of the cross product to find the factor of amplification of the rate of spin. Basically, he could find the perpendicular “distance” (in this case probably counted by pixels) to the shot and multiply that by the force value of the shot (believe it or not to calculate the moment on a flat plane in higher level engineering, it is rare to actually use the cross product since it is typically easier to just note in what direction the moment will occur and find the magnitude through simple multiplication of perpendicular pieces, which is normally the magnitude of force multiplied by the portion of distance it is perpendicularly offset by). This would give him a constant to apply to the rate of spin.

          He could also use the same force value of the bullet to calculate the amount of translation an enemy receives. For example, he could have weak bullets have a force amplifier of 1 and the standard translation be about 2 pixels so that they barely move in the direction you shoot them. Yet if you upgraded to a large cannon type weapon you could give it an amplifier of 20 so that the robot moves 40 pixels and likely explodes from the damage and spins away to his doom. Bonus points if the spin and translation happen at the same time so it feels like you literally blew him away.

          • Zukhramm says:

            Do you have some additional source of his reasoning besides the blog post that the rest of us doesn’t have?

            There are multiple reasons for using the cross product. Even without proper force it’s still reasonable to be interested in the component of the bullet’s direction in the rotational direction. Just taking the angle gives a pretty big error for large angles (which is fine if you want dramatic spins, I guess). Also, the cross product will scale the spin by the distance to the center of mass, which I guess doesn’t matter if robots are mostly circular.

            • topazwolf says:

              No real need to get short with me. My reasoning is the fact that he had angles but not vectors. To have a force (and by extension a cross product) one needs both magnitude and direction, specifically a vector though I grant that he could use trigonometry to create a vector from an angular direction (which is fairly inefficient if the programming language is not specifically set up for doing such operations). He has direction in relative degrees which is a far cry from having vector notation.


              I will concede that cross products can be done using trigonometry, but again that adds unnecessary complexity.

              I am just doubtful that Shamus has stored his data in vectors. He has not had any reason to do so, nor has he mentioned anything about it. Also if he had his data in vectors he would have no need of referencing direction by angle since that is a mathematically inferior way to approach it.

              Also on an entirely subjective note based on no evidence in particular, Shamus does not seem the type to me to create a mathematically consistent and constrained simulation environment that is designed to use calculus constraints without good reason. And since I have not yet seen a reason for him to have set up this environment I have concluded that he likely has not devoted large amounts of time to ensuring such a thing.

              Also (again) on another completely biased note, I believe that if Shamus really wanted to do such math in his code he would use radians instead of degrees. This completely and utterly speculation that is likely incorrect.

              Side note: Finding center of mass for a complex irregular object that is rotating is not something to be done lightly.

              TLDR: Setting up his game to allow for such functions would add complexity to the code and Shamus would have to have a valid reason to want to do this. Since no reason or mention of this complexity has been made, it is likely not something he has added to his code.

              • Shamus says:

                Actually, I do keep everything in vectors.

                I used angles because my vector class has a nice little built-in vector.GetAngle () thing that converts the vector. It probably is mathematically inferior. (Glancing at the source I see it does an atan () operation.) However, from a coding sense it’s SUPER efficient since the whole impact & spin business is three or four lines of completely readable code.

                And in the end, I need the spin to be expressed in degrees, since that’s how I turn the sprite on-screen. (I have a lookup table to spare me the constant sin / cos operations.)

                Your paragraph on calculus is mostly opaque to me. I don’t even know if that refutes or supports your point.

                The robots don’t have any “weight” information, so doing anything even remotely simulation-ish with physics is right out. The granularity just isn’t there. Although, I’ve been toying with the idea of implementing a super lo-fi system of generic light/med/heavy types that react differently to impacts. It’s hard to tell if this would be visually amazing or barely perceptible. I’ve got a list of different feedback experiments like this that I toy with now and again. Some are great. Some are subtle. Some are dumb and bad and slow.

                • topazwolf says:

                  Welp, I retract all my previous reasoning as being completely false. I will also admit that you and I program in completely different manners. I like to keep my code dense but organized with every line serving a purpose, but maximized for computational efficiency. I do not typically worry about compact readability.

                  I will now concede that my logic was based upon and invalid set of core premises and admit that Zukhramm was at least partially correct in that my reasoning was flawed. I will however assume that their is a reason that you do not use cross products. May I assume that you are just more comfortable seeing the values for turning expressed in degrees rather than any other form?

                  My paragraph on calculus was just expressing the difficulty of using a cross product if your data was not set up for it. If you have the magnitude of the force (say 4N or so)[F] and the magnitude of direction (the length) [d] from the collision point to the center of the object (say 2m) and the angle between them, you can find the exact moment (a rotational force [RIP proper science termonology] if you will) that is created by using the formula F*d*sin(angle). By using math you can convert this into revolutions per second and find how fast and in what direction to spin it.

                  Basically my argument was that you likely didn’t set up the code to do things like this. You actually have it set up to where you can quite easily if you wanted to, but you may not prefer this method.

                  Weighting the robots would be kinda neat for variation in enemies.

                  I am curious if you have decided on a final art direction. Will you be doing a post on that later?

                  If you want any math explained in greater detail I will be happy to oblige.

                  • Shamus says:

                    I don’t understand how a cross product can help me in this 2D situation. Wouldn’t the cross product of any of these vectors just point out of the screen?

                    As for compact readability: I really started thinking about readability as a core goal when watching Carmack’s keynote. Like, “How would it change my programming habits if I changed my priorities?” This 2D project is a chance to kind of cut all those corners and just make it clean and clear.

                    It’s entirely possible that this whole “2D is easy mode” business is actually “programming for simplicity and clarity is easy mode”. I actually think I need more time with the project to say for sure.

                    • Paul Spooner says:

                      Yeah, vector pointing out of the screen is the axis of rotation, magnitude is rate of rotation. Quick back-check: Do you always want the robot to rotate around a vector normal to the display surface? Will the rate of rotation always be largest when the projectile vector and the moment arm are at right angles?
                      As you say, the 2D is just a simplification of the 3D case… and cross products work just fine for 3D torque calculations.

                    • Shamus says:

                      Okay. I think I see where you’re going with this. I couldn’t imagine why I would bother getting a cross product, since I’ll always get the same answer and I already know that answer.

                      But you’re saying we don’t care about the direction of the vector, all we care about is the magnitude, which is our spin. Although, getting the cross-product and then getting vector length seems like it would be more computationally expensive than what I’m doing now. Then again, I can’t imagine a case where performance will matter. This calculation only happens when a robot dies. Unless the player kills a hundred robots a frame (that would be an interesting design doc!) there’s just no way it can matter.

                    • Abnaxis says:

                      I think the problem here is there are a lot of physics people talking to a lot of prgramming people, and there is a lot being lost in the translation. As a physicist with a computer engineering degree, I’ll try to help.

                      First, here’s the background: spin depends on a force applied to an object that is not in-line with it’s center of mass/axis of rotation. The physics equation for what you’re trying to do is:

                      (F x r) / I^2

                      where F is sort-of-like like force/energy combined into one (it’s the energy of the bullet that is translated into a force that increases the rotational energy of the body so as to obey Conservation of Energy), r is the distance from the force to the axis of rotation, and ‘I’ represents a combination of the geometry and the mass of the shape. It takes big, pain-in-the-ass calculus to get the true value for all these numbers, but suffice it to say that ‘I’ takes both the density and the spread of the mass into account.

                      Note: if you drop the square on the bottom of the fraction, you get instantaneous acceleration according to physics. I^2 is more correct, which will give you rotational energy of the enemy as a result of the bullet transferring its energy into them. I would try both I^2 and ‘I’ on bottom–sometimes people can surprise you in their ability to intuit how much faster and object that is twice as big should rotate compared to a smaller object.

                      I don’t know if you keep your vectors in normalized form, but if you do you can make the equation (B x r) * F/I^2, where B is the normalized bullet vector and F is a made-up number you come up with for the force/energy of the bullet.

                      Note 2: a fun thing about doing cross products in 2D is that the X and Y components are always zero. The equation I posted above– X1*Y2-X2*Y1 –will give you the z-component, and only takes one line of code.

                      Now, to the physicists out there, you need to realize that in the world of graphical programming, units are completely arbitrary. A bullet can have an energy of 2. “2 what?” you ask? Doesn’t mater, it makes the graphics looks nice. Some programmers will assign units to them for communication purposes–the temperature units in Dwarf Fortress have been dubbed Urists by the community, complete with conversion to transform them to real-life units–but internal units of measure are decided completely by programmer fiat.

                      Bearing all of this in mind, the code as I would envision it is this:

                      ________________________________

                      /*normalized bullet vector*/

                      BulletVector B;

                      /*line connecting center of rotation to impact point*/

                      RotationArm R;

                      /*Energy of bullets in arbitrary units–a bullet of F=2 will spin a body twice as fast as a bullet with F=1*/

                      double F;

                      /*Combination mass & size of enemy again in arbitrary units–an enemy with I=2 rotate a quarter as fast as an enemy with I=1*/

                      double I;

                      /*equation to get the number of degress of spin the robot gets, this should be correct-signed if I remember my OpenGL correctly, but you may need to switch the order of subtraction or it will spin the wrong way*/

                      spin = (B.x*R.y-R.x*B.y) * F / (I*I);

                      /*since the units are matters of convenience, you can go straight to spinning the robot with the equation output*/

                      glRotate(deadBody,spin);

                      ____________________________________

                      The advantage of doing the code this way over Shamus’s method, is that somewhere there may be edge case where subtracting the vectors yields unpredictable results–the above is the physics correct way of doing this, and thus should always be consistent.

                      Second, it gives you two numbers to fiddle with–F and ‘I’–to give unique feels to enemies and to weapons, and it really is a matter of “mess with this number until they look right.” If you want to exaggerate the spin of an enemies, just lower I and they will spin faster. If you want to accentuate the impact of a bullet, just increase F.

                      Third, it’s a mere handful lines of code. If you wanted, you could go through a big morass of calculus and physics to do everything perfectly accurate, making assumptions about the material the creatures are made of and how far out of the screen they stick, etc., etc., but that’s way, way over-simultaion, and those equations just serve give you a correct number for the center of rotation and I. Artistically, you’re much better of making up a number for them and tweaking ’til it looks right.

                    • Piflik says:

                      Since you are working in 2D, this would be extremely simple. You can treat the two 2D vectors as 3D vectors with a 0 z-component. The result of the cross product will be 0 in x and y, so the z-component will also be the magnitude of the vector and the exact spin with correct sign.

                      (using your variables from your post below)

                      to_impact = _position – impact_location;
                      _death_spin = (impact_direction.x * to_impact.y – impact_direction.y * to_impact.x) * DEATH_SPIN;

                    • Cybron says:

                      Most of what I work on isn’t terribly time sensitive, so I can definitely say that programming for clarity is very helpful. That said, 2D has to be a heck of a lot simpler than 3D.

                      Both together is probably a pretty great change.

                    • Volfram says:

                      Piflik is right, if you take the cross-product, you can then just read the Z value as your spin rate, probably in degrees. Might need to be scaled, possibly by a negative value, but at least that value will be constant.

                      Cross-product has the advantage of not requiring any Trigonometry or root calculations, both of which are very slow.

                      I spent a while reading around the threads thinking “Man, can’t you guys just give Shamus a break? His solution’s super easy!” before reaching the conclusion. Their solution is also super-easy, and probably a bit faster.

                    • Abnaxis says:

                      I want to stress that to me, the important thing is not about efficiency (seriously, that is over-optimization right there), nor is it completely about code simplicity (though code simplicity is a consideration). My concern is quality.

                      In the “Juice” video posted, did you notice all the different functions they had available for creating bounce to make their code juicy? I can guarantee, adding those options made the implementation more complicated, but it was worth it because sometimes it just feels better for a brick to vibrate after you hit it with a ball, and not just nudge back.

                      To me, this issue is that same sort of dichotomy–yes, the method implemented works and nobody in the world is going to point at the rate of rotation of the robots and say “that is just completely off.” However, in my experience creating systems that follow the same functional form as real-life physics intuitively feels better to someone playing. It’s gut instinct (a child who knows nothing about algebra will draw a fairly accurate parabola if you ask them to draw the path a thrown ball takes through the air) and it can make a difference.

                      If the difference between a physics-based approach and making up something simple that looks right enough is 1-2 lines of code, why not use the option that will look more intuitive to users?

                    • Demo says:

                      The point of using the cross product over angle subtraction is that they wouldn’t give the same answer in most cases; the cross product result would look more physically ‘right’.

                      As an example suppose you added an enemy that was a bar and one of the following two shots killed it.

                      | <-
                      |
                      | <-
                      |
                      |
                      |

                      In an angle subtraction, either of these two shots would produce the same amount of spin. Taking the cross product instead, the shot hitting the edge of the enemy would produce a significantly greater amount of spin than that landing near the centre.

                • Volfram says:

                  The robots clearly have a “health” stat, perhaps basing the robot weight on the maximum “health” value would work?

              • Zukhramm says:

                I’m sorry. I’m not trying to be short with you. I don’t even know what that means actually.

                • topazwolf says:

                  I was trying to revive the punnage from the podcast in which Shamus actually makes a pun at the expense of (fictional) dwarfism. It was a whim to revive a string of puns in the mild of some maths. I used such a phrase because you (as was later proven correctly) disagreed with reasoning. It was a half-hearted attempt at humorously defending my then current viewpoint which has since changed.

                  I am an advocate of puns and I feared that this entire conversation would go without any. Not offense intended.

    • Zak McKracken says:

      correct.

      In vector mathematics it’s the cross product of force vector and vector from impact point to the center of rotation.

      In geometrical terms it’s the product of the force exerted by the impact times the length of the line from the center of rotation to the trajectory of the shot that is perpendicular to that shot (oh how I wish I could make a small drawing now).

      Both, of course divided by the inertial moment of the robot (i.e. a light bot or one with most mass close to the center will be spinning faster than a heavy one)

      To put some sugar on top: The momentum of the shot that does not go into spinning the robot would (in the real world) go into accelerating it in the direction of the shot. I.e. if you hit the center, it would be knocked back, if you hit it in the extremitites it would be mostly spinning, and in between it spins a bit and is knocked back a bit (actually, this is a linear function of the shortest distance between the center of gravity and the shot trajectory).This would go well with the fact that the robot is knocked back (and resumes position) when it’s taking a non-lethal hit.

      Then again, if the difference thing looks good (and at least in the GIF it does)… who cares? Although I’ll say I’m not sure why the difference seems to deliver good results. Wouldn’t that give you a bigger spin if you hit closer to the center of Gravity? Or did I misunderstand which two values are being subtracted?

      • Deoxy says:

        The momentum of the shot that does not go into spinning the robot would (in the real world) go into accelerating it in the direction of the shot. I.e. if you hit the center, it would be knocked back, if you hit it in the extremitites it would be mostly spinning, and in between it spins a bit and is knocked back a bit (actually, this is a linear function of the shortest distance between the center of gravity and the shot trajectory).This would go well with the fact that the robot is knocked back (and resumes position) when it’s taking a non-lethal hit.

        and down below in the thread, someone else says this:

        It is slightly strange that you are selling the punch of hits so well while the bad robot is still alive and then the killing blow only spins it.

        That’s very true – and the solution to the problem is the one you posted. I like it.

  4. Chamomile says:

    Since this particular piece of unsolicited advice happens to be on topic, I’ll mention that I think the robot becoming a silhouette doesn’t look right to me. Seems like it would be better if the lights noticeably dimmed but didn’t quite go all black, like the power had failed but the lenses were still tinted, rather than what it is now, which just looks like…I don’t even know, a glitch or something.

    That’s just me, though. This sort of thing is subjective.

    • Shamus says:

      This is a tricky trade-off. It’s no big deal when you’re fighting one robot, but in big noisy fights I didn’t want “dead” robots to stand out with the living ones. There’s a lot of visual clutter and a lot of chaos, and having dying robots retain their lighting means that they would still look alive to the player, particularly if the robot isn’t spinning very fast. From a gameplay perspective, you want defeated foes to vanish from play as fast as possible, but for aesthetics it’s fun to see them crash first.

      • Rili says:

        I would suggest a dimming or flickering animation for the dying robot that sells the kill. It’s also more juicy that way, or so I hear.

        Likewise, it might be cool if bullet momentum was applied to the falling robot. Not just spinning but pushback. It is slightly strange that you are selling the punch of hits so well while the bad robot is still alive and then the killing blow only spins it.

        And while writing that I thought of the next annoying suggestion.
        Bake some spin into the pushback effect while the bad robot is still alive. Right now it gets pushed away and then compensates, maybe it should also be spun slightly and then right itself again.

        • ThaneofFife says:

          Shamus, I agree with your point about not wanting dead robots to stand out, but I think there may still be a way to implement the suggestion.

          I suggest having the robot’s eye quickly fade out, rather than turn off all at once. Have it get brighter for like 1/5 of a second (like it’s overloading; this can coincide with its brains being blown out) and then go black in the remaining 4/5 of the second. It would be a little like what happens to your laptop’s power brick when you unplug it from the wall.

          Here’s what you would see in the first second after an enemy death:
          -0.0sec robot suffers fatal hit
          -0.2sec robot’s eye goes to 125% brightness
          -0.4sec robot’s eye goes to 75% brightness
          -0.6sec robot’s eye goes to 50% brightness
          -0.8sec robot’s eye goes to 25% brightness
          -1.0sec robot’s eye goes to 0% brightness. Completely dark.

          I also really like Rili’s idea of having momentum transfer work on death, in addition to spin. If the robot spun and corrected a little while hit, that would be more satisfying too. Maybe it could mess up that robot’s aim some?

          Finally, have you thought about having a couple of different semi-random results on death? For example, the animation you show above could be the most common result. But, maybe some enemies could have a 10% chance of exploding upon death (and doing damage to everything around them). Maybe others would have a 20% chance of continuing to fire wildly as they died (maybe hitting their allies as well as the player).

          Or, maybe you could just randomly vary the color of particles produced during the death animation, which would look cool, but have no gameplay impact.

          • I don’t like the semi-random death things. Especially that explosion one – if the player is about to die, and is really up-close to the last robot and has killed it, you don’t want to punish them for surviving by blowing them up.
            I feel like those kind of results should, if they are included at all, be reproducible – e.g. a robot will explode if it takes more than 50% of its health in a single hit, or something.
            But mostly, these ideas add too much programming and balancing work to the project, with very little to add to the game (and a lot of chance that they ruin it.)

          • Ambience 327 says:

            I completely agree that the eyes fading out (quickly, but fading nonetheless) would really sell the dead robot thing without it looking like a glitch, and without leaving it a confusing nightmare of “which robots are still alive”.

            I am LOVING this series. Keep it up!

        • Brandon says:

          I like this idea. I also think if it’s spinning when it hits the ground, the broken bits should fly off in the direction of the spin, or something of that sort.

      • Ozy says:

        I think you may be overestimating the problem? This immediately reminded me of a part of Stage 4 of Subterranean Animism, (starting about :25) where one of the bullet types is the same colors, same shape, and almost the same size as one of the collectible items, and while this did indeed make me think, “This seems like it should be confusing,” I’ve never had trouble differentiating them because they move differently, and in a shump, the player is very finely attuned to particle movement.

        Likewise, it seems to me that if only dead robots travel on a ballistic trajectory, that would be enough to convey that its dead to a competent player, even in a very visually noising environment.

      • Rax says:

        I tend to agree with Chamomile, how about a TV noise effect replacing the “eye”? “TV noise” means this (warning: LOUD): http://www.youtube.com/watch?v=PH54cp2ggFk

  5. Lovecrafter says:

    I would just like to point out that there seems to be a glitch in the animation where the eyes of Good Robot aren’t on its face for a brief moment. It happens right as Good Robot fires the second shot.

  6. Kilt'd says:

    I know this is off topic for this Good Robot post, but if robots can take multiple hits to destroy then can I suggest a health bar or some other indication of how damaged a robot is? It’s fine as it looks now if you’re fighting one robot at a time, but if you’re fighting a large group it feels like you could lose track of how much more you need to shoot at a given robot before it goes down. It’d also be nice to see you’re doing damage when each shot connects, and it could indicate which enemies can take more punishment than others.

    • Cuthalion says:

      Maybe even just jagged lines of red or glowiness, like cracks in the bad robots’ hulls. (Or the good robots’. I’m not sure which side the protagonist is on.)

    • Nick Powell says:

      I think just having the little black particle effect come off the robot when it gets hit would solve all of these.

      When I’m playing a game, just seeing that I’ve hit an enemy is usually enough for me to roughly keep track of how close they are to being destroyed.

      • Piflik says:

        This might work for a single enemy, where it is quite simple to keep track of how often it has been hit, but if you have an armada of robots, all looking the same, flying chaotically around the player, it would be quite confusing trying to remember which robot has been hit and how often…

  7. Joshua says:

    You are going to post ways to buy this game once you’re finished, right? I could definitely go with some of this retro action, especially since I also loved the original Descent.

  8. Akri says:

    Ooh, those closeup images are going to be very helpful in developing version 2.0 of my Good Robot plushie.

  9. Thearpox says:

    Speaking of bullets, where did the decision to make them a stream of particles came from? I know you added the tail…

    This is my personal opinion, you don’t have to follow it, but I actually much prefer being able to see the bullets. I’ve got some amount of bullet hell experience, (I actually play Touhou while listening to the Diecast. Helps with not staring at the same screen for an hour.) and I really like to see the projectiles clearly.

    Helps with clearly seeing the borders of where to avoid them/hit with them, with all the fuzziness the stream of particles introduces. Also, I do not think it precludes seeing the direction the bullet is going. You can add the tail while still having it maintain a concrete shape. And having the bullet and the tail maintain a very distinct and different color/some other way of distinction doesn’t seem very hard.

    Also, having the bullets have a more concrete shape is pretty invaluable when you are swarmed by bullets/enemies. The smaller shape keeps the screen less busy, and helps stop the projectiles from intersecting. (May I just say that I really hate when projectiles intersect? I really hate when projectiles intersect. Projectiles should never intersect.) I actually cannot play almost any games when the bullets or whatever is used is a stream of particles. And this goes not only for bullet hells, for many other games too.

    Once again, my personal opinion, and I may be wrong about the way this is implemented, seeing as I only have several screenshots to go off, but here it is.

  10. Mchael Enzweiler says:

    Part of the visual confusion is that there are so many black objects. The player is going to be thinking in terms of black = enemy, so changing the color of a killed object would help eliminate confusion. I’d suggest trying to make robots and fragments flare to white and fade, as though affected by an energy weapon. They can still drop as if gravity is affecting them as they fade, but the fade to white and disintegrate kind of goes along with the idea of futuristic weapons rather than just solid ballistic projectiles. I also think this s a good idea because having the fragments hit the bottom of the cave is not only a distraction because it creates movement and more black objects, it also makes the 2D nature of the cave too obvious. I know it’s 2D, but the desired effect is that it’s really a 3D environment viewed from the side. Having falling objects react to the 2D cave bottom belies this. Awesome work, and awesome blog. Can’t wait to read more!

    • Trix2000 says:

      Considering that most things – including the terrain and the player robot itself – are black, I don’t think it’ll be a problem. Especially considering that things that are ‘alive’ seem to all have colored lights on them. I’d worry that white stuff would stand out too much.

  11. Cuthalion says:

    Reading this is highly therapeutic. Thank you, Shamus. Having recently programmed (ok, I’m still programming it) a 2d (isometric) engine, and with far less experience that you (“easy mode”? Hah!), I’ve been running into many of these same problems and puzzles. And I think I’ve had those, “Oh. That was easy. Kind of disappointingly so,” moments. I’ve definitely had plenty of braintwisters. So it’s refreshing to see even a veteran programmer go through the same process, even if they’re having an easier time of it. ;)

  12. SteveDJ says:

    It looks like your list of “when you kill a robot” is missing #8 — dead robot releases remaining arsenal, but launched without direction/target/purpose.

    At least, that what it looks like is happening now. If not, then what am I seeing? When you kill the robot, what are those two rockets seeming to just fly away at random?

  13. Phantos says:

    That was a lot of shots to take down just one enemy. I hope the baddies aren’t bullet-sponges.

    Ah, there’s another piece of nomenclature for a game function.

  14. D-Frame says:

    Feedback channels. I remember when I was wondering why my explosions didn’t feel heavy enough and I couldn’t figure out why. I had nice explosion animations, lots of debris flying around, a really heavy boom sound, smoke, I even included a visual shockwave effect. And then I added camera shake, which only took about six lines of code, and suddenly you could almost feel the explosions in your guts. Sometimes the simplest features have the greatest effects.

  15. When people say the guns in a game feel “weak”, I suspect they’re often not talking about mechanical stopping power but about the lack of key feedback channels.

    Pretty much this. I chalked it up to kinaesthetics mostly, but whatever.

    I remember always struggling to convey this concept in the past. Example: when I started playing Halo 2 and a lot of the weapons didn’t “feel right” or felt weak. I’d try telling this to my friends and some of them would just say, “Oh well it’s actually just as good as it was in the first game.” No dude, you don’t get it; it doesn’t matter if it is powerful, it doesn’t FEEL powerful–it’s not satisfying to use. But as I said, I didn’t know how to communicate this at the time, and it was frustrating.

    That was one of the things Halo:CE did really well, making their weapons feel powerful and fun, not just BE powerful. It’s been hit and miss throughout the rest of those games, but it seems to just steadily get worse with each installment–all because NOBODY on those teams wanted to keep those same few feedback channels that made it really work in the first place. Seriously, WHY do you have to change the sound effects EVERY SINGLE GAME? Some of these are awful.

    I mean, look at this comparison video of the human pistol. Now in fairness, most of these really aren’t bad (in terms of sound, use was different), but they do feel like a step down from the original. The one I’m complaining about the most here is the Halo 4 version. Just. What the heck was that?

    The plasma weapons are probably the ones that got it the worst in terms of sound and feel.

    PS: That gif is just so much fun to watch. ^_^

    • Aldowynthe says:

      Halo: CE was great in a lot of ways. dat pistol. The shotgun’s fun too, esp. against flood.

      Anyways, I think there’s a bit of overlap between ‘kinaesthetics’ and Shamus’ ‘feedback channels’, especially where shooting a gun (or generally using a weapon) is concerned

    • Klay F. says:

      Holy Crap. The Halo 4 pistol sounds like its made of plastic. How the hell did that slip everyone by?

      • Volfram says:

        Wow, yeah, the Reach and Halo 4 pistols made me wince at how pathetic they sounded.

        This is one of the reasons why even though I KNOW it’s a perfectly good(many would say great, actually) gun, I will probably never own a Glock. It just doesn’t look as good as the M1911A1(which I do have) or the Beretta M9(which I would like one of)

        Crazy, yes. Glock’s an ugly gun.

        Ironically, the Heckler&Koch HK45 is a piece of sexy, and it’s also made largely of plastic.

      • Probably for the same reason this turned into this which does this.

        Plus, I mean, it’s a terrible weapon. It’s been terrible since… I was going to say Reach, but I guess since H3.* Regardless of what ever power it may possess, its reduced magazine size, rate of fire, and accuracy made it utterly useless. Reach saw the return of the scope which served no purpose other than to try and make H1 pistol fans shut up, and the return of increased RoF was made negligent by the reduced firepower, making it more useless. In H4, I swear it’s worse. Devs claim they are big pistol fans, but they give us a crappy weapon. Whether or not it’s their intent, it feels like they’re patting us on the head, giving us this thing, saying behind a false smile, “You’re so dumb.” Either give us something that is at least usable, or just tell us, “Your fabled pistol isn’t coming back.” Don’t do what you’re doing now.

        Sorry for the rant.

        *(H2’s pistol, while technically not as powerful, served a different function which at least worked somewhat.)

        • Brandon says:

          The problem with this is that video games have taught us that pistols are as accurate as rifles, and certainly more accurate than automatic rifles, which is completely contrary to real life. The reason pistols are common is that they are much cheaper, much smaller, easier to carry and conceal. They are in no way more accurate than larger firearms. I’d argue a weak pistol that has low accuracy is probably the more real-world correct pistol.

          • Volfram says:

            Your argument would be correct in general. Handguns are overall more convenient to carry than long-guns, and generally quicker to “ready.”(Don’t know about cheaper… most of my pistols cost me more than most of my rifles did) Long guns are way better as far as accuracy, capacity, and stopping power.

            On the opposite end are derringers, which are VERY easy to carry and conceal, but not really useful outside about 3 feet, and they’re questionable even then.

            • And this would all hold more true if we weren’t discussing a *video game* set over 500 years in the future. It’s not about “realism” (an absurd term to use in games anyway). It’s about the mechanics in the game, good and bad. It’s about making something that is usable, viable, and fun. And in most of the games, the human pistol is none of these things. That’s not okay, and it’s not the only weapon that suffers from this (the poor AR), it’s what I chose to focus on at the time.

              • Volfram says:

                In the interest of authenticity, I actually went to the range and recorded some gunshots for use in my game.

                Even the might Marlin model 1890, chambered for .45-70 Government rounds, actually…sounds even less impressive than the Halo 4 pistol. Very high-pitched. Quite disappointing, really. I initially recorded gunshots from several different sizes, but then found that they don’t really sound that different.(Not when you can’t feel it, I guess.)

                Seems the alternative is to overcharge the bass on everything(even the smallest handguns) and tweak the falloff to make it sound satisfying.

                [edit]Yeah actually, if you take the original gunshot sound, duplicate it, run that at half speed, clip to length, and then bass-boost the half-speed one, it sounds REALLY satisfying. I should put together a YouTube video with comparisons.

                Still toying with the idea of blowing up some Tannerite* to get explosives or grenades. That stuff sounds impressive.

                *Sporting goods stores often sell “reactive targets” ranging from small targets designed to be detonated by a .22 to larger targets for long-range rifle fire.

              • WJS says:

                It doesn’t matter if it’s set 500 years in the future or not; the idea that a larger weapon should be worse is just ridiculous.

  16. rofltehcat says:

    You could apply that rotation code to some sort of boss: Hit it at the right angle and it spins away from you.
    It might have some sort of death laser and even might have to aim that death laser to hit some special scenery (pillars? vault door? huge-ass generator?) to cause some sort of effect (collapse ceiling?).

    Of course it might look completely different :D

    Looking forward to play this!

  17. HiEv says:

    Now you just need to have the XP fly out of the defeated enemy Mincraft-style or something like little glowing gears. That would give you feedback on that stat.

  18. Benjamin says:

    The movements of the enemy when struck are a nice touch; the fact that the enemy returns to a target position implies intent, giving us the illusion of life. Good example of a small effort going a long way.

  19. Ravens Cry says:

    I think I like feedback channels as a term better than ‘juicy’. Juicy alone is kind of vague, like the kind of thing you see on Clients from Hell. Feedback channels you can break into sub-categories easily.

  20. Bruno M. Torres says:

    Please, please, post a video. This looks amazing.

  21. muelnet says:

    Just noticed the parallaxing in the background. Nice work. It’s one of those little things that makes a 2D game world feel more alive.

  22. MadTinkerer says:

    “This is actually kind of disappointing. It’s like that feeling when you’re just screwing around in Portal because you’re stuck and you end up accidentally solving the puzzle. You’re robbed of that delightful “Eureka!” moment.”

    According to the book Droidmaker, the optimal algorithm for digital motion blur was invented in a similar manner. They stumbled across the answer while attempting to solve what they thought was an unrelated problem, and basically got motion blur for “free” as a side effect of implementing the other idea.

  23. anaphysik says:

    “when you kill a robot a cluster of sparks fly out the back of the robot as if you were blowing its robo-brains out.”

    Will we be able to disable gore?

  24. Florin says:

    Hi Shamus,

    Looking at the background in the screenshots it looks like you have a layered thing going on there. Are the layers in the back the caves through which you have passed before? Are they caves that you will be exploring in the future? Or I am over-analyzing it and it’s only random so that the background looks better ?

  25. Kingmob says:

    I know this has been talked about at length above, but I feel it hasn’t really been properly expressed how simple the solution to your bullet impact problem is, also in terms of coding. Unless I’m very much mistaken:
    – Take the dot product to get the knockback force.
    – take the cross product to get the ‘rotational force’ and direction (the vector will either point away or towards the screen, determining the direction of spin).

    You can give each character a mass and each weapon a force to even further distinguish them without much effort.

    Surely this must be cleaner and easier to read than what is currently used? It also gives better results (the reason the angle trick works is because it is basically an approximation of the cross product at small angles).

    • Shamus says:

      Simpler and cleaner than this?

      to_impact = _position – impact_location;
      angle_out = to_impact.Angle ();
      angle_in = impact_direction.Angle ();
      _death_spin = GLmathAngleDelta (angle_out, angle_in) * DEATH_SPIN;

      That’s it. That’s the whole thing. All I want is a single float that says how many degrees to rotate each frame. This talk of cross-products and dot products and rotational forces that people are proposing sounds like the solution to a WAY more complex problem.

      • Abnaxis says:

        It sounds like one, because they aren’t breaking it into programming steps, they’re giving all the theory behind it.

        I went into more detail above, but I think I lost it in an edit. In a more proper way, here’s what kingmob is getting at:

        to_impact = _position – impact_location;
        death_spin_angle_delta = impact_direction.x * to_impact.y – to.impact.x * impact_direction.y * bullet_energy / (math.pow(enemy_size,5))*DEATH_SPIN;
        death_knockback_vector = impact_direction.x * to_impact.x + to.impact.y * impact_direction.y * bullet_energy / (math.pow(*enemy_size,3))*impact_direction*DEATH_BLOWBACK;

        EDIT: Heh, that looks kinda ugly in the formatting for the thread, but all those equations should fit on one line each in a proper IDE.

        bullet_energy and enemy_size are arbitrary-united magnitudes that represent the energy the bullet collides with and the size of an enemy. You can then fiddle with bullet_energy and enemy_size to you heart’s content, and you should get knock-back and spin that look correct from a physics standpoint. Also, the math.pow part is just to make the ratio of knockback vs. spin to look right–if you only want to do spin, you can drop the math.pow.

        • WillRiker says:

          THAT’S supposed to be “simpler and cleaner” than what Shamus has? You must be working with different definitions of those words than I am.

          What it really comes down to is–Shamus’s solution is an approximation, but it works well enough. This is one of those areas that I think is prone to oversimulation–sure, Shamus COULD rewrite this all in such a way that it uses vectors and the cross product to perfectly physically model the torque force of the impact on the enemy, but that would require more work and, as you’ve demonstrated, more difficult to understand code. And in the end, the difference will be completely unnoticeable to people actually playing the game.

          • Abnaxis says:

            The point is, and I should have been clearer, is that using proper vector math is cleaner without enhancement and easier to add to. For my example, I added all the stuff Kingmob was talking about adding. If I only wanted to replicate Shamus’s code, it would be:

            to_impact = _position – impact_location;
            death_spin_angle_delta = impact_direction.x * to_impact.y – to_impact.x * impact_direction.y * DEATH_SPIN;

            Which looks simpler, yes?

            The code I put in the previous reply adds in variables for letting different bullets have different impacts, different enemies having different sizes, and adds knock-back in there as well. Leaving out any one of those enhancements will make it look simpler, the previous code was just the full shebang. And even after all those enhancements, it’s still 3 lines of equations versus 1 equation and 3 OpenGL calls that I inherently don’t trust.

            I also think you’re being unfair, because you’re judging how readable the code is when I type it into a forum. It looks much better when formatted properly.

            Finally, you’re assuming nobody will notice the difference, but that isn’t a given without testing. In my experience, feedback based on physics (note: not perfectly simulating physics just roughly based on physics) intuitively feels better than pulling a number out of a hat. Physics usually needs exaggerated to get the impact you want, but it’s better to keep the functional form the same.

            • Piflik says:

              You’re missing a set of brackets, but this is what I would have done (and what I wrote further up before seeing your post here). Since Shamus is working in 2D and thus his vectors are 0 in their z-component (if treated like 3D-vectors), the result of the cross-product is perpendicular to the x/y-plane. It has a non-0 value in z only, and this can be directly used for the spin. It also has the correct sign already.

              to_impact = _position – impact_location;
              _death_spin = (impact_direction.x * to_impact.y – impact_direction.y * to_impact.x) * DEATH_SPIN;

              (I know this is personal preference, but I really hate underscores in my variable names…)

              • Abnaxis says:

                Yeah, I’m famous for forgetting my damn parenthesis. Also not a big fan of underscores either, but I wanted to stress that you get the actual delta angle out of doing the math without any more graphics calls. I was writing the code to communicate, not the way I would actually write it.

      • Kingmob says:

        Well I guess the problem is that ‘simpler’ means different things to different people. As Abnaxis has pointed out, to replicate your code this, you actually need very little code and it is likely optimised quite well (most languages are heavily optimised for common linear algebra). In addition, it is easy to extend to more complex ‘physics’ (like knockback and such with the dot product) and it makes mathematical sense.

        However, it needs to make sense to the coder of course and if you are not familiar with such things it might actually confuse you instead of help you. I just think that it would benefit you in the long run to understand the background a little, since you’ll run into it in the future as well.

  26. arron says:

    Rather than have the lights go out straight away when the robot is killed – what about having the lights flickering and having a shower of sparks as the unit burns out as it falls? Graphical chrome perhaps, but it would look cooler and slightly more realistic.

  27. Sacae says:

    This is my first post after lurking a long while.

    But, I just want to say I love the feedback on the missiles being shot of sky.

    Being destroyed, hitting the ground, and making debris. That must feel like good feedback, it looked it to me.

    What Im wondering is what kind of feedback channels you have set in place for being hit yourself.

    One thing I thought of is when you get hit in the front have the flashlight flicker.

    In a sense its a simpler way of shaking the screen or blurring in first person, which disturbs the overall combat and messes with the flow. It will give the player more reason to not be hit.

    I dont know if Im making much sense but it works in my head.

  28. topazwolf says:

    I want to hereby apologize in my part of the mathematical conundrum up above. The basic idea seems to have mutated into fractal complexity of discussion about theories (from at least 4 perspectives), underlying math, and dimensional analysis. At this point, there is no possible method of approach in reading that will give a solid idea about what we were talking about and there is no possibility of convincing anyone that it is an easier approach.

    This has gone too far. I say let Shamus use his angles (which is a perfectly valid approach) and be done with it!

    Though of course if he adds physical simulation to the game, then we will have to revisit it.

    • Shamus says:

      I actually don’t mind. It’s an interesting discussion. It was a bit frustrating for me at the start because I had NO IDEA what the physics types were proposing or trying to accomplish, but Abnaxis straightened it all out.

      Kenny voice: Every day’s a school day.

      • Abnaxis says:

        Really? I keep looking back at some stuff I posted and flinching, at least when it comes to giving the enemies weight.

        I think my problem is, I’m trying to give you an equation that uses the bulk of the enemy (technically, the mass-moment of inertia), but there are a lot of different ways to conceptualize it and I haven’t been consistent. You could assume every robot is a sphere and assign a number for the radius. You could assume every robot is a sphere and assign a number for the volume. You could just slap a number on every robot and run with it. You could combine approaches or do something completely different.

        The thing is, once you pick one way or the other it’s easy, but I’ve been kind of moving half-assedly between different paradigms and my pseudo-code has a mess of probably-unnecessary and definitely-unclear exponents as a result. Sorry

        • Zukhramm says:

          I’d just ignore anything related to mass, volume and moment of inertia. The important part is the rotation being proportional to the (2d-fake) cross-product, not the magnitude.

          Same thing with everything about torques, energies and forces. It just complicates things. Just add the result as the velocity of the rotation.

          • Abnaxis says:

            I’d probably try both ways, and see what I liked better. When you start adding mass and bullet power to the calculations, you’re essentially communicating to the player that “this enemy is different”–that might be valuable and it might not.

            Once an implementation is decided on, the “complication” is “multiply by weapon strength, divide by enemy bulk,” no matter how you go with it. The difference is whether you let the computer equations take care of any latent non-linearity or you use your instinct and tuning to do it.

            It’s confusing for me to describe because my thought process is a gnarled, twisted thing that takes five detours before settling on something palatable. Hence the inconsistencies when it comes to mass, when it can be as simple as “slap a number on it and play with it.”

    • Volfram says:

      After doing some introspection, I’ve actually come to agree with the Physics nuts…in principal. You are right, however, it is Shamus’s project, he can do the calculation however he wants.

      Dot product has the advantage of not using any trigonometry. I went ahead in D and did a speed test, built-in atan2 function(the D standard library’s functions tend to be blazing-fast. The built-in sort function is 10x as fast as anything I have manually written, including Quicksort) compared to calculating JUST the Z value of a cross-product. Results:

      using trig, performed 1895990 operations.
      using crossproduct, performed 2326577 operations.

      Both tests performed over 1 second, X and Y values were randomized during the calculation(to combat optimization). Of course, randomization is very slow, and I’m reasonably sure the compiler isn’t optimizing my program in debug mode, so without the randomization, we get:

      using trig, performed 8554153 operations.
      using crossproduct, performed 21914945 operations.

      A little over twice as fast.

      For code readability, this:

      to_impact = _position – impact_location;
      angle_out = to_impact.Angle ();
      angle_in = impact_direction.Angle ();
      _death_spin = GLmathAngleDelta (angle_out, angle_in) * DEATH_SPIN;

      becomes this:

      //assuming known shot_direction vector
      to_impact = _position – impact_location;
      //calculate only the Z value of a cross product
      _death_spin = (shot_direction.x*to_impact.y-shot_direction.y*to_impact.x) * DEATH_SPIN;

      My prediction: Shorter code, lower memory footprint, 4x speed increase.(the original appears to calculate atan twice)

      • Zukhramm says:

        That the performance is better is nice, but the real reason the cross product is better though, is that it give better values. Just using the angle is essentially approximating the sin(v) with v. Which there’s no reason to do in the situation where sin(v) is easier to compute.

        Also, am I in the physics nuts? I do see myself more as a programmer than a physicist.

  29. Bubble181 says:

    Just to say something else than the others…I thought this game was going to be in a “weightless” environment, Descent-style. Meteors in outer space and all that.

    If so, the “falling down and exploding into debris” thing is sort of odd: there’s no “down” to fall to, after all.

    This may be because somewhere along the line they became regular floating robot, instead of floating robots in space, of course :)
    It does LOOK cool, though, and I wouldnt’ want to just have them explode in place – that’d be less interesting, visually.

  30. Syal says:

    I’m assuming there’s at least one enemy type that will fade to black, spin downward, and then reactivate and start shooting at you again?

  31. One concept I’ve needed a word for is the way games use multiple audio / visual cues to let you know that a thing happened.

    I think that’s called “a game” :P

    No but seriously, Game Feedback is as good as anything.
    You could call it Player Feedback even, or Audio-Visual or Sensory Feedback.
    Some games have tactile or force feedback.

    I don’t think there is a single game that does not have some form of “player reward” or “game behavior” in response to a player action.

    Technically it could also be a “input reaction”.

    You could also term it a positive feedback loop and so on.

    Myself I prefer to just call it “User Feedback” (which can be a tad broad as it’s used for users commenting on your software as well for example).

    As to in terms of making specific events in the game have as many possible routes of player feedback as possible I guess you could call it Player reward network or Player reward grid.

    Myself I like “player reward network” (and a reward may be positive or negative BTW!)

  32. Love the animation of the mob er mook. But instead of going just black/silhouette…
    Why not arc some electricity across it at the same time (as if there was a electrical overload or similar), this could maybe be done by swapping between a few frames (decals?) as it falls down providing a simple “animation texture”.

  33. Mimir says:

    Have you considered to give the ‘brains’ that are being blown out a different color from the bullets? The main reason i didn’t see it at first was that both were purple. You could try making them the same color as the robot’s eye

Leave a Reply

Comments are moderated and may not be posted immediately. Required fields are marked *

*
*

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun.

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>