I found this on Youtube:
The short version is that the amount of money in your wallet is stored in an 8-bit unsigned integer (0-255). To make it appear that you have more money, the game just appends a "0" at the end. So the variable stores a 68, but displays $680. And this is where the exploit comes in. If you bring the money you have to only $10, when you go to zero while gambling, your money will roll over back to 255 (or $2550) since the variable can't go negative. The game thinks you made a killing in the game and you automatically advance. Makes sense.
Except...
I remembered that if you buy a drink at the bar, they cost $5. Which means that sometimes the money in your wallet can end in a 0 or a 5. So I tried this out, and if you enter the poker game with just $5 in your wallet, your money will suddenly become $2555 after you pay the $10 ante. So what appears to be happening is that there is a separate flag which determines if a 0 or a 5 gets displayed at the end. And if you look at your wallet, when you have just $5 left, it will actually display $05. 0 with a 5 at the end. What I can't figure out is, why do it this way? Wouldn't it be simpler to use a 16-bit integer?
PQ1 gambling exploit
- notbobsmith
- Village Elder
- Posts: 5359
- Joined: Sun Mar 09, 2014 4:02 pm
- Location: Massachusetts
- Gender: Male
- Tawmis
- Grand Poobah's Servant
- Posts: 20911
- Joined: Wed Oct 08, 2008 1:19 am
- Gender: Not Specified
- Contact:
Re: PQ1 gambling exploit
Interesting. Curious how no one in QA caught that.
Tawmis.com - Voice Actor
Comic Relief Podcast!
Neverending Nights
Hello, my name is Larry. Larry Laffer!
Comic Relief Podcast!
Neverending Nights
Hello, my name is Larry. Larry Laffer!
- Rath Darkblade
- The Cute One
- Posts: 12930
- Joined: Fri Oct 24, 2008 5:15 am
- Location: Lost in Translation
- Gender: Male
- Contact:
Re: PQ1 gambling exploit
*looks up "difference between 8-bit unsigned integer and 16-bit integer" on google*
All right. "8 bit" refers to any number in binary from 0 to 255, in binary written as 0000 0000 to 1111 1111 (those are 8 “bits” or binary digits).
16 bit refers to numbers from 0 to 65535.
So, maybe they simply didn't want Sonny to be able to bet so much? $65,535 is a lot of money, even in fictional games.
What would make sense is dividing the number into three bytes, where:
- Byte #1 being only 0 to 2; and
- Byte #2 and #3 being 0 to 9 -- UNLESS ...
- If Byte #1 is "2", then Byte #2 can only be 0 to 5, and Byte #3 can be 0 to 9 -- UNLESS ...
- If Byte #1 is "2", and Byte #2 is "5", then Byte #3 can only be 0 to 5.
This is a bit fiddly, but logic-wise, it can be done. Behold:
Just translate that to C++, or whichever language you like, and you're ready to rock 'n roll.
All right. "8 bit" refers to any number in binary from 0 to 255, in binary written as 0000 0000 to 1111 1111 (those are 8 “bits” or binary digits).
16 bit refers to numbers from 0 to 65535.
So, maybe they simply didn't want Sonny to be able to bet so much? $65,535 is a lot of money, even in fictional games.
What would make sense is dividing the number into three bytes, where:
- Byte #1 being only 0 to 2; and
- Byte #2 and #3 being 0 to 9 -- UNLESS ...
- If Byte #1 is "2", then Byte #2 can only be 0 to 5, and Byte #3 can be 0 to 9 -- UNLESS ...
- If Byte #1 is "2", and Byte #2 is "5", then Byte #3 can only be 0 to 5.
This is a bit fiddly, but logic-wise, it can be done. Behold:
Code: Select all
Let_Byte1 = 0, 1, or 2;
Let_Byte2 = 0 to 9;
Let_Byte3 = 0 to 9;
IF Byte1 = 2
AND Byte2 = 5
THEN Let_Byte3 = 0 to 5
ELSE Byte2 = 0 to 9
AND Byte3 = 0 to 9
END IF
- notbobsmith
- Village Elder
- Posts: 5359
- Joined: Sun Mar 09, 2014 4:02 pm
- Location: Massachusetts
- Gender: Male
Re: PQ1 gambling exploit
The high dollar value is only a problem if the player uses the exploit, which they don't seem concerned about. On the other hand, if a regular integer was used, you could have the player lose if they go negative.Rath Darkblade wrote: ↑Sat May 11, 2024 11:07 pm *looks up "difference between 8-bit unsigned integer and 16-bit integer" on google*
All right. "8 bit" refers to any number in binary from 0 to 255, in binary written as 0000 0000 to 1111 1111 (those are 8 “bits” or binary digits).
16 bit refers to numbers from 0 to 65535.
So, maybe they simply didn't want Sonny to be able to bet so much? $65,535 is a lot of money, even in fictional games.
What would make sense is dividing the number into three bytes, where:
- Byte #1 being only 0 to 2; and
- Byte #2 and #3 being 0 to 9 -- UNLESS ...
- If Byte #1 is "2", then Byte #2 can only be 0 to 5, and Byte #3 can be 0 to 9 -- UNLESS ...
- If Byte #1 is "2", and Byte #2 is "5", then Byte #3 can only be 0 to 5.
This is a bit fiddly, but logic-wise, it can be done. Behold:
Just translate that to C++, or whichever language you like, and you're ready to rock 'n roll.Code: Select all
Let_Byte1 = 0, 1, or 2; Let_Byte2 = 0 to 9; Let_Byte3 = 0 to 9; IF Byte1 = 2 AND Byte2 = 5 THEN Let_Byte3 = 0 to 5 ELSE Byte2 = 0 to 9 AND Byte3 = 0 to 9 END IF
I don't think I follow what your code is trying to do. A simpler solution, which I think it what they did, is to have the unsigned integer hold the money, and another variable to hold if you have a five or zero. so if you buy a drink from the bartender, it would look something like this:
Code: Select all
if (five == true) {
five = false; //subtract 5 if you have a 5
}
else {
money = money - 1; // subtract "10"
five = true; // add "5"
}
- Rath Darkblade
- The Cute One
- Posts: 12930
- Joined: Fri Oct 24, 2008 5:15 am
- Location: Lost in Translation
- Gender: Male
- Contact:
Re: PQ1 gambling exploit
I'm not sure what the problem is. My code is simply saying as follows:notbobsmith wrote: ↑Sun May 12, 2024 12:12 am I don't think I follow what your code is trying to do.
1. Sonny can only have up to $255.
2. Therefore, we divide the number "255" into three variables, where:
a. Byte1 represents the "hundreds" digit (and can be 0, 1 or 2);
b. Byte2 represents the "tens" digit (and can be 0 to 9);
c. Byte3 represents the "singles" digit (and can be 0 to 9).
3. BUT, to avoid instances of Sonny getting $299 (which won't work! ), we add two caveats:
a. If "Byte1" is "2" (i.e. Sonny has $200 and above), then "Byte2" can only be 0 to 5 (i.e. up to $250 and up).
b. If "Byte1" is "2" AND "Byte2" is 5 (i.e. $250-something), then "Byte 3" can only be 0 to 5 (to avoid Sonny getting $256, $257 etc.)
c. Otherwise (i.e. Sonny has between $0 and $200) ... then "Byte 2" and "Byte 3" can be 0 to 9. (And then Sonny can have $0 to $99, or $100 to $199, etc.)
Agreed. I'm not sure why Sierra didn't do that. Then again, according to wikipedia:
So if you're using a 16-bit integer, Sonny can have up to $65,535. That's incredibly generous for a poker game.A 16-bit register can store 2-to-the-power-of-16 different values. The range of integer values that can be stored in 16 bits depends on the integer representation used. With the two most common representations, the range is 0 through 65,535 for representation as an (unsigned) binary number.
- notbobsmith
- Village Elder
- Posts: 5359
- Joined: Sun Mar 09, 2014 4:02 pm
- Location: Massachusetts
- Gender: Male
Re: PQ1 gambling exploit
That seems really complicated when devising a way to add and subtract.Rath Darkblade wrote: ↑Sun May 12, 2024 7:57 pmI'm not sure what the problem is. My code is simply saying as follows:notbobsmith wrote: ↑Sun May 12, 2024 12:12 am I don't think I follow what your code is trying to do.
1. Sonny can only have up to $255.
2. Therefore, we divide the number "255" into three variables, where:
a. Byte1 represents the "hundreds" digit (and can be 0, 1 or 2);
b. Byte2 represents the "tens" digit (and can be 0 to 9);
c. Byte3 represents the "singles" digit (and can be 0 to 9).
3. BUT, to avoid instances of Sonny getting $299 (which won't work! ), we add two caveats:
a. If "Byte1" is "2" (i.e. Sonny has $200 and above), then "Byte2" can only be 0 to 5 (i.e. up to $250 and up).
b. If "Byte1" is "2" AND "Byte2" is 5 (i.e. $250-something), then "Byte 3" can only be 0 to 5 (to avoid Sonny getting $256, $257 etc.)
c. Otherwise (i.e. Sonny has between $0 and $200) ... then "Byte 2" and "Byte 3" can be 0 to 9. (And then Sonny can have $0 to $99, or $100 to $199, etc.)
Agreed. I'm not sure why Sierra didn't do that. Then again, according to wikipedia:
So if you're using a 16-bit integer, Sonny can have up to $65,535. That's incredibly generous for a poker game.A 16-bit register can store 2-to-the-power-of-16 different values. The range of integer values that can be stored in 16 bits depends on the integer representation used. With the two most common representations, the range is 0 through 65,535 for representation as an (unsigned) binary number.
"1. Sonny can only have up to $255." Why? Remember that the only reason that there is the $2550 limit is because they used the unsigned 8-bit integer. It doesn't have to have that limit. In practice, this is just fine. Sonny starts with $1000, spends $320 before entering the game and has to do well playing poker. The poker session ends when he wins enough. It's unlikely that he will get past $2000. I usually end with ~$1500. You only encounter the "problem" if you deliberately try the exploit.
- Rath Darkblade
- The Cute One
- Posts: 12930
- Joined: Fri Oct 24, 2008 5:15 am
- Location: Lost in Translation
- Gender: Male
- Contact:
Re: PQ1 gambling exploit
OK, fair enough. I thought that having an 8-bit integer means that 1 to 256, as wikipedia told me when I looked up "8-bit integers".
As for it being complicated - teaching a computer to do math (from scratch) is complicated. I was thinking of a way to do it when all you have is 3 bytes.
As for it being complicated - teaching a computer to do math (from scratch) is complicated. I was thinking of a way to do it when all you have is 3 bytes.