1 2 3 4 5 6 7
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
I tested my theory of changing the initial RTC within the savestate file. It didn't work. It took a change of at least 1000 to yield a different initial seed at the beginning of room 2. Further, that seed did not change equally to the change in RTC timer. For example:
Initial RTC                    Initial Seed
1000                           34203 
1500                           34203
1999                           34203
2000                           55990
1000000000000                  46218
According to c-squares lua script. The number of 'changes' when the initial is set varies drastically with different initial RTC values as well. Any ideas? EDIT: With further testing... Starting RTC of 86400000 = Starting of 0 Starting RTC of 86401000 = Starting of 1000 So it seems that a change of at least 1 whole second in RTC value is necessary to change the initial seed....though that still doesn't explain why the initial seed changes at a different rate than the milliseconds after midnight.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
DrD2k9 wrote:
According to c-squares lua script. The number of 'changes' when the initial is set varies drastically with different initial RTC values as well. Any ideas?
Well, yes. First, although the initial seed depends on the amount of milliseconds since midnight, the game's internal framerate is only about 12 frames per second. That means that every batch of (1000 / 12) = 83 milliseconds will yield the same seed. Second, when the seed is initialized, it is immediately advanced once. The way the random algorithm works, adjacent values end up being non-adjacent after one step.
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
Radiant wrote:
Well, yes. First, although the initial seed depends on the amount of milliseconds since midnight, the game's internal framerate is only about 12 frames per second. That means that every batch of (1000 / 12) = 83 milliseconds will yield the same seed.
But it doesn't. It takes a change of 1000 milliseconds in the RTC setting to yield a different seed. EDIT: And it recycles every 86400000 milliseconds (1 day). So it seems that we're limited to 86,400 potential options for our initial seed. What I'm trying to figure out is a way to calculate what RTC time will yield the initial seed we want for the game. I don't particularly want to manually test 86,400 options.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
DrD2k9 wrote:
What I'm trying to figure out is a way to calculate what RTC time will yield the initial seed we want for the game. I don't particularly want to manually test 86,400 options.
Oh, I see: milliseconds is divided by thousand for some reason. The initial seed is (time in seconds) * 20 + ((time in milliseconds) / 1000) * 20 BUT note that creating the seed will immediately advance it once (i.e. to generate the first random number in logic 2, which is then ignored since guards can't spawn the first time you enter the room). So the value you'll see in your lua panel is the seed AFTER one advancement.
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
Radiant wrote:
The initial seed is (time in seconds) * 20 + ((time in milliseconds) / 1000) * 20 BUT note that creating the seed will immediately advance it once (i.e. to generate the first random number in logic 2, which is then ignored since guards can't spawn the first time you enter the room). So the value you'll see in your lua panel is the seed AFTER one advancement.
I appreciate your attempts, but I'm not following you. Sorry. I have discovered this though
RTC       SEED     DIFFERENCE from previous seed(2 byte HEX)
0         61749
1000      44703    4296
2000	   27657    4296
3000	   10611    4296
4000	   59101    4296
5000	   8340     C649
6000	   56830    4296
7000	   39784    4296
8000	   22738    4296
9000	   5692     4296
10000     20467    C649
11000     3421     4296
12000     51911    4296
13000     34865    4296
14000     17819    4296
This seems to be a usable pattern, but I don't know how to write a formula to predict from this information.
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
That pattern continues all the way through RTC 58000 but then breaks down. And, no, I did not brute force test all 60 possibilities. I wrote a formula, but it only worked up to that point. RTC of 59000 has a 0xC649 difference the previous seed. That shouldn't be expected until RTC 60000. Then RTC of 60000 returns to the 0x4296 difference. My formula worked for a while, but then broke down...I'm missing something.
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
Thanks DrD2k9 for the information. According to Radiant, the RNG is advanced once immediately after creating the seed. So I took your values and looked at the previous seed: (for each of these, the first number is the index, where index(0)=0, and the second number is its corresponding seed value)
0000ms:
13868 00004
13869 61749

1000ms:
34202 00022
34203 44703

2000ms:
18552 00040
18553 27657

3000ms:
64966 00058
64967 10611

4000ms:
35972 00076
35973 59101

5000ms:
59867 00095
59868 08340

6000ms:
17297 00113
17298 56830

7000ms:
05687 00131
05688 39784

8000ms:
23757 00149
23758 22738

9000ms:
64083 00167
64084 05692

10000ms:
13126 00186
13127 20467

11000ms:
07684 00204
07685 03421

12000ms:
61746 00222
61747 51911

13000ms:
25552 00240
25553 34865

14000ms:
38110 00258
38111 17819
It looks like the sequence of initial seeds (before advancing it) starts at 4 for 0ms, then goes 22 (for 1000ms), 40 (for 2000ms), 58, 76, 95, ... Normally the seed goes up by 18, but in some cases the number jumps by 19. It appears to occur every five numbers, but, as you said, at 59000 milliseconds it jumps by 19 instead of 18. Assuming that you mean that 59000ms is the first exception to this rule, the average seed increase appears to be between 18.203 and 18.204. Notably, this number is approximately the clock frequency of MS-DOS, normally cited to be 18.2Hz. My conjecture is that the initial seed is the DOS clock frequency times RTC time (in seconds) plus 4, mod 65536. Could you send the seed value for RTC 86399000ms? (This is one second before 86400000ms, which you said starts the cycle over).
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
FractalFusion wrote:
Could you send the seed value for RTC 86399000ms? (This is one second before 86400000ms, which you said starts the cycle over).
Room 2 seed is 11374. EDIT: so the previous seed should be 161
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
FractalFusion wrote:
which you said starts the cycle over.
I noted that it 86400000 = 0 for RTC It may also recycle before then.
Active player (378)
Joined: 9/25/2011
Posts: 652
Unfortunately, I haven't been able to come up with a predictive way of determining the next rock positions and have the skimmer move in time to avoid them. There's a lot of randoms going on that have nothing to do with the rock placement, and it's been very difficult taking them all into account. I'll try using automated saving and loading of save states next to find a way, but I'm starting to think this may not be doable.
Active player (378)
Joined: 9/25/2011
Posts: 652
I just had another thought: how about using joystick input to get around the clunky frame limitation of typing? It could well make for better routes, and may make tackling the skimmer sequence easier.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
c-square wrote:
There's a lot of randoms going on that have nothing to do with the rock placement, and it's been very difficult taking them all into account.
They're about the time delay between rocks. But yeah, makes it more complicated. Since randomness advances each frame when you're moving, it should be doable to make all rocks spawn to the side while you stick in the middle.
Active player (378)
Joined: 9/25/2011
Posts: 652
Radiant wrote:
Since randomness advances each frame when you're moving, it should be doable to make all rocks spawn to the side while you stick in the middle.
So far I've been trying to dodge the rocks, to little success. Manipulating the rocks might work, however there are two problems that need to be overcome: 1) Figuring out when we need to manipulate the rocks I've written a function to figure out what the next rocks are going to be, but it's not yet very accurate:
function getNextRock1(rockseed)
	nextrock1 = calcRnd(rockseed, 80, 136)
	return nextrock1
end

function getNextRock2(rockseed)
	nextrock2 = calcRnd(rockseed, 20, 70)
	return nextrock2	
end

function getNextSeed(seed)
	return slotRNG[seed]
end

function getNextRocks()
	v0 = 240153
	seedAddr = 246039
	rock1 = jpcrr.read_byte(v0 + 30)
	rock1Countdown = jpcrr.read_byte(v0 + 34)
	rock2 = jpcrr.read_byte(v0 + 32)
	rock2Countdown = jpcrr.read_byte(v0 + 35)
	rockseed = jpcrr.read_word(seedAddr)
	if (rock2Countdown > rock1Countdown) then
		if rock1Countdown > 1 then
			rockseed = getNextSeed(rockseed)
			nextrock1 = getNextRock1(rockseed)
		end
		if rock2Countdown > 1 then 
			rockseed = getNextSeed(rockseed)
			nextrock2 = getNextRock2(rockseed)
		end
		if rock2Countdown > 1 and 5 >= rock2Countdown - rock1Countdown then
			rockseed = getNextSeed(rockseed)
			nextrock1 = getNextRock1(rockseed)
		end
		if rock1Countdown > 1 and  rock1Countdown - rock2Countdown < 5 then
			rockseed = getNextSeed(rockseed)
		end
	end
	if rock1Countdown <= 1 then
		rockseed = getNextSeed(rockseed)
	end
	if rock2Countdown <= 1 then
		rockseed = getNextSeed(rockseed)
	end
	if rock1Countdown == 0 and rock2Countdown == 0 then
		countSeed=jpcrr.read_word(seedAddr)
		countSeed=getNextSeed(countSeed)
		count1 = calcRnd(countSeed,3,30)
		countSeed=getNextSeed(countSeed)
		count2 = calcRnd(countSeed,3,30)
		rock1Pos = jpcrr.read_byte(v0+31)
		rock2Pos = jpcrr.read_byte(v0+33)
		if (rock2Pos < rock1Pos  and count1 <= count2) or (rock1Pos < rock2Pos and count2 <= count1)  then
			rockseed = getNextSeed(rockseed)
			nextrock1 = getNextRock1(rockseed)
			rockseed = getNextSeed(rockseed)
			nextrock2 = getNextRock2(rockseed)
		else
			rockseed = getNextSeed(rockseed)
			nextrock2 = getNextRock2(rockseed)
			rockseed = getNextSeed(rockseed)
			nextrock1 = getNextRock1(rockseed)
		end
	elseif rock1Countdown <= 1 and rock2Countdown <= 1 then
		if rock1Countdown <= rock2Countdown then
			rockseed = getNextSeed(rockseed)
			nextrock1 = getNextRock1(rockseed)
			rockseed = getNextSeed(rockseed)
			nextrock2 = getNextRock2(rockseed)
		else
			rockseed = getNextSeed(rockseed)
			nextrock2 = getNextRock2(rockseed)
			rockseed = getNextSeed(rockseed)
			nextrock1 = getNextRock1(rockseed)
		end
	elseif rock1Countdown <= 1 then
		rockseed = getNextSeed(rockseed)
		nextrock1 = getNextRock1(rockseed)
	elseif rock2Countdown <= 1 then
		rockseed = getNextSeed(rockseed)
		nextrock2 = getNextRock2(rockseed)
	end
	return rock1, rock2, nextrock1, nextrock2
end
(I apologize for the lack of comments.) It works fine if the rock countdowns are both large, but has trouble once they're 1 or 0, which is why there's so much code trying to adjust it. Feel free to check it out and correct it. 2) Manipulating seeds on the frames we want to It's possible to use up or down to enter a direction without actually moving the skimmer, so manipulating seeds is possible while staying in one place. The problem is that because we're using text input, although it's possible to stop moving on a desired frame, you then have to wait a number of frames before the engine will pick up your command to start moving again. This makes seed manipulation unpredictable. I'm wondering if joystick input is instantaneous and gets around the keyboard input limitation.
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
c-square wrote:
I just had another thought: how about using joystick input to get around the clunky frame limitation of typing? It could well make for better routes, and may make tackling the skimmer sequence easier.
For what it's worth, I don't mind doing the skimmer sequence manually. It just won't give us as much control of the random seed heading into Ulence Flats if I do so. Speaking of randomization in Ulence Flats. Once we decide on a final process for the skimmer sequence, I'll see what I can do about not having to take the key out of the skimmer to save a few frames.
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
SUCCESS! I've got a spreadsheet that works for choosing what starting seed I want. It took a combination of calculations and brute force to complete the spreadsheet, but it's done. I can now set the initial RTC to yield a desired seed value upon Room 2. Now to see if I can find a starting RTC that yields the longest spider droid delay as well as no guards on the Arcada.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
DrD2k9 wrote:
SUCCESS! I've got a spreadsheet that works for choosing what starting seed I want.
:D
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
I've found an initial RTC that yields no guards on the Arcada and only requires one 'y' input to advance the random seed to yield the longest time for the spider droid to appear. I've run through the game up through exiting the escape pod and was able to confirm that variable v93 was set to 250, which I believe is the longest possible. Now then...Do we want to try and manipulate acid drops, or just deal with the random seed where we are when we get past them? Also on the note of randomness... Does the guy who buys the skimmer work on an RNG timer? Does the blue droid in the Deltaur airlock work on one?
Active player (378)
Joined: 9/25/2011
Posts: 652
Looks like there's no delay for joystick input. It should be easy to update JPC-rr so you can use the number keys to control the joystick, if you'd like. There is one problem I'm running into: I can send an AXISA command with a positive number, and Roger goes left. Same with AXISB and up. However, I haven't figured a way to go right or down yet. The input doesn't take negative numbers. Anyone else have an idea? I'll play with it more tomorrow.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
DrD2k9 wrote:
Now then...Do we want to try and manipulate acid drops, or just deal with the random seed where we are when we get past them?
Even without TAS'ing, I find that reasonably often I can enter the room and walk straight to the right without hitting anything. I'll check on the probability of that.
Does the guy who buys the skimmer work on an RNG timer? Does the blue droid in the Deltaur airlock work on one?
No to both. The skimmer guy appears immediately when you get off the skimmer. The blue droid appears 249 ticks after you enter the room.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
Right, so those acid drops are pretty straightforward. When entering the room, random() is called three times for their delays: 9-71, 1-71, and 1-71 ticks respectively. After that amount of ticks, they spawn. When they do, an immediate is made check on EGO's X coordinate. This is done only once when the drop appears, not while it falls (note that this makes the sequence entirely unfair to a human player, as there is no way to see the drops coming!) If EGO is at X = 84 through 91, he'll get hit by the first drop. 94 through 101, the second drop. 109 to 116, the third drop. I've tested a bunch of times and find that at fastest speed, moving straight through the room gets me past the drops 66% of the time. So this should be easy to manipulate; the odds are good that the seed you already have will get you past them.
DrD2k9
He/Him
Editor, Judge, Expert player (2213)
Joined: 8/21/2016
Posts: 1088
Location: US
Radiant wrote:
Right, so those acid drops are pretty straightforward....the odds are good that the seed you already have will get you past them.
Good to know. What I originally meant with my question was, do we want to try and manipulate the random calls to control what seed we get coming out of that room? Or do we just want to see where it's at when entering the skimmer sequence?
c-square wrote:
Looks like there's no delay for joystick input. It should be easy to update JPC-rr so you can use the number keys to control the joystick, if you'd like.
My first question: Is that much work necessary? What is the potential range of seed changes that can happen through the skimmer sequence? Second question: Might it be simpler to just make a run with my current RTC time and see where the seed is at the end of the skimmer sequence when performed manually; compare that number with the seed spreadsheet and see where it leaves us for the slots; then use that information to determine how much manipulation we actually need to worry about during the skimmer sequence? If we end up with a relatively good starting point for the slots with this method, we don't have to try and automate so much of the skimmer sequence.
Player (26)
Joined: 8/29/2011
Posts: 1206
Location: Amsterdam
DrD2k9 wrote:
Or do we just want to see where it's at when entering the skimmer sequence?
Oh, right. This one, I'd say. The skimmer sequence isn't going to be any faster regardless of where the randomizer is at.
Active player (378)
Joined: 9/25/2011
Posts: 652
DrD2k9 wrote:
c-square wrote:
Looks like there's no delay for joystick input. It should be easy to update JPC-rr so you can use the number keys to control the joystick, if you'd like.
My first question: Is that much work necessary? What is the potential range of seed changes that can happen through the skimmer sequence?
No, it's not. If we're searching for the perfect run, then we'll have to do that exercise, but it's very possible to get a quick, decent run without it. In the few passes I've done, the skimmer sequence has called random anywhere between 300 and 600 times, making it hard to target a specific range manually. However, if you want to limit the number of random calls, press "up" when you're still. That will prevent the shadow hop random calls. I still want to try to get an autopilot working, as I feel I'm close now. But if you want to go ahead and do the run manually, feel free. You likely have enough info to do a fast run, and I'll be happy to help out if or when you need it.
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
c-square wrote:
Looks like there's no delay for joystick input. It should be easy to update JPC-rr so you can use the number keys to control the joystick, if you'd like. There is one problem I'm running into: I can send an AXISA command with a positive number, and Roger goes left. Same with AXISB and up. However, I haven't figured a way to go right or down yet. The input doesn't take negative numbers. Anyone else have an idea? I'll play with it more tomorrow.
What are the specifics of joystick input in JPC-rr? Are there commands other than AXISA and AXISB, and if so, what do they do? What are the possible values for AXISA and AXISB? Did you try a number at the top of its possible range?
DrD2k9 wrote:
Does the guy who buys the skimmer work on an RNG timer?
Not really, but there is one situation in that room where random() is called, which Radiant already mentioned on a previous page. If you leave the skimmer key in the skimmer and walk off and come back, there is a 34% chance of it being stolen. If you can manipulate it so that it won't be stolen, then you don't need to take out the key. (Also, there is no need to say "no" to that guy the first time. Just walk off after he gives his first offer.) Edit: The alien waiting to be killed by the slot machine runs on an RNG timer. It takes 71+54*(x-2) ticks for him to be killed, where x is a random number between 2 and 7.
Active player (378)
Joined: 9/25/2011
Posts: 652
FractalFusion wrote:
What are the specifics of joystick input in JPC-rr? Are there commands other than AXISA and AXISB, and if so, what do they do? What are the possible values for AXISA and AXISB? Did you try a number at the top of its possible range?
I figured it out. The starting value (center) for the joystick axes is 10,000. Left and up is zero, right and down is 20,000. Of course, when things start looking good, something else comes up: My simple autopilot is still too slow to react after the rock placements are set. You have three frames to get out of the way of a rock. Even with instantaneous movement, that's not always possible. However, my (semi)predictive autopilot is faring better, and is getting out of the way of the rocks.... until the game freezes for some unknown reason and just hangs. Still more to look into...
1 2 3 4 5 6 7