Author Topic: Bot DNA  (Read 19586 times)

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
Bot DNA
« on: July 16, 2007, 02:38:01 AM »
I'm hoping to encourage some brainstorming about new DNA forms here.  I'll start with some of my own observations and ideas:

1.  First, the current DNA system has lead me to a strong conclusion.  The stack is very easily manipulated by evolution.  The memory locations much less so.  A new system should take advantage of the stack more fully, and reduce or eliminate dependence on memory locations.

2.  Viruses are key to most evo sims.  They should be encouraged.  But their method of propagation is a little overpowered in the current system, I think.  It should be easier for bots to spread viruses, and more difficult for viruses to enter a non receptive host.

3.  The linear nature of current DNA is limiting.  It should be easier for bots to run several much shorter strands in "parallel" than one long, linear one.  Especially with something like viruses, induced behavior should be additive and not necessarily disrupt existing behavior.

4.  Conditions shouldn't be separated from the stores that they influence.  Something like:
cond
*.nrg 5000 >
start
50 .repro store
stop

Would be better off looking like this:

*nrg 5000 > 50 .repro store

Maybe remove all the flow commands, or keep just start and stop (for junk DNA purposes).  I'm not quite sure how a system like this would work, but probably the condition operators (>, <, etc.) toggle whether stores work or not.

Probably there would be a parallel boolean stack (as there is now), and stores simply check against the top of this stack to see if they are active or not.

5.  DNA commands should be easily performed and understood by a human.  Things like the bitwise operators tend to make the DNA look even more indecipherable than is necessary.  Evolution will use whatever tools it has at hand, but humans don't like doing bitwise ANDing in their heads.

6.  Codules (basically sub functions that can't be set up recursively) are important for allowing branching logic.  I'm further advancing the idea that there would be "core" codules that interact in very defined ways, passing control to each other, and lesser codules, that act simply as functions, returning when they're done to where they were called.

7.  Probably something like half of the sysvars relate to vectors in one way or another.  I'm playing with the idea of using vectors as the basic type instead of integers.  But it's not as easy to do as I would like, so I may just sit on this idea.  Basically, it would be alot better to do something like:

*.refvel .move store

instead of

*.refvelup .up store
*.refveldx .dx store

8.  It's unrealistic to know exact details about your position, orientation, etc.  I'd move sysvars towards being entirely relative.  Sysvars would return information as if the bot is stationary and at the world origin (0,0).

9.  Arbitrary values need to be removed where appropriate.  For instance, instead of 100 .shootval store -2 .shoot store you might do something like 100 .nrgshot store.  Eyes also should probably be redone to return values representing distance more accurately.

10.  Most sysvars should be reworked to accept and return values in a normalized range.  Something like -1000, 1000.

11.  I was also playing with the idea of having all values be floating point in the range -1 to 1, but there are some places where this doesn't work out well (such as .body for instance)

12.  Where possible, sysvars should give and return information.  That is, act as both input and output.

13.  As a general rule, passing A to a sysvar and passing B to a sysvar should mean that passing their average gives a result that is related to A and B.  For instance, while -2 and -6 shots are both feeding shots, -4 is not.

14.  Where possible, choices should be dumbed down where these choices aren't important.  I was toying with the idea of making ties strictly for aggressive feeding and allowing only a single tie to be created per bot.  (The connective properties of ties would be moved to another mechanism).  Then instead of creating a tie and remembering its number, you'd just have to create a tie.  Feeding wouldn't need to know about which tie to use, because there would be only one.

Haven't worked through all the consequences of this yet, but it's the track of thinking I'm on.

Structure
This is the big one.  There are several ideas I've toyed with:
  • The first involves creating a linear assembly line of codules.  Something like a pipeline.  After one codule is finished executing, it passes control to the next one, until finally the last one somehow gives values to sysvars to cause action.  Mutations could change the order of the codules being executed.  The result is somewhat similar to the evolution of metabolic pathways, but it's still too linear for my liking.
  • The second involves a web of codules.  Each cycle, a codule would receive a stack filled with its input parameters, manipulate those parameters, and produce an output stack (the stack after it's done executing).  Codules could be connected to other codules by connecting one's output to another's input.  Sysvars would be simple codules that give output and receive input.

    The problem is that it would then take several cycles for data to be processed from the inputing sysvars, through the DNA, to the outputing sysvars.  Also, this creates a problem when it takes one calculation 2 cycles to do, while a more sophisticated, branching calculation can take 10 or more.  DNA would be encouraged to sacrifice sophistication for simplicity, which is backwards of what I'd like to aim to achieve.
  • An alternative is to run the DNA several times in a cycle, but here there are issues with how many times to run the DNA.
  • Another idea is to simply prevent any looping at all (no recursion), which collapses the web into more of a feed forward neural net.  This is what I'm currently thinking.

    Input sysvars would pass their values to any codules they're connected to.  These codules process their data and send it to the next codule.  But I'm not sure how to set it up so that the different execution paths don't end up with a racing condition against each other.
-------------------------------------------------------------
That's pretty much all I have at the moment.
« Last Edit: July 16, 2007, 02:39:32 AM by Numsgil »

Offline googlyeyesultra

  • Bot Destroyer
  • ***
  • Posts: 109
    • View Profile
Bot DNA
« Reply #1 on: July 16, 2007, 07:24:35 AM »
Alrighty, I'll through in my two cents. Or however much this turns out to be.

1) I have no strong opinions here, as I rarely run evolutions.

2) Ensure that viruses are still viable for F1 competition. After all, a virus loses not only its offensive power, but also its ability to spread through other bots (even if you don't kill them with it) if you make it too hard to infect other species.

3) I don't do evolutions much, but I can imagine shear havoc with parallel threads. For instance, two threads running simultaneously like this would be havoc (since they'd run infinite numbers of themselves, which presumably would be allowed, since you can run multiple threads at a time).

Here's an example in psuedocode:
Thread1
run parallel Thread2
run parallel Thread2
endthread

Thread 2
run parallel Thread1
run parallel Thread1
endthread

Not only would this be an infinite loop, but it's also going to start running ridiculous numbers of threads until the game either crashes or decides to kill the offending bot. So, I'd say a single thread at a time.

4) Make this optional, so that both forms of code are supported. This would actually allow for nested conditionals, and for more options and more control.

5) Humans don't like doing crazy logic operations? What? All those SG bots in the league weren't evolved, you know. Humans can create equally illegible code as evolution can. Besides, someone, someday will think of a use for that kind of thing en masse. No harm to having more sysvars, but there might be harm if they are removed.

6) Definitely agreed. Codules are a must. I'd say unless they use a goto command, have them pass control to the next codule linearly. Also, add a variable that allows a codule to reference what codule activated it, so that it would be able to pass control back to that, or to the codule after it.

7) Might be nice. Don't know. Would break most old bots, though.

8) I'm plus minus on this. Although it is a bit strange for a bot to know its exact locations, presumably a bot would be able to say "Oh, look, that's the big tree/lake/oasis/whatever! I know I'm not near any walls, 'cause I've been here before."

9) Eyes can be redone. I mildly disagree with changing shots, however. Personally, I don't consider the current system particularly bad, but it's really not a big deal.

10) Meh, 32000 is easy enough to remember. Once again, really either way would work. Just probably not worth spending time programming compared to things like metabolism, E-grid, etc.

11) Please, please don't. Please? Completely and totally break every scrap of bot code in existance? Not to mention we'd have to remember that we need to accelerate at .75, as apposed to a more standard 750.

12) Would probably work, so long as we can get the specifics ironed out. Would a bot ever be able to read the value it had placed in the variable, or only the readback value?

13) I honestly don't like this. A bit overcomplicated for you to read our minds and figure out what we all consider averages for variables. Besides, I'm still against multi-threading, so it would never be called on at the same time, and a lot of bots depend on later code overwriting earlier code. Not to mention this makes defensive genes worthless, as it would place the average in (which would still be likely detrimental to the bot).

14) What if you are tied to a bot, and another bot tied to you? How can you reference the tie you were attacked with to delete/leach from it? I am interested in any ideas for structural replacements to ties, as sophisticated multibots are nearly impossible, and mostly suck in combat.

15) Wait, you didn't have a #15. Oh, well.

Structure:
Use number two (the web), but let a bot run all of it's codules in one cycle. After all, we've already got SG bots. Do we really need further single codule bots? Also, making a codule per cycle means that shipping data off to small functions to perform common operations is ridiculously wasteful, which is relatively backwards to me. Copy and pasting the same formulas repeatedly should be more costly than making one function that repeatedly handles it.

By different execution paths, do you mean multi-threaded DNA? If so, well, you hopefully already know my opinion on simultaneous code threads.

Somehow I think that was more than 2 cents.

Offline Trafalgar

  • Bot Destroyer
  • ***
  • Posts: 122
    • View Profile
Bot DNA
« Reply #2 on: July 16, 2007, 10:14:02 AM »
Edit: I don't know why the quotes aren't working, but I have to leave, so I'm not going to try to figure it out now.

Quote from: Numsgil
I'm hoping to encourage some brainstorming about new DNA forms here.  I'll start with some of my own observations and ideas:

1.  First, the current DNA system has lead me to a strong conclusion.  The stack is very easily manipulated by evolution.  The memory locations much less so.  A new system should take advantage of the stack more fully, and reduce or eliminate dependence on memory locations.
It might be better to streamline stores by eliminating the store operator. If referencing an address with a . caused a store, then evolution might manage to evolve stores more often. This would make SGizing conditions impossible, though, unless there's a command to toggle between the old and new behavior.

Quote from: Numsgil
2.  Viruses are key to most evo sims.  They should be encouraged.  But their method of propagation is a little overpowered in the current system, I think.  It should be easier for bots to spread viruses, and more difficult for viruses to enter a non receptive host.
I've been considering how to implement an antivirus for an evo sim without disrupting zerobot evolution. I was thinking a shepherd bot that would destroy any bots which are making viruses. The main reason is because virus-spreading isn't subject to mutation (as far as I know).

Also, I'm finding it a pain to deliberately infect a particular bot with a virus, since the virus shot actually flies off in a random direction, and completely ignores aim commands (I checked the source to verify that - the documentation on vshoot is wrong).

Quote from: Numsgil
3.  The linear nature of current DNA is limiting.  It should be easier for bots to run several much shorter strands in "parallel" than one long, linear one.  Especially with something like viruses, induced behavior should be additive and not necessarily disrupt existing behavior.
If they run in parallel, coordinating numerous parallel code strands, making their conditions not conflict, and making them not fight over the same variables, would be a major pain in the ass.

Quote from: Numsgil
4.  Conditions shouldn't be separated from the stores that they influence.  Something like:
cond
*.nrg 5000 >
start
50 .repro store
stop

Would be better off looking like this:

*nrg 5000 > 50 .repro store
This is essentially what SGizing is about, and with PyBot I can take it a step further.
I write this: setaim when (aim!=315) = 315
and it turns into this: 315 .setaim *.aim 315 sub sgn abs mult store
Which stores 315 into .setaim if *.aim doesn't already hold 315.

I also have almost all the stores in Guardian set up to only do the store if the variable isn't already set to whatever's going to be written to it. This slows down the sim further but reduces energy costs. Guardian is very energy efficient (except it splurges on movement speed and defenses) and very CPU inefficient (much of the reason is because the CPU inefficiency is necessary to make it so energy efficient).

Quote from: Numsgil
Maybe remove all the flow commands, or keep just start and stop (for junk DNA purposes).  I'm not quite sure how a system like this would work, but probably the condition operators (>, <, etc.) toggle whether stores work or not.
As long as the condition operators continue to cost energy, and regular math and bitwise operators don't, it would still be more (energy) efficient for bot authors to use SGizing instead of the actual condition operators. As for evolution, I'm not sure how to make it work better. It seems to me that it works fairly well as-is. Real evolution generally takes thousands of years or more to evolve new abilities (like eyes, or thumbs, etc).

Quote from: Numsgil
5.  DNA commands should be easily performed and understood by a human.  Things like the bitwise operators tend to make the DNA look even more indecipherable than is necessary.  Evolution will use whatever tools it has at hand, but humans don't like doing bitwise ANDing in their heads.
I for one use bitwise anding, both for SGized conditions, and for using a variable to store bitflags indicating what features in the bot should be toggled on. What's really indecipherable is when an evolved bot is shooting and turning and crap, and there's not a single store or reference to .shoot in the entire DNA. It's powered by a simple 'angle inc' or 'angle dec' at the beginning of a start. (dist would work too)

Quote from: Numsgil
6.  Codules (basically sub functions that can't be set up recursively) are important for allowing branching logic.  I'm further advancing the idea that there would be "core" codules that interact in very defined ways, passing control to each other, and lesser codules, that act simply as functions, returning when they're done to where they were called.
While it could be useful to have functions (I already do something similar, but it's really more like macros), I don't think allowing something like goto and gosub would be a good idea. It would encourage evolution to create utterly unreadable spaghetti code. I would much rather it be linear, at least then you can try to follow it in your mind.

Quote from: Numsgil
7.  Probably something like half of the sysvars relate to vectors in one way or another.  I'm playing with the idea of using vectors as the basic type instead of integers.  But it's not as easy to do as I would like, so I may just sit on this idea.  Basically, it would be alot better to do something like:

*.refvel .move store
I'm not sure if this is a good idea or a bad idea. Wouldn't it make some bots slower, from every multiplication, division, etc, being performed on two numbers instead of just one?

Quote from: Numsgil
8.  It's unrealistic to know exact details about your position, orientation, etc.  I'd move sysvars towards being entirely relative.  Sysvars would return information as if the bot is stationary and at the world origin (0,0).
Having refveldn and the like be relative is already a pain in the ass, and having aimshoot be relative to your current angle is an even bigger one (since angle isn't, apparently). Making more things relative would not be a good thing, in my opinion.

Quote from: Numsgil
9.  Arbitrary values need to be removed where appropriate.  For instance, instead of 100 .shootval store -2 .shoot store you might do something like 100 .nrgshot store.  Eyes also should probably be redone to return values representing distance more accurately.
This might make it harder for evolution to evolve bots that fire a variety of different shots. But who knows. The only shooting I've seen evolved so far was from .shoot dec.

Quote from: Numsgil
10.  Most sysvars should be reworked to accept and return values in a normalized range.  Something like -1000, 1000.
Which sysvars? This could make things more confusing, but I don't know which ones you're talking about.

Quote from: Numsgil
11.  I was also playing with the idea of having all values be floating point in the range -1 to 1, but there are some places where this doesn't work out well (such as .body for instance)
Haha. Yeah. This would break so many things.

Quote from: Numsgil
12.  Where possible, sysvars should give and return information.  That is, act as both input and output.
That would be nice. It would also be nice if it were possible for a bot to tell if another bot is shooting things by looking at .shoot (I've tried, it's always 0).

Quote from: Numsgil
13.  As a general rule, passing A to a sysvar and passing B to a sysvar should mean that passing their average gives a result that is related to A and B.  For instance, while -2 and -6 shots are both feeding shots, -4 is not.
I don't think this is feasible in practice. For example, shootval with info shots.

Quote from: Numsgil
14.  Where possible, choices should be dumbed down where these choices aren't important.  I was toying with the idea of making ties strictly for aggressive feeding and allowing only a single tie to be created per bot.  (The connective properties of ties would be moved to another mechanism).  Then instead of creating a tie and remembering its number, you'd just have to create a tie.  Feeding wouldn't need to know about which tie to use, because there would be only one.
How about instead making tie commands default to tiepres if tienum is not set? This would help evolution without screwing up multibots and such. (I note that Guardian will tie to a hostile to destroy it even when it is already tied to a friendly or veggie)

As for structure changes, it seems to me that the current structure works decently well. I'm trying evolution with zerobots with ridiculously large genomes now too, to see how that works out (15k, quite close to Guardian's size).

I would suggest that info shots and memory writing with ties should set the variable after the rest of the cycle has run, so that on the next cycle, the bot can try to fix it if it is coded to. Right now they can instakill, and there's no way to stop it besides instakilling the attacker first.
« Last Edit: July 16, 2007, 10:14:52 AM by Trafalgar »

Offline Jez

  • Bot Overlord
  • ****
  • Posts: 788
    • View Profile
Bot DNA
« Reply #3 on: July 16, 2007, 03:34:06 PM »
Quote from: Trafalgar
Edit: I don't know why the quotes aren't working, but I have to leave, so I'm not going to try to figure it out now.
The forum only allows a certain number of quotes per post IIRC, try splitting your post in half or thirds and I'll move this one, or replace some of your quotes with [code]

Quote from: Trafalgar
It might be better to streamline stores by eliminating the store operator. If referencing an address with a . caused a store, then evolution might manage to evolve stores more often. This would make SGizing conditions impossible, though,

Still a good idea IMO, 1G bots and the current evo bots can be a real pain to read.

Quote from: Trafalgar
Also, I'm finding it a pain to deliberately infect a particular bot with a virus, since the virus shot actually flies off in a random direction, and completely ignores aim commands (I checked the source to verify that - the documentation on vshoot is wrong).

  The game was meant to have been changed to work like that, added to known bugs.

I'm also a fan of making bots own input relative.

Not a fan of any form of instakill, sysvars have been changed before because of that so I hope the mkshell/slime variable gets sorted.
If you try and take a cat apart to see how it works, the first thing you have in your hands is a non-working cat.
Douglas Adams

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
Bot DNA
« Reply #4 on: July 16, 2007, 10:25:46 PM »
Quote from: googlyeyesultra
3) I don't do evolutions much, but I can imagine shear havoc with parallel threads. For instance, two threads running simultaneously like this would be havoc (since they'd run infinite numbers of themselves, which presumably would be allowed, since you can run multiple threads at a time).

Here's an example in psuedocode:
Thread1
run parallel Thread2
run parallel Thread2
endthread

Thread 2
run parallel Thread1
run parallel Thread1
endthread

For threads, I'm imagining they don't communicate with each other.  They don't spawn new threads.  They just receive input from sysvars and output data to other sysvars.  Multiple data sent to the same sysvar is averaged together (which is why it's important that averaging two pieces of data results in a number that is related to the two pieces).  This is important because it allows a bot to receive additional DNA from another source and have its original DNA still be untouched.  Only its behavior will change.

So threading is more like having several extra people in identical cockpits driving the same robot you are.  The end robot behavior is like a democratic vote between all the pilots.

Quote
5) Humans don't like doing crazy logic operations? What? All those SG bots in the league weren't evolved, you know. Humans can create equally illegible code as evolution can. Besides, someone, someday will think of a use for that kind of thing en masse. No harm to having more sysvars, but there might be harm if they are removed.

Humans can write complex things just fine.  It's reading them that's a pain.  Doubly so if it's an evolved bot.  Ideally a human should have little problem reverse engineering a section of DNA and understanding what it does.  This way evolution can become transparent.  This is one area where there's a conflict between the needs of Darwinbots as an evolution simulator, and the needs of Darwinbots as a battle bot arena.

Quote
6) Definitely agreed. Codules are a must. I'd say unless they use a goto command, have them pass control to the next codule linearly. Also, add a variable that allows a codule to reference what codule activated it, so that it would be able to pass control back to that, or to the codule after it.

There are two methods I'm imagining for passing control from one codule to the next.  The first is like a pure goto statement.  Full control is moved from the first codule to the second.  The other method is more similar to the way functions work.  A secondary codule is called, manipulates the stack, and returns control to the codule that called it, where it called it.

In both cases, looping needs to be strictly impossible, or you'll end up with the possibility for an infinite loop in the DNA and a hung simulation.  Bad all around.

Quote
7) Might be nice. Don't know. Would break most old bots, though.

I'm not too concerned about backwards compatibility.  I'm imagining something like "Darwinbots 3".  A whole new iteration of the program.  So many things changed that older bots just can't feasibly be moved to the new version in any sort of easy manner.

Quote
8) I'm plus minus on this. Although it is a bit strange for a bot to know its exact locations, presumably a bot would be able to say "Oh, look, that's the big tree/lake/oasis/whatever! I know I'm not near any walls, 'cause I've been here before."

I'm hoping to come up with a reasonable system to address this problem.  Maybe something like pheremone markers bots can lay down.

Code: [Select]
10) Meh, 32000 is easy enough to remember. Once again, really either way would work. Just probably not worth spending time programming compared to things like metabolism, E-grid, etc.
The problem is that not all sysvars use the whole 32000 range.  Again, this is more closely tied with evolution that bot writing.  I feel it's important for evolution when the output for a commnd or sysvar can act as the raw input for another input or sysvar and produce reasonable results.

Code: [Select]
11) Please, please don't. Please? Completely and totally break every scrap of bot code in existance? Not to mention we'd have to remember that we need to accelerate at .75, as apposed to a more standard 750.
The main problem is that there are areas where it doesn't make sense.  Addition wouldn't really work, for instance.  Again, I'm not too concerned about backwards compatibility.

Code: [Select]
12) Would probably work, so long as we can get the specifics ironed out. Would a bot ever be able to read the value it had placed in the variable, or only the readback value?
I'm thinking sysvars would start out with the input value, and if a bot changes this value, then it acts as a write command.

Code: [Select]
13) I honestly don't like this. A bit overcomplicated for you to read our minds and figure out what we all consider averages for variables. Besides, I'm still against multi-threading, so it would never be called on at the same time, and a lot of bots depend on later code overwriting earlier code. Not to mention this makes defensive genes worthless, as it would place the average in (which would still be likely detrimental to the bot).
This depends on the variable.  I'd say 80% of sysvars are already averagable.  There are just a few exceptions.  .shoot comes to mind (but that's easy enough to split into several shooting sysvars).  As far as defensive genes go, I think primary defenses should be made more effective so the need for defensive genes is reduced.

Code: [Select]
14) What if you are tied to a bot, and another bot tied to you? How can you reference the tie you were attacked with to delete/leach from it? I am interested in any ideas for structural replacements to ties, as sophisticated multibots are nearly impossible, and mostly suck in combat.
This is still pretty raw in my mind, but at the moment I'm imagining having ties last only for a single cycle, or maybe be extremely brittle.  But either way, bots can't modify or delete ties made to itself.  A bot that is being sucked to death would need to find another means of removing the offending bot.  Maybe shooting it, or accelerating fast enough to break the tie, or brushing against another bot or shape to scrape the other bot off.

Basically, I'm imagining a combat system where it's better to leech on a bot that's much larger than you, shoot at a bot that's roughly the same size as you, and ingest (phagocytosis) a bot that is smaller than you.

Code: [Select]
Structure:
Use number two (the web), but let a bot run all of it's codules in one cycle. After all, we've already got SG bots. Do we really need further single codule bots? Also, making a codule per cycle means that shipping data off to small functions to perform common operations is ridiculously wasteful, which is relatively backwards to me. Copy and pasting the same formulas repeatedly should be more costly than making one function that repeatedly handles it.

Right, definately a problem.

Code: [Select]
By different execution paths, do you mean multi-threaded DNA? If so, well, you hopefully already know my opinion on simultaneous code threads.
Hopefully I've persuaded you with my above argument.
« Last Edit: July 16, 2007, 10:30:01 PM by Numsgil »

Offline googlyeyesultra

  • Bot Destroyer
  • ***
  • Posts: 109
    • View Profile
Bot DNA
« Reply #5 on: July 16, 2007, 10:54:37 PM »
I still don't like multi-threads. Can you imagine how hard it would be to debug a bot in? Not only would you have to check the last gene that had activated that referenced the misbehaving variable, but every single one that activated and referenced it (which, in large bots, could be a ridiculous amount). Does that also mean that 30 .repro store 70 .repro store will make 50 .repro store, even if done in one gene?

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
Bot DNA
« Reply #6 on: July 16, 2007, 10:56:09 PM »
Quote from: Trafalgar
It might be better to streamline stores by eliminating the store operator. If referencing an address with a . caused a store, then evolution might manage to evolve stores more often. This would make SGizing conditions impossible, though, unless there's a command to toggle between the old and new behavior.

This is an interesting idea, I'll work through the consequences on paper and see how it would work.  Maybe every sysvar is just a command.

Quote
I've been considering how to implement an antivirus for an evo sim without disrupting zerobot evolution. I was thinking a shepherd bot that would destroy any bots which are making viruses. The main reason is because virus-spreading isn't subject to mutation (as far as I know).

Also, I'm finding it a pain to deliberately infect a particular bot with a virus, since the virus shot actually flies off in a random direction, and completely ignores aim commands (I checked the source to verify that - the documentation on vshoot is wrong).

This is a really delicate area.  Viruses are probably one of the best features-- they work really well in both evo sims and battle bots.  But I think having a bot police its own genome is just too difficult and has too many problems.  I was talking with shvarz about it once, and he said that real organisms don't really have a method of dealing with viral infection other than dying so that the virus doesn't spread.

So I'm thinking that viral defense should be stronger, and internal methods of removing viruses (.delgene) removed altogether.  The effect is basically the same, and we can even make viruses easier to control as a weapon without overpowering them too much.

I might even make a way for a virus to convert its entire host into new viral particles and have them all explode out in a fiery explosion!  Hehe, woudln't that be a fun way to spread a virus

Quote
If they run in parallel, coordinating numerous parallel code strands, making their conditions not conflict, and making them not fight over the same variables, would be a major pain in the ass.

I'm imagining that there's no communication between strands except if they write to the same sysvar.  If there's a conflict, I'd like to average the values.  The only problem is with sysvars that don't average well.  .shoot, for instance.  Which is why it's important to try and convert as many sysvars as possible to a system where averaging results in average behavior.

Quote
This is essentially what SGizing is about, and with PyBot I can take it a step further.
I write this: setaim when (aim!=315) = 315
and it turns into this: 315 .setaim *.aim 315 sub sgn abs mult store
Which stores 315 into .setaim if *.aim doesn't already hold 315.

I also have almost all the stores in Guardian set up to only do the store if the variable isn't already set to whatever's going to be written to it. This slows down the sim further but reduces energy costs. Guardian is very energy efficient (except it splurges on movement speed and defenses) and very CPU inefficient (much of the reason is because the CPU inefficiency is necessary to make it so energy efficient).

I'd like to see SG methods become the primary supported method (it's how evolution likes to work, too), easier to read, and less hacky.  Maybe instead of storing to 0 as a free action, you can use some nice conditions that just happen to be inserted into the body of the gene.  I'm still working out how it would work.

Quote
As long as the condition operators continue to cost energy, and regular math and bitwise operators don't, it would still be more (energy) efficient for bot authors to use SGizing instead of the actual condition operators. As for evolution, I'm not sure how to make it work better. It seems to me that it works fairly well as-is. Real evolution generally takes thousands of years or more to evolve new abilities (like eyes, or thumbs, etc).

Eric and I had a discussion a while ago about what sorts of DNA costs are good.  After reading through other simulators' code and forums, all signs point to the idea that you shouldn't charge bots for the length or complexity of their genome because you invariably favor shorter, stupider behavior.  I'd like to move to dumbing down the costs for DNA.  Just enough to prevent runaway genome growth that slows the program to a crawl.

Quote
I for one use bitwise anding, both for SGized conditions, and for using a variable to store bitflags indicating what features in the bot should be toggled on.

You could also use memory locations for this.  I dunno, I do see some places where bitwise is good, but it just makes the DNA look too Greek.  And you can really produce the same behavior with other commands.

Quote
What's really indecipherable is when an evolved bot is shooting and turning and crap, and there's not a single store or reference to .shoot in the entire DNA. It's powered by a simple 'angle inc' or 'angle dec' at the beginning of a start. (dist would work too)

Yeah, this is definately an issue.

Quote
While it could be useful to have functions (I already do something similar, but it's really more like macros), I don't think allowing something like goto and gosub would be a good idea. It would encourage evolution to create utterly unreadable spaghetti code. I would much rather it be linear, at least then you can try to follow it in your mind.

I think a raw goto statement would be bad for this reason.  Within a codule, the program flow should be readily understandable.  Only when a codule gets to the end of itself should it pass full control to another codule.

Code: [Select]
I'm not sure if this is a good idea or a bad idea. Wouldn't it make some bots slower, from every multiplication, division, etc, being performed on two numbers instead of just one?
Speed isn't the primary issue.  I can probably even write some sort of DNA analyzer that trims DNA down when it's time to run it so you're not running junk.  My primary concern is with dot and cross products.  They both return scalars in 2D.  I guess I need to examine some existing robots and see how they would work if they were vectors.

Code: [Select]
Having refveldn and the like be relative is already a pain in the ass, and having aimshoot be relative to your current angle is an even bigger one (since angle isn't, apparently). Making more things relative would not be a good thing, in my opinion.
Wouldn't it be easier if everything was relative?  Then you wouldn't need to convert between absolute and relative.  It would be an entirely self consistant way of observing the universe.

Code: [Select]
That would be nice. It would also be nice if it were possible for a bot to tell if another bot is shooting things by looking at .shoot (I've tried, it's always 0).
That sounds reasonable.

Code: [Select]
I don't think this is feasible in practice. For example, shootval with info shots.
Yeah, I'm not sure how to address things like this.

Code: [Select]
As for structure changes, it seems to me that the current structure works decently well. I'm trying evolution with zerobots with ridiculously large genomes now too, to see how that works out (15k, quite close to Guardian's size).
It's alright.  Definately better than most other simulators where agents can only run X many commands per cycle.  But I think it can be improved to allow for some added complexity and features (sexual reproduction becomes alot easier if the DNA isn't quite so linear).

Code: [Select]
I would suggest that info shots and memory writing with ties should set the variable after the rest of the cycle has run, so that on the next cycle, the bot can try to fix it if it is coded to. Right now they can instakill, and there's no way to stop it besides instakilling the attacker first.
Yeah, this is definately an issue.  But if bots can override ties and info shots, then it makes them largely useless since a bot could just explicitly set every single sysvar.
« Last Edit: July 16, 2007, 10:57:32 PM by Numsgil »

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
Bot DNA
« Reply #7 on: July 16, 2007, 10:59:38 PM »
Quote from: googlyeyesultra
I still don't like multi-threads. Can you imagine how hard it would be to debug a bot in? Not only would you have to check the last gene that had activated that referenced the misbehaving variable, but every single one that activated and referenced it (which, in large bots, could be a ridiculous amount). Does that also mean that 30 .repro store 70 .repro store will make 50 .repro store, even if done in one gene?

Threads wouldn't interfere with each other.  Only their end results would have any interaction.  And within a thread, it's as if the thread has total control of the bot.  So 30 .repro store 70 .repro store would result in 70 .repro store for that thread.  After all threads are executed, their final effects are averaged, but until that time a thread has no inkling of what other threads are doing.

Offline googlyeyesultra

  • Bot Destroyer
  • ***
  • Posts: 109
    • View Profile
Bot DNA
« Reply #8 on: July 16, 2007, 11:08:19 PM »
Would this be a seperate command from goto and codules? If so, no further objections. I could live with it, and maybe use it from time to time. Still, having no ability to not use multi-threading when it doesn't serve a purpose well would be quite annoying.

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
Bot DNA
« Reply #9 on: July 16, 2007, 11:19:55 PM »
Yes and no.  I'm thinking that instead of a single root codule that calls other codules, you have several codules that are considered to be roots, with each starting it's own execution path.

Offline googlyeyesultra

  • Bot Destroyer
  • ***
  • Posts: 109
    • View Profile
Bot DNA
« Reply #10 on: July 17, 2007, 12:30:09 AM »
So if I didn't want the multi-threading features, I could just use one root with a lot of branches?

Offline Martian

  • Bot Neophyte
  • *
  • Posts: 44
    • View Profile
Bot DNA
« Reply #11 on: July 17, 2007, 04:00:14 AM »
Why not make store take 3 values and only work when there is a non zero value on the stack.  

And change >, <, = etc. to take two values and place 1 on the stack if the condition is true and 0 if it isn't. Like the mult operator.  

Then
Code: [Select]
50 .repro *.nrg 5000 > store would work.

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
Bot DNA
« Reply #12 on: July 17, 2007, 04:49:19 AM »
Quote from: googlyeyesultra
So if I didn't want the multi-threading features, I could just use one root with a lot of branches?

Right

Quote
Why not make store take 3 values and only work when there is a non zero value on the stack.  

And change >, <, = etc. to take two values and place 1 on the stack if the condition is true and 0 if it isn't. Like the mult operator.  

Then CODE50 .repro *.nrg 5000 > store

But then wouldn't it be difficult to have a single condition control multiple store statements?

Offline Martian

  • Bot Neophyte
  • *
  • Posts: 44
    • View Profile
Bot DNA
« Reply #13 on: July 17, 2007, 05:37:33 AM »
Quote from: Numsgil
But then wouldn't it be difficult to have a single condition control multiple store statements?

I was thinking that we could have this and genes.

Code: [Select]
cond
 *.eye5 25 >
 *.refeye *.myeye !=
 *.refpoison *.refshell =>
start
 16 .shootval store
 -6 .shoot store
stop

cond
 *.eye5 25 >
 *.refeye *.myeye !=
 *.refpoison *.refshell <
start
 16 .shootval store
 -1 .shoot store
stop

would become
Code: [Select]
cond
 *.eye5 25 >
 *.refeye *.myeye !=
start
 16 .shootval store
 -6 .shoot .*.refpoison *.refshell => store
 -1 .shoot *.refpoison *.refshell < store
stop

Which is a lot more readable. It would also make Single Gene bots less complicated. But then we should leave the bitwise operators.

For example

Code: [Select]
cond
*.eye5 30 >
start
-1
.shoot
*.memval -2 =
*.refeye 0 =  |
store 'Shoot if the bot is hit with venom or if its a veggie (Checking with .memloc, .memval)
stop

Which would be a good use for bitwise operators.

Offline googlyeyesultra

  • Bot Destroyer
  • ***
  • Posts: 109
    • View Profile
Bot DNA
« Reply #14 on: July 17, 2007, 05:44:51 AM »
I humbly ask that you read this ridiculously long post.

Alright. Now understanding the general plan for multithreading, I'd be willing to go with it. No objections there.

Ultimately, for conditions, I'd like a multi-tiered system. At the top, we'd have root codules that would be executed every cycle. In those would be simple genes that called other codules. Thus, root codules to standard codules. Standard codules could and should link to a multitude of other standard codules. Then, in codules, genes should still have the "cond" statement to allow conditions to apply to all operations in that gene. Then, you could have conditions attached to each statement, like "*.nrg 1500 > 50 .repro store". One tricky bit would be deciding when the condition section ended, since we can't assume it ends at a store (some genes merely add values to the stack to be processed later). Perhaps a "condstop" operator could be used, of some sort, inside of the start/stop section of a gene. Essentially, it would look like "*.nrg 1500 > 50 .repro store condstop". That would also mean that you could attach non-stores to conditions without creating lots of genes, like "*.eye5 0 > 50 mult condstop", which would multiply the top stack value by 50 and place that on the stack, if eye5 say something. It would also allow for easy nested conditionals, as the condstop could encompass multiple lines, if needed.

Alright. The above method would certainly allow quite a bit of SG-ifying, but SG-ifying wouldn't really make the bot better in any way (you are still spending energy on condition checking, and viruses are probably receiving an overhaul, so I doubt .delgene inc .delgene inc will really be valid.)

I suppose the thing preventing threads from interacting with each other until they had already finished would prevent the racing condition problem.

To deal with shots, change .shoot to a universal shoot command. It would take the first to values on the stack to determine what kind of shot it was, and the second value to determine it's shootval. Essentially, shoot wouldn't need a store anymore. So a energy feeding shot with a shootval of 50 would be "50 -1 shoot". We'd probably have to do the same thing with quite a few other variables, and turn things into commands. Store, obviously, would still remain, for usage in any variables that don't support the command-ized form, or for free variables to store information. For multi-threading, perhaps we could do some sort of randomization for ones that don't mix well (so if codule1 tried to use an energy shot and codule2 tried to use a body shot, it would randomly choose one. Variables/commands that are more easily averaged (like up) could simply be averaged.

While we're speaking of new commands, try to include some basic trig functions (for fancy aiming), logarithmic functions (for calculating how much damage shots should do), and any other obscure ones you can think of that I have missed. Also, even if things like refxpos and refypos are relative to your own bot, you should be able to calculate angle from different locations (still relative to your own bot, once again, for aiming).

I still think that raw gotos and gotosubs are essential. Say, if I've got a function that determines how much I should power up a shot. Perhaps a multi-gene one. I can't exactly wait until the end of the shooting gene/codule is over before I call that function. We could always disable these in mutations, and have a third command that would goto as soon as the gene/codule finished. Maybe gotoafter?

How will a bot react when it finishes a codule that has no goto commands? Will it automatically continue on to the next codule, or will it just end the program then? In theory, if the former is true, then could you end DNA execution early by creating a blank codule at the end of the DNA and call that?

With the whole vector vs. integer thing, allow both. Sometimes, for instance, to prevent orbiting, you solely want a certain direction (like *.veldx -1 mult .dx store), or when you only want to accelerate towards a bot in one direction, and only match it's sideways velocity. A lot of the time, it would be a lot faster and easier just to use it as a vector, however.

Erm, yes, I think I'm done rambling. For now.

Edit: I'm not done rambling!

If you split the .shoot into a plethora of things like .vshoot .wasteshoot .nrgshoot, .medicshoot, .infoshoot, .venomsoot, and .bodyshoot, what mechanism would be implemented to prevent me from firing every single one of them in one cycle? Essentially, bots could start throwing everything but the kitchen sink at their target and would no longer have to strategically decide which is better at a certain time.
« Last Edit: July 17, 2007, 05:59:28 AM by googlyeyesultra »