Odd random () behavior in FTE ?

Discuss programming topics for the various GPL'd game engine sources.
Post Reply
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Odd random () behavior in FTE ?

Post by frag.machine »

Ok guys, I am here scratching my head with an... bug ? Odd but acceptable behavior ? I don't know how to define this.

I recently restarted work in Mighty Quake (which BTW right now changed to be a first person... thing ? ) and sharing my time between the painful creation of non-completely garbage artwork and fleshing out the gameplay, but some serious rendering performance issues started to arise with Darkplaces. After all, I am basically trying to render several hundreds of bmodel entities at once, some of them with dynamic lights, and there are points in the map where the framerate drops to below 10 fps when in first person mode. And I haven't even started to actually populate it... :(

After fiddling with Darkplaces settings for some time I decided to experiment running the mod with FTE. "Probably it won't work without a lot of rewriting, something essential must be broken like some builtin", I thought but to my surprise not only things worked (mostly) without flaws at the first try but FPS are between 90 and 110 even on spots where things looked like a slide show, so congratulations Spike! Your engine really rocks. There are minor problems due the fact I am running a relatively old build and different folders names, but overall I am not only considering to support both engines in my mod, but is very likely that FTE becomes the default choice.

However, I am observing a strange behavior while running the mod on FTE: while in Darkplaces most randomically generated maps have (most of time) layouts heterogeneous enough to ensure good opportunities of exploration and gameplay, every map generated on FTE has pretty much the same boring, single and short corridor layout. The length sometimes is shorter or longer, but the variation is almost inexistent. WTF ?

There are no runtime errors or console warnings; I am not doing anything unusual like using obscure DP extensions for control the world generation; everything apparently works as expected, but at the same time, this is NOT what was expected (or how was working in DP). Since my QC code relies heavily on several calls to random() to define all aspects of the generated map (how many portals, how many roads/paths, their length, how many corners, how many builds, etc) this makes me believe that in FTE random () behaves vastly different from Darkplaces (and apparently in a very repetitive way). Is that the case ? Is there something I can do to force a better random seeding ?
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Odd random () behavior in FTE ?

Post by Spike »

http://xkcd.com/221/

fte's random is very close to vanilla's. the difference being that the result is nudged down by 1/32768th or so.
both fte and dp use the standard libc rand() function, its just that fte assumes rand_max is 32767 while DP uses the native value. fte always has 15bits of entropy (the min required), while DP uses whatever the system uses - which is 15 in windows.
dp additionally biases up by 0.5/32768. So if you combine that with the previous thing, add that number to fte's random() and not when in DP, and the two randoms will return the exact same set of values on windows (different seeds, though that varies between engine restarts anyway).

here's some fun code that should give you a way to replace the system(engine) random number generator with something with more entropy. Its not perfect of course, but it should get the job done.

Code: Select all

#pragma target fte //switch to extended opcodes
#define RSH_U(v,u) ((v>>u)&0x7fffffffi) //rightshifts need to not use sign extension, equivelent to clearing the high bit.
float xorshift128f(void)
{
static int x, y, z, w; //static means their value is retained between calls. make these globals if you wish to seed the generator.
while(!x && !y && !z && !w)
{ //first run, stuff should not be 0. seed them to something which is not 0.
x=(int)(random()*65535) | (int)(random()*65535)<<16i;
y=(int)(random()*65535) | (int)(random()*65535)<<16i;
z=(int)(random()*65535) | (int)(random()*65535)<<16i;
w=(int)(random()*65535) | (int)(random()*65535)<<16i;
}
    int t = x ^ (x << 11i);
    x = y; y = z; z = w;
    w = w ^ RSH_U(w , 19i) ^ t ^ RSH_U(t , 8i);
    //NOTE: returns 0-1 inclusive
    return (float)(w&0x7fffffffi) / ((float)0x7fffffffi); //truncate to 31 bits to avoid unsigned values
};
#pragma target id //and back to restricting opcodes to ones that vanilla supports
float myrandom()
{
    if (canuseintopcodes) //fte=1, dp=0
        return xorshift128f();
    else
        return random();
};
I fully expect you to tweak those seeds in order to regenerate the exact same area time and time again. And across a network too. Just make sure they're never all 0.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Odd random () behavior in FTE ?

Post by frag.machine »

Heh, obligatory Playstation "random" number generator reference :D

Thanks for the explanation, I will take the time to investigate more deeply the issue.
Unfortunately, updating FTE to the more recent build fubared the random map code. :( Oh well...
Hopefully I can fix my code, I really want to make this mod work in both engines.

EDIT: Okay, after updating to the actual latest version (fteqw64 build 4996), things changed. Not sure if for better or worse, but hey.

Now every time I try to generate a map the engine aborts, apparently because I am using findentity ().
Funny thing is, the same progs.dat was working with previous versions of FTE. Funnier yet, if you use:

pr_dumpplatform -O ftedefs -Ffte

The extension is listed in the resulting file, and has the same builltin number and declared with the same signature as in dpextensions.qc (which is already part of my mod).

Finnaly, FTE it says "mod forgot to ensure support for builtin 98: findentity". WHAT ?

:?: :surprised: :!: :confused:
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Post Reply