Skip to content

Add basic laughing stock predictor - #874

Open
Ignose wants to merge 22 commits into
mainfrom
LaughingStock
Open

Add basic laughing stock predictor#874
Ignose wants to merge 22 commits into
mainfrom
LaughingStock

Conversation

@Ignose

@Ignose Ignose commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@Ignose
Ignose marked this pull request as ready for review August 20, 2026 17:57
Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated
Ignose and others added 6 commits August 20, 2026 15:06
Backs the mocked mafia RNG functions with kol-rng, which simulates the
same PHP 5.3.10 Mersenne Twister that KoL uses, so the predictor can be
exercised end to end.

The expected drops were recorded against the fixedDropTurns
implementation and do not match the triangular number version. The
1-in-50 drops past combat 56 are unchanged, but the deterministic drops
are now keyed one combat earlier, and the first one lands on key 0 where
the fight > charges filter in expectedDropsToday can never return it.
@gausie

gausie commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Correction on my last comment — I'd written that test with toMatchSnapshot, which nothing else in this repo does. Rewrote it as a plain toEqual against an explicit list and dropped the __snapshots__ directory, then force-pushed over my own commit. Same failure, just legible in the diff now.

The substance is unchanged: the expected drops are the pre-triangular-n ones, and the deterministic half disagrees.

@spaghetti-squash spaghetti-squash left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the pity count/threshold the only reason we have to compute all of the drops prior to the point your'e at?

Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts
Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated

for (let i = 0; i < getDeterministicDrops(deterministicFights); i++) {
const fight = 1 + (i * (i + 1)) / 2;
const rng = phpSeed(getSeed(classId, pathId, daycount) + 381 * (fight - 1));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is creating a new php seed each instance actually Correct here? I thought php rngs persisted stateful information, based on my first reading of the code. Maybe I'm wrong! I do see that fight is included in the seed so I guess that's fine, actually.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea; phpSeeds are alchemy to me.

Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment on lines +31 to +48
class FruitTracker {
private pityCount = 0;
private pityThreshold = 10;

getFruit(rng: Rng): Item {
const threshold = this.pityCount < 3 ? this.pityThreshold : 3;
const isAdvanced = phpMtRand(rng, 1, 30) <= threshold;

if (isAdvanced) {
this.pityCount++;
this.pityThreshold = 10;
return ADVANCED_FRUIT[phpMtRand(rng, 0, 2)];
}

this.pityThreshold += 10;
return BASIC_FRUIT[phpMtRand(rng, 0, 18)];
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably put the rng into the constructor of this but otherwise cool and woke

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might not actually work, given that we call it a lot with different rng seeds every time (as fight increments)? idk. Do what feels natural, I guess.

Comment thread src/resources/2026/LaughingStock.ts Outdated
Comment thread src/resources/2026/LaughingStock.ts Outdated
Co-authored-by: neil <78829653+spaghetti-squash@users.noreply.github.com>
Comment thread src/resources/2026/LaughingStock.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants