Files
Stat-Dashboard/mockups/sample_scenarios.py
T

57 lines
4.8 KiB
Python

"""Three deliberately different fictional games and latent player personalities."""
import math
PERSONAS={
'tourist':dict(minutes=2.2,fast=0,tail=0,decay=1,payer=0,budget=0,repeat=0,sink=.06,xp=.65),
'social':dict(minutes=18,fast=.36,tail=.16,decay=65,payer=.10,budget=500,repeat=.12,sink=.08,xp=.45),
'collector':dict(minutes=10,fast=.38,tail=.10,decay=40,payer=.32,budget=2400,repeat=.18,sink=.22,xp=.9),
'competitor':dict(minutes=9,fast=.42,tail=.12,decay=35,payer=.12,budget=1500,repeat=.38,sink=.32,xp=1.15),
'grinder':dict(minutes=19,fast=.43,tail=.13,decay=45,payer=0,budget=0,repeat=.28,sink=.035,xp=1.45),
'budget':dict(minutes=7,fast=.24,tail=.025,decay=18,payer=.45,budget=220,repeat=.10,sink=.17,xp=.8),
'impulse':dict(minutes=3.5,fast=.05,tail=.003,decay=10,payer=.32,budget=300,repeat=.02,sink=.15,xp=.7),
'whale':dict(minutes=23,fast=.62,tail=.20,decay=85,payer=1,budget=25000,repeat=.55,sink=.25,xp=1.0),
}
SCENARIOS={
'willow-v1':dict(name="Willow's Park",genre='Social hangout and collecting',scenario='stable',players=8000,
weights=[.43,.18,.15,.015,.10,.07,.05,.005],minutes=.9,retention=.9,automatic=.08,
labels={'social':'Social regular','collector':'Set collector','competitor':'Challenge chaser','grinder':'F2P collector','budget':'Occasional gifter','impulse':'Impulse decorator','whale':'Cosmetic whale','tourist':'One-visit explorer'},
products=[('Friend gift',29),('Decoration pack',79),('Festival cosmetic',199),('Collector crate',499)],
passes=['VIP lounge','Extra display slots','Garden expansion','Festival access'],
places=['Town square','Community garden','Collection trail'],
fields=[('friendsMet','Friends met'),('giftsSent','Gifts sent'),('collectionCount','Collection discoveries'),('cosmeticsOwned','Cosmetics owned'),('socialMinutes','Social minutes')],
activities=[('hangout','Social hangout','hangout_joined','hangout_left',['area_joined','interaction_started','interaction_completed']),
('collection','Collection trail','collection_started','collection_ended',['item_found','set_progress_saved'])]),
'orbit-v1':dict(name='Orbit Racers',genre='Round-based competitive racing',scenario='declining',players=9000,
weights=[.48,.025,.075,.20,.12,.055,.037,.008],minutes=.8,retention=.9,automatic=.20,
labels={'social':'Social racer','collector':'Garage collector','competitor':'Ranked competitor','grinder':'Time-trial grinder','budget':'Budget tuner','impulse':'Impulse upgrader','whale':'Garage whale','tourist':'First-race dropout'},
products=[('Race retry',19),('Paint bundle',99),('Upgrade kit',249),('Credit vault',799)],
passes=['VIP garage','Extra car slots','Track pack','Custom paint studio'],
places=['Neon circuit','Mountain sprint','Ranked lobby'],
fields=[('raceStarts','Races entered'),('roundWins','Race wins'),('bestLapSeconds','Best lap (seconds)'),('rating','Ranked rating'),('garageCars','Garage cars'),('upgradeLevel','Upgrade level')],
activities=[('race','Ranked race','race_entered','race_left',['starting_grid_ready','checkpoint_reached','finish_line_crossed']),
('garage','Garage tuning','garage_opened','garage_closed',['car_selected','upgrade_applied'])]),
'dungeon-v1':dict(name='Dungeon Workshop',genre='Co-op dungeon RPG and crafting',scenario='discovery_surge',players=16000,
weights=[.48,.065,.12,.025,.18,.075,.05,.005],minutes=1.05,retention=1.05,automatic=.11,
labels={'social':'Co-op regular','collector':'Loot collector','competitor':'Dungeon speedrunner','grinder':'Progression grinder','budget':'Starter-pack buyer','impulse':'Impulse reviver','whale':'Power spender','tourist':'Curious newcomer'},
products=[('Adventurer starter',49),('Revive token',29),('Crafting supplies',149),('Royal gem chest',999)],
passes=['VIP guild','Extra inventory','Crafting queue','Companion slot'],
places=['Guild village','Crystal depths','Ancient forge'],
fields=[('quests','Quests completed'),('crafts','Items crafted'),('dungeonClears','Dungeon clears'),('bossKills','Boss kills'),('materials','Materials held'),('powerScore','Power score')],
activities=[('dungeon','Co-op dungeon','dungeon_entered','dungeon_left',['first_room_cleared','boss_reached','boss_defeated']),
('crafting','Crafting attempt','crafting_opened','crafting_closed',['recipe_selected','materials_committed','item_crafted'])]),
}
def acquisition_weight(config,day):
if config['scenario']=='stable': return 1+.045*math.sin(day/8)
if config['scenario']=='declining': return 1 if day<52 else math.exp(-(day-52)/16)
if day<80:return .75+.1*math.sin(day/9)
return {80:1,81:1.2,82:1.4,83:1.8,84:2.5,85:6,86:12,87:22,88:36,89:44}[day]
def retention_factor(config,day):
if config['scenario']=='declining': return .22+.78*math.exp(-max(0,day-57)/14)
if config['scenario']=='discovery_surge' and day>=80:return 1.12
return 1