creatures caves welcome, guest
downloads   gallery   dev   community   creatchi   forum   mycaves
bookmarks | search | post new topic
Development Forum
old
VAxx in Snotrock Hunt Script?   
Malkin

Malkin
Australia  
Manager


 visit Malkin's website: Malkin's page at CWiki
  4/24/2014

I've read the Hungry Critter Tutorial and I'm still confused by what's going on here in the snotrock with 'setv va00 10000'.

it sets the temporary variable in the snotrock to a very large number, I know that much, but what is it used for? Once it gets into the NEGV and using va00, va01 and va02, I get a little lost. [nblush]

Does 'setv va01 rely ownr targ', in this instance, roughly translate to 'set the variable va01 to be the distance between my target object and the owner of the script'?




*looking for food
doif ov00 eq 2
doif pose eq 10 or pose eq 17
gsub erup
stop
endi
* search for food close by
rnge 200
setv va00 10000
seta va02 null
inst
esee 2 11 8
* only check tuba that can be eaten
doif ov05 eq 1
* only check food roughly on the same height
setv va01 rely ownr targ
doif va01 lt 0
negv va01
endi
doif va01 lt 100
setv va01 relx ownr targ
doif va01 lt 0
negv va01
endi
doif va01 lt va00
setv va00 va01
seta va02 targ
endi
endi
endi
next
* if found some change mission to approach food
doif va02 ne null
seta ov16 va02
setv ov00 3
* otherwise walk in a straight line searching
else
gsub walk
endi
endi

*approaching food
doif ov00 eq 3
inst
targ ov16
doif targ ne null
setv va00 posx
else
targ ownr
setv ov00 2
endi
targ ownr
slow
* if you're facing the wrong way turn around
doif posx gt va00 and ov10 gt 0
call 1000 0 0
elif posx lt va00 and ov10 lt 0
call 1000 0 0
endi
gsub walk
inst
doif ov16 ne null
doif touc ownr ov16 eq 1
gsub eat
endi
else
setv ov00 2
endi
slow
endi


Thanks for any ideas!


My TCR Norns
 
RisenAngel
Sanely Insane

RisenAngel

Manager


 visit RisenAngel's website: The Realm
  4/24/2014

The snotrock's hunting subroutine is similar to other subroutines present in other critters coded by Creature Labs (for example, the stickletrout).

The variable with the freakishly huge number is apparently meant to store the distance between the snotrock and whatever meal it happened the spot. The problem is that the value in it is never used (va00 is used again in the bit under "doif ov00 eq 3," but the value in it gets assigned to posx), so I'm inclined to believe that it serves no practical purpose whatsoever (it's the same deal with the corresponding variable in the other critters with hunting scripts).

As for va01 and va02, the "negv" is there because the snotrock can either be left or right of and higher or lower than its target, and sometimes the distance returned by "relx" and "rely" is negative (yes, those two variables do indeed return the distance between two objects, compared to their positions in the world at the time). So to better judge the distance, it makes the number positive. Presumably, this would have been used to help the snotrock close in on the tube...but just like va00 above, these values are also never used again outside this part of the script.

So in the grand scheme of things, that part of the script has no effect on how the snotrock functions. I'm guessing the people who wrote the script meant to do something more with that but either didn't have time to finish it, couldn't get it to work, or simply forgot about it. Alternatively, it could just be there to mess with the heads of anyone trying to read the code. :P


~ The Realm ~
Risen Angel's Creatures Blog


 
Papriko
Peppery One

Papriko



  4/24/2014  1

Small sidenote: instead of
doif va01 lt 0
negv va01
endi
I would rather use
absv va01
This is the absolute command, which basically does exactly the same as the doif, but in just 1 step and with marginally less resources.


Lets play plants! Photosynthesis... Photosynthesis... Photosynthesis...
 
evolnemesis
Code Monkey

evolnemesis



  4/24/2014

It's to make sure va00 has a value (edge case)...

in this part of the code, there is a comparison done: presumably this would cause an error if va00 was null or had no value at that point:


* only check tuba that can be eaten
doif ov05 eq 1
* only check food roughly on the same height
setv va01 rely ownr targ
doif va01 lt 0
negv va01
endi
doif va01 lt 100
setv va01 relx ownr targ
doif va01 lt 0
negv va01
endi
*this would cause an error if va00 were not assigned some value at first
doif va01 lt va00
setv va00 va01
seta va02 targ
endi
endi
endi


the doif va01 lt va00 would cause an error if va00 were not set to something. Presumably it was done this way in order for the snotrock to find the closest food. You see similar things in general functions or subroutines that look for a minimum (or maximum) value in a set of data (in this case the code is looking for the minimum distance out of the set of food sources in range).

In routines like this, the code will set the min (or max) variable to something arbitrary, which is always going to be higher (or lower) than anything in any set of data it may be looking through, and then compares it to each value, replacing it once the processing starts and it finds a real value in the data that is lower (or higher)... The reason why you might want an arbitrary value rather than just taking the first value in the set, or a number that might be in the set, is that the set might be empty, and then your subroutine (and anything depending on its output) would choke. By setting an arbitrary value, you can at least have a value for it to return no matter what.

In this case, nothing can be further than 10000 units, so the routine sets va00 to 10000 at start; and once it finds something closer, it replaces va00 with that closer distance. So while it has no further use in the code after this, at that point it is used to determine the closest food source, and the arbitrary value is important in order to avoid errors in logic if there is no food source found.


"For small creatures such as we, the vastness is bearable only through love."
"We are a way for the cosmos to know itself." - Carl Sagan

 
Ghosthande
Prodigal Sock

Ghosthande


 visit Ghosthande's website: Breeders Beware
  4/28/2014

Actually, CAOS doesn't work like Javascript or C++; all VAxx and OVxx variables by default have an initial, pre-defined value of zero. This is testable; use any variable as a number without defining it first and it will return zero. Treat it like something not a number, without defining it first, and the agent will error because it is already set to a numeric value (zero).

I don't know exactly what the coder was thinking when they wrote the comment; I've seen other comments that don't make complete sense in light of the way the game engine, agent, etc. work, so it's possible that they didn't know this was the case.



 
Papriko
Peppery One

Papriko



  4/28/2014

I thought undefined variables will return the null-agent when treated like an agent and return "" when used like a string...

Lets play plants! Photosynthesis... Photosynthesis... Photosynthesis...
 
evolnemesis
Code Monkey

evolnemesis



  4/28/2014

and 0 when treated as a number value... So it won't raise an error, but in this case having 0 in that variable to start would be bad... Since we are looking for a minimum and seeing if the distance is less than that variable each time... We don't want 0 in ov00 to start because then no distance will ever be less than ov00, and we can never use it to find the piece of food with the minimum distance...

Again, it's like the general problem of finding a minimum in a set where you don't know the size, or even if it has any members, but you know that the members can't be above some value... You use an arbitrary value, which is greater than anything in the set can be, as your first 'minimum' to compare each of the values in the set with.

In this case, no food can be further than 10000 because of the size of a world map, so 10000 is chosen as the starting point for ov00, the 'minimum distance' variable... ov00 is then compared with the distance to each piece of food in range one by one, and replaced with any lower distance it finds. This eventually gives you the distance to the closest piece. If there is no food to compare, you want that routine to return 10000, not 0... because a return of 0 would imply the snotrock is right on top of some food, which is not the case.


"For small creatures such as we, the vastness is bearable only through love."
"We are a way for the cosmos to know itself." - Carl Sagan

 
Ghosthande
Prodigal Sock

Ghosthande


 visit Ghosthande's website: Breeders Beware
  4/28/2014

@evol: yeah, I know all that. I was only replying to the first paragraph or two of your post, not commenting on the entire thing.

Papriko wrote:
I thought undefined variables will return the null-agent when treated like an agent and return "" when used like a string...



Nope. Liam and Moe both could attest to the myriad problems that arose when I started using variables to store things other than basic numbers... almost always because I didn't specify that a variable was "" or NULL prior to using it.



 
evolnemesis
Code Monkey

evolnemesis



  4/28/2014

Yeah, the comment about it raising an error was added by me in the code section just to point out the line in question, sorry about that... if you look in the original code above my forum comment you'll see it's not there.

I didn't know it was the case that the interpreter set a value. Although, it's really best to explicitly set initial values for variables and assume the environment will not set them for you in general, just as good programming practice... As you can attest to with your problems with string/agent variables...

Still, you do at least get logic errors when not setting a value in this case... Even if the script won't crash if you don't set a value here, it certainly won't do what it was supposed to.


"For small creatures such as we, the vastness is bearable only through love."
"We are a way for the cosmos to know itself." - Carl Sagan

 
Papriko
Peppery One

Papriko



  4/29/2014

evolnemesis wrote:
Again, it's like the general problem of finding a minimum in a set where you don't know the size, or even if it has any members, but you know that the members can't be above some value...


Setting an overly huge (or small value if looking for a biggest one) is just the easy solution :P
When you wanna do it "right" (or better said pedantic), you would first set it to a definitely incorrect value. Since we check for an absolute and hence positive value, -1 would be an example of that.

After that we see if our set has any members at all. In the above code it could be implemented as a "doif targ <> null". When we have no members at all, this whole process is pointless anyways and we could just cancel it.

When we still continue at this point, we can be sure that there is at least one member of the set. When we still have the -1 saved, we overwrite it with the first value as a reference. After that is done, we proceed as usual.



As I said, this is a very pedantic way of doing it, you only need it for really complex stuff which needs to be 100% failsafe. Using a high fixed value works fine too for simple cases such as snotrocks. When it fails, nobody cares, since it just causes a confused snotrock. You only do that method when a failed or confused script may cause horrible horrible things or when you have no certain fixed value you can set.


Lets play plants! Photosynthesis... Photosynthesis... Photosynthesis...
 
Malkin

Malkin

Manager


 visit Malkin's website: Malkin's page at CWiki
  4/29/2014

Wouldn't the value of 10000 be a nonsense value anyway, because the norn meso isn't 10000 pixels in length?

My TCR Norns
 
Papriko
Peppery One

Papriko



  4/29/2014

Yeeeeaaah, true, but you could try to repopulate snotrocks in other rooms too and who knows how big those get?
It always depends on the context. For snotrocks this works fine (partially also because the default checking radius is smaller than 10k anyways I think?), but sometimes you just need something more elaborate and I felt like writing it down :D


Lets play plants! Photosynthesis... Photosynthesis... Photosynthesis...
 
evolnemesis
Code Monkey

evolnemesis



  4/29/2014

yeah the checking radius is only 200... it uses an esee loop which enumerates over all objects it considers food in sight range, and before the loop, it sets the snotrock's sight range at 200 with that 'rnge' statement... really either way if you use 10000 or -1 it's a nonsense value in this particular case...

The only real reason to use a large value here is that it allows for simpler code and easier logic assertions... if you use something like -1, then you will need to check specifically for the -1 every time before making the 'less than' comparison because the -1 value will always be less than the distance, and we are looking for the minimum, so instead of one 'if less than' statement you would have a couple of nested ifs instead, like ('if ov00 not equal to -1 then check if distance is less than ov00, and if it is, set ov00 to the distance, otherwise, just set ov00 to the distance...). It would add about 3-4 lines to the script that isn't really necessary in this case...

But you definitely have a point, using a large value here is a shortcut... Something like you describe is semantically more correct for the general case... In a case where you don't know that much about the values in your set (For example, a critter whose sight isn't limited, or is using enum instead of esee in a very large map), then setting any arbitrary value for a routine like this can be dangerous (you run into this problem in coding when sorting a set of strings for example, or a set of real numbers that can be anything positive or negative). Then you want to make a kind of 'false' case that you can't really compare directly with any of the values, and do an extra check for the false case first before actually comparing... ('null' works well for things like this, and actually that is one major reason why many languages initialize variables to null at start... this exact problem comes up a lot, and making things null helps avoid logic errors with comparisons, since null can't be compared directly with anything that isn't null.

In this case, the script doesn't use the value at the end either way, since it just uses ov00 as a 'distance comparer' during the esee-next loop, where it goes through everything in range, one by one, and picks a new target the snotrock wants to look at if it's closer than the last one... If esee never finds anything in range, then the script never even gets to that part of the code because it passes over the whole loop, and the script never tries to set a target for the snotrock, never compares the 10000 to anything or looks at it again, and the snotrock just keeps wandering around.


"For small creatures such as we, the vastness is bearable only through love."
"We are a way for the cosmos to know itself." - Carl Sagan

 


downloads
cobs
adoptions
creaturelink
metarooms
breeds
 
gallery
art
wallpaper
screenshots
graphics
promos
sprites
dev
hack shack
script reservations
dev resources
active projects
dev forum
 
community
links
advice
chat
polls
resources
creatchi
 
forum
bookmarks
general
news
help
development
strangeo
survivor
mycaves
log in
register
lost pw
0 online
creatures caves is your #1 resource for the creatures artificial life game series: creatures, creatures 2, creatures 3, docking station, and the upcoming creatures family.

contact    help    privacy policy    terms & conditions    rules    donate    wiki