Author Topic: 2.5 Dimension mode?  (Read 7416 times)

Offline jknilinux

  • Bot Destroyer
  • ***
  • Posts: 468
    • View Profile
2.5 Dimension mode?
« on: December 07, 2009, 05:45:37 PM »
Here's the official thread for the 2.5D mode suggestion.

Here's my first mention from a previous thread:

Quote
Also, can we implement some sort of 2.5D mode, so it (DB3) won't actually have to deal with 3D graphics? Maybe a memory location that, if set to 1, brings the bot to a parallel 2D sim, moving it slightly in the 3rd dimension, where things in each 2D level can only interact with that which is in their level. It can switch back to 0 if it wants to return to the original one. Maybe we can implement each 2D sim in this mode on a different core/computer? on second thought, this would be a great way to induce speciation by setting slightly different physics to each parallel 2D plane... Perhaps we can use this as an alternative to the roving teleporter option too for IM?

So, add your thoughts here!

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #1 on: December 07, 2009, 06:20:51 PM »
It's an interesting idea, but I don't want to control it discretely inside the DNA.  My thinking with DNA is that we do away with "magic numbers" and have the entire -1000 to 1000 values of a memory location be meaningful, and that the ("phenotype") behavior that those memory locations map continuously.

So for example with .up, if you do 10 .up vs. 20 .up, the end behavior is very similar.  Whereas with something like .fixpos, it was inherently discontinuous (either fixed or not fixed), and originally even dealt with magic numbers (0 vs. 1).

So I'd be inclined to have moving between layers only indirectly be controlled from DNA.  Maybe something similar to "buoyancy".

Offline abyaly

  • Bot Destroyer
  • ***
  • Posts: 363
    • View Profile
2.5 Dimension mode?
« Reply #2 on: December 08, 2009, 06:57:52 PM »
Why are the memory values being restricted to the range of +- 1000? It seems like it would be easier to let them take up all of the variable's values.


Also, I don't think you meant continuous there, since .fixpos is a continuous map.
Lancre operated on the feudal system, which was to say, everyone feuded all
the time and handed on the fight to their descendants.
        -- (Terry Pratchett, Carpe Jugulum)

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #3 on: December 08, 2009, 08:09:47 PM »
I misspoke about it being 1000.  It's actually 10000.  Here's the reasoning:

1.  DNA for DB3 is base 10.  Evolution doesn't really care what base the underlying system is in and base 10 is easier for us humans to read and understand.  So there's no bit shifting or ANDing and the like.  Everything's set up as if it were in base 10 (underlying representation isn't, necessarily, though)
2.  I wanted to be able to store the value in a 16 bit integer (so it had to be < 16000)
3.  The number should be nice and round to remember.  ie: some power of 10. (so it had to be 1, 10, 100, 1000, or 10000)
4.  I wanted to be able to store essentially pointers to other memory locations.  So it had to be at least 1000.  (that meant 1000 or 10000)
5.  I wanted it to be +-1000, but for angles, 1080 is the nearest number to 1000 that still has nice division properties (360*3 = 1080.  1080 has numerous ways to evenly divide it up).

So 10000 was the only cap that fulfilled all properties.  

...

Though I wrote the DNA module several years ago, so I might want to rethink some of the underlying assumptions before a first release.

Specifically, 1080 might be a better cap.  I'd probably expand it to each bot having 1080 memory locations as well.  Maybe just generally expand things as if it were a base 60 number system.

For the uninitiated, a little history lesson might be illustrative.  Has anyone ever wondered why there are 360 degrees for a circle?  Why not 100, or 1000?  The answer is that it was roughly equal to the number of days in a year (early math was astronomy based) and it's a nice round number in base 60, which is what most early number systems were based on.  See wiki.  Why base 60?  Because it is an extremely composite number system.  Meaning it has lots of ways to evenly fraction numbers.  We still use base 60 for time (60 seconds in a minute fractions up really nicely).

...

Or maybe go for broke and fully do base 60.  Have 60^2 - 1 = 3599 memory locations (0 is special).  Have them each hold a value between -3599 and 3599 (two digits base 60, with an extra bit for sign).

It would be really weird.  I don't think there are any base 60 based computer languages   But it would make doing things like evenly dividing up the memory locations and converting from linear to angular units easier.  sine, for instance, could operate on a domain of -3600 to 3600, or the full 3600 decidegree circle forwards and back.  And then output values normalized to the -3600, 3600 range.  If you want to reproduce 60/40 with a kid you can do that.  But more exotic fractions are equally meaningful.

Or I might even decide to lop of negative numbers.  Just do 0..3599 as the entire range and domain of all operations.  Negative numbers tend to cause problems because not all things make sense to go negative (negative nrg?).

Offline abyaly

  • Bot Destroyer
  • ***
  • Posts: 363
    • View Profile
2.5 Dimension mode?
« Reply #4 on: December 09, 2009, 03:56:21 AM »
How does a base 10 representation mean that the upper limit should be a power of 10?
We can still write the numbers in base 10 even if some strange number like 32768 is the cap.

Divisibility, though, is an argument I can stand behind. Having a number with very many divisors does make things pretty nice, but it's only a necessary concern if we are still going to restrict memory values to integers.

In the interest of making bot controls as close to analog as possible, floating point numbers have an advantage. Earlier I mentioned that .fixpos was a continuous function... this is because it has a discrete domain, just like .up does in the current implementation. All such functions are trivially continuous. The jump from (0 .up) to (1 .up) is just as arbitrary as the jump from (0.fixpos) to (1 .fixpos).
Lancre operated on the feudal system, which was to say, everyone feuded all
the time and handed on the fight to their descendants.
        -- (Terry Pratchett, Carpe Jugulum)

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #5 on: December 09, 2009, 12:55:09 PM »
When I say base I don't mean how humans write the numbers. We need to write in base 10 because that's what we know.  I mean more how the virtual machine works. If there was a log function, for instance, it's base would be the base of the virtual machine, for instance (not necessarily meaning you couldn't also have a log10 or log2 function, of course).

I strongly considered floating point numbers. But they aren't any more continuous than integers because of machine epsilon (right now memory is 16 bit, so comparing with 32 bits wouldn't be fair.  Comparing with half floats would be more fair). Evolution wouldn't care, but I figured that bot makers wouldn't appreciate .1 = .09999998. And they have a weird property that numbers close to 0 have higher precision. So then I thought about fixed point. But that isn't any different from integers in the end.  You can just say that a range of +-10000 is the same as +-1 with an epsilon of .0001.
« Last Edit: December 09, 2009, 01:02:02 PM by Numsgil »

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #6 on: December 09, 2009, 02:42:27 PM »
Having slept on it I do really like the idea of doing +-3599 as the range, and having 3599 memory locations.  I like the idea of doing just positive numbers as well.  It plays nicely with most commands and sysvars I can think of.  The downside is that it doesn't play nicely with sine and cosine, and it could make for some weird flow control (eg: something like if positive then sub else add).  

With codules (functions) present you might be able to fake negative numbers, too, by building a series of functions to manipulate values, and use the boolean stack to store sign information.

Offline jknilinux

  • Bot Destroyer
  • ***
  • Posts: 468
    • View Profile
2.5 Dimension mode?
« Reply #7 on: December 10, 2009, 01:06:12 PM »
To make the movement more analog, we could add more 2D "planes" to make it 2.75D or 2.9D, etc.... As we keep adding planes, we get closer and closer to true 3D, such as where infinitely many planes = 2.999...D. The problem is that in true 3D, a bot should take up more space than just one plane. Maybe we should implement that possibility?

Or, we could just have values, such as 5000.fixpos = quite well stuck, but a hard enough collision will knock it loose, 10000 = completely stuck, 50 = barely stuck, etc...

Similarly, with 2 planes, value 0 = in plane 1, 5000 = "halfway" between planes (imagine a sphere halfway between two sheets 1" apart, it takes up a small amount of space within each sheet but has most of it's mass inbetween)(this is where we implement weird physics ideas, such as taking up a certain amount of space in both planes, etc...), 10000 = in plane 2. (This is all assuming the values are 0-10000 inclusive)

Also, here's a quick question: Can DB code round up/down for division? For example 11/2 = 5?
Even though it is inexact, it isn't a horrendous issue if one offspring, for example, gets 1 more nrg than the other with offspring_nrg = nrg/2. So maybe this could give the benefit of having divisibility no matter what, like FP? But perhaps there is some application I'm unaware of that requires exact results...

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #8 on: December 10, 2009, 05:05:33 PM »
Quote from: jknilinux
To make the movement more analog, we could add more 2D "planes" to make it 2.75D or 2.9D, etc.... As we keep adding planes, we get closer and closer to true 3D, such as where infinitely many planes = 2.999...D. The problem is that in true 3D, a bot should take up more space than just one plane. Maybe we should implement that possibility?

If we wanted, there's nothing stopping us from actually doing 3D.  I chose not to because some things are harder to program for in DNA (eyes would be more difficult, for instance) and it would be hard for users to really make heads or tails of what's going on.  2D allows us to match the mental model we have of the microscopic world: large and flat, just like a microscope slide.

So my point is if we asymptotically approach 3D we're better off just going for full 3D.  Which isn't something I'm ruling out in the future but not something I think we want to tackle right away.  

Quote
Or, we could just have values, such as 5000.fixpos = quite well stuck, but a hard enough collision will knock it loose, 10000 = completely stuck, 50 = barely stuck, etc...

That's my plan for something like fixpos, yeah.  The details will depend on whether I want to go with drag or friction as the model used to slow things down.  But basically it'll involve changing a coefficient.

Quote
Similarly, with 2 planes, value 0 = in plane 1, 5000 = "halfway" between planes (imagine a sphere halfway between two sheets 1" apart, it takes up a small amount of space within each sheet but has most of it's mass inbetween)(this is where we implement weird physics ideas, such as taking up a certain amount of space in both planes, etc...), 10000 = in plane 2. (This is all assuming the values are 0-10000 inclusive)

From a technical point of view that's a problem.  Which plane do we use to give the bot its sensory readback?  And it creates a tight coupling between planes which means you can't distribute planes easily across different computers, etc.  Bots need to be discretely in one plane or another for this to really work.  Of course this still runs into issues.  Imagine a bot trying to switch planes only to find that there's a large shape blocking the way in the new plane.  Or even another bot.

Quote
Also, here's a quick question: Can DB code round up/down for division? For example 11/2 = 5?
Even though it is inexact, it isn't a horrendous issue if one offspring, for example, gets 1 more nrg than the other with offspring_nrg = nrg/2. So maybe this could give the benefit of having divisibility no matter what, like FP? But perhaps there is some application I'm unaware of that requires exact results...

Most DNA operators in DB3 follow the rounding rules we learned in school (>= 0.5 -> 1, else 0).  Division is the exception: it always truncates the result, so that it matches up with mod, which always returns the remainder.

Floating point does not solve this problem, either.  Let's say we use 32 bit floating point numbers.  That means that there is 23 bits (well, 24 bits denormalized) for mantissa.  Ignoring exponent and sign for a moment, that means that we can't represent the difference between, say, 1 and 1 + 2^-25, because they'll both have the same bit pattern in the mantissas.  So just in the same way that we can't represent 0.5 in integers, we can't represent 1 + 2^-25 in floating point.  We have to round either way.

Floating point has the additional oddity that most fractions can't be represented exactly.  The usual ones like 1/3 can't be represented exactly, but we also can't represent something common like 0.1 exactly either.  Because the mantissa is base 2.  I just absolutely know that if we allow floating point numbers in DNA we'll get someone wondering why 1000.43 1000 sub .43 == is giving false.  And I don't want to go down the route of having to code in epsilons in to our DNA code.

Not to mention the equally frustrating problems of NaNs.  0 0 div would produce a NaN.  Then every other number it touches, through addition, subtraction, etc. will be NaN.  An absolute pain to debug.

See C++ FAQ if you aren't familiar with the pitfalls of float.

Incidentally, double has the same problems, just with higher accuracies.

Offline jknilinux

  • Bot Destroyer
  • ***
  • Posts: 468
    • View Profile
2.5 Dimension mode?
« Reply #9 on: December 10, 2009, 06:44:58 PM »
Alright, well maybe analog dimension-switching isn't going to work out so well...
Evolution should be able to deal with a digitized implementation, such as if .dimension is divisible by 2, be in slate 1, else slate 2. Besides, there's lots of digitization in nature anyway...

Anyway, to avoid obstacles while dimension-switching... could we implement a sort-of 3d vision system, with 1 eye pointing above and the other pointing below the plane the organism is on? That way, it can detect if there is an organism/object "above" it, and if it tries to teleport when something is above/below it anyway, it just won't be able to.

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #10 on: December 10, 2009, 08:50:45 PM »
Quote from: jknilinux
Alright, well maybe analog dimension-switching isn't going to work out so well...
Evolution should be able to deal with a digitized implementation, such as if .dimension is divisible by 2, be in slate 1, else slate 2. Besides, there's lots of digitization in nature anyway...

From our experience in DB2, sysvars that don't use the entire domain are unlikely to be used by evolution.  So then you could make it a positive/negative distinction, if you wanted, but that lacks a certain "elegance" that I've been trying to push on to DB3 DNA.  But I might be kidding myself that all sysvars can be meaningfully mapped to a continuous range.  Some sysvars might just need to be discrete by nature.  Maybe some sort of bool memory range...

In nature, on an essentially molecular level things are more or less discrete.  A proton pump will pump one proton per pump.  But even by the time you get to the cellular level the vast numbers of discrete processes have made biological behavior essentially continuous.  Thousands of proton pumps pumping at varying rates creates a continuum.

The core problem is that if you want to do something like discrete read only sysvars (say, *isfixed) and use that to influence continuous output sysvars (if not fixed, then store values to up), you invariably introduce some very crude math or branching behavior.

One idea I'm kind of playing with right now is overloading the sign bit for digital data.  I already sort of do it for the sqr command, for instance (sqr operates only on the value component of the value on the stack.  It's basically sign(val) * sqrt(abs(val)) ).  So then maybe purely digital data could be represented as +-0.  But I'm not all that happy about overloading the meaning of the sign bit like that.  The fact that there's a sign bit at all kind of rubs me the wrong way.  I probably need to look at more microprocessor designs and get some ideas.

Quote
Anyway, to avoid obstacles while dimension-switching... could we implement a sort-of 3d vision system, with 1 eye pointing above and the other pointing below the plane the organism is on? That way, it can detect if there is an organism/object "above" it, and if it tries to teleport when something is above/below it anyway, it just won't be able to.

I'll need to think about this a bit more to figure out a good plan.  Something like flOw maybe.  Where you can get an idea of what's going on in different layers without an exact idea.
« Last Edit: February 02, 2018, 09:40:16 AM by Numsgil »

Offline ikke

  • Bot Destroyer
  • ***
  • Posts: 300
    • View Profile
2.5 Dimension mode?
« Reply #11 on: December 12, 2009, 03:23:24 AM »
If you want easy divisibility as a criterion use the following algorithm to define your max number
1) establish the highest prime you want your base to be divisible by
2) decrease the number by 1.
if the number is the highest order of a prime myltiply ense move on to the next lower number

example
I want a number to be divisible by 11
next is 10 10 is not the highest order of a prime so next
9=3^2 so include
8=2^3 so include
7=7^1 so include
6 next
5=5^1 so include
4=2^2 not highest order of 2 so next
3=3^1 so next
2=2^1 so next
11*9*8*7*5 is your number (=27720)

Offline Moonfisher

  • Bot Overlord
  • ****
  • Posts: 592
    • View Profile
2.5 Dimension mode?
« Reply #12 on: December 12, 2009, 05:59:24 AM »
Actualy the "fuzzy logics" kinda idea sounds interesting. Things probably aren't as black and white in nature...
And I definately think introducing ranges for the sysvars will help a lot. It's hard for evolution to hit -6 .shoot store... best I've seen is .shoot inc.
And I think I've seen some who used math to push a value into .shoot, but then it also fires energy shots and such. -1 and -2 are one step from eachother, a bot is just as likely to kill itself as it is to feed.

Offline abyaly

  • Bot Destroyer
  • ***
  • Posts: 363
    • View Profile
2.5 Dimension mode?
« Reply #13 on: December 12, 2009, 10:13:20 AM »
Yeah. Shoot should not end up as a wacky batch purpose variable like it did in DB2.
Info shots, energy shots, feeding shots, and killing shots are all fundamentally different things.
Lancre operated on the feudal system, which was to say, everyone feuded all
the time and handed on the fight to their descendants.
        -- (Terry Pratchett, Carpe Jugulum)

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
2.5 Dimension mode?
« Reply #14 on: December 12, 2009, 03:42:58 PM »
Quote from: ikke
If you want easy divisibility as a criterion use the following algorithm to define your max number
1) establish the highest prime you want your base to be divisible by
2) decrease the number by 1.
if the number is the highest order of a prime myltiply ense move on to the next lower number

example
I want a number to be divisible by 11
next is 10 10 is not the highest order of a prime so next
9=3^2 so include
8=2^3 so include
7=7^1 so include
6 next
5=5^1 so include
4=2^2 not highest order of 2 so next
3=3^1 so next
2=2^1 so next
11*9*8*7*5 is your number (=27720)

The numbers get big really, really fast, which is sort of unfortunate.  27720 is a bit larger than I want.  It doesn't quite fit in a 16 bit signed integer and that would be a lot of sysvars

Removing 11 and doing 9*8*7*5 = 2520 would be more manageable.  The upshot over 3600 is that it's divisible by 7.  The downside is that 3600 maps better to degrees, so 90 degrees, 45 degrees, maps to 900 and 450 with 3600, instead of 630 and 315 for 2520.

Sort of torn, actually.  Assuming we do integers, which would people prefer?


Quote from: Moonfisher
Actualy the "fuzzy logics" kinda idea sounds interesting. Things probably aren't as black and white in nature...
And I definately think introducing ranges for the sysvars will help a lot. It's hard for evolution to hit -6 .shoot store... best I've seen is .shoot inc.
And I think I've seen some who used math to push a value into .shoot, but then it also fires energy shots and such. -1 and -2 are one step from eachother, a bot is just as likely to kill itself as it is to feed.


Quote from: abyaly
Yeah. Shoot should not end up as a wacky batch purpose variable like it did in DB2.
Info shots, energy shots, feeding shots, and killing shots are all fundamentally different things.

That's the prime example of what I want to avoid for DB3.  .shoot involved "magic" numbers.  And even if you try to level the playing field by modding the value so it takes -6, -16, -26, etc. it's still a real pain.  For DB3 I'll break each shot type into its own sysvar and the values the sysvars hold will represent .shootval instead.