@allemandi/gacha-engine
Version:
Practical, type-safe toolkit for simulating and understanding gacha rates and rate-ups.
1 lines • 17.6 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/gacha-engine.ts"],"sourcesContent":["import {\n RarityInput,\n GachaEngineConfig,\n WeightedGachaEngineConfig,\n FlatRateGachaEngineConfig,\n} from './types';\n\nexport class GachaEngine {\n private static readonly SCALE = 1_000_000;\n private static readonly MAX_SAFE_SCALE = Math.floor(Number.MAX_SAFE_INTEGER / GachaEngine.SCALE);\n\n private mode: 'weighted' | 'flatRate';\n private pools: RarityInput[] = [];\n private rarityRatesScaled: Record<string, number> = {};\n private flatRateMap: Map<string, number> = new Map();\n private dropRateCacheScaled = new Map<string, number>();\n private flatRateRateUpItems: string[] = [];\n\n constructor(config: GachaEngineConfig) {\n this.mode = config.mode;\n\n if (config.mode === 'weighted') {\n const weightedConfig = config as WeightedGachaEngineConfig;\n this.pools = weightedConfig.pools;\n this.rarityRatesScaled = this.scaleRarityRates(weightedConfig.rarityRates);\n this.validateConfig(weightedConfig.rarityRates);\n } else if (config.mode === 'flatRate') {\n const flatConfig = config as FlatRateGachaEngineConfig;\n this.pools = flatConfig.pools; // Keep pools for reference\n\n for (const pool of flatConfig.pools) {\n for (const item of pool.items) {\n if (item.weight < 0) {\n throw new Error(`FlatRate item \"${item.name}\" must have non-negative weight`);\n }\n this.flatRateMap.set(item.name, item.weight); // direct probability\n if (item.rateUp) {\n this.flatRateRateUpItems.push(item.name);\n }\n }\n }\n const total = Array.from(this.flatRateMap.values()).reduce((sum, v) => sum + v, 0);\n if (Math.abs(total - 1.0) > 1e-6) {\n throw new Error(`FlatRate item rates must sum to 1.0, but got ${total}`);\n }\n } else {\n throw new Error(`Unknown gacha mode: ${this.mode}`);\n }\n }\n\n private scaleRarityRates(rarityRates: Record<string, number>): Record<string, number> {\n const scaled: Record<string, number> = {};\n for (const [rarity, rate] of Object.entries(rarityRates)) {\n if (rate < 0 || rate > 1) {\n throw new Error(`Rarity rate for \"${rarity}\" must be between 0 and 1, got ${rate}`);\n }\n scaled[rarity] = this.toScaled(rate);\n }\n return scaled;\n }\n\n private toScaled(probability: number): number {\n if (probability > GachaEngine.MAX_SAFE_SCALE / GachaEngine.SCALE) {\n throw new Error(`Probability ${probability} too large for safe integer arithmetic`);\n }\n return Math.round(probability * GachaEngine.SCALE);\n }\n\n private fromScaled(scaledInt: number): number {\n return scaledInt / GachaEngine.SCALE;\n }\n\n private validateConfig(originalRates: Record<string, number>): void {\n const configuredRarities = new Set(Object.keys(this.rarityRatesScaled));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const missing = Array.from(usedRarities).filter(r => !configuredRarities.has(r));\n\n if (missing.length > 0) {\n throw new Error(`Missing rarity rates for: ${missing.join(', ')}`);\n }\n\n const totalRate = Object.values(originalRates).reduce((sum, rate) => sum + rate, 0);\n if (Math.abs(totalRate - 1.0) > 1e-10) {\n throw new Error(`Rarity rates must sum to 1.0, got ${totalRate}`);\n }\n\n for (const pool of this.pools) {\n if (pool.items.length === 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has no items`);\n }\n\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n if (totalWeight <= 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has zero total weight`);\n }\n\n for (const item of pool.items) {\n if (item.weight < 0) {\n throw new Error(`Item \"${item.name}\" weight must be non-negative, got ${item.weight}`);\n }\n }\n\n if (!pool.items.some(i => i.weight > 0)) {\n throw new Error(`Rarity \"${pool.rarity}\" must have at least one item with positive weight`);\n }\n }\n }\n\n getItemDropRate(name: string): number {\n if (this.mode === 'flatRate') {\n return this.flatRateMap.get(name) || 0;\n }\n\n if (this.dropRateCacheScaled.has(name)) {\n return this.fromScaled(this.dropRateCacheScaled.get(name)!);\n }\n\n for (const pool of this.pools) {\n const item = pool.items.find(i => i.name === name);\n if (item) {\n if (item.weight === 0) {\n this.dropRateCacheScaled.set(name, 0);\n return 0;\n }\n\n const totalPoolWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const baseRarityRateScaled = this.rarityRatesScaled[pool.rarity];\n const itemWeightScaled = this.toScaled(item.weight);\n const totalWeightScaled = this.toScaled(totalPoolWeight);\n const numeratorScaled = Math.round((itemWeightScaled * baseRarityRateScaled) / GachaEngine.SCALE);\n const rateScaled = Math.round((numeratorScaled * GachaEngine.SCALE) / totalWeightScaled);\n\n this.dropRateCacheScaled.set(name, rateScaled);\n return this.fromScaled(rateScaled);\n }\n }\n\n throw new Error(`Item \"${name}\" not found`);\n }\n\n getCumulativeProbabilityForItem(name: string, rolls: number): number {\n const rate = this.getItemDropRate(name);\n if (rate === 0) return 0;\n if (rate >= 1) return 1;\n\n const cumulativeFailProbability = Math.pow(1 - rate, rolls);\n return 1 - cumulativeFailProbability;\n }\n\n getRollsForTargetProbability(name: string, targetProbability: number): number {\n if (targetProbability <= 0) return 0;\n if (targetProbability >= 1) return 1;\n\n const rate = this.getItemDropRate(name);\n if (rate <= 0) return Infinity;\n return Math.ceil(Math.log(1 - targetProbability) / Math.log(1 - rate));\n }\n\n getRateUpItems(): string[] {\n if (this.mode === 'weighted') {\n return this.pools.flatMap(p => p.items.filter(i => i.rateUp).map(i => i.name));\n } else {\n return this.flatRateRateUpItems;\n }\n }\n\n getAllItemDropRates(): { name: string; dropRate: number; rarity: string }[] {\n if (this.mode === 'flatRate') {\n return Array.from(this.flatRateMap.entries()).map(([name, dropRate]) => ({\n name,\n dropRate,\n rarity: 'flatRate',\n }));\n }\n\n return this.pools.flatMap(p =>\n p.items.map(i => ({\n name: i.name,\n dropRate: this.getItemDropRate(i.name),\n rarity: p.rarity,\n }))\n );\n }\n\n roll(count: number = 1): string[] {\n const results: string[] = [];\n for (let i = 0; i < count; i++) {\n if (this.mode === 'flatRate') {\n const rand = Math.random();\n let cumulative = 0;\n for (const [name, rate] of this.flatRateMap.entries()) {\n cumulative += rate;\n if (rand < cumulative) {\n results.push(name);\n break;\n }\n }\n } else {\n const rarity = this.selectRarity();\n const pool = this.pools.find(p => p.rarity === rarity)!;\n const item = this.selectItemFromPool(pool);\n results.push(item.name);\n }\n }\n return results;\n }\n\n private selectRarity(): string {\n const rand = Math.floor(Math.random() * GachaEngine.SCALE);\n let cumulative = 0;\n\n for (const [rarity, scaledRate] of Object.entries(this.rarityRatesScaled)) {\n cumulative += scaledRate;\n if (rand < cumulative) return rarity;\n }\n\n return Object.keys(this.rarityRatesScaled)[0];\n }\n\n private selectItemFromPool(pool: RarityInput): { name: string; weight: number } {\n const items = pool.items.filter(i => i.weight > 0);\n const scaledItems = items.map(i => ({\n ...i,\n scaledWeight: this.toScaled(i.weight),\n }));\n\n const totalScaledWeight = scaledItems.reduce((sum, i) => sum + i.scaledWeight, 0);\n const rand = Math.floor(Math.random() * totalScaledWeight);\n let cumulative = 0;\n\n for (const item of scaledItems) {\n cumulative += item.scaledWeight;\n if (rand < cumulative) {\n return { name: item.name, weight: item.weight };\n }\n }\n\n return items[0]; // Fallback\n }\n\n getDebugInfo(): {\n scale: number;\n rarityRatesScaled: Record<string, number>;\n rarityRatesFloat: Record<string, number>;\n } {\n const rarityRatesFloat: Record<string, number> = {};\n for (const [rarity, scaledRate] of Object.entries(this.rarityRatesScaled)) {\n rarityRatesFloat[rarity] = this.fromScaled(scaledRate);\n }\n\n return {\n scale: GachaEngine.SCALE,\n rarityRatesScaled: { ...this.rarityRatesScaled },\n rarityRatesFloat,\n };\n }\n}\n"],"names":[],"mappings":"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"}