Elite's Bot Tutorial
Contents
Meet Animal Minimalis
This is Animal Minimalis: (He's been slightly modified to produce offspring with more energy, but otherwise he's the same)
'Animal Minimalis 'by Nums cond *.eye5 0 > *.refeye *.myeye != start *.refveldx .dx store *.refvelup 30 add .up store stop cond *.eye5 50 > *.refeye *.myeye != start -1 .shoot store *.refvelup .up store stop cond *.eye5 0 = *.refeye *.myeye = or start 314 rnd .aimdx store stop cond *.nrg 15000 > start 30 .repro store stop end
We're going to be using him to demonstrate each of the things I show you.
Basic Types of Shots
Did you know that there are a whole range of shots: not just -1 shots? The type of shot you fire depends on what number you put into .shoot.
- -1 Standard energy feeding shot
- -2 Energy shot
- -3 Venom shot
- -4 Waste shot
- -5 Poison shot (can only be fired automatically)
- -6 Body feeding shot
Feeding
To feed from another bot you need to use either a -1 shot or a -6 shot.
Simpler bots may only ever use -1 shots, but they miss out on the advantages of using -6 shots. -6 shots do not trigger poison, and so are particularly helpful when facing an enemy that uses poison. -6 shots are also usually more efficient against vegetables and will also kill them quicker. Of course there are also occasions when a -1 shot may be preferable to a -6 shot, for example if your enemy has a thick shell.
Vegetables are much more easily fed on by -6 shots than -1 shots. You can see this in action with Animal Minimalis. Load him up and see how it does. Then modify him to use only -6 shots. Load him up again and you will see that he is much better at killing veggies.
For maximum efficiency you need to use an evaluation system to decide which shot to use when facing an enemy. You would probably want to use -6 shots on veggies, bots with poison and bots with no poison or shell, and -1 shots on bots with shell. You can decide yourself on what to do with bots with both poison and shell. You will need to make use of the refvars .refpoison and .refshell. You might also use .refnrg and .refbody to evaluate an enemy.
Waste
Putting -4 in .shoot fires a waste shot. You should put a gene in your bot somewhere to dispose of waste, but you can make do without; especially if your bot is only designed to last only for a short time (ie. in a league). .shootval determines how much waste you will fire.
Here's a simple 'waste disposal' gene. I've done the work for you, so now you've got no excuse ...
cond *.waste 40 > start .backshot inc -4 .shoot store *.waste .shootval store stop
This gene will make a bot fire all of it's waste out of it's rear end when the amount of waste it's carrying exceeds 40.
If the amount of waste you're carrying exceeds the 'waste threshold' set at the start of the sim, then the bot will start to store random values in random memory locations.
The most common 'accident' is for a bot to store a number in .fixpos and become stuck to the spot.
Memory Shots
Now you're wondering: "what happens when I put a positive number into .shoot"
This type of shot, rather than taking energy from another bot, will alter another bot's memory. You can use this sneaky tactic to gain a tactical advantage over other bots.
Store a memory location in .shoot and that memory location will be overwriten by the contents of .shootval. Sounds complicated? Here's an example from Light's bot Icarus, which used this tactic to dominate the F2 league for a while:
.aimdx .shoot store 314 .shootval store
This shot would cause the poor bot that got hit by it to turn 90 degrees to the right.
You can also use memory shots to fix a bot by shooting 1 into .fixpos. You can counter this by using the gene below, which will unstick your bot if it becomes stuck. You should probably include this gene anyway just in case.
cond start .fixpos *.fixed mult dec stop
Some bots in the past have used memory shots as a offensive weapons, forcing bots to use up massive amounts of energy by storing ridiculously high values in movement sysvars, or forcing bots to feed so heavily on their body that they died. This was supposed to have been fixed, but ...
Shootval
For version 2.36 and above, you can use .shootval to increase the power and range of shots. Did you know that? Using this feature will give you a great advantage over bots that don't, so what are you waiting for!
Here's how it works:
- Putting negative numbers in .shootval will increase the range of -2 shots and -6 shots..
- Putting positive numbers in .shootval will increase the power of -1 shots, -2 shots and -6 shots.
The multiplier is log base 2 of .shootval. So putting -4 or 4 in shootval will double the range or shot strength. Putting -8 or 8 in .shootval will triple it. Putting -16 or 16 in .shootval will quadruple it and so on.
Animal Minimalis demo
Here's Animal Minimalis with powered-up shots. See how much better he performs.
cond *.eye5 0 > *.refeye *.myeye != start *.refveldx .dx store *.refvelup 30 add .up store stop cond *.eye5 50 > *.refeye *.myeye != start 8 .shootval store -1 .shoot store *.refvelup .up store stop cond *.eye5 0 = *.refeye *.myeye = or start 314 rnd .aimdx store stop cond *.nrg 15000 > start 30 .repro store stop end
Backshot and Aimshoot
.backshot and .aimshoot can be used to aim shots at directions other than the direction the bot is facing. Can you think of a use for this?
Storing a positive number in .backshot makes the bot fire backwards on that cycle. A simple way of doing this is using inc
.backshot inc
.aimshoot allows you to specify an angle to shoot at. The angle is measured counter-clockwise from the bot's eye5 vector (where it's facing). Here's some examples:
314 .aimshoot store
Fires 90 degrees to the left of the bot's eye.
628 .aimshoot store
Fires directly behind the bot.
You can use .aimshoot in conjunction with .shang and .shflav to fire back at enemies that hit you. Take a look at this neat gene:
cond *.shflav 0 != *.shflav -2 != start 1256 *.shang sub .aimshoot store 8 .shootval store -6 .shoot store 0 .shflav store stop
Notice anything? *.shang is measured clockwise from 90 degrees right of the bot's eye (for some reason) and so 1256 *.shang sub (1256 - *.shang) compensates for this.
Poison and Shell
Now, what about defending against other bot's shots? There are two ways of defending against shots:
Poison
"Don't attack me - I'm poisonous!"
Poison is stored by using .strpoison. You can see how much poison you have stored by referencing .poison.
If an enemy -1 shot hits you, you will fire poison back at your attacker. When poison hits an enemy, one of his memory locations will be set to zero for a period of time.
The memory location specified in the .ploc of the bot that fired the poison defines which memory location will be affected. If .ploc is not specified then a random memory location will be affected.
Good targets of poison (put into .ploc) are:
- .shoot (perhaps the most popular: prevents your enemy from shooting),
- .eye5 (blinds your enemy)
- .refeye or .myeye (disables enemy conspec recognition).
Shell
You can make a nice thick shell to protect you from body shots ...
Shell can be made by using .mkshell. You can see how much shell you have made by referencing .shell.
Shell defends against -6 (body) shots and venom. It will wear away slowly as it is hit but the big disadvantage of shell is that it makes you heavier and slower. Shell does not defend against -1 shots, which will just go straight through it.
Animal Minimalis demo
I've modified Animal Minimalis to use shell and poison. Give him a try. Feel free to play around with him.
cond *.robage 0 = start .shoot .ploc store stop cond *.eye5 0 > *.refeye *.myeye != start *.refveldx .dx store *.refvelup 30 add .up store stop cond *.eye5 50 > *.refeye *.myeye != start -1 .shoot store *.refvelup .up store stop cond *.eye5 0 = *.refeye *.myeye = or start 314 rnd .aimdx store stop cond *.poison 500 < start 50 .strpoison store stop cond *.shell 250 < start 100 .mkshell store stop cond *.nrg 15000 > start 30 .repro store stop end
Venom
Yey, venom - this stuff is great fun!
Venom is similar to poison. It can be stored using .strvenom. You can see how much venom you have stored by referencing .venom. The effects of venom are determined by the sysvars .vloc and .venval. .vloc serves the same function as .ploc - specifying a memory location. However, rather than just setting a memory location to zero, venom sets it to a specific value (.venval)
Venom can be fired by storing -3 in .shoot. The amount of venom you fire depends on .shootval. More venom lasts longer.
You can do all kinds of fun things with venom:
- Making an enemy move
- Storing 1 in .fixpos, rooting an enemy to the spot
- Storing -2 in .shoot, making your enemy fire energy
- Storing your .myeye in his .refeye, fooling refeye/myeye based conspec recognition systems
- Storing -32000 in .mkshell or .strpoison, stripping your enemy of his defences
The possibilities are endless.
Animal Minimalis demo
Here's Animal Minimalis modified to use venom. Can you see how it works?
This technique was 'borrowed' from PY.
def venomcounter 51 cond *.robage 0 = start .shoot .vloc store -2 .venval store stop cond *.eye5 0 > *.refeye *.myeye != start *.refveldx .dx store *.refvelup 30 add .up store stop cond *.eye5 50 > *.refeye *.myeye != start .venomcounter inc -1 .shoot store *.refvelup .up store stop cond *.venomcounter 19 > start 50 .shootval store -3 .shoot store 0 .venomcounter store stop cond *.eye5 0 = *.refeye *.myeye = or start 314 rnd .aimdx store 0 .venomcounter store stop cond *.venom 500 < start 50 .strvenom store stop cond *.nrg 15000 > start 30 .repro store stop end
You may need to check out this wiki article is you are unsure as to what the first line does.
Alga Toxicus
Here's an alga I made that uses poison and venom
cond *.robage 0 = start .shoot .ploc store .shoot .vloc store -2 .venval store stop cond start 120 rnd .aimdx store -3 .shoot store stop cond *.nrg 1000 > start 50 .repro store 100 .strpoison store 100 .strvenom store stop end
It is easy to substitute the values for the posion and venom for your own. Have a play around, go on ... come back when you're ready to move onto viruses.
Viruses
Viruses are cyan-coloured shots that can be used to inject a gene into other bots. You can do tons of stuff with viruses. I couldn't possibly cover all the possibilities here but here's the basics, and you can have an experiment yourself.
Making and firing viruses
Here's how to make and fire a virus:
- Copy one of your genes into .mkvirus
If you want to make gene number one into a virus then store 1 into .mkvirus. If you want to copy the current gene into a virus then use *.thisgene. This can be used to create self-replicating viruses.
- Fire the virus
The virus takes time to be copied. The larger the gene, the longer it takes. The time taken is the length of the gene multiplied by two.
*.vtimer tells you what the status of the virus is: If *.vtimer = 0 then there is no virus being copied, and you must create one by storing a gene number into .mkvirus. If *.vtimer > 1 then the virus is being prepared - be patient. Once *.vtimer reaches 1 the virus is ready - fire it by storing a positive number into .vshoot. The bigger the number you put into .vshoot, the further the virus will go but be aware that .vshoot is also the energy cost. about 100 will do for a reasonably-ranged virus.
Viruses
If you want your virus to self-replicate then add this to the viral code:
*.thisgene .mkvirus store 200 .vshoot store
As to what the virus does the choice is yours. Here are some examples:
' Breaks up multibots and prevents tie-feeders from feeding *.tiepres .deltie store
' Deletes all of the infected bot's genes *.thisgene 1 rnd 2 mult -1 add add .delgene store
' Makes the infected bot reproduce itself to death 50 .repro store
' Stops the infected bot from shooting 0 .shoot store
' Stops the infected bot from reproducing 0 .repro store
And so on ... feel free to think up some more.
Some of these viruses are rather deadly. You certainly don't want them executing in your gene code so you're going to have to add something to stop them executing when they're in you.
The simplest way is for your to use a memory location to identify you and your species. Add this gene to your gene code:
cond *.robage 0 = start 7 989 store stop
And this condition to your virus:
cond 7 *989 !=
Now your virus will only execute in enemy bots. Problem solved!
Animal Minimalis demo
Here's Animal Minimalis modified to use a virus.
cond *.robage 0 = start 7 989 store stop cond *.vitmer 0 = start 3 .mkvirus store stop cond 7 *989 != start *.thisgene 1 rnd 2 mult -1 add add .delgene store stop cond *.eye5 0 > *.refeye *.myeye != start *.refveldx .dx store *.refvelup 30 add .up store 50 .vshoot store stop cond *.eye5 50 > *.refeye *.myeye != start -1 .shoot store *.refvelup .up store stop cond *.eye5 0 = *.refeye *.myeye = or start 314 rnd .aimdx store stop cond *.nrg 15000 > start 30 .repro store stop end
The virus is gene 3. You can substitute it for a virus of your own.
Defending against viruses
There are ways of countering viruses, but most of them are very, very complex, involving elaborate gene-checking. There are some simple ways though.
1) Remember that a self-replicating virus has to use .mkvirus to propagate itself. It's actually telling you where it is in your genome! Use .delgene to delete it:
cond *.mkvirus 0 != start *.mkvirus .delgene store stop
2) A much underused way of defending against viruses is to use slime. Slime can be made by using .mkslime and you can see how much slime you have made by referencing .slime. Slime wears away slowly over time though, you will need to replace it periodically. Slime also reduces the chance of enemy ties hitting you.
A few hundred units of slime will keep all but the most determined virusbot at bay.
Animal Minimalis demo
Here is Animal Minimalis, modified to use the anitvirus methods we've been discussing.
cond *.eye5 0 > *.refeye *.myeye != start *.refveldx .dx store *.refvelup 30 add .up store stop cond *.eye5 50 > *.refeye *.myeye != start -1 .shoot store *.refvelup .up store stop cond *.eye5 0 = *.refeye *.myeye = or start 314 rnd .aimdx store stop cond *.slime 300 < start 100 .mkslime store stop cond *.nrg 15000 > start 30 .repro store stop cond *.mkvirus 0 != start *.mkvirus .delgene store stop end
Ending Thoughts
Well, I hope this tutorial has been useful to you. Good luck with coding a new advanced bot!
Elite