'gossip' progs - randomness in greet progs

For builders to discuss and ask building questions.
Post Reply
User avatar
Kelemvor
Sword Grand Master
Sword Grand Master
Posts: 2295
Joined: Mon Apr 11, 2005 6:14 pm
Location: The Fugue Plain within the Crystal Spire

'gossip' progs - randomness in greet progs

Post by Kelemvor » Sun Jul 01, 2007 8:47 pm

Code: Select all

>greet_prog 10~
The above code defines a greet prog which will trigger 10% of the time.

If I placed several 10% progs on an NPC, would they all have a 10% chance of activating? Or would only the first one which is rolled be the one that is seen?

What I want to achieve is one of several random comments from the NPC to trigger now and then when someone walks in. I dont want a person to walk in and be hit with a whole bunch of them at once.

(okay, I know I said I'd leave this sort of thing 'til I got a hard coder lined up.. but it's the best fun I've had in a month and it keeps my wife happy if I'm typing away and she can't see the green on black of the MUD :) )
...never send to know for whom the bell tolls,
it tolls for thee.
Amalia
Sword Grand Master
Sword Grand Master
Posts: 331
Joined: Wed Feb 01, 2006 6:51 pm
Location: Ardeep Forest
Contact:

Post by Amalia » Sun Jul 01, 2007 9:29 pm

I think an if-else string could solve it for you-- so it only triggers the next rand prog if the first one didn't go off.

Edit: if you have enough of them (I suspect the problem might become evident somewhere around 7 nested rand progs) that there are some that are too unlikely to show up, there might be some way to rotate which prog went off first... though I can't think offhand how that might be done.
Last edited by Amalia on Sun Jul 01, 2007 9:33 pm, edited 1 time in total.
Dear Enemy: May the Lord hate you and all your kind, may you be turned orange in hue, and may your head fall off at an awkward moment.
User avatar
Japcil
Sword Grand Master
Sword Grand Master
Posts: 1143
Joined: Fri Jun 17, 2005 5:32 pm
Location: Golden Oaks
Contact:

Post by Japcil » Sun Jul 01, 2007 9:31 pm

Code: Select all

>greet 10~
blah
>greet 10~
blah
both can activate.

Code: Select all

greet prog 100~
if rand (80)
  if rand (50)
    do something half of the time
  else
    if rand (10)
      do something a little of the time
else
  do something most of the time
    endif
  endif
endif
Only one will activate.
Image
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Mon Jul 02, 2007 3:20 am

Correct. The best way to achieve that is to use imbricated/nested if-checks since - as it was pointed out above - using several greet progs could lead to situations (rare, but possible) where ALL greet_progs will trigger.

I'd do the following :

1. Determine how often you would like incoming PCs to get a rumour. The more wandering mobs you have, the smallest the percentage chance should be (unless you want PCs to be spammed with rumours). Let's say, for the sake of this example, that you want an mob to spurt out a rumour with only a 15% chance. This is the number we are going to use for the greet_prog: it will be a greet_prog 15.

2. Write down all the rumours, and determine whether they should all have the same probability to be given or not. A system where some rumours (the more obvious ones) are given more often than other rumours is realistic, but it's harder to get it right. A system where all the rumours have the same probability is simpler (though still not trivial). For the sake of the example, I'll assume that you want all rumours to be given with the same probability.
Side comment wrote:If I have 3 rumours, I want each of them to have a 33.33333% chance to appear, so I can simply build my greet_prog like this:

Code: Select all

>greet_prog 15~
if rand(33)
  sayto $n Rumour 1!
endif
if rand(33)
  sayto $n Rumour 2!
endif
if rand(33)
  sayto $n Rumour 3!
endif
~
This is not correct though - for the same reason that using 3 greet_progs will not work very well: if we use 3 distinct random if-checks, it can happen that the three of them will succeed. That is, it can happen that the mob is going to say Rumour 1! then Rumour 2! then Rumour 3!, and we want to avoid that.

That means that, instead of using consecutive if-checks, we need to use nested if-checks.

With 3 rumours, the process should go as follows:

- Will the first rumour be given? Well, it should be given with a 33% chance (33.3333...% to be precise). If the first rumour is given, the program should then end.

- Otherwise (= else), then either Rumour 2 or Rumour 3 should be given. If we are in this case, both rumours should be equally likely to be given. That means that there would be a 50% chance for Rumour 2 to be given.

- Finally, if Rumour 2 is not given, then we give Rumour 3.

Turning that into code, we get something like this:

Code: Select all

>greet_prog 15~
if rand(33)  <- 33% chance of Rumour 1 being given
  sayto $n Rumour 1!
else
  if rand(50)  <- Otherwise, 50% chance of Rumour 2 being given
    sayto $n Rumour 2!
  else
    sayto $n Rumour 3!  <- Otherwise, well... 100% chance of Rumour 3 being given
  endif
endif
~
And we shouldn't forget the "endif"s!
3. Once you know how many rumours you want, create the structure of the programs, with nested if-rand(something)-checks. To figure out the (something) numbers, you can check the post referred under the heading "Using imbricated rand checks" in there.

If you want some rumours to be more likely to appear than others, you can modify the numbers in the rand() things, but it's very easy to get them wrong.

Code: Select all

greet prog 100~
if rand (80)
  if rand (50)
    do something half of the time
  else
    if rand (10)
      do something a little of the time
    endif
  endif
else
  do something most of the time
endif
The program above, for example, will work as follows:

Code: Select all

if rand (80)  ____________________________________________________
  if rand (50)  _____________________________                     |
    do something half of the time ___________| 50% of 80% = 40%   |
  else                                                            |
    if rand (10)           ------------------|                    | 80%
      do something a little of the time | 4% | 40%                |
    endif                  ------------------|                    |
  endif __________________________________________________________|
else
  do something most of the time                                   | 20%
endif
The numbers are to be read from right to left. First, we have a rand(80) check. It has a 80% chance of succeeding. Therefore, "do something most of the time" will actually be done only 1 in 5 times (= 20% chance).

If the rand(80) succeeds, we get another rand check. This time, the value is 50%. The "do something half of the time" part will thus be done half of the time IF the initial rand(80) check succeeds. That means that it is done only 4 out of 10 times (= 40%).

If the rand(80) succeeds but the rand(50) fails ... which will happen in 40% of the executions of this programme, we reach another if-check. This if-check will succeed only in 10% of the cases when we reach it. 10% of 40% is 4%. Thus, "do something a little of the time" will only be done with a 4% probability.

And if the rand(10) fails... nothing is done.

Summing this up, this programme will do this:
- 40% probability to "do something half the time"
- 4% probability to "do something a little of the time"
- 36% probability to do nothing
- 20% probability to "do something most of the time"

That shows how tricky nested rand-if-checks can be :)
Image
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Mon Jul 02, 2007 3:22 am

Forgot that the link above had not been updated after the forum was moved over here.

The post can be found there: http://www.gallwey.com/fk/board/viewtopic.php?t=380.

And Sharni turned it into a lesson at http://www.gallwey.com/fk/builders/imbr ... dprogs.php.
Image
User avatar
Japcil
Sword Grand Master
Sword Grand Master
Posts: 1143
Joined: Fri Jun 17, 2005 5:32 pm
Location: Golden Oaks
Contact:

Post by Japcil » Mon Jul 02, 2007 5:46 am

Bah! Wouldn't it be $r and not $n or is that only in rand_prog?

Or is $r for case like:

sayto $r Hello there.

And produces "Hello there" to a random person in the room?
Image
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Mon Jul 02, 2007 10:53 am

I am not sure.

$r designates a random character in the room in a rand_prog. I'm not sure if $r is defined in other kinds of programs though.

In this case, the programme should use $n, since the mob is to talk to the character who triggered the greet_prog, not just any character in the room.

And don't feel bad about making mistakes in nested if-checks. Things like that are far from trivial, and many people make similar mistakes. :)
Image
Post Reply