Skip to content

Commit

Permalink
Merge pull request #628 from Pseudo-Corp/seeded-rng-2
Browse files Browse the repository at this point in the history
seeded rng
  • Loading branch information
Pseudonian authored Jan 11, 2025
2 parents 516b604 + e64ddb5 commit 862b876
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 24 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"break_infinity.js": "^2.0.0",
"clipboard": "^2.0.11",
"eventemitter3": "^4.0.7",
"fast-mersenne-twister": "^1.0.3",
"i18next": "^22.4.9",
"localforage": "^1.10.0",
"lodash.clonedeepwith": "^4.5.0",
Expand Down
3 changes: 2 additions & 1 deletion src/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
octeractGainPerSecond
} from './Calculate'
import { quarkHandler } from './Quark'
import { Seed, seededRandom } from './RNG'
import { checkMaxRunes, redeemShards, unlockedRune } from './Runes'
import { useConsumable } from './Shop'
import { player } from './Synergism'
Expand Down Expand Up @@ -214,7 +215,7 @@ export const addTimers = (input: TimerInput, time = 0) => {
+ (3 / 4 - 2 / 3) * +(player.singularityChallenges.noAmbrosiaUpgrades.completions >= 20)

while (player.blueberryTime >= timeToAmbrosia) {
const RNG = Math.random()
const RNG = seededRandom(Seed.Ambrosia)
const ambrosiaMult = Math.floor(ambrosiaLuck / 100)
const luckMult = RNG < ambrosiaLuck / 100 - Math.floor(ambrosiaLuck / 100) ? 1 : 0
const bonusAmbrosia = (player.singularityChallenges.noAmbrosiaUpgrades.rewards.bonusAmbrosia) ? 1 : 0
Expand Down
31 changes: 10 additions & 21 deletions src/ImportExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Synergism } from './Events'
import { addTimers } from './Helper'
import { PCoinUpgradeEffects } from './PseudoCoinUpgrades'
import { getQuarkBonus, quarkHandler } from './Quark'
import { Seed, seededBetween, seededRandom } from './RNG'
import { playerJsonSchema } from './saves/PlayerJsonSchema'
import { shopData } from './Shop'
import { singularityData } from './singularity'
Expand Down Expand Up @@ -362,8 +363,6 @@ export const importSynergism = async (input: string | null, reset = false) => {
localStorage.setItem('Synergysave2', saveString)
await localforage.setItem<Blob>('Synergysave2', item)

localStorage.setItem('saveScumIsCheating', Date.now().toString())

await reloadShit(reset)
saveCheck.canSave = true
return
Expand Down Expand Up @@ -502,7 +501,7 @@ export const promocodes = async (input: string | null, amount?: number) => {
el.textContent = i18next.t('importexport.promocodes.antismith')
} else if (input === 'Khafra' && !player.codes.get(26)) {
player.codes.set(26, true)
const quarks = Math.floor(Math.random() * (400 - 100 + 1) + 100)
const quarks = Math.floor(seededRandom(Seed.PromoCodes) * (400 - 100 + 1) + 100)
player.worlds.add(quarks)
el.textContent = i18next.t('importexport.promocodes.khafra', {
x: player.worlds.applyBonus(quarks)
Expand Down Expand Up @@ -602,7 +601,7 @@ export const promocodes = async (input: string | null, amount?: number) => {
// The same upgrade can be drawn several times, so we save the sum of the levels gained, to display them only once at the end
const freeLevels: Record<string, number> = {}
for (let i = 0; i < rolls; i++) {
const num = 1000 * Math.random()
const num = 1000 * seededRandom(Seed.PromoCodes)
for (const key of keys) {
if (upgradeDistribution[key].pdf(num)) {
player.singularityUpgrades[key].freeLevels += upgradeDistribution[key].value
Expand Down Expand Up @@ -859,25 +858,16 @@ export const promocodes = async (input: string | null, amount?: number) => {

player.worlds.sub(quarks < amount ? amount - quarks : amount)
} else if (input === 'gamble') {
if (
typeof player.skillCode === 'number'
|| typeof localStorage.getItem('saveScumIsCheating') === 'string'
) {
if (
(Date.now() - player.skillCode!) / 1000 < 3600
|| (Date.now() - Number(localStorage.getItem('saveScumIsCheating')))
/ 1000
< 3600
) {
if (typeof player.skillCode === 'number') {
if ((Date.now() - player.skillCode!) / 1000 < 3600) {
return (el.textContent = i18next.t(
'importexport.promocodes.gamble.wait'
))
}
}

const confirmed = await Confirm(
i18next.t('importexport.promocodes.gamble.confirm')
)
const confirmed = await Confirm(i18next.t('importexport.promocodes.gamble.prompt'))

if (!confirmed) {
return (el.textContent = i18next.t(
'importexport.promocodes.gamble.cancelled'
Expand All @@ -899,8 +889,7 @@ export const promocodes = async (input: string | null, amount?: number) => {
))
}

localStorage.setItem('saveScumIsCheating', Date.now().toString())
const dice = (window.crypto.getRandomValues(new Uint8Array(1))[0] % 6) + 1 // [1, 6]
const dice = seededBetween(Seed.PromoCodes, 1, 6) // [1, 6]

if (dice === 1) {
const won = bet * 0.25 // lmao
Expand All @@ -924,7 +913,7 @@ export const promocodes = async (input: string | null, amount?: number) => {

const rewardMult = timeCodeRewardMultiplier()

const random = Math.random() * 15000 // random time within 15 seconds
const random = seededRandom(Seed.PromoCodes) * 15000 // random time within 15 seconds
const start = Date.now()
const playerConfirmed = await Confirm(
i18next.t('importexport.promocodes.time.confirm', {
Expand Down Expand Up @@ -1112,7 +1101,7 @@ export const addCodeBonuses = () => {

const sampledMult = Math.max(
0.4 + 0.02 * player.shopUpgrades.calculator3,
2 / 5 + (window.crypto.getRandomValues(new Uint16Array(2))[0] % 128) / 640
2 / 5 + seededBetween(Seed.PromoCodes, 0, 127) / 640
) // [0.4, 0.6], slightly biased in favor of 0.4. =)
const minMult = 0.4 + 0.02 * player.shopUpgrades.calculator3
const maxMult = 0.6
Expand Down
19 changes: 19 additions & 0 deletions src/RNG.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MersenneTwister } from 'fast-mersenne-twister'
import { player } from './Synergism'

export const seededRandom = (index: SeedValues) => MersenneTwister(player.seed[index]++).random()

/**
* Generates a random number (inclusive) between {@param min} and {@param max}.
* @param min min
* @param max max
*/
export const seededBetween = (index: SeedValues, min: number, max: number) =>
Math.floor(seededRandom(index) * (max - min + 1) + min)

export const Seed = {
PromoCodes: 0,
Ambrosia: 1
} as const

export type SeedValues = typeof Seed[keyof typeof Seed]
4 changes: 3 additions & 1 deletion src/Synergism.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1541,7 +1541,9 @@ export const player: Player = {
blueberryInventory: new BlueberryInventoryCache()
},

lastExportedSave: 0
lastExportedSave: 0,

seed: Array.from({ length: 2 }, () => Date.now())
}

export const blankSave = Object.assign({}, player, {
Expand Down
6 changes: 5 additions & 1 deletion src/saves/PlayerSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -761,5 +761,9 @@ export const playerSchema = z.object({
return blankSave.caches
}),

lastExportedSave: z.number().default(() => blankSave.lastExportedSave)
lastExportedSave: z.number().default(() => blankSave.lastExportedSave),

seed: z.number().array().default(() => blankSave.seed)
.transform((value) => arrayExtend(value, 'seed'))
.refine((value) => value.every((seed) => seed > Date.parse('2020-01-01T00:00:00Z') && seed < Date.now() + 1000))
})
24 changes: 24 additions & 0 deletions src/types/FastMersenneTwister.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
declare module 'fast-mersenne-twister' {
interface api {
genrand_int32: () => number
// [0,0x7fffffff]
genrand_int31: () => number
// [0,1]
genrand_real1: () => number
// [0,1)
genrand_real2: () => number
// (0,1)
genrand_real3: () => number
// [0,1), 53-bit resolution
genrand_res53: () => number

randomNumber: () => number
random31Bit: () => number
randomInclusive: () => number
random: () => number // returns values just like Math.random
randomExclusive: () => number
random53Bit: () => number
}

export function MersenneTwister (seed?: number): api
}
2 changes: 2 additions & 0 deletions src/types/Synergism.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,8 @@ export interface Player {
* When the player last exported the save.
*/
lastExportedSave: number

seed: number[]
}

export interface GlobalVariables {
Expand Down

0 comments on commit 862b876

Please sign in to comment.