# Talk:Energy Drop

## From old wiki

Since robots must expend a certain portion of their energy to fire a bullet, and this portion is always between 0.1 and 3.0, detecting a drop in a robot's energy between 0.1 and 3.0 is a very good indicator they've fired a bullet.

Most bullet impacts cause more damage than 3.0, so this system is fairly reliable; low-power bullets and wall collisions may cause mis-detections, however. This trick is the basis of most (probably all) bullet dodging systems. This trick is (apparently) also used with gun cooling rates in CoolMovement.

--Kuuran

To make it more reliable, a bot can calculate the energy drop caused by a bullet hit to the enemy in the "bulletHitEvent". This way the detection is more acurate, even if it will take some more code (and it is usually not worth if you are coding a Micro or a Nano). -- Albert

NB: The bullet was in fact fired the tick before you detect it, and had moved one tick as soon as it fired, so the position it fired from is where the enemy was the tick before you detected it, and it the time it was fired is 2 ticks before you detected it. And if that sounds complicated, it's because it is. -- Tango

to PEZ:
I remember that u once had mencioned, at wiki pages, something about using opponents gunheat to detect bullet firing. The problem is that i don't remember where... Do u remember where it was? I'm having trouble to get opps gun heat, cant find the appropriated method. I also tried to assume a gunheat for opp. when detected the energyDrop, and then try to calculate using guns coolRate each turn, but i wasn't able to figure out the relations between bullet_power & gunHeat... Do u know anything about these? Thnx.
PS:I f anyone else knows anything about... -- Axe

My nanobot Freddie dodges opponents when their gunheat is less than .02. I worked out a formula for it in the bot:
if ((heat -= 0.1) <= 0.2) {
heat = 1;
}
if ((last_energy -= e.getEnergy()) <= 3 && last_energy > 0) {
heat = 0.2 * (last_energy - 0.1) + 0.92;
}

The code gives Freddie the coolest graph in Robocode and the highest specialization index. --Alcatraz

Thnx,
I'm not sure that i have understood the reason for the:

if ((heat -= 0.1) <= 0.2) {
heat = 1;
}

My pupose with it is to improve the bullet detection ensuring that an energy drop while heat>0, won't generate a bullet detection. Something like:

if (((heat-=0.1) <= 0) &&  (last_energy -= e.getEnergy()) <= 3 && last_energy > 0) {
//enemy fired bullet!!
heat = 0.2 * (last_energy - 0.1) + 0.92;
}

Assuming that the formula for gunHeat is (0.2 * (last_energy - 0.1) + 0.92)... Is that correct? -- Axe

Yeah, that formula is all you need. The first part was just for dodging purposes. -- Alcatraz

Thnx, Alcatraz! -- Axe

The formula is firepower/5 + 1, the - 0.1 (or purely - getGunCoolingRate()) is required because it's already cooled one tick after you detect energydrop, I'm not sure where you get 0.92 though. -- Kuuran

I don't know either. But it worked. -- Alcatraz

I'll try Kuuran's formula, unfortunately Alcatraz formula isn't working for me. Tell u later... -- Axe

Kuuran's formula is correct, but maybe the variable last_energy in Alcatraz formula indicates the powerdrop and just is reused to decrease codesize. But then i still don't understand the -0.1 in this place: it seems already accounted for in the +0.92 (whis is 1-0.1 + a fudge factor?). I am currently also working on a nano that uses the Gun cooling rate to dodge. It works pretty well against some top nano's and hopelessly looses from others. Problem is there is not enough room left for a decent gun. I will release him soon anyway, just to see if this is a direction to go with movement. --Loki

Dummy is brilliant, just look to his TimmyTheCheerfulMonkey as proof. Inspired by that, and for all those AM systems that need something like this, here is a virtually foolproof set of OneOnOne filter to find the bullet power fired (if any) of every EnergyDrop:

First you will need to track enemy velocity, HitRobotEvents, and BulletHitEvents.

If EnergyDrop of any amount is detected:

• If the robot hit you, you will each take 0.6 damage. If a HitRobotEvent fired this turn subtract 0.6 from the EnergyDrop.
• If the absolute value of the enemy's velocity has dropped from greater than 2 to 0, and the robot did not hit you, then it hit a wall. The formula for wall damage is
damage = Math.max(0, Math.abs(velocity) / 2 - 1);
Subtract this amount from the EnergyDrop. Note that velocities of less than or equal to 2 produce no damage, so checking for the velocity drop as an indicator of damage attributable to walls is foolproof.
• If a BulletHitEvent fired this turn, use the damage formula to calculate the damage it should cause. The formula is
damage = 4 * power; if (power > 1) damage += 2 * (power - 1);
Subtract this amount from the EnergyDrop.

Whatever remains is the power of the bullet fired.

If you want to be hyper-accurate you should include one last check to see if the inactivity time has hit. If it has the bots will lose (I believe) a constant 0.1 per tick. If you are losing this, subtract that amount from your opponent's EnergyDrop as well. Modification for Melee is possible, but you can never be foolproof there, as opponent bullets hitting other opponents are an unknown. Comments? -- Kuuran

No other comments than a big THANKS for splitting this up. It might seem like small details, but when WaveSurfing you can't be too accurate. I'll see if I can fit this into CassiusClay and will get back with questions should I stumble. -- PEZ

If you want to be even more than hyper-accurate, you may want to check onHitByBullet() and adjust enemy EnergyDrop accordingly, as the enemy can fire a bullet, while his previous bullet hits you (so he gains and loses energy in the same tick). I'm not sure wether checking for RobotHits is useful, though; ever seen a bot dodge at point blank range? :-p --Dummy, still lurking around, still needs to learn to use the 'Preview' feature while editing stuff ;)

Heh, I knew I forgot something, yeah, energy gain. The robot hits is more to know the enemy fired than to really worry about the bullet, it can be important for collecting stats or to reset gun heat. -- Kuuran

I've been debugging my EnergyDrop detection (thanks for reminding me of energy gain ;)), and came to the conclusion that the energy drop resulting from a wall hit can never be precisely detected. You only know the enemy's velocity from the last tick before the wall hit, so, if he was accelerating/decelerating, your damage calculation will be off by +/-.5. -- ABC

• Using the last acceleration and adding it to the last velocity should give you the current velocity, unless it hit max velocity or started a direction change. In most bots (not flood) you can detect if it hit max velocity, and probably detect what it's using as max velocity, or just assume 8. But you're right, it's always a best guess, is complicated, and if they're changing direction right as they hit the wall the calculation is wrong. Also, since deceleration rate is 2 I guess you'd be off by +0.5, 0 or -1 (not +/-0.5) just using last tick's velocity. It will usually be 0, since bots tend to spend much more time cruising than changing speeds. -- Kuuran
• Yes, but I feel much safer just ignoring the energy drop/gain of the enemy if a wall hit was detected than using a best guess that can give me false enemy bullets. You could also use the gun heat as an indicator of the enemy's firing probability, but you'd still be off by up to 1 (like you said) on the bulletpower used. -- ABC

Out of curiousity ABC, how much code do you have to maintain the state of an enemies energy? I am currently only looking at energy at scan time and I am sure I can gain some added benefit there but I am wondering if it is worth the effort now or if it is something for later. -- jim

I'm not sure I understand your question. I have something very close to what Kuuran described up there, as close as I could get to a 100% acurate enemy bullet fire detection. Coupled with a more precise hit point calculation (both real and simulated) and some other small tweaks, It looks like it was worth around 5 ranking points for Shadow... -- ABC

• That was what I was interested in. It makes a difference but not that much of a difference. My gun improvements should lead to a bigger rumble improvement (I hope) so my efforts are better spent there. But I have added it to my to-do list. Thanks! -- jim

On a different tact, is all of this is predicated on the fact that you use the default Robocode Event priorities? What happens if you set the EventPriority of your scan event to 99? If I read things correctly, would that not mean that your scan event would trigger before any of the other events triggered and thus you would be able to ignore the other worries about everything but wall strikes. I have to be wrong as I do this and my surfing is far from perfect but thats the assumption I am under right now :) -- jim

Event priorities are just the execution order of the code you put in the handlers, they don't influence the main Robocode loop. Your code (event handlers and run method) will always be executed after every action that can influence the bot's energy has been executed for that tick. So, no matter how you set the priorities, you'll always see the opponent with the same energy in every event. There is no way to execute the scan event before the bulletHits/wallHits/bulletFire happen. -- ABC

• Could you walk me through a simple example first? Say one where the enemy is at energy 50, going to fire on this tick, and is going to fire a 3.0 power bullet in this tick. I am not quite getting it. Thanks! -- jim

Sure. If the enemy only fires a 3.0 bullet it's simple, you'll see him with 47 energy anywhere on your code. But if, in this same tick, he get's hit by a bullet, he'll be at 47-energyLoss. What I'm saying is that Robocode will execute all the actions like the bots/bullets movement and collisions (and consequent energy losses/gains), and only after everything happens will it generate the events that are executed by your code. You will see the enemy with 47-energyLoss in every event handler, the execution order (priority) doesn't matter. It's like everything (movement/collisions/etc) happens _exactly_ at the same time, and in the scan you always see the end result. Changing the priorities does not influence the order of the events, just the order of execution of your code in the handlers. -- ABC

• OK my understanding was broken but I now get it. This is why following an enemies energy is so important. He can shoot and hit me in the same tick and I would in theory never know it right now. Food for thought -- jim

Does inactivity kick in for all bots at the same time? Does it occur (default) 450 ticks after the last bullet landed, or damage was taken (e.g. wall / robot collision)? I'm pretty sure firing bullets does not reset the inactivity timer. -- Martin

I think that bullets with less than 1.0 power do not count, so if both bots fire 0.1 power bullets, inactivity will kick in after 450 ticks. The energy of all bots is drained simultaniously until one dies, then the inactivity timer will be reset. If you win by inactivity timeout, you do not get a bonus. -- GrubbmGait

Not having looked at the code, this is my guess based on my experience:

• Firing 0.1 will not reset the timer, but the timer will stop after around 30-40 energy is removed.
• Simply firing high powered bullets will ensure that the inactivity will not kick in.
• Wall collisions do reset the timer to some extent.

My guess is that the timer is never "reset" but reversed something like this: onEnergyLoss: Timer -= energyLost * C, where C is a constant. Someone who knows more might want to confirm it though. -- Kinsen

After some test runs i have discovered a bit more about the inactivity timer, at the begining of each round a number from 1 to 10 is chosen this is the amount of energy loss that must take place in order for the timer to be reset

• wall hits that do damage < 1 do not count to total energyloss needed to reset the time
• bullet under power 1 or the damage do not count to total energyloss needed to reset the time
• i have not tested ram damage, it could go either way(could not count becuase it causes < 1 damage, could count becuase it gives a ram bonus)

I hope this clears some things up, and if you want a to test to see how good you energydrop detection try it out on

• Sittingduck - tests your ability to detect inactivity time
• Crazy - to test your ability to calculate wall damage
• Walls - i dont why but sometimes on a stopNgo bot i made(regular energydrop dectection) seemed to not move for a shot or two

give these a shot, doesn't mean your perfect but pretty close - Gorded

## Contents

Easy Question?1319:52, 14 December 2012

## Easy Question?

Hi mates.

How to detect inactivity?

It sounded like an easy problem to solve but now i struggle with it for quite a while and i guess i ask a little around now.

My solution so far is - counting all energy drops of my bot and if the energy difference has a value of 0.1 the inactivity timer has kicked in. Well, it works not very well and is quite a lot of code to just detect inactivity. Wall hits and inactivity is something that does not work very well for now. Has anyone solved this problem or might have a simpler solution? Any ideas would be gladly appreciated.

If you ask - why does he bother with inactivity? - well, i have no answer that doesn't sounds nitpicking.

Wompi14:52, 12 December 2012

How about if they dropped 0.1 and you drop 0.1 in the same tick? That should cancel out most cases, except maybe extreme endgame. If they drop 0.1 several ticks in a row then you can be sure that they weren't just firing.

Skilgannon19:44, 12 December 2012

Well that is similar to what I do in Nene. I just check if the power was 0.1 and the last time I detected them firing was 1 turn ago. Since I don't count my own bullets damaging them as 'them firing', this works out very well in a normal rumble.

I also remove the last wave if I added one. This is 'safe' because if they fired there isn't going to be an inactivity counter kicking in the turn after they fired. But just to be safe, I only assign the 'lastWave' and 'lastWaveFireTime' variables if the power is equal to 0.1 (or rather within 0.001 of 0.1), specifically for the anti-activity counter.

Chase02:09, 13 December 2012

@Skilgannon - this sounds like a good idea to recheck my energy drop against the enemy drop if i hit a wall. Because in all other cases i can detect inactivity 100% based on my energy profile and just adjust the enemy energy on that. Actually i came to think about inactivity because i observed that in melee end games it happens quite frequently that the inactivity timer kicks in (long range and bullets < 1.0). The main "concern" i have, is winning by inactivity makes you loose all bonuses (have to recheck if the bonus get lost for all opponents).

@chase - i hade a quick peek at your code and it looks like you have the same "trouble" with your solution, as i had with my first try. Because an enemy can still shoot <1.0 bullets and the inactivity will not be canceled. This means basically that your waves on inactivity are of by 0.1 bullet power (0.3 pix per turn) . Probably not worth of thinking about it but if you add the uncertainty of wall damage that could become more "serious".

Well, maybe i should explain a little more why i'm nitpicking on this. Based on observations i made on almost all high ranked wave surfer bots, i'm playing with a experimental trick movement for those bots, based on 'forced' wall hits and shooting the same turn i hit the wall. I guess theoretically it could work quite nice and just for the sake of curiosity.

Wompi12:25, 13 December 2012

In theory you are quite right. In practice it could be less satisfying than expected. I and probably some more take into account accelerating/decelerating bots, although it will never be 100% proof. Decelerating at the right moment could give you the opportunity to fire a specific bulletpower without detection.
The discussion about inactivity timer got my attention though, I'll see if I can come up with something for my next release.

GrubbmGait14:38, 13 December 2012

just an update ... if the opponent dies by inactivity you get no score bonus for him. You also get no bonus if you die by inactivity for all alive opponents. It is still unclear what the conditions for inactivity in melee are. I tested 8 sitting ducks and 2 bots shooting 0.1 bullets and there was no inactivity trigger. Just 2 bots (0.1) and the inactivity kicks in around 450. I tested some other scenarios (3 bots, just shooting till everyone is below 40 energy) to, with very different inactivity behavior.

@GrubbmGait - actually, imagine a bot who drives with speed 4 to the wall and before he hits set speed to 2 and shoots with 1.0. There is no way to detect if it is a bullet or the wall hit damage.

Wompi16:31, 13 December 2012

I thought you wanted to detect inactivity because it confuses wave detection and looks like a bunch of 0.1 power waves are being fired. Gun heat tracking can help distinguishing inactivity from 0.1 power bullets being fired.

But trying to use wall hits to conceal a shot will make you bots movement quite predictable.

Analysing the last example, a bot with speed 4 which sets speed to 2 and shoots with power 1.0 will be shown in the opponents radar as a bot which decelerated from speed 4 to 0 and decreased 1.6 energy. Combat would detect a 1.0 power wave being fired (it ignores 0.6 energy drop whenever someone decelerates more than 2 in a single tick). But if it hits the wall with constant speed 2, then the 1.6 energy drop would be ambiguous. It could mean a 1.6 power bullet was fired and the bot stopped, or a wall hit with a 1.0 power bullet being fired. Currently, Combat would guess it is a 1.0 power bullet and if it was a 1.6 power bullet, dodging would be sub-optimal, but it would still react to the firing.

Another worse scenario: You hit the wall with constant speed 2. A false 0.6 power wave would be detected and gun heat tracking would kick in. Then, there would be a 12 tick window when a shot would go undetected. If it is a power 3.0 bullet, it would hit long after the 0.6 wave was dodged. Maybe I should disable gun heat tracking for 0.6 power bullets shot near walls.

MN18:16, 13 December 2012

If you hit the wall with speed <2.0 you get no wall damage. So the 4 (2) -> 0 shoot 1.0 example would result in an 1.0 energy drop. Same as if you hit the wall with speed 4 and no shooting.

For the inactivity thing - nope it is not to confuse wave detection it just messed with my bullet calculation. I guess i should not bring up 2 different things in one thread, sorry for that. Both things are just related to "Energy drop" and by now i want a almost 100% energy calculation.

Wompi19:36, 13 December 2012

I thought all collisions resulted in 0.6 damage. Combat would detect a 0.4 bullet being fired in the example above, and would react to the firing, although it should detect a wall collision with 1.0 damage. Sort of a Performance Enhancing Bug.

The energy drop is ambiguous and the real collision damage is anything between 0.0 and 1.0. Maybe dodging a "thick" wave representing bullet powers from 0.1 to 1.0 can account for this uncertainty. Similar to waves in melee where you don't know exactly in which tick the wave was fired due to gaps in radar scans. And taking extra care with gun heat tracking (maybe assuming the lowest case).

MN01:43, 14 December 2012

If you hit suddenly slowed before hitting the wall, Nene would assume it hit the wall and did not fire a bullet. Allowing you to get away with a free shot.

But I remind you that slamming into the wall may lower your own score (if you mess up). It also gives a huge and useful data spike and stops your robot. Which means may not work against the top bots very well. Since they are made to capitalize on that. After hitting a wall your avenue of escape is much smaller.

As I have shown with Nene very well, movement trumps targeting. You can hit the top 10 with a gun from 2004 (even if said gun from 2004 was the best from that time).

Chase03:26, 14 December 2012

@MN: check out http://robowiki.net/wiki/Robocode/Game_Physics#Collisions
@Wompi: I detect accelerating/decelerating bots, except when they only do it that last tick before hitting the wall, like your example. That's why I said it is not 100% proof.

As for the inactivity timer, a top bot would not have that situation often. Usually they fire until 0.1 energy left, and then just keep moving. When inactivity timer kicks in, the battle is immediately over. To counter that, you could move closer or even ram the opponent when it stops firing.

Just out curiosity, what is the purpose of keeping track of your own energy? I can't think of anything useful for me.

GrubbmGait09:01, 14 December 2012

Tracking your own energy helps detect inactivity damage kicking in. If the opponents energy drops 0.1, it could be due to inactivity or due to a 0.1 power bullet being fired. You can't be sure. But if your own energy drops 0.1 and you didn't shoot, it should be due to inactivity.

Not tracking inactivity damage results in a bunch of false 0.1 power waves being detected at end game. Usually not an issue, but having highly accurate wave detection is cool.

MN19:43, 14 December 2012

Remembered one case where inactivity damage is a big issue. Reference bots of targeting challenges don't shoot and always outlast candidates with inactivity damage. If they wrongly detect 0.1 power waves, it introduces a lot of noise in their wave histories and makes dodging weaker.

MN19:51, 14 December 2012

Yes, i'm using a range based calculation for the wall hits right now. The damage range is always 0 to -1.0 or 0 to +0.5 related to the last detected velocity. It makes the enemy gun heat calculation quite difficult.

If you combine the forced wall hit damage with some sort of chase bullet gun it would provide a quite challenging wave pattern, i guess.

And like i said above it is just an experimental movement, nothing to beat a certain bot. I would be happy if i can trick some wave surfer bots a little. To make it fully competitive it would need way more thoughts about it. Mostly i learn some new things while getting along with these experiments and that is the most fun for me.

Actually being predictable is not necessarily a bad thing. For example if you want to use a bullet catcher system to drain the enemy energy to a certain level. On the other hand you can move along the wall and if you time the wall hit, lets say, right after the enemy shoots, you got 10 to 16 + bulletTicks turns to find a better spot or dodge the bullet.

Yes, inactivity is probably nothing to worry about for top bots. But there are some bots out there who shoot always <1.0 bullets and dodging those bots to a certain energy level can take some time.

I'm tracking my energy most of the time for statistics like damage taken, bullets shot, wall damage and i have a energy slop system for me and the enemy to pick my right bullet power. Or better - if he/me looses energy based on his current slop which turn would he be at zero energy.

Wompi12:49, 14 December 2012