Resting outside is nearly always interrupted

Everything about development and the OpenMW source code.
User avatar
sjek
Posts: 440
Joined: 22 Nov 2014, 10:51

Re: Resting outside is nearly always interrupted

Post by sjek » 17 May 2015, 07:30

exactly getting it would need somehow seeding the generator althought goes over my head.

in previous fix

Code: Select all

int x = OEngine::Misc::Rng::rollDice(hoursToWait);
if (x > fSleepRandMod * hoursToWait)
mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait)
rand generator isn't always reliable in OEngine::Misc::Rng::rollDice(hoursToWait)

Code: Select all

 int Rng::rollDice(int max)
{
return static_cast<int>((std::rand() / (static_cast<double>(RAND_MAX)+1.0)) * (max));
http://www.cplusplus.com/reference/cstdlib/rand/
Notice though that this modulo operation does not generate uniformly distributed random numbers in the span (since in most cases this operation makes lower numbers slightly more likely).
http://en.cppreference.com/w/cpp/numeric/random/rand
stackoverflow

just some found googling std rand
"life is crazy"
"craziness has beauty which only crazies understand" some movie clip in the head.
https://wiki.openmw.org/index.php?title=Testing

User avatar
Mesons
Posts: 11
Joined: 15 Jun 2014, 23:43

Re: Resting outside is nearly always interrupted

Post by Mesons » 17 May 2015, 08:11

I don't think the deviations from random would be noticeable in gameplay.

Golken
Posts: 27
Joined: 04 May 2015, 05:03

Re: Resting outside is nearly always interrupted

Post by Golken » 22 May 2015, 00:20

Seeing as it would be used a lot throughout the game, if the random function(s) used aren't completely reliable we would want to switch to better ones. Or, if the original game's RNG isn't too uniform either, then we'd want to use a similar/the same RNG (with same pitfalls/tendencies) to get closer to original experience, with a CFG option (post 1.0?) to switch to a more uniform one instead.

User avatar
sjek
Posts: 440
Joined: 22 Nov 2014, 10:51

Re: Resting outside is nearly always interrupted

Post by sjek » 24 May 2015, 14:32

http://forums.bethsoft.com/topic/151314 ... p=23885619
1. Slight flaw. fSleepRandMod works as probability coefficient and is in overall usual modifier, but fSleepRestMod doen't make sense at all. Instead of providing some diminishing factor, so player will be more likely to be interrupted after X hours, it's just calculates at what percent of choosed hours you will be waked. As a consequence, more hours you choose to rest - more hours you will rest unwaked even if you should be interrupted. [facepalm]

2. Exploit. It was easy. If fSleepRestMod formula is so stupid, there must be some exploit. And here it is. Just choose to rest one hour every time. You will not be waked. Ever. You will sleep in wilderness as in your new bed from IKEA store. [facepalm again]
possibly cfg and/or making it optional while writing game mechanic to scripts
"life is crazy"
"craziness has beauty which only crazies understand" some movie clip in the head.
https://wiki.openmw.org/index.php?title=Testing

Chris
Posts: 1583
Joined: 04 Sep 2011, 08:33

Re: Resting outside is nearly always interrupted

Post by Chris » 24 May 2015, 16:12

sjek wrote:http://forums.bethsoft.com/topic/151314 ... p=23885619
1. Slight flaw. fSleepRandMod works as probability coefficient and is in overall usual modifier, but fSleepRestMod doen't make sense at all. Instead of providing some diminishing factor, so player will be more likely to be interrupted after X hours, it's just calculates at what percent of choosed hours you will be waked. As a consequence, more hours you choose to rest - more hours you will rest unwaked even if you should be interrupted. [facepalm]

2. Exploit. It was easy. If fSleepRestMod formula is so stupid, there must be some exploit. And here it is. Just choose to rest one hour every time. You will not be waked. Ever. You will sleep in wilderness as in your new bed from IKEA store. [facepalm again]
I don't see this as a particularly big deal. As long as it's not something a player can inadvertently exploit, I wouldn't give it much thought. If someone goes through the trouble of purposely doing multiple one-hour rests to avoid wilderness interruptions, then plugging that hole will almost assuredly just drive them to find some other way to get the same result.

User avatar
sjek
Posts: 440
Joined: 22 Nov 2014, 10:51

Re: Resting outside is nearly always interrupted

Post by sjek » 24 May 2015, 18:43

well playing ingame it's kinda thought provoking why all the creatures hasn't died to extinction given how much adventurers and npc's there is in the wilderness with constant interruption.

if thinking that first hours is half sleeping for diminishing interruptions makes sense. somewhat dagoth ur style

modyfying fsleeprestmod / possibility for custom mechanic gmst's goes after dehardcoding stuff or not.... late night
"life is crazy"
"craziness has beauty which only crazies understand" some movie clip in the head.
https://wiki.openmw.org/index.php?title=Testing

Chris
Posts: 1583
Joined: 04 Sep 2011, 08:33

Re: Resting outside is nearly always interrupted

Post by Chris » 25 May 2015, 04:34

sjek wrote:well playing ingame it's kinda thought provoking why all the creatures hasn't died to extinction given how much adventurers and npc's there is in the wilderness with constant interruption.
The world is much bigger than what you see in game. The area of High Rock and Hammerfell that Daggerfall covered is about the same size (if not less, due to the ocean inlet) as Vvardenfell. Daggerfall is about 62000 square miles, whereas Oblivion is 16 square miles, and Morrowind is smaller than that. Even if you wiped out all life in what the game gave you, that's much much less than 0.1% (closer to 0.01%) of the "real" island.

ahehalftalftow
Posts: 9
Joined: 27 Jul 2015, 19:48

Re: Resting outside is nearly always interrupted

Post by ahehalftalftow » 15 Aug 2015, 11:05

I did some rough math, with the current formula being used in /apps/openmw/mygui/waitdialog.cpp, compared to
sjek wrote: in previous fix

Code: Select all

int x = OEngine::Misc::Rng::rollDice(hoursToWait);
if (x > fSleepRandMod * hoursToWait)
mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait)
here is the results:

//(x > fSleepRandMod * hoursToWait) //Sjek's formula
hours: 1 Interruptions: 0/100,000
hours: 2 Interruptions: 50,114/100,000
hours: 3 Interruptions: 66,794/100,000
hours: 4 Interruptions: 50,232/100,000
hours: 5 Interruptions: 60,108/100,000
hours: 6 Interruptions: 66,571/100,000
hours: 7 Interruptions: 71,463/100,000
hours: 8 Interruptions: 62,612/100,000
hours: 9 Interruptions: 66,423/100,000
hours: 10 Interruptions: 70,145/100,000
hours: 11 Interruptions: 72,813/100,000
hours: 12 Interruptions: 66,624/100,000
hours: 13 Interruptions: 69,208/100,000
hours: 14 Interruptions: 71,334/100,000
hours: 15 Interruptions: 73,386/100,000
hours: 16 Interruptions: 68,721/100,000
hours: 17 Interruptions: 70,750/100,000
hours: 18 Interruptions: 72,279/100,000
hours: 19 Interruptions: 73,656/100,000
hours: 20 Interruptions: 69,673/100,000
hours: 21 Interruptions: 71,268/100,000
hours: 22 Interruptions: 72,750/100,000
hours: 23 Interruptions: 73,824/100,000
hours: 24 Interruptions: 70,825/100,000

//(x < fSleepRandMod * hoursToWait) //The Current Formula
hours: 1 Interruptions: 100,000/100,000
hours: 2 Interruptions: 49,886/100,000
hours: 3 Interruptions: 33,206/100,000
hours: 4 Interruptions: 24,910/100,000
hours: 5 Interruptions: 39,892/100,000
hours: 6 Interruptions: 33,429/100,000
hours: 7 Interruptions: 28,537/100,000
hours: 8 Interruptions: 25,032/100,000
hours: 9 Interruptions: 33,577/100,000
hours: 10 Interruptions: 29,855/100,000
hours: 11 Interruptions: 27,187/100,000
hours: 12 Interruptions: 24,922/100,000
hours: 13 Interruptions: 30,792/100,000
hours: 14 Interruptions: 28,666/100,000
hours: 15 Interruptions: 26,614/100,000
hours: 16 Interruptions: 24,972/100,000
hours: 17 Interruptions: 29,250/100,000
hours: 18 Interruptions: 27,721/100,000
hours: 19 Interruptions: 26,344/100,000
hours: 20 Interruptions: 25,268/100,000
hours: 21 Interruptions: 28,732/100,000
hours: 22 Interruptions: 27,250/100,000
hours: 23 Interruptions: 26,176/100,000
hours: 24 Interruptions: 25,034/100,000

Code: Select all

#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
int hours=1;
while (hours < 25){
int counter=0;
int runs=100000;
while ( runs > 0 ){
 if( static_cast<int>((std::rand()/(static_cast<double>(RAND_MAX)+1.0)) * (hours)) > 0.25*hours ){
counter++;
}
runs--;
}
std::cout << "hours: " << hours << " Interruptions: " << counter << "/100,000" << std::endl;
hours++;
}
return 0;
}
the only difference being the direction of the inequality (> vs <)

User avatar
scrawl
Posts: 2152
Joined: 18 Feb 2012, 11:51

Re: Resting outside is nearly always interrupted

Post by scrawl » 15 Aug 2015, 14:36

My theory is that it's

Code: Select all

(x < fSleepRandMod * hoursToWait) //The Current Formula
with the slight alteration

Code: Select all

(x < int(fSleepRandMod * hoursToWait))
That formula gives a couple of data points I have experimentally confirmed in vanilla:

hours: 1 Interruptions: 0/100,000
hours: 2 Interruptions: 0/100,000
hours: 3 Interruptions: 0/100,000
...
hours: 24 Interruptions: 25,034/100,000

Still looking for Hrnchamd's confirmation to see if this is a 100% accurate, but he seems to be busy lately so I'm going to commit this change later today.

User avatar
Jyby
Posts: 408
Joined: 10 Dec 2013, 04:16

Re: Resting outside is nearly always interrupted

Post by Jyby » 15 Aug 2015, 16:08

hmm...
Last edited by Jyby on 15 Aug 2015, 16:18, edited 1 time in total.
Macbook Air 2013 - 1.7GHz Intel i7 - 8 GB - 512 GB SSD - Intel HD 5000
Windows 10 PC - 4GHz Intel i7 - 16 GB - 512 GB SSD - EVGA GTX 1060 SSC

Post Reply