Advanced Vault Design


If it doesn't fit anywhere else, it belongs here. Also, come here if you just need to get hammered.

User avatar

Pandemonium Purger

Posts: 1341

Joined: Monday, 24th October 2011, 06:13

Post Sunday, 9th February 2014, 16:23

Advanced Vault Design

I am looking for some more specific explainations on the Advanced Vault Design page. Specifically, how random numbers are chosen from a code-defined group of numbers. The example given:

  Code:
NAME: random_test
# Put it on D:1 so it's easy to test.
PLACE: D:1
ORIENT: float
MAP
xxxxxxxxxxxxxxxxxxx
x........{........x
xxxAxxxxxBxxxxxCxxx
xxx.xxxxx.xxxxx.xxx
xxx@xxxxx@xxxxx@xxx
ENDMAP


Now let's say you want A, B, and C to be randomly rock or floor, but B should be floor if both A and C are rock. Here's one way to do it (add these lines to the map definition):

  Code:
: local asolid, csolid
: if crawl.random2(2) == 0 then
:   asolid = true
:   subst("A = x")
: else
:   subst("A = .")
: end
: if crawl.random2(2) == 0 then
:   csolid = true
:   subst("C = x")
: else
:   subst("C = .")
: end
: if asolid and csolid then
:   subst("B = .")
: else
:   subst("B = .x")
: end


This code uses crawl.random2(N) which returns a number from 0 to N-1 (in this case, returns 0 or 1). So we give A a 50% chance of being rock, and the same for C. If we made both A and C rock, we force B to be floor, otherwise we use a subst that gives B the same 50% chance of being rock.

What I don't understand is... any of this. Lets simplify the example. What if there is just A and B? What would the code be to make both A and B 50%? I am sure there are multiple ways to accomplish this in code, like 50% for A, otherwise B, etc. But as a layman I don't understand this code and just want to make a few maps with random elements.

  Code:
XXX@XXX
XXAABXX
XAXXXBX
XX.BBXX
XBXAXXX
XXBB.XX
XXXXBAX
XXXABAX
XX.BAXX
X>XXXXX
XXXXXXX


So if I want A to have a 50% chance to be rock or empty space and B to have the opposite (rock instead of space), what is my code?
seattle washington. friends for life. mods hate on me and devs ignore my posts. creater of exoelfs and dc:pt
User avatar

Pandemonium Purger

Posts: 1341

Joined: Monday, 24th October 2011, 06:13

Post Sunday, 9th February 2014, 16:36

Re: Advanced Vault Design

I'm just going to place all my questions here, the last time I tried to ask in IRC was not productive

in header declarations:

  Code:
SUBST: ? = TUV


Does this mean that each instance of ? has a 33% to be T, U, or V? So if I write:

  Code:
SUBST: ? = TUVW


...That chance is lowered to 25% for each glyph?

And regarding this code:

  Code:
SUBST: ? : TUV


So that means every instance ? is defined, by a one in three chance, to one of those three glyphs? So if I write:

  Code:
SUBST: ? : TU


...then every instance of ? will be T, or U, but only one and never the other, and at an equal chance?
seattle washington. friends for life. mods hate on me and devs ignore my posts. creater of exoelfs and dc:pt
User avatar

Shoals Surfer

Posts: 311

Joined: Wednesday, 15th August 2012, 07:13

Post Sunday, 9th February 2014, 20:34

Re: Advanced Vault Design

Either this is some subtle joke far over my head, or you missed Technical Support/Contributions/Anywhere-but-CYC


Edit: Unless Crazy Yiuf's really is a wellspring of in-depth technical knowledge about the game?
Spoiler: show
Psst, hey kid... you like roguelikes?
User avatar

Pandemonium Purger

Posts: 1341

Joined: Monday, 24th October 2011, 06:13

Post Sunday, 9th February 2014, 20:39

Re: Advanced Vault Design

It really belongs in coding if you want to get technical, and no, this isn't some stupid joke. Coding hasn't been visited in weeks though, and people who code view this forum. thanks for your post.
seattle washington. friends for life. mods hate on me and devs ignore my posts. creater of exoelfs and dc:pt

Lair Larrikin

Posts: 18

Joined: Monday, 14th May 2012, 23:16

Post Sunday, 9th February 2014, 23:40

Re: Advanced Vault Design

Do you have any experience with programming? The code snippets are Lua code. It looks like there's a tutorial for the basics of Lua here and you can try snippets of Lua code here.
So if I want A to have a 50% chance to be rock or empty space and B to have the opposite (rock instead of space), what is my code?

I think it would be this
  Code:
: if crawl.random2(2) == 0 then
:   subst("A = x")
:   subst("B = .")
: else
:   subst("A = .")
:   subst("B = x")
: end

I'll try to break this down.
  Code:
crawl.random2(2)

As the page mentions, this gives a value of 0 half of the time and a value of 1 the other half of the time.

  Code:
crawl.random2(2) == 0

This asks "Is the value of crawl.random2(2) equal to 0?" If so, this statement evaluates to true. If, not the statement evalutes to false. So, half of the time this will be true, half of the time it will be false.

  Code:
 if crawl.random2(2) == 0 then
...
else
...
end

This says "If crawl.random2(2) evaluates to true, do the things listed after this line, stop at the line containing else, then jump to the end. If crawl.random2(2) evaluates to false, do the things listed after the line containing else."

So, 50% of the time it will do this:
  Code:
subst("A = x")
subst("B = .")

If it doesn't do that, it will do this:
  Code:
subst("A = .")
subst("B = x")

For this message the author Dole has received thanks:
twelwe
User avatar

Pandemonium Purger

Posts: 1341

Joined: Monday, 24th October 2011, 06:13

Post Sunday, 9th February 2014, 23:46

Re: Advanced Vault Design

Thanks for the reply. I still feel as though I don't understand what the code is doing.

  Code:
crawl.random2(2) == 0


So if I want the chance to be 33%, is the code:

  Code:
crawl.random2(3) == 0


or is it:

  Code:
crawl.random3(2) == 0


Better yet, what do those numbers mean?
seattle washington. friends for life. mods hate on me and devs ignore my posts. creater of exoelfs and dc:pt

Dungeon Master

Posts: 634

Joined: Sunday, 22nd September 2013, 14:46

Post Sunday, 9th February 2014, 23:56

Re: Advanced Vault Design

random2(x) chooses a random number from 0 to x-1 (think of it as "random up 2 x"). So random2(3) == 0 would be true 1/3rd of the time: the other 2/3rds of the time random2(3) would be equal to 1 or to 2.


So if I want A to have a 50% chance to be rock or empty space and B to have the opposite (rock instead of space), what is my code?

The best way to do it would probably be:
  Code:
SHUFFLE: AB
SUBST: A = x
SUBST: B = .



Also, if you're looking for 1/2 chances, instead of
  Code:
 if crawl.random2(2) == 0 then

you could do
  Code:
 if crawl.coinflip() then



Lastly, everything you wrote in the second post in the thread seems correct.

For this message the author wheals has received thanks:
twelwe

Slime Squisher

Posts: 368

Joined: Thursday, 11th April 2013, 21:07

Post Monday, 10th February 2014, 00:36

Re: Advanced Vault Design

twelwe wrote:Thanks for the reply. I still feel as though I don't understand what the code is doing.

crawl.random2() makes a call to the function registered in the Lua lib "crawl" called "random2".

In the DCSS code, files containing Lua libraries tend to be prefixed as l_whatever.cc, in this case the "crawl" lib is defined in l_crawl.cc:
  Code:
987 static const struct luaL_reg crawl_clib[] =

999     { "random2",        crawl_random2 },

This tells us that the function exposed as random2 is defined above (unsurprisingly) as crawl_random2:

crawl_random2 can be found in l_crawl.cc line 662:
  Code:
LUARET1(crawl_random2, number, random2(luaL_checkint(ls, 1)))

Which means that the Lua function crawl_random2() is a wrapper for another function (in this case, a C++ function that also has the name random2()) which is defined elsewhere.

(Understanding this step may seem irrelevant for the purpose of random2, but the names of the Lua and C functions don't always match up so it's good to know this if you want to understand what other Lua functions are doing.)

grep for "int random2" finds its definition in random.cc, line 119:
  Code:
119 int random2(int max)
120 {
121     if (max <= 1)
122         return 0;
123
124     uint32_t partn = UINT32_MAX / max;
125
126     while (true)
127     {
128         uint32_t bits = get_uint32();
129         uint32_t val  = bits / partn;
130
131         if (val < (uint32_t)max)
132             return (int)val;
133     }
134 }

All this amounts to a fancy way of saying "Give this function a number called "max", and it will return a number randomly that is >=0 but less than max."

Trying to call crawl.random3() would either do nothing or spit out an error: There is no Lua function in the crawl lib named random3.

If you want to pick a number between 0 and 2, one way of doing that would be to call crawl.random2(3) which just tells the random2() function to pick a number >=0 and less than 3.


Disclaimer: I don't know programming that well myself so hopefully none of this is drastically wrong, but I hope it helps.

For this message the author Implojin has received thanks:
twelwe

Ziggurat Zagger

Posts: 6454

Joined: Tuesday, 30th October 2012, 19:06

Post Monday, 10th February 2014, 01:14

Re: Advanced Vault Design

Implojin wrote:
twelwe wrote:Thanks for the reply. I still feel as though I don't understand what the code is doing.

crawl.random2() makes a call to the function registered in the Lua lib "crawl" called "random2".

In the DCSS code, files containing Lua libraries tend to be prefixed as l_whatever.cc, in this case the "crawl" lib is defined in l_crawl.cc:
  Code:
987 static const struct luaL_reg crawl_clib[] =

999     { "random2",        crawl_random2 },

This tells us that the function exposed as random2 is defined above (unsurprisingly) as crawl_random2:

crawl_random2 can be found in l_crawl.cc line 662:
  Code:
LUARET1(crawl_random2, number, random2(luaL_checkint(ls, 1)))

Which means that the Lua function crawl_random2() is a wrapper for another function (in this case, a C++ function that also has the name random2()) which is defined elsewhere.

(Understanding this step may seem irrelevant for the purpose of random2, but the names of the Lua and C functions don't always match up so it's good to know this if you want to understand what other Lua functions are doing.)

grep for "int random2" finds its definition in random.cc, line 119:
  Code:
119 int random2(int max)
120 {
121     if (max <= 1)
122         return 0;
123
124     uint32_t partn = UINT32_MAX / max;
125
126     while (true)
127     {
128         uint32_t bits = get_uint32();
129         uint32_t val  = bits / partn;
130
131         if (val < (uint32_t)max)
132             return (int)val;
133     }
134 }

All this amounts to a fancy way of saying "Give this function a number called "max", and it will return a number randomly that is >=0 but less than max."

Trying to call crawl.random3() would either do nothing or spit out an error: There is no Lua function in the crawl lib named random3.

If you want to pick a number between 0 and 2, one way of doing that would be to call crawl.random2(3) which just tells the random2() function to pick a number >=0 and less than 3.


Disclaimer: I don't know programming that well myself so hopefully none of this is drastically wrong, but I hope it helps.


Actually that's a very accurate and not-too-technical way of describing how it works.
Spoiler: show
This high quality signature has been hidden for your protection. To unlock it's secret, send 3 easy payments of $9.99 to me, by way of your nearest theta band or ley line. Complete your transmission by midnight tonight for a special free gift!
User avatar

Pandemonium Purger

Posts: 1341

Joined: Monday, 24th October 2011, 06:13

Post Monday, 10th February 2014, 01:23

Re: Advanced Vault Design

Some of you should consider updating the AVD wiki page(s). These are very good explanations for some not-very-clear mechanics.
seattle washington. friends for life. mods hate on me and devs ignore my posts. creater of exoelfs and dc:pt

Lair Larrikin

Posts: 18

Joined: Monday, 14th May 2012, 23:16

Post Monday, 10th February 2014, 02:18

Re: Advanced Vault Design

Some of the things here (conditionals, function calls) are general programming concepts. Once you understand them it's just a matter of knowing Lua syntax and how to access functions specific to Crawl.

Returning to the original example:
  Code:
: local asolid, csolid

We need a way to remember what we do with A and what we do with C. This line declares two variables so we can do that. The "local" at the start of the line means that these variables can only be accessed inside this map declaration. You can give variables an initial value (asolid = false) but we didn't.
  Code:
: if crawl.random2(2) == 0 then
:   asolid = true
:   subst("A = x")
: else
:   subst("A = .")
: end

This is similar to the example code I posted. "asolid = true" takes the variable we declared earlier and gives it the value of true. Note that this is different from "asolid == true" which asks "is asolid equal to true?" Also note that if the we end up taking the else path, asolid is never assigned a value.
  Code:
: if crawl.random2(2) == 0 then
:   csolid = true
:   subst("C = x")
: else
:   subst("C = .")
: end

Similar to the above chunk of code.
  Code:
: if asolid and csolid then
:   subst("B = .")
: else
:   subst("B = .x")
: end

The first line is slightly confusing. What we're asking is "are both asolid and csolid equal to true?" If you wanted to be more verbose, the first line is equivalent to
  Code:
if asolid == true and csolid == true then

But wait, what if we never assigned a value to asolid or csolid? In Lua, if you do not give a variable a value, it is equivalent to Nil, which means that it has no value. (Sidenote: this is distinct from saying that a variable has a value of 0.) When used in a conditional statment like the first line, Nil means false. So, if either asolid or csolid was never given a value, we end up following the else path.

For this message the author Dole has received thanks:
twelwe

Blades Runner

Posts: 546

Joined: Saturday, 7th May 2011, 02:43

Post Monday, 10th February 2014, 10:00

Re: Advanced Vault Design

Dole wrote:The first line is slightly confusing. What we're asking is "are both asolid and csolid equal to true?" If you wanted to be more verbose, the first line is equivalent to
  Code:
if asolid == true and csolid == true then


This is not actually true.
in "if asolid == true and csolid == true", the code will execute only if asolid and bsolid have a value of true.
in "if asolid and csolid", it will execute if both asolid and bsolid are neither nil nor false (which is a pretty wide range -- they could be strings, tables, or even functions, and the conditional would still fire. )
Most relevantly, if a variable like asolid is declared in the global scope and you haven't initialized asolid as a local variable in your function, then you will get the global value of asolid when testing it. So it's good to make sure you have initialized anything you might be testing in a conditional.

But wait, what if we never assigned a value to asolid or csolid? In Lua, if you do not give a variable a value, it is equivalent to Nil, which means that it has no value. (Sidenote: this is distinct from saying that a variable has a value of 0.) When used in a conditional statment like the first line, Nil means false. So, if either asolid or csolid was never given a value, we end up following the else path.


This part deserves to be on the wiki, because the behaviour of nil here is not a general programming concept.C has NULL, Python has None, but you can't go accessing variables that were never declared in either of these languages, without triggering errors.

For this message the author savageorange has received thanks:
Dole

Lair Larrikin

Posts: 18

Joined: Monday, 14th May 2012, 23:16

Post Monday, 10th February 2014, 12:51

Re: Advanced Vault Design

savageorange wrote:
Dole wrote:The first line is slightly confusing. What we're asking is "are both asolid and csolid equal to true?" If you wanted to be more verbose, the first line is equivalent to
  Code:
if asolid == true and csolid == true then


This is not actually true.

They are equivalent for the purposes of this example, but in general you are correct. I should have been more specific.

But wait, what if we never assigned a value to asolid or csolid? In Lua, if you do not give a variable a value, it is equivalent to Nil, which means that it has no value. (Sidenote: this is distinct from saying that a variable has a value of 0.) When used in a conditional statment like the first line, Nil means false. So, if either asolid or csolid was never given a value, we end up following the else path.


This part deserves to be on the wiki, because the behaviour of nil here is not a general programming concept.C has NULL, Python has None, but you can't go accessing variables that were never declared in either of these languages, without triggering errors.


But we did declare them in the first line of the example, we never just gave them a value. I was trying to explain what happens if you do that with a variable and try to access it later.

EDIT: Perhaps the point here is that the first line of the example should really read
  Code:
local asolid,csolid = false,false

Return to Crazy Yiuf's Corner

Who is online

Users browsing this forum: No registered users and 18 guests

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.