Talk:Portia

From Robowiki
Revision as of 05:40, 25 September 2009 by Zyx (talk | contribs) (→‎Portia 1.24a: good job)
Jump to navigation Jump to search

How many call to sin & cos do you do each tick? If it is below 10,000, that isn't a reason, or you think it is slow while in fact it isn't. Oh I see... you have a lot of small classes, which is obfuscated I think (no one name the class a,aa,ab,...) » Nat | Talk » 10:15, 12 July 2009 (UTC)

Hey Nat, I've tested it, and its speed is about half the speed of Shadow. I believe I'm using about 700 trigonometry functions and 200 sqrts each tick, depending on the situation. If that's not it, I'm not sure what is. Maybe its the simulated bullets, I'll have a look for a next version. I've speed and size optimized the .jar, that's why you see the "a,aa,ab,...". --Positive 18:23, 12 July 2009 (UTC)
Just curious, what program are you using for the speed and size optimizations? I'd be interested in trying it on DrussGT to see if it solves my skipped turn problems =) Also, one way to speed up your bot quite a bit is to only aim your gun for the 4 ticks before you fire, and the rest of the time just point your gun straight at the enemy's location. --Skilgannon 21:23, 12 July 2009 (UTC)
I used ProGuard 4.3 for the optimization. Tell me what it does for Druss. :) Just aiming your gun for the opponent is a good idea, and Portia already does it. :) 22:11, 12 July 2009 (UTC)
I just noticed, Portia doesn't do it for the solo gun. Adding it now. :) --Positive 21:54, 16 July 2009 (UTC)

By the way, I'd like to hear your opinion about Portia (if you've played with him). I think the meleemovement is quite different from most bots, and it seems to be doing great (6th in the meleerumble at the moment). --Positive 22:11, 12 July 2009 (UTC)

Congrats on a really awesome debut, dude! The rating will still fluctuate quite a bit until you hit full pairings and ~2,000 battles, but I bet it stays at 5th or 6th. I've been easing back into work on Diamond -- now I'm even more motivated. ;) --Voidious 22:36, 12 July 2009 (UTC)

Thank you. :) I'm glad my bot poses a new challenge to you. :P For the solo part, I've already spent many hours trying to defeat Dookious as well. Not very successfull though, at least not after he activates that damn flattener. ;)

Hi there, welcome to Robocode. Thanks for making me run some melee battles again, great movement you got there, congrats. I'm even thinking about making my own melee bullet detector now... --ABC 23:47, 13 July 2009 (UTC)

ABC, are you checking the wiki all the time and make no comment? PS. Sorry if I get Portuguese wrong, result from Google Translate » Nat | Talk » 12:44, 14 July 2009 (UTC)
Not all the time, but I still check the wiki and the RR server frequently. My life has been a bit too busy to participate actively, though. Your Portuguese was correct, and I didn't forget the email you sent me, btw. :) --ABC 14:28, 14 July 2009 (UTC)
Thank you. :) --Positive 19:43, 14 July 2009 (UTC)

DC Pattern Matching or DC Play-it Forward? If it is really DC-PM, I'm really interested on how it works. » Nat | Talk » 13:11, 3 August 2009 (UTC)

What's the difference? --Positive 13:27, 3 August 2009 (UTC)
Well, I'm guessing you just mean a DC / "Tron's Gun" style gun, which used to be called a "forward pattern matcher" and was once generally considered PM. But the consensus is that it really isn't pattern matching at all, so I think Nat is wondering if you're doing some new type of DC gun that also uses pattern matching. --Voidious 13:30, 3 August 2009 (UTC)
Yes, I based the gun on TronsGun page. So I guess that makes it a forward pattern matcher. Portia 1.12 makes a "pattern" based on the opponents: displacement vectors for roughly the last 30 ticks, current velocity, acceleration, and other variables like distance to wall. It then stores that "pattern" 100 turns later in the KD-tree, with a reference to the turn it was recorded, if the opponent is still alive. :) --Positive 13:53, 3 August 2009 (UTC)
What do you do with those 30 displacement vectors? Do you have like 35 dimensions in your tree, or is it something else? Great job with the new gun, looks like you might snag 3rd (knock on wood). --Voidious 14:12, 3 August 2009 (UTC)
Thanks (quickly knocks on wood as well)! :) It calculates 3 displacement vectors over those 30 turns, and takes 1 heading difference and 3 displacements from them for dimensions. I don't think 35 dimensions would be very managable. :P --Positive 14:41, 3 August 2009 (UTC)
Wow, really amazing! Huge congrats on 3rd place with 1.12 - and closing in on Aleph! --Voidious 00:44, 4 August 2009 (UTC)
Thankyou. I didn't dare hope such a jump. :) It's pretty exciting how much you can do, and is still possible in melee. :) --Positive 11:04, 4 August 2009 (UTC)

You really are amazing me - congrats on overtaking Aleph for the #2 spot! If I were ABC, I might start getting a little scared. =) But Shadow still has a pretty incredible lead (3.83 was about 1% APS higher than 3.84) ... for now. Best of luck in your quest for the throne! Hope to catch up sometime. --Voidious 16:55, 11 August 2009 (UTC)

Big congrats from me too, great work. Don't stop now, you are going places! ;) --ABC 17:04, 11 August 2009 (UTC)

Very nice job man. I don't know if there are differences on the 1v1 code of versions 1.0 and 1.13, if there are you should enter version 1.13 in the 1v1 competition to compare it to Shadow, maybe there is a chance to boost Portia by turning seconds to firsts? Although looking at their battles, would make me think that you should be improving you gun, check the bullet damage difference between them. Good luck, and congrats again. --zyx 17:18, 11 August 2009 (UTC)

Oh my... very nice stuff here! I really need to finish my accursed melee bot and see if I can at least overtake Diamond. Hmm... I wonder what you would get if you combined Gaff's 1v1 gun, DrussGT's 1v1 movement, Portia's melee movement, and Shadow's melee gun... :) --Rednaxela 18:13, 11 August 2009 (UTC)

In terms of Melee performance... probably something a lot like the current Shadow. :-) --Voidious 18:19, 11 August 2009 (UTC)

Thank you. :) I'm as amazed as you guys. Don't worry, I still have some more ideas. :) Turning more seconds into firsts would be great. The thing is that 1v1 in the meleerumble is a lot different from in the solorumble, so I think something special is needed for that. Right now I'm thinking about perhaps extending the bullet simulation for 1v1, to combine with the Stop 'n go. Would you recommend any quick 1v1-gun technique? --Positive 20:30, 11 August 2009 (UTC)

Congrats from me too! For one-on-one, I think you should take a look into Wave Surfing. I know it isn't fast, but it's fun! And perhaps DC-GF gun will help you too. » Nat | Talk » 23:28, 11 August 2009 (UTC)

A DC-GF gun is certainly not needed. Diamond, and even more so Shadow, have quite strong 1v1 guns that are non-GF DC. Keeping it simple and not using a second gun for 1v1 would probably be a more sensible approach. I'd recommend keeping Portia with the same DC-PIF gun it has now, but simply improving it's 1v1 performance. I recommend experimenting with the dimensions that are used in the KD-Tree, as well as the number of nearest neighbors returned from that at a time. --Rednaxela 00:18, 12 August 2009 (UTC)

I don't think 1v1 performance is even that important in Melee. How much energy you take into the final duel is usually way more important. Some really solid HOT-avoidance is useful, but it sounds like you already have that.

Have you benchmarked your gun at all? You might try some Targeting Challenges if you really think there are lots of points there. I agree you don't need any specific technique, e.g. GuessFactors. Making every aspect of your data collection as accurate as possible is really important. Make sure all your attributes are working right, try different weights and attributes and cluster sizes. Try removing attributes that you "know" are good, but that you've never considered removing, try the exact opposite of what you think should work... =) Good luck.

--Voidious 00:52, 12 August 2009 (UTC)

You're right, the 1v1 code isn't so important in melee. However, I often see Portia lose against robots like Infinity and Griezel because Portia misses most shots. I really like the the idea of somehow using the main DC gun in 1v1, that'd solve the Infinity "problem". :) I haven't done any benchmarking, mainly because I often delete and rewrite entire parts, and the benchmarks would be lost. But I can see how in this case it might be smart. In any case, those definitely are some great tips. Thank you. :) --Positive 12:15, 12 August 2009 (UTC)

Okay I was just buzy with making some screenshots for the Portia page, when I realized it would be cooler to put up a video on youtube for it. Now I've seen some video's on youtube, but there isn't much info on the wiki. I'm thinking to put a description like "For more info about this free programming game, visit robowiki.net" and tag "robocode". I was wondering if you agree and/or have some recommendations? --Positive 22:00, 13 August 2009 (UTC)

I think that would be very cool. I've searched YouTube for Robocode vids a few times so that I could show people what Robocode is like, and while there are some videos there, not too many are showing high level / modern bots. And that's fine, but slightly less impressive when trying to attract newcomers. =) --Voidious 22:10, 13 August 2009 (UTC)
Exactly. :) If more people like to do something like this, we could put a wiki page up for it as well. Do you suggest any tags or description? --Positive 22:14, 13 August 2009 (UTC)

I'm not sure how much it is affecting performance (your MeleeRumble score still seems OK), but I'm seeing a NullPointerException for Portia 1.14 (on both my systems):

java.lang.NullPointerException
	at positive.bd.a(Unknown Source)
	at positive.bf.a(Unknown Source)
	at positive.bf.a(Unknown Source)
	at positive.Portia.onScannedRobot(Unknown Source)
	at robocode.ScannedRobotEvent.dispatch(ScannedRobotEvent.java:297)
	at robocode.Event$HiddenEventHelper.dispatch(Event.java:249)
	at net.sf.robocode.security.HiddenAccess.dispatch(HiddenAccess.java:195)
	at net.sf.robocode.host.events.EventManager.dispatch(EventManager.java:486)
	at net.sf.robocode.host.events.EventManager.processEvents(EventManager.java:459)
	at net.sf.robocode.host.proxies.BasicRobotProxy.executeImpl(BasicRobotProxy.java:403)
	at net.sf.robocode.host.proxies.BasicRobotProxy.execute(BasicRobotProxy.java:119)
	at robocode.AdvancedRobot.execute(AdvancedRobot.java:565)
	at positive.Portia.run(Unknown Source)
	at net.sf.robocode.host.proxies.HostingRobotProxy.run(HostingRobotProxy.java:250)
	at java.lang.Thread.run(Thread.java:619)

--Voidious 20:52, 15 August 2009 (UTC)

Hrm, how much of it are you seeing? --Positive 21:03, 15 August 2009 (UTC)

I saw it a few times each battle on my Linux RoboRumble client, so I ran one battle on my Mac and saw it a couple of times there too (to get the stack trace). Once was right as Portia won the round, the other wasn't (but maybe was right before/after a kill). --Voidious 21:06, 15 August 2009 (UTC)

I'll have to ponder about this. Thank you for the headsup. :) --Positive 21:11, 15 August 2009 (UTC)

As you note you can't seem to reproduce it, I'll just mention that I was also seeing this happen to Portia 1.14 very frequently. It seems to have disappeared in 1.15 though as I haven't seen it throw an exception yet. --Rednaxela 23:41, 18 August 2009 (UTC)
Hmm, it's possible the exception you saw was being caused as a side effect of the solved bug. Could you perhaps do me a favour: run Portia with 9 other bots in your 1.6.1.4 client, run some rounds and look at the output screen. Do you see Portia printing "Caught exception..." there? Thanks for helping in any case. :) --Positive 01:44, 19 August 2009 (UTC)

There's something I've been wondering about. I know your melee movement is largely based on bullet dodging, but I imagine you take other risk-type things into account, as well. I can't help but wonder how well your movement actually dodges bullets - i.e., I wonder if perhaps the bullet dodging just serves as an effective Random Movement, rather than bullet dodging, per se? For instance, against 9 Shiz or HawkOnFire bots, would Portia perform incredibly well, because it actually dodges the HOT very effectively? What against about 9 LT/CT guns? Have you measured the effectiveness of the bullet dodging in this way? Just curious... --Voidious 18:18, 18 August 2009 (UTC)

Yes, I have tested it. It does dodge HOT quite effectively. LT/CT is harder, because there are many different implementations for it. I think it does a best guess, and if it's not correct it will attribute to an at least hard to predict movement. In other words, I don't think its just a good Random Movement. --Positive 20:06, 18 August 2009 (UTC)
My melee bot in progress is still very much a fledgeling, but I find it's HOT dodging, which is somewhat similar to Portia's, is notably better than the movement of MiniSurreptitious. --Rednaxela 22:37, 18 August 2009 (UTC)
I'm also slightly sceptical about the effectiveness of bullet dodging. Like Voidious said, you should see amazing survival scores against a field of HawkOnFires, and I'm not seeing them. In fact, Shadow scores about the same (or slightly worse) with its new HOT surfing movement as it does with the traditional minimum risk movement. The positional strategy in melee is the bigger factor, no use in bullet dodging yourself into the middle of the field where you will die almost instantly... --ABC 12:08, 19 August 2009 (UTC)
I don't know if it counts as amazing, but if you try Portia 1.16 against a field of HawkOnFire's you'll see about an 85% survival rate. :) --Positive 13:29, 23 August 2009 (UTC)
That is impressive, and certainly proves that your implementation of bullet dodging works. It didn't do much for Portia's ranking, though. But please keep it up, it also took me a while to make my 1on1 bullet dodging outrank the random moving champion of that time... ;) --ABC 17:05, 24 August 2009 (UTC)

Well, Portia 1.15 is about 1% aps lower than 1.13 now, and I really wonder why. Voidious and Rednaxela, I'd be very grateful if you could check if Portia is reporting bugs (in its output screen) in your 1.6.1.4 clients. --Positive 19:45, 19 August 2009 (UTC)

I will run some battles for you manually when I get home and let you know what I find. Like Rednaxela, I didn't notice any exceptions with 1.15 when I watched it for a bit. Sorry, having bad versions and wondering if it's due to weird errors sucks. =( --Voidious 19:49, 19 August 2009 (UTC)
Yes, I'm still seeing it with 1.15. I only had to run one battle, and saw this error in rounds 1 and 22.
positive.Portia 1.15: Exception: java.lang.NullPointerException
java.lang.NullPointerException
	at positive.bd.a(Unknown Source)
	at positive.bf.a(Unknown Source)
	at positive.bf.a(Unknown Source)
	at positive.Portia.onScannedRobot(Unknown Source)
	at robocode.peer.robot.EventManager.onScannedRobot(Unknown Source)
	at robocode.peer.robot.EventManager.dispatchEvent(Unknown Source)
	at robocode.peer.robot.EventManager.processEvents(Unknown Source)
	at robocode.peer.RobotPeer.execute(Unknown Source)
	at robocode.peer.proxies.BasicRobotProxy.execute(Unknown Source)
	at robocode.AdvancedRobot.execute(Unknown Source)
	at positive.Portia.run(Unknown Source)
	at robocode.peer.RobotPeer.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:619)
I'll try to watch some battles and see if I can understand the scenario better. I'm using 3x HawkOnFire, 2x Coriantumr, 2x zyx.nano.BacillusComma 1.0, 1x Diamond 1.272, and 1x zyx.micro.Ant 2.1 as the other bots. --Voidious 21:55, 19 August 2009 (UTC)
Do you see it printing 'Caught an exception...' as well? --Positive 22:31, 19 August 2009 (UTC)
No, I'm not seeing that at all, though I think I remember seeing it in 1.14? The NPE seems very intermittent, I can't reproduce it every match. I tried clearing the data dir and I got it at round 5, but I think that was just coincidence. I really doubt an NPE would be JVM dependent, though, maybe you can try the above test bed? I'll probably tinker with it more later, I'll let you know if I find anything... --Voidious 22:54, 19 August 2009 (UTC)
Okay, I finished running 3 seasons of 35 rounds in my 1.6.1.4 using your configuration (except Ant 1.1 instead of 2.1) (Java 1.6.0_14, pre-superpack version), and I haven't seen any errors at all. Of course, feel free to tinker, but I think I'll try to add some diagnostics to the next version so it will be more easy to find what's wrong. Thanks for your help. :) --Positive 23:35, 19 August 2009 (UTC)

If you guys have been getting more exceptions, I'd like to hear it! --Positive 13:29, 23 August 2009 (UTC)

If you haven't had any exceptions, I'd like to hear it too. :) --Positive 15:54, 24 August 2009 (UTC)

Sorry, I was busy this weekend and forgot to check. I'll run some matches for you later today. --Voidious 15:55, 24 August 2009 (UTC)
Great, thanks for the help. --Positive 12:59, 25 August 2009 (UTC)
Sorry for the delay on this... And unfortunately, it took me 3 matches, but I hit the NPE again:
=========================
Round 31 of 35
=========================
SYSTEM: Bonus for killing zyx.nano.BacillusComma 1.0 (1): 9
SYSTEM: Bonus for killing kawigi.mini.Coriantumr 1.1 (2): 2
positive.Portia 1.16: Exception: java.lang.NullPointerException
java.lang.NullPointerException
	at positive.bc.a(Unknown Source)
	at positive.be.a(Unknown Source)
	at positive.be.a(Unknown Source)
	at positive.Portia.onScannedRobot(Unknown Source)
	at robocode.peer.robot.EventManager.onScannedRobot(Unknown Source)
	at robocode.peer.robot.EventManager.dispatchEvent(Unknown Source)
	at robocode.peer.robot.EventManager.processEvents(Unknown Source)
	at robocode.peer.RobotPeer.execute(Unknown Source)
	at robocode.peer.proxies.BasicRobotProxy.execute(Unknown Source)
	at robocode.AdvancedRobot.execute(Unknown Source)
	at positive.Portia.run(Unknown Source)
	at robocode.peer.RobotPeer.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:619)
Sadly, it seems too infrequent for me to reproduce it reliably and see what's going on in the match, though I will try it with replays. By the way, have you tried reproducing it with your compiled/rumble version of Portia? I imagine you usually develop/test from your real source code/classes, before obfuscating / packaging into a .jar. That's the only significant difference I can think of as to how I'm reproducing this. I still say a NPE isn't likely to be JVM-dependent -- and I'm actually on a different computer and JVM now than I was last week. --Voidious 22:33, 26 August 2009 (UTC)
I was glad to realize I already had replays enabled, so I could replay the above match. It definitely appears to happen right after Portia kills Coriantumr. The result is Portia is disabled for that round. Maybe there is some issue with receiving an onRobotDeath and an onScannedRobot of the same bot on the same tick? Keep in mind that onScannedRobot will always process last, so you could get a scan of a "dead" robot. Hope that helps. --Voidious 22:42, 26 August 2009 (UTC)
Scratch that - I reproduced it again and it was not timed right after a kill, and in fact it didn't seem to be in sync with any other events (like onBulletHit, onHitByBullet, onBulletHitBullet). This time it was later in a round, down to 3 bots. --Voidious 22:59, 26 August 2009 (UTC)
I've have installed the super pack and ran several matches, but can't reproduce it (with the packed version). I think you're right, it has probably got something to do with my pc. I'll try to install it on someone elses pc, see what happens. :) The method the error is occuring in is huge, so I'll need to use the original classes to find exactly where its happening. I guess I'm a little disappointed, I was expecting many errors to account for the lowered %APS, but I guess it has something to do with my 'improvements'... Thanks for testing, I really appreciate it! --Positive 23:51, 26 August 2009 (UTC)
No problem. Actually, I still don't understand how a NPE could be JVM or platform specific. Subtler things like rounding errors I can understand... but whether or not an object reference is null or not, it seems harder to explain how that could be different under different JVMs. If you want to post a Portia with some additional debugging or anything, I'll gladly run some more matches for you. Good luck! --Voidious 04:02, 27 August 2009 (UTC)
I haven't been able to reproduce it on the other pc either (running several matches and with different clients), but I think I might have found the cause of the problem: I've read through the code you're getting the error at, and it's possible it will get a NPE if Portia has skipped turns. So I'm making a workaround/test for that, and hopefully have a new version soon. :) --Positive 16:19, 28 August 2009 (UTC)
When you have the time to take a look, could you post the all-game statistics Portia 1.17 is showing when you run it in your client? I'm very curious... --Positive 15:08, 29 August 2009 (UTC)
I'd test myself... but I can't access robocoderepository.com. It looks like domain name is gone... --Rednaxela 16:22, 29 August 2009 (UTC)
Sure. Here are the results from my 3 MeleeRumble clients:
Total, all-game statistics for Portia:
- Matches fought: 11
- Rounds fought: 385
- 1st places: 197 (51.16883116883117%)
- 2nd places: 71 (18.441558441558442%)
- 3rd places: 28 (7.2727272727272725%)
- Rounds one or more turns was skipped: 8
- Matches one or more turns was skipped: 8
- Rounds one or more strange exceptions were thrown: 0
- Matches one or more strange exceptions were thrown: 0
...
Total, all-game statistics for Portia:
- Matches fought: 105
- Rounds fought: 3675
- 1st places: 2011 (54.72108843537415%)
- 2nd places: 600 (16.3265306122449%)
- 3rd places: 293 (7.9727891156462585%)
- Rounds one or more turns was skipped: 27
- Matches one or more turns was skipped: 23
- Rounds one or more strange exceptions were thrown: 0
- Matches one or more strange exceptions were thrown: 0
...
Total, all-game statistics for Portia:
- Matches fought: 99
- Rounds fought: 3464
- 1st places: 1967 (56.78406466512702%)
- 2nd places: 564 (16.28175519630485%)
- 3rd places: 289 (8.34295612009238%)
- Rounds one or more turns was skipped: 32
- Matches one or more turns was skipped: 23
- Rounds one or more strange exceptions were thrown: 0
- Matches one or more strange exceptions were thrown: 0
Looks like you've got the exceptions taken care of... Now you can get back to whooping our butts and making it look easy. =) --Voidious 17:02, 29 August 2009 (UTC)
Thank you, I'll get back to that. :P --Positive 17:23, 29 August 2009 (UTC)
I'm sorry to say, but I saw 2 NPE's for Portia 1.18 in 35 round battle for the meleerumble. Client is running with only some browser-activity. :-( --GrubbmGait 01:28, 30 August 2009 (UTC)
Thanks for reporting. Could you perhaps copy/paste a stacktrace (so I have an idea where the problem lies)? I haven't seen Portia 1.18 throw any exceptions on my system as of yet. --Positive 13:43, 30 August 2009 (UTC)
I saw it in the meleerumble window, so no stacktrace available. It did not seem to hurt the score though. Late this evening I will try to run some local battles to see if I can reproduce it. --GrubbmGait 15:40, 30 August 2009 (UTC)
I tried to eliminate any possible source of the NPE I could find in Portia 1.19. Please tell me if you have any more. :) --Positive 21:09, 30 August 2009 (UTC)
Checked it with version 1.19 outside the rumble, no NPE's or other strange things happened. --GrubbmGait 01:30, 31 August 2009 (UTC)
Thanks for checking! --Positive 17:52, 31 August 2009 (UTC)

1.22

There are a lot of duplicates in the top-10 right now, but Portia 1.22 seems to have slipped into the #2 spot, 0.03 APS ahead of Shadow... whether it holds or not, you're very close! --Darkcanuck 05:54, 22 September 2009 (UTC)

Nearly! It is now tied with Shadow, but with better Survival, yet less PL. This should give a hard battle for Shadow! » Nat Pavasant » 11:02, 22 September 2009 (UTC)

I'm pretty excited as well, whether it holds or not. :) --Positive 11:11, 22 September 2009 (UTC)

Now it seems that Portia is slightly lower, but still within a margin that I'd consider explainable by random luck. Still, either way, nice stuff Positive :) --Rednaxela 12:20, 22 September 2009 (UTC)

Very nice! Wow, this battle is heating up. =) Good luck in your quest for the throne! --Voidious 12:24, 22 September 2009 (UTC)

Portia 1.24a

Looks like it's going to top Shadow finally, nice stuff :) --Rednaxela 19:54, 24 September 2009 (UTC)

Thank you. :) It's a pretty exciting race. I wonder what score Portia would get if it had a solo mode as good as Diamond's or Shadow's. --Positive 21:48, 24 September 2009 (UTC)
Nice work! If your solo mode is weak, I'd bet that you could put Diamond's throne in jeopardy by improving it... --Darkcanuck 02:37, 25 September 2009 (UTC)
Congrats, man! I too wonder how much you could gain from a stronger 1v1 game. Any plans to implement Wave Surfing? I've found it quite fun to do both melee and 1v1, actually - by the time I get frustrated in one, I usually have some inspiration in the other. --Voidious 03:11, 25 September 2009 (UTC)
Good job man. About the 1v1 I don't it matters that much on the melee score, actually being more random than adapting may be better since the other bots usually won't have time to learn much about you. Of course dodging HOT is important as many melee bots will just shoot HOT, and Wave Surfing is really fun to implement and see it dodge bullets. --zyx 03:40, 25 September 2009 (UTC)