JavaScript must be enabled to play.
Browser lacks capabilities required to play.
Upgrade or switch to another browser.
Loading…
/* ═══════════════════════════════════════════════════ THORNFIELD UNIVERSITY: STUDENT X-CHANGE PROGRAMME MASTER VARIABLE INITIALISATION All game state lives here. ═══════════════════════════════════════════════════ */ /* ─── Player Character ─── */ <<set $pc = { /* Identity */ maleFirstName: "", femaleFirstName: "", firstName: "", lastName: "", age: 18, gender: "male", orientation: "heterosexual", orientationDrift: 0, reason: "", /* Male Appearance (pre-transform) */ maleHeight: "average", /* Female Appearance (post-transform, set during CC) */ race: "white", skinTone: "light", bodyType: "slender", weight: "average", height: "average", breastSize: "C", buttSize: "average", hairColour: "blonde", hairLength: "long", hairStyle: "straight", eyeColour: "hazel", /* Grooming */ pubicHair: 0, legHair: 0, lastShaved: 0, /* Core Stats (0-100) */ energy: 100, health: 100, mood: 70, stress: 10, arousal: 0, confidence: 50, willpower: 60, intelligence: 50, femininity: 10, /* Beauty System (composite) */ beautyBase: 40, beautyGrooming: 0, beautyMakeup: 0, beautyClothing: 0, beautySkincare: 0, beautyFitness: 0, beautyTotal: 40, lastGymDay: 0, /* Makeup */ makeupStyle: "none", makeupApplied: false, /* Hair & Grooming */ hairStyle: "straight", pubicStyle: "natural", /* Modifications */ tattoos: [], piercings: [], /* Sex Stats */ sexStats: { oral: 1, vaginal: 1, anal: 0, handjob: 1, flexibility: 1, stamina: 1, dirtyTalk: 0, deepThroat: 0, squirting: 0 } }>> /* ─── Scholarship (CCUMDUP) ─── */ <<set $scholarship = { active: true, weeklyQuota: 5, baseWeeklyQuota: 5, finalsQuota: 10, currentWeekServiced: 0, currentWeekCredits: 0, totalServiced: 0, totalCredits: 0, rating: 5.0, totalRatings: 0, ratingSum: 0, onProbation: false, probationWeeks: 0, isFinalsWeek: false, selfiesPending: 0, housingTier: "standard", weekLog: [], allTimeLogs: [], weeklyHistory: [], activeRequest: null, inService: false, /* Fairness */ totalServices: 0, mercyActive: true, rerollAvailable: true, rerollDay: 0, requestsToday: 0, lastServiceDay: 0 }>> /* ─── University Settings ─── */ <<set $university = { name: "Thornfield University", demographics: { white: 40, black: 25, asian: 15, latina: 15, other: 5 }, maleRatio: 60, femaleRatio: 40, /* Racial mix can be set separately for men and women. While splitDemographics is false both read the shared table above. */ splitDemographics: false, demographicsMale: { white: 40, black: 25, asian: 15, latina: 15, other: 5 }, demographicsFemale: { white: 40, black: 25, asian: 15, latina: 15, other: 5 }, difficulty: "normal", quotaMultiplier: 1.0, requestFrequency: 2.5, academicDifficulty: 1.0 }>> /* ─── World / Calendar ─── */ <<set $world = { time: 480, day: 1, dayOfWeek: 1, week: 1, semester: 1, year: 1, month: 9, dayOfMonth: 1, yearActual: 2025, season: "autumn", isSpringBreak: false, isSummerBreak: false, isFinalsWeek: false, /* Post-graduation continuation: the programme ends, the city does not */ postGrad: false, postGradDay: 0, rentDue: 0, rentOwed: 0 }>> /* ─── Transformation ─── */ <<set $transformation = { pillType: "petite", pointsTotal: 0, pointsSpent: 0, pointsRemaining: 0, addons: { birthControl: false, stdProtection: false, rest: false, noPeriod: false, intelligenceBoost: false, flexibility: false, noHair: false, gagReflex: false, metabolismControl: false, stretchy: false, wet: false, libidoIncrease: false }, sideEffects: { memoryLoss: 0, randomOrgasm: 0, sexualFluidAddiction: 0, bimbofication: 0, squirting: 0, orgasmDenial: 0, lactation: 0, increasedSensitivity: 0, submissive: 0, strongOrgasms: 0, fertility: 0, internalHeat: 0, exhibitionist: 0, pheromones: 0, oralLover: 0, analLover: 0, eroticDreams: 0, masturbationDenial: 0 } }>> /* ─── Skills ─── */ <<set $skills = { oral: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "💋", name: "Oral", category: "sexual" }, vaginal: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "🔥", name: "Vaginal", category: "sexual" }, anal: { level: 0, xp: 0, xpNext: 100, lastUsed: 0, icon: "🍑", name: "Anal", category: "sexual" }, handjob: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "✋", name: "Handjob", category: "sexual" }, stamina: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "💪", name: "Stamina", category: "sexual" }, flexibility: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "🤸", name: "Flexibility", category: "sexual" }, dirtyTalk: { level: 0, xp: 0, xpNext: 100, lastUsed: 0, icon: "🗣️", name: "Dirty Talk", category: "sexual" }, deepThroat: { level: 0, xp: 0, xpNext: 100, lastUsed: 0, icon: "😮", name: "Deep Throat", category: "sexual" }, intelligence: { level: 3, xp: 0, xpNext: 100, lastUsed: 0, icon: "🧠", name: "Intelligence", category: "academic" }, studying: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "📚", name: "Studying", category: "academic" }, charm: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "✨", name: "Charm", category: "social" }, persuasion: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "🤝", name: "Persuasion", category: "social" }, composure: { level: 1, xp: 0, xpNext: 100, lastUsed: 0, icon: "🧘", name: "Composure", category: "social" }, camSkill: { level: 0, xp: 0, xpNext: 100, lastUsed: 0, icon: "📷", name: "Cam Work", category: "performance" }, dance: { level: 0, xp: 0, xpNext: 100, lastUsed: 0, icon: "💃", name: "Dance", category: "performance" }, cheerleading: { level: 0, xp: 0, xpNext: 100, lastUsed: 0, icon: "📣", name: "Cheerleading", category: "performance" } }>> /* ─── NPCs ─── */ <<set $npcs = []>> <<set $npcs_named = {}>> <<set $npcIdCounter = 1000>> /* ─── Finance ─── */ <<set $finance = { money: 0, debt: 0, transactions: [], totalEarned: 0, totalSpent: 0 }>> /* ─── Jobs ─── */ <<set $jobs = { current: [], onShift: false, shiftJob: "", barista: { active: false, shifts: 0, tips: 0, performance: 50, tier: 0 }, bartender: { active: false, shifts: 0, tips: 0, performance: 50, tier: 0 }, tutor: { active: false, sessions: 0, students: 0, performance: 50, tier: 0 }, cheerleader: { active: false, practicesMissed: 0, gamesAttended: 0, hasOutfit: false, teamRank: 0, practiceDay: 0 }, camGirl: { active: false, shows: 0, viewers: 50, tokens: 0, rating: 0, hasRingLight: false, tier: 0 }, fansOnly: { active: false, subs: 0, posts: 0, revenue: 0, lastPostDay: 0, contentTypes: [], rating: 0, ratingCount: 0, ratingSum: 0, lastRating: 0, requests: [], requestsFilled: 0, requestsDeclined: 0, lastRequestDay: 0 }, stripper: { active: false, shifts: 0, tips: 0, regulars: 0, canBackRoom: false, tier: 0 }, hooker: { active: false, clients: 0, earnings: 0, arrested: 0, phoneUnlocked: false, tier: 0 }, escort: { active: false, clients: 0, earnings: 0, agencyRep: 0, tier: 0 }, brothel: { active: false, shifts: 0, earnings: 0, houseRep: 0, tier: 0 }, dealer: { active: false, stock: { weed: 0, ecstasy: 0, cocaine: 0 }, earnings: 0, heatLevel: 0, supplierUnlocked: false } }>> /* ─── Pregnancy ─── */ <<set $pregnancy = { isPregnant: false, weeksPregnant: 0, discovered: false, confirmed: false, confirmedDay: 0, riskFlag: false, riskDay: 0, periodDue: 0, terminated: false, fatherName: "", fatherId: "", fatherRace: "", babyCount: 1, babyGenders: [], roommateNoticed: false, profNoticed: false, decisions: [], outcome: "", children: [], totalPregnancies: 0, /* Where you plan to deliver: chosen from week 30 */ birthPlan: "", /* Body changes carried by the pregnancy itself, tracked separately from the weight system so they can be kept or lost afterwards */ bodyChanges: { breastStart: "", buttStart: "", breastSteps: 0, buttSteps: 0, resolved: false, kept: false } }>> /* ─── Children ─── */ <<set $children = { list: [], dayCare: false, dayCareOwed: 0, lastCareDay: -1, neglect: 0, welfareVisits: 0, removed: 0, bond: 0 }>> /* ─── Journal ─── */ <<set $journal = { entries: [], autoGenerate: true, lastEntryDay: 0 }>> /* ─── Phone ─── */ <<set $phone = { messages: [], contacts: [], nextMessageId: 1, campusHub: { activeRequests: [], completedToday: [], selfieQueue: [], weeklyStats: {}, notifications: [] }, chirpr: { followers: 0, tweets: [], canTweet: true, lastTweetDay: 0, lastTweetPeriod: "", lastReplyDay: 0, announcedPregnancy: false, trending: [] }, fansOnly: { active: false, subscribers: 0, posts: 0, revenue: 0, price: 9.99 }, instaGlam: { followers: 0, posts: 0, engagement: 0 }, theme: "default", notifications: 0 }>> /* ─── Reputation ─── */ <<set $reputation = { slut: 0, partyGirl: 0, goodStudent: 50, camGirl: 0, sweetheart: 30, troublemaker: 0, popular: 20 }>> /* ─── Hygiene ─── */ <<set $hygiene = { cleanliness: 100, lastShower: 0, lastShowerTime: 0 }>> /* ─── Roommate ─── */ <<set $roommate = { name: "", gender: "female", personality: "", race: "", appearance: {}, opinion: 50, trust: 30, awareness: 0, awarenessMilestone: 0, walkedIn: 0, sharedClothes: false, isConfidant: false, yearsWith: 1, movedOut: false, events: [] }>> /* ─── Relationship ─── A partner arc. Stages: none | seeing | dating | exclusive. tension rises when the quota and the relationship collide. */ <<set $relationship = { partnerId: null, partnerName: "", partnerGender: "", stage: "none", tension: 0, knowsAboutProgramme: false, dates: 0, startedDay: 0, endedReason: "" }>> /* ─── UI State ─── */ <<set $ui = { toastQueue: [], phoneOpen: false, phoneApp: "home", leftPanelTab: "nav", activePopup: null, popupData: {}, lastToastId: 0, returnPassage: "" }>> /* ─── Roll System State ─── */ <<set $lastRoll = { skill: "", skillLevel: 0, difficulty: 0, baseChance: 0, modifiers: [], finalChance: 0, rolled: 0, outcome: "", xpGained: 0, leveledUp: false, newLevel: 0 }>> /* ─── Flags ─── */ <<set $flags = { introComplete: false, transformationComplete: false, firstService: false, firstOrgasm: false, firstAnal: false, firstGroup: false, firstPregnancy: false, firstDrunk: false, firstBlackout: false, firstArrest: false, firstCamShow: false, firstFansOnlyPost: false, ccComplete: false, orientationComplete: false, metRoommate: false, metMentor: false }>> /* ─── Campus State ─── */ <<set $campus = { encountersSeen: 0, lastEncounterDay: 0 }>> /* ─── Greek Life ─── */ <<set $greekLife = { pledging: false, member: false, sorority: "", pledgeStage: 0, hazingComplete: false, sisterhood: 0, rank: "none", eventsAttended: 0, fratPartiesAttended: 0, lastPartyDay: 0, rushAvailable: false, rushDeclined: false }>> /* ─── Substances ─── */ <<set $substances = { drunkLevel: 0, drinksToday: 0, lastDrinkTime: 0, hangover: false, hangoverSeverity: 0, alcoholTolerance: 0, weed: { high: false, doses: 0, tolerance: 0 }, ecstasy: { high: false, rolling: false, comedown: false, doses: 0, tolerance: 0 }, cocaine: { high: false, doses: 0, tolerance: 0, addiction: 0 }, /* Dealer relationship: how often you have bought, and how often paid in kind */ dealerBuys: 0, dealerTrades: 0, dealerOffered: false, combosSeen: [], goggleLog: [], maskedDrunk: 0 }>> /* ─── Cheats (phone app, off by default) ─── */ <<set $cheats = { enabled: false, used: false, uses: 0 }>> /* ─── Notifications (phone drawer) ─── */ <<set $notifications = { items: [], unread: 0 }>> /* ─── Social ─── */ <<set $social = { clubsMember: [], eventsAttended: 0, lastEventDay: 0, /* Street propositions: high reputation has consequences you did not ask for */ propositions: 0, propositionsRefused: 0, propositionsAccepted: 0, lastPropositionDay: -1 }>> /* ─── Academic System ─── */ <<set $academic = { classes: [], professors: [], currentSemester: 1, gpa: 0, probationWarnings: 0, totalAttended: 0, totalSkipped: 0, classesChosen: false, researchBonus: 0, extraCredit: { stage: 0, lastOfferDay: 0 }, /* Prof. Drake: predation arc. stage: 0 not approached | 1 overture made | 2 argument heard 3+ arrangement depth (escalation bodies hang off this) -1 ended: she got out, or he gave up The investigation layer is available from stage 1 onward and gets HARDER the deeper the arrangement went. */ drakeCase: { stage: 0, profIndex: -1, classIndex: -1, lastOfferDay: -99, declined: false, retaliating: false, earnedGrade: null, evidence: [], confronted: false, reported: false, resolved: false } }>> /* ─── Gym Tracking ─── */ <<set $gym = { totalVisits: 0, workedOutToday: false }>> /* ─── Health Tracking ─── */ <<set $health = { hasSTD: false, stdType: null, stdDay: 0, stdSymptomatic: false, birthControlActive: false, birthControlDays: 0, adjustedThisSemester: false, cycleDay: 14, lastWeekGymVisits: 0 }>> /* ─── Inventory (Starlet-style) ─── */ <<set $inventory = { wardrobe: [ {id: "clinic_tshirt", name: "Clinic T-Shirt", type: "top", style: "vanilla", quality: "basic", sexy: 0, beauty: 0, price: 0, description: "A plain white t-shirt from the CCUMDUP clinic. Smells faintly of antiseptic.", icon: "top"}, {id: "clinic_sweats", name: "Clinic Sweatpants", type: "bottom", style: "vanilla", quality: "basic", sexy: 0, beauty: 0, price: 0, description: "Grey sweatpants. Comfortable but shapeless.", icon: "bottom"}, {id: "clinic_underwear", name: "Basic Cotton Underwear", type: "underwear", style: "vanilla", quality: "basic", sexy: 0, beauty: 0, price: 0, description: "Plain white cotton briefs. Functional.", icon: "underwear"}, {id: "clinic_bra", name: "Sports Bra", type: "bra", style: "vanilla", quality: "basic", sexy: 0, beauty: 0, price: 0, description: "A basic sports bra. Supportive but not flattering.", icon: "bra"}, {id: "clinic_sneakers", name: "White Sneakers", type: "shoes", style: "vanilla", quality: "basic", sexy: 0, beauty: 1, price: 0, description: "Clean white sneakers. At least they match everything.", icon: "shoes"} ], currentOutfit: { top: "clinic_tshirt", bottom: "clinic_sweats", dress: null, bra: "clinic_bra", underwear: "clinic_underwear", shoes: "clinic_sneakers", accessories: [] }, styleIdentity: "vanilla", /* Consumables */ razors: 3, skincareUses: 0, makeupUses: { natural: 3, glam: 0, goth: 0, bimbo: 0, slutty: 0 }, /* Equipment */ hasLaptop: false, hasWebcam: false, hasCamera: false, hasRingLight: false, hasBackdrop: false, sexToys: [], wornPlug: null, toysOut: [], plugWornSince: 0, plugSpotted: 0, cigarettes: 0, hasVape: false, hasPurse: false, hasTote: false, /* Contraception */ condoms: 0, pregnancyTests: 0, onPill: false, hasIUD: false, /* Drugs */ drugs: {} }>> /* ─── Corruption (hidden score 0-100) ─── */ <<set $corruption = { score: 0, tier: "innocent", lastGain: "" }>> /* ─── The Velvet Room (BDSM Club) ─── */ <<set $velvetRoom = { discovered: false, visited: false, membership: "none", sessionsAttended: 0, subTraining: 0, domTraining: 0, lastVisitDay: 0, petPlayUnlocked: false, bondageUnlocked: false, impactUnlocked: false }>> /* ─── Blackmail System ─── */ <<set $blackmail = { active: false, blackmailer: "", evidenceType: "", stage: 0, totalPaid: 0, totalComplied: 0, investigating: false, cluesFound: 0, resolved: false, resolutionType: "" }>> /* ─── Hypnosis: Dr. Crane ─── */ <<set $hypnosis = { discovered: false, sessionsAttended: 0, lastSessionDay: 0, redFlags: 0, evidence: [], suspicious: false, confronted: false, reported: false, resolved: false, lingering: false, triggersPlanted: [] }>> /* ─── Body Writing ─── */ <<set $bodyWriting = { active: false, texts: [], lastAppliedDay: 0, totalWritten: 0 }>> /* ─── Dreams ─── */ <<set $dreams = { lastDreamDay: 0, totalDreams: 0, lastDreamType: "", recurringTheme: "" }>> /* ─── Calendar Events ─── */ <<set $calendar = { dynamicEvents: [], notificationsSeen: [] }>> /* ─── Glory Holes ─── */ <<set $gloryHole = { libraryDiscovered: false, barDiscovered: false, timesUsed: 0, lastVisitDay: 0 }>> /* ─── Temp (ephemeral state for multi-passage flows) ─── */ <<set $temp = {}>>
<<goto "CharacterCreation_Intro">>
<<set $ui.ccMode = true>> <div class="cc-header"> <h1>Thornfield University</h1> <div class="tagline">Student X-Change Programme</div> </div> <div class="cc-section"> <p>You stare at the letter in your hands, reading it for the third time. The words haven't changed.</p> <p><em>Dear Student,</em></p> <p><em>We are pleased to inform you that you have been selected for the College Campus Unity & Morale Development Uplift Program (CCUMDUP). This prestigious scholarship provides FULL tuition coverage, priority housing, and a generous living stipend.</em></p> <p><em>In exchange, you will participate in specialized student support services, details of which are outlined in the enclosed agreement.</em></p> <p><em>To accept, please report to the Thornfield University Student Services Office no later than September 1st.</em></p> <p>Full tuition. Free housing. No more instant noodles eaten standing up over the sink. There's one catch, and it's printed in the same friendly typeface as everything else: the programme requires you to take X-Change Petite for the full duration of your enrolment.</p> <p>Three years as a woman. Three years of "specialized student support services," a phrase somebody in an office got paid to build.</p> <p>You look at the stack of overdue bills on your desk. The red ones are on top, because the red ones are always on top. Then you look back at the letter.</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "CC_Reason">><</link>> </div>
<div class="cc-section"> <div class="cc-section__title">📝 Why are you doing this?</div> <div class="cc-section__subtitle">Whatever you tell yourself in the car park is the version you have to live with.</div> <div class="choice-group"> <<link '<span class="choice-btn">💸 "I can\'t afford tuition any other way."<br><small>Poverty background. You need this badly enough to stop arguing with it.</small></span>' "CC_MaleName">> <<set $pc.reason = "poverty">> <</link>> <<link '<span class="choice-btn">🎲 "I lost a bet with my fraternity."<br><small>A dare. Your brothers are never letting this go.</small></span>' "CC_MaleName">> <<set $pc.reason = "bet">> <</link>> <<link '<span class="choice-btn">🔍 "I\'m genuinely curious about the experience."<br><small>Exploration. You have wondered. Quietly, for years.</small></span>' "CC_MaleName">> <<set $pc.reason = "curious">> <</link>> <<link '<span class="choice-btn">👨👩👦 "My parents signed me up without asking."<br><small>Forced. They needed the money and signed on your behalf.</small></span>' "CC_MaleName">> <<set $pc.reason = "forced">> <</link>> <<link '<span class="choice-btn">🏠 "I want the premium housing and perks."<br><small>Opportunist. You are here for the housing and the stipend.</small></span>' "CC_MaleName">> <<set $pc.reason = "opportunist">> <</link>> <<link '<span class="choice-btn">🌈 "I\'m already questioning my gender identity."<br><small>Identity. This reads to you as a door, not a price.</small></span>' "CC_MaleName">> <<set $pc.reason = "identity">> <</link>> </div> </div>
<div class="cc-section"> <div class="cc-section__title">👤 Your Identity (Male)</div> <div class="cc-section__subtitle">Enter your current name, the one on your student ID.</div> <div style="margin-bottom: var(--space-lg);"> <label style="display:block; color: var(--text-secondary); margin-bottom: var(--space-xs); font-size: var(--text-sm);">First Name</label> <<textbox "$pc.maleFirstName" "" autofocus>> </div> <div style="margin-bottom: var(--space-lg);"> <label style="display:block; color: var(--text-secondary); margin-bottom: var(--space-xs); font-size: var(--text-sm);">Last Name</label> <<textbox "$pc.lastName" "">> </div> </div> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "CC_FemaleName">><</link>> </div>
<div class="cc-section"> <div class="cc-section__title">👩 Your New Identity (Female)</div> <div class="cc-section__subtitle">Choose your female name. Your surname ($pc.lastName) stays the same.</div> <div style="margin-bottom: var(--space-lg);"> <label style="display:block; color: var(--text-secondary); margin-bottom: var(--space-xs); font-size: var(--text-sm);">Female First Name</label> <<textbox "$pc.femaleFirstName" "" autofocus>> </div> <p style="color: var(--text-tertiary); font-size: var(--text-sm);">This is what everyone will call you for the next three years.</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">Continue to Appearance →</span>' "CC_Appearance">> <<if !$pc.femaleFirstName || $pc.femaleFirstName.trim() === "">><<set $pc.femaleFirstName = "Alex">><</if>> <<set $pc.firstName = $pc.femaleFirstName>> <</link>> </div>
<<set $temp.ccPoints = 0>> /* Appearance costs/bonuses: set defaults */ <<set $temp.raceCost = 0>> <<set $temp.skinCost = 0>> <<set $temp.orientCost = 0>> <<set $temp.bodyCost = 0>> <<set $temp.weightCost = 0>> <<set $temp.heightCost = 0>> <<set $temp.breastCost = 0>> <<set $temp.assCost = 0>> <<set $temp.eyeCost = 0>> <<set $temp.hairColCost = 0>> <<set $temp.hairLenCost = 0>> <<set $temp.hairStyleCost = 0>> <div class="cc-points" id="cc-points-display"> <span>Available Points:</span> <span class="cc-points__value" id="cc-points-value">0</span> </div> <div class="cc-section"> <div class="cc-section__title">🎨 Female Appearance</div> <div class="cc-section__subtitle">Design your new body. Some choices cost points, others earn them. You'll earn points from side effects next.</div> </div> /* All grids rendered by JS */ <div class="cc-section"><div class="cc-section__title">Race / Ethnicity</div><div class="cc-grid" id="cc-race"></div></div> <div class="cc-section"><div class="cc-section__title">Sexual Orientation</div><div class="cc-grid" id="cc-orient"></div></div> <div class="cc-section"><div class="cc-section__title">Body Type</div><div class="cc-grid" id="cc-body"></div></div> <div class="cc-section"><div class="cc-section__title">Weight</div><div class="cc-grid" id="cc-weight"></div></div> <div class="cc-section"><div class="cc-section__title">Height</div><div class="cc-grid" id="cc-height"></div></div> <div class="cc-section"><div class="cc-section__title">Breasts</div><div class="cc-grid" id="cc-breasts"></div></div> <div class="cc-section"><div class="cc-section__title">Ass</div><div class="cc-grid" id="cc-ass"></div></div> <div class="cc-section"><div class="cc-section__title">Eyes</div><div class="cc-grid" id="cc-eyes"></div></div> <div class="cc-section"><div class="cc-section__title">Hair Colour</div><div class="cc-grid" id="cc-haircol"></div></div> <div class="cc-section"><div class="cc-section__title">Hair Length</div><div class="cc-grid" id="cc-hairlen"></div></div> <div class="cc-section"><div class="cc-section__title">Hair Style</div><div class="cc-grid" id="cc-hairstyle"></div></div> <div class="cc-section"><div class="cc-section__title">Skin Tone</div><div class="cc-grid" id="cc-skin"></div></div> <<run setTimeout(function(){ XCLC.CC.renderAllGrids(); }, 50)>> <div class="choice-group"> <<link '<span class="choice-btn">Continue to Side Effects →</span>' "CC_SideEffects">> /* Store appearance points total */ <<set $temp.ccPoints = $temp.raceCost + $temp.skinCost + $temp.orientCost + $temp.bodyCost + $temp.weightCost + $temp.heightCost + $temp.breastCost + $temp.assCost + $temp.eyeCost + $temp.hairColCost + $temp.hairLenCost + $temp.hairStyleCost>> <</link>> </div>
/* Side effects: earn points by taking drawbacks */ <div class="cc-points" id="cc-se-points-display"> <span>Available Points:</span> <span class="cc-points__value" id="cc-se-points"><<print $temp.ccPoints>></span> </div> <div class="cc-section"> <div class="cc-section__title">⚠️ Side Effects (Earn Points)</div> <div class="cc-section__subtitle">X-Change Petite comes with potential side effects. Higher levels = more points but stronger effects. Use these points to buy add-ons on the next page.</div> </div> <div class="cc-section"> <div id="cc-se-list"></div> </div> <<run setTimeout(function(){ XCLC.CC.renderSideEffects(); }, 50)>> <div style="margin-top: var(--space-lg); text-align: center;"> <<link '<span class="choice-btn" style="background: var(--accent-red-dim); border-color: var(--accent-red); color: var(--accent-red); text-align: center;">💀 Just Fuck My Shit Up (Max All)</span>'>> <<run XCLC.CC.maxAllSE()>> <</link>> </div> <div class="choice-group"> <<link '<span class="choice-btn">Continue to Add-ons →</span>' "CC_Addons">> <<run XCLC.CC.updateSEPoints()>> <</link>> </div>
/* Add-ons: spend points on benefits */ <div class="cc-points" id="cc-points-display"> <span>Available Points:</span> <span class="cc-points__value" id="cc-addon-points"><<print $temp.ccPoints>></span> </div> <div class="cc-section"> <div class="cc-section__title">💊 Add-ons (Spend Points)</div> <div class="cc-section__subtitle">Purchase beneficial modifications for your new body. Each costs points earned from appearance choices and side effects.</div> </div> <div class="cc-section"> <div id="cc-addon-list"></div> </div> <<run setTimeout(function(){ XCLC.CC.renderAddons(); }, 50)>> <div class="choice-group"> <<link '<span class="choice-btn">Continue to University Settings →</span>' "CC_University">><</link>> </div>
<div class="cc-section"> <div class="cc-section__title">🏛️ University Configuration</div> <div class="cc-section__subtitle">Shape the world around you.</div> </div> <div class="cc-section"> <div class="cc-section__title">Difficulty</div> <div class="cc-section__subtitle">Controls your weekly service quota and how aggressively NPCs pursue you.</div> <div class="cc-grid" id="cc-difficulty"></div> </div> <div class="cc-section"> <div class="cc-section__title">Campus Demographics</div> <div class="cc-section__subtitle">Adjust the racial distribution and gender ratio of NPCs you encounter. Sliders auto-normalize to 100%.</div> <div id="cc-demographics"></div> </div> <<run setTimeout(function(){ XCLC.CC.renderUniversity(); }, 50)>> <div class="choice-group"> <<link '<span class="choice-btn">Continue to Agreement →</span>' "CC_Agreement">><</link>> </div>
<div class="cc-section"> <div class="cc-section__title">📜 CCUMDUP Scholarship Agreement</div> <div class="cc-section__subtitle">Read carefully before signing.</div> </div> <div class="contract"> <h2>SCHOLARSHIP AGREEMENT</h2> <h3>ARTICLE I: PROGRAM OVERVIEW</h3> <p>The College Campus Unity & Morale Development Uplift Program ("CCUMDUP") provides full tuition coverage in exchange for specialized student support services.</p> <h3>ARTICLE II: PARTICIPANT OBLIGATIONS</h3> <p>Recipients ("Support Specialists") shall:</p> <ul> <li>Maintain continuous X-Change Petite transformation (provided at no cost)</li> <li>Service minimum <<print $scholarship.weeklyQuota>> unique Premium Students ("Daddies"/"Mommies") weekly</li> <li>Respond to service requests within 30 minutes, regardless of academic obligations</li> <li>Address all Premium Students as "Daddy" or "Mommy" per respect protocols</li> </ul> <h3>ARTICLE III: SERVICE VALUATION</h3> <ul> <li>Standard oral/vaginal service: 1 credit</li> <li>Anal service: 2 credits</li> <li>Internal completion: +1 bonus credit (Pregnancy risk acknowledged)</li> <li>Finals Week: DOUBLE quota (<<print $scholarship.finalsQuota>> minimum)</li> </ul> <h3>ARTICLE IV: AVAILABILITY CLAUSE</h3> <p>Support Specialists must prioritize Daddy/Mommy de-stressing over personal activities including but not limited to: studying, sleeping, eating. Service requests received during Late Night hours carry additional rating weight if declined.</p> <h3>ARTICLE V: RATING SYSTEM</h3> <p>Performance is rated 1-5 stars by each Premium Student. Average rating below 4.0 triggers academic probation. Below 3.0 triggers scholarship review and potential termination.</p> <h3>ARTICLE VI: DURATION</h3> <p>This agreement covers the full duration of the recipient's enrollment at Thornfield University (6 semesters / 3 academic years). Early termination requires full tuition repayment.</p> <h3>ARTICLE VII: SELFIE VERIFICATION</h3> <p>Following each service encounter, the Support Specialist must upload a verification selfie to the CampusHub application. Failure to provide verification may result in the encounter not being counted toward weekly quota.</p> </div> <div style="margin-top: var(--space-xl); text-align: center;"> <p style="color: var(--text-secondary);">By continuing, you agree to all terms of the CCUMDUP Scholarship Agreement.</p> <div class="choice-group"> <<link '<span class="choice-btn" style="background: var(--accent-primary-dim); border-color: var(--accent-primary); text-align: center;">✍️ Sign the Agreement</span>' "CC_Transformation">> /* Finalize CC */ <<set $flags.ccComplete = true>> <<set $pc.gender = "male">> /* Still male until transformation */ /* Apply add-on bonuses */ <<if $transformation.addons.intelligenceBoost>> <<set $skills.intelligence.level += 2>> <</if>> <<if $transformation.addons.flexibility>> <<set $skills.flexibility.level += 2>> <</if>> <<if $transformation.addons.libidoIncrease>> <<set $pc.arousal = 20>> <</if>> /* Point resolution: remaining points → cash or debt */ <<if $temp.ccPoints > 0>> <<set $finance.money = $temp.ccPoints * 10>> <<elseif $temp.ccPoints < 0>> <<set $finance.debt = Math.abs($temp.ccPoints) * 10>> <<set $finance.money = 0>> <<else>> <<set $finance.money = 0>> <</if>> <</link>> </div> </div>
<<set $pc.gender = "female">> <<set $flags.transformationComplete = true>> /* Add-on grants. The catalogue advertises "+2 starting intelligence levels" and "+2 starting flexibility levels". Before this, neither add-on had any effect anywhere in the codebase. */ <<if $transformation.addons.intelligenceBoost>> <<set $skills.intelligence.level += 2>> <<set $skills.studying.level += 1>> <</if>> <<if $transformation.addons.flexibility>> <<set $skills.flexibility.level += 2>> <</if>> <div class="cc-header"> <h1>The Transformation</h1> </div> <div class="cc-section"> <p>The clinic room is white on white and cold enough that your arms have gone to gooseflesh. A nurse hands you a small pink pill, X-Change Petite, and a paper cup of water.</p> <p>"Whenever you're ready, hun. Whole thing takes about thirty seconds." She says it the way a dental hygienist says <em>this might pinch</em>.</p> <p>You look at it sitting in your palm. It weighs nothing. It is smaller than an aspirin.</p> <<if $pc.reason === "poverty">> <p>You think about the bills, and the voice on the phone that always uses your full name. You swallow it dry, before you can talk yourself out of it.</p> <<elseif $pc.reason === "bet">> <p>You think about your brothers howling in the kitchen when you drew the short straw. <em>They'll stop laughing when they see the housing.</em> You swallow it.</p> <<elseif $pc.reason === "curious">> <p>Your heart is going hard, and not from fear. You have wanted to know for a very long time. You swallow it.</p> <<elseif $pc.reason === "forced">> <p>You didn't choose this. You're here anyway, in a paper gown, with somebody else's signature on your form. You swallow it.</p> <<elseif $pc.reason === "opportunist">> <p>Three years for a free ride and a corner room. You toss it back like a breath mint.</p> <<elseif $pc.reason === "identity">> <p>Your hand shakes, and not from fear. You have been waiting for someone to hand you exactly this. You swallow it feeling calmer than you have in years.</p> <</if>> </div> <div class="choice-group"> <<link '<span class="choice-btn">...</span>' "CC_Transformation2">><</link>> </div>
<div class="cc-section"> <p>It does not take thirty seconds. It takes about nine.</p> <p>It starts as warmth low in your stomach, the way whisky starts. The warmth becomes <em>heat</em>, and the heat becomes something with an opinion. Your skin pulls tight and then loose. Your hips ache like a deep bruise as they widen. Your ribs draw in. There is a long dragging pressure across your chest that resolves, all at once, into weight. You feel yourself getting <em>smaller</em>, and you make a sound you have never made before.</p> <p>When it stops you are gripping the edge of the examination table with both hands, breathing like you ran here. The gown hangs loose at the shoulders and tight everywhere else. The nurse holds up a mirror without being asked.</p> <p>A <<print $pc.race>> woman looks back and does exactly what you do, half a beat late. <<print $pc.height.charAt(0).toUpperCase() + $pc.height.slice(1)>>, <<print $pc.bodyType>>, <<print $pc.hairLength>> <<print $pc.hairColour>> hair, <<print $pc.eyeColour>> eyes. <<print $pc.breastSize>> cup breasts pushing the thin cotton out of shape, shifting when you breathe. You turn slightly and the <<print $pc.buttSize>> curve of your ass moves against the gown a half second after you do.</p> <p>"Looking good, <<print $pc.femaleFirstName>>!" the nurse says brightly. "Your student ID has been updated. Your dorm room is in Hamilton Hall, Room 207."</p> <<if $transformation.sideEffects.bimbofication > 0>> <p>Something in your head has gone soft at the edges. You reach for a thought and it slides sideways out of your hand. You shake it off. Side effect of the pill, probably. Probably.</p> <</if>> <<if $transformation.sideEffects.increasedSensitivity > 0>> <p>The gown is the cheapest cotton in the building and it feels like being dragged over with a soft brush. Every time you shift, the hem moves across your thighs and your breath catches somewhere it has no business catching.</p> <</if>> <<if $transformation.sideEffects.lactation > 0>> <p>Your chest is heavy and tight and full. You look down at two dark circles spreading through the cotton. The nurse looks too, entirely unbothered. "That's the lactation. Perfectly normal, sweetheart. You'll want to express every few hours or it gets uncomfortable."</p> <</if>> <p>She hands you a paper bag with your first outfit folded inside it, and a phone with CampusHub already installed and already logged in.</p> <p>"Welcome to Thornfield, <<print $pc.femaleFirstName>>. Orientation's at nine tomorrow. Don't be late, they do notice."</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">Go to your dorm room →</span>' "Orientation_DormArrival">> <<set $flags.orientationComplete = false>> <<initPhone>> <</link>> </div>
<<set $world.time = 1020>> /* 5:00 PM, arrived late afternoon */ <h2>🏠 Hamilton Hall, Room 207</h2> <p>You stand in front of the door to your new dorm room, a bag of clothes in one hand, your phone in the other. The hallway smells like old carpet and cheap air freshener, and somewhere down the corridor a door keeps slamming.</p> <p>Your key card works on the second try. The door swings open onto a small, functional room: two single beds, two desks, a shared closet, a bathroom barely wider than its own door. One side has already been claimed. Posters, fairy lights, an open laptop, a stuffed rabbit slumped against the pillow.</p> <p>Someone's already here.</p> /* Generate a random roommate */ <<generateRoommate>> <<include "Roommate_MeetFirstTime">> <div class="choice-group"> <<link '<span class="choice-btn">👋 "Hey, I\'m <<print $pc.femaleFirstName>>. Nice to meet you."</span>' "Orientation_MeetRoommate_Friendly">> <<set $roommate.opinion += 10>> <</link>> <<link '<span class="choice-btn">😶 Give a small wave. "Hi."</span>' "Orientation_MeetRoommate_Shy">> <<set $roommate.opinion += 0>> <</link>> <<link '<span class="choice-btn">😰 Stare at her. This is your first conversation as a woman.</span>' "Orientation_MeetRoommate_Nervous">> <<set $roommate.opinion += 5>> <</link>> </div>
<<set $flags.metRoommate = true>> <p>You shake her hand and immediately regret how odd it feels. Your hand is smaller than it was a week ago. Softer, too, with none of the callus you spent twenty years earning. <<print $roommate.name>> pumps it twice like she's closing a deal.</p> <p>"<<print $pc.femaleFirstName>>! Love that name. So are you a freshman too? What's your major?"</p> <p>She doesn't wait for an answer. Inside a minute you learn that she's from Connecticut, that she's undeclared but "probably gonna do comms or something," that she has already scouted the cafeteria and rates the pasta, and that Sigma Chi is throwing a welcome party tonight and you are both going, apparently.</p> <<include "Orientation_RoomSetup">>
<<set $flags.metRoommate = true>> <p><<print $roommate.name>>'s smile doesn't dip an inch. "A woman of few words. Respect. I talk enough for two people, so honestly this works out."</p> <p>She isn't exaggerating. Within ten minutes she has given you her entire life story, decided which desk is yours, and pressed a granola bar into your hand like it's a housewarming gift.</p> <<include "Orientation_RoomSetup">>
<<set $flags.metRoommate = true>> <p>Your voice comes out higher than you expect. Lighter. You hear it leave your mouth and flinch at it, and <<print $roommate.name>> catches the flinch.</p> <p>"Hey. First day jitters?" She says it gently, without making a thing of it. "Totally normal. I cried on the drive here. Like, ugly cried, at a rest stop." She takes your bag out of your hand. "C'mon. Let's get you unpacked."</p> <p>She's kind in a way you weren't braced for. Maybe this won't be so bad.</p> <<include "Orientation_RoomSetup">>
<<set $world.time = 1080>> /* 6:00 PM */ <div class="divider"><span class="divider__text">Later</span></div> <p>You've unpacked what little you own. It took four minutes. <<print $roommate.name>> lent you a towel and demonstrated the shower, which involves jiggling the handle at a very specific angle or the water stays cold out of spite.</p> <p>Your phone buzzes. CampusHub notification:</p> <div class="alert alert--info"> 📱 <strong>CampusHub:</strong> Welcome to the CCUMDUP Program, <<print $pc.femaleFirstName>>! Orientation is tomorrow at 9:00 AM in the Admin Building. Your first service requests will begin after orientation. Enjoy your first night! </div> <<set $phone.messages.push({ id: $phone.nextMessageId++, from: "CampusHub", icon: "📱", text: "Welcome to CCUMDUP! Orientation tomorrow at 9 AM. Your first service requests begin after orientation.", read: false, day: $world.day, time: $world.time })>> <p><<print $roommate.name>> reads over your shoulder before you can stop her. "CampusHub? Is that a student services thing? I don't think I got that one."</p> <p>You lock the phone against your thigh. "Yeah. Just admin stuff."</p> <p>"Cool cool cool." She's already pulling on shoes. "Dinner? Caf shuts at eight."</p> <div class="choice-group"> <<link '<span class="choice-btn">🍽️ "Sure, I\'m starving."</span>' "Orientation_Dinner">> <<set $roommate.opinion += 5>> <</link>> <<link '<span class="choice-btn">😴 "I\'m actually wrecked. Rain check?"</span>' "Orientation_Sleep">> <<set $roommate.opinion -= 5>> <</link>> </div>
<<set $world.time = 1200>> /* 8:00 PM */ <h2>🍽️ Thornfield Dining Hall</h2> <p>The cafeteria is loud with freshmen doing impressions of people who aren't nervous. Every table is full. <<print $roommate.name>> cuts through the crowd like she's got tenure.</p> <p>She was right about the pasta. You eat slowly, still getting used to a smaller mouth and a narrower jaw, and everything tastes brighter than it used to. Salt. Garlic. The cheap parmesan. Whatever they did to you rewired your tongue along with the rest.</p> <<if $transformation.sideEffects.bimbofication >= 2>> <p><<print $roommate.name>> is telling a story about her high school and you lose the thread of it somewhere in the middle. You nod along. You have absolutely no idea what she's talking about anymore. Volleyball, maybe. It was definitely about volleyball.</p> <</if>> <<if $transformation.sideEffects.pheromones >= 2>> <p>Two tables over, a guy has been looking at you for longer than looking is polite. So has his friend. So, you realise, has half the row behind them. <<print $roommate.name>> clocks it and grins into her drink. "Okay, someone's popular already. He's cute, right? He's cute."</p> <</if>> <<if $transformation.sideEffects.exhibitionist >= 1>> <p>You are extremely aware of how the clinic t-shirt fits you. It pulls tight across your chest every time you reach for your fork, and every time you reach for your fork you feel the room notice. You should hate that. You keep reaching for the fork.</p> <</if>> <p>"So what's your deal?" <<print $roommate.name>> asks, winding spaghetti onto her fork. "Boyfriend back home? Secret talent? Weird hobby I should know about before I sleep six feet from you?"</p> <div class="choice-group"> <<link '<span class="choice-btn">🤷 "Just a regular girl trying to get through college."</span>' "Orientation_DinnerEnd">> <<modStat "mood" 5 "Nice dinner with roommate">> <</link>> <<link '<span class="choice-btn">😏 "If I told you, you wouldn\'t believe me."</span>' "Orientation_DinnerEnd">> <<modStat "confidence" 5 "Mysterious vibe">> <<set $roommate.opinion += 5>> <</link>> </div>
<<set $world.time = 1260>> /* 9:00 PM */ <p>You walk back together. The campus is genuinely beautiful at night, all warm uplighting on old stone, oak trees leaning over the walkways, a bass line thumping somewhere down on Greek Row like a pulse under the whole place.</p> <p>"That was fun," <<print $roommate.name>> says. "Roommate bonding, step one, complete. Step two is where we trade our deepest secrets, but I'll give you a few days."</p> <p>She yawns hugely on the stairs. "I'm dying. Night, <<print $pc.femaleFirstName>>."</p> <p>You lie in bed in your new body and stare at the ceiling. The mattress takes your weight differently. Your hair fans out across the pillow and gets in your mouth. Your chest rises and falls and there's more of it to rise and fall, and you can feel your own heartbeat somewhere behind it. You keep waiting to stop noticing. You don't.</p> <<if $transformation.sideEffects.eroticDreams >= 1>> <p>Sleep takes you, and then it takes you somewhere else. Hands you can't see the owner of. A mouth at your throat. You surface once around three in the morning, flushed to the collarbone, thighs pressed together, sheets wound tight around your legs, and you lie very still until it passes.</p> <</if>> <p>Tomorrow, orientation. Then whatever this is becomes your life.</p> <div class="choice-group"> <<link '<span class="choice-btn">💤 Sleep</span>' "Day1_Morning">> <<sleep>> <<set $flags.orientationComplete = false>> <</link>> </div>
<<set $world.time = 1200>> <p>"No worries. I'll smuggle you a cookie." <<print $roommate.name>> waves and bangs out the door.</p> <p>Alone, finally. You sit on the edge of a bed that isn't yours yet and just breathe. Across the room, the bathroom mirror catches you. A stranger looks back, and she's pretty, which is somehow the strangest part: <<print $pc.hairColour>> hair, <<print $pc.eyeColour>> eyes, a face that reacts a beat before you tell it to.</p> <p>You unpack. It doesn't take long. The clinic sent you off with a plain bra and briefs, a t-shirt, yoga pants, and flip-flops. That is the whole wardrobe.</p> <p><<print $roommate.name>> comes back near eleven and puts a cookie on your desk without comment. "Night, <<print $pc.femaleFirstName>>."</p> <p>Sleep comes slowly. Everything is different.</p> <div class="choice-group"> <<link '<span class="choice-btn">💤 Sleep</span>' "Day1_Morning">> <<sleep>> <<set $flags.orientationComplete = false>> <</link>> </div>
<<set $world.dayOfWeek = 1>> <<set $world.time = 420>> /* 7:00 AM */ <<set $pc.energy = 100>> <<set $pc.mood = 60>> <h2>☀️ Day 1: Monday Morning</h2> <p>The alarm goes at seven. For about four seconds you don't know where you are. Then you feel the weight on your chest and the hair across your face, and the whole week arrives at once.</p> <p><<print $roommate.name>> is already up, wrapped in a towel, doing something intricate and violent to her own eyelid with a pencil.</p> <p>"Morning, sunshine. Bathroom's yours in two minutes. Orientation's at nine and they lock the doors, which I choose to believe is a lie."</p> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Take a shower and get ready</span>' "Day1_Routine">> <<shower>> <</link>> <<link '<span class="choice-btn">⏩ Skip the shower, just get dressed</span>' "Day1_Dressed">><</link>> </div>
<p>The shower is an education. Hot water runs over skin that reports back in far more detail than it used to, and it finds places that weren't there last month. You keep your hands efficient and your mind somewhere else, with mixed results.</p> <<if $transformation.sideEffects.increasedSensitivity >= 2>> <p>Somewhere else isn't an option. Every drop lands like a struck match. Soap across your ribs makes your breath catch, and when the spray hits your nipples your knees actually consider it. You end up braced flat against the tile with your forehead on your forearm, waiting it out, water going cold before you trust yourself to move.</p> <<modStat "arousal" 20 "Shower sensitivity">> <</if>> <<if $transformation.sideEffects.lactation >= 1>> <p>Something's leaking. You look down and yes, that's milk, beading at both nipples and running in thin lines down your stomach. You press one gently and a fine stream arcs onto the shower floor and vanishes down the drain. Fine. That's a thing now.</p> <</if>> <p>You towel off, pull on the clinic clothes, which are also your only clothes, and face the mirror.</p> <<include "Day1_MirrorCheck">>
<p>You pull on yesterday's clothes, which are also tomorrow's clothes, and check yourself in the bathroom mirror.</p> <<include "Day1_MirrorCheck">>
<div class="card"> <div class="card__title">🪞 Mirror Check</div> <p>You see a <<print $pc.height>>, <<print $pc.bodyType>> <<print $pc.race>> girl with <<print $pc.hairLength>> <<print $pc.hairColour>> hair and <<print $pc.eyeColour>> eyes. <<print $pc.breastSize>> cup breasts, <<print $pc.buttSize>> ass.</p> <p>Outfit: Basic clinic t-shirt, yoga pants, flip-flops. (No makeup, no accessories.)</p> <p>Beauty: <<print $pc.beautyTotal>> | Hygiene: <<print $hygiene.cleanliness>>%</p> </div> <p><<print $roommate.name>> looks you up and down with open pity. "Okay. We are getting you clothes. I'd lend you something, but." She gestures between her frame and yours, which is not a close match. "Mall. This weekend. Non-negotiable."</p> <p>She grabs her bag. "Twenty minutes. Move."</p> <div class="choice-group"> <<link '<span class="choice-btn">🏛️ Head to orientation</span>' "Day1_Orientation">><</link>> </div>
<<set $world.time = 540>> /* 9:00 AM */ <<set $flags.orientationComplete = true>> <h2>🏛️ Orientation: Admin Building Auditorium</h2> <p>The auditorium is packed. You and <<print $roommate.name>> get seats near the back, which turns out to matter. A woman in a very sharp blazer takes the podium.</p> <p>"Welcome to Thornfield University. I'm Dean Victoria Ashford. For the next three years, this campus is your home."</p> <p>The speech does what these speeches do. Academic rigour. Community. A story about her own freshman year that has clearly been told two hundred times. You're halfway to sleep when she changes gear.</p> <p>"And we are especially proud of our CCUMDUP scholarship recipients, whose selfless dedication to campus morale makes Thornfield the warm and welcoming community it is today. Will our CCUMDUP scholars please stand?"</p> <p>The blood goes out of your face all at once. You stand, because everyone is waiting, and around the room seven or eight other girls stand with you. All transformed. All wearing the same careful blank expression. The audience applauds the way people applaud at weddings. Down in the front row, three guys turn around in their seats to look, and one of them says something that makes the other two laugh.</p> <p>You sit. <<print $roommate.name>> leans in, genuinely curious. "What's CCUMDUP? Is that a mentoring thing?"</p> <p>"Something like that," you say.</p> <<modStat "stress" 15 "Public humiliation">> <<modStat "confidence" -5 "Standing up at orientation">> <<divider "Campus Tour">> <p>Afterwards, student ambassadors herd everyone outside for the tour:</p> <ul> <li>📚 <strong>Lecture Halls</strong>, where your classes will be</li> <li>📖 <strong>Library</strong>, quiet on the ground floor and famously not on the upper ones</li> <li>💪 <strong>Gym</strong>, free for students, locker rooms included</li> <li>🍽️ <strong>Cafeteria</strong>, meal plan included</li> <li>🏛️ <strong>Admin Building</strong>, the Dean's office and the health centre</li> <li>🎭 <strong>Student Center</strong>, clubs, events, and the good sofas</li> <li>🏡 <strong>Greek Row</strong>, fraternities and sororities</li> <li>🏙️ <strong>Off-campus shuttle</strong>, running to the mall and downtown and back</li> </ul> <p>Your phone buzzes twice on the way round.</p> <div class="alert alert--warning"> 📱 <strong>CampusHub:</strong> Orientation complete! Your service window opens tomorrow. First 5 encounters benefit from the MERCY RULE (reduced difficulty). Good luck, <<print $pc.femaleFirstName>>! </div> <<set $phone.messages.push({ id: $phone.nextMessageId++, from: "CampusHub", icon: "📱", text: "Orientation complete! Service window opens tomorrow. First 5 encounters have reduced difficulty (Mercy Rule). Good luck!", read: false, day: $world.day, time: $world.time })>> <p>The tour lets out at the Campus Quad. <<print $roommate.name>> peels off toward the club sign-up tables, waving over her shoulder.</p> <p>One thing left before the day is yours: registration. An ambassador puts a tablet in your hands.</p> <p>"Pick your classes. You need five."</p> <div class="choice-group"> <<link '<span class="choice-btn">📚 Register for classes</span>' "ClassSelection">><</link>> </div>
<<checkStreetProposition>> <<run XCLC.Service.checkForNewRequest()>> <h2>🗺️ Campus Quad</h2> <p>It's <<showTime>>, <<showDate>>. <<showPeriod>>.</p> <p><<print XCLC.Campus.getAtmosphere()>></p> <p><em><<print XCLC.Campus.getAmbient()>></em></p> <<if $scholarship.activeRequest>> <<set _req = $scholarship.activeRequest>> <<set _elapsed = $world.time - _req.createdAt>> <<set _remaining = 30 - _elapsed>> <div class="alert alert--info">📱 <strong>CampusHub Request!</strong> <<print _req.npc.firstName>> wants <<print _req.serviceType>> at <<print _req.locationName>>. (<<print _remaining>> min remaining)</div> <div class="choice-group"> <<link '<span class="choice-btn">✅ Accept request</span>' `($scholarship.activeRequest && $scholarship.activeRequest.isGroup) ? "GroupMeet" : "ServiceMeet"`>> <<run XCLC.Service.acceptRequest()>> <<advanceTime 10>> <</link>> <<link '<span class="choice-btn">❌ Decline</span>' "CampusMap">> <<run XCLC.Service.rejectRequest()>> <</link>> </div> <</if>> <<if $hygiene.cleanliness < 40>> <div class="alert alert--warning">⚠️ You're not exactly fresh. Maybe hit the shower before seeing anyone.</div> <</if>> <<if $pc.energy < 20>> <div class="alert alert--warning">⚠️ You're exhausted. You should probably sleep.</div> <</if>> <<if $scholarship.currentWeekServiced < $scholarship.weeklyQuota && $world.dayOfWeek >= 4>> <div class="alert alert--info">📱 CampusHub: You've serviced <<print $scholarship.currentWeekServiced>>/<<print $scholarship.weeklyQuota>> this week. Deadline is Sunday.</div> <</if>> <<set _seEvents = XCLC.Campus.checkSEPublic()>> <<for _i = 0; _i < _seEvents.length; _i++>> <div class="alert alert--warning"><<print _seEvents[_i].text>></div> <<if _seEvents[_i].type === "randomOrgasm">> <<modStat "arousal" -30 "Public orgasm">> <<modStat "confidence" -5 "Public orgasm">> <<modRep "slut" 3 "Public orgasm">> <</if>> <<if _seEvents[_i].type === "lactation">> <<modStat "confidence" -3 "Milk stains">> <</if>> <</for>> <<set _encounter = XCLC.Campus.rollEncounter()>> <<if _encounter>> <<set $temp.quadNPC = _encounter.npc>> <<if _encounter.type === "approached">> <<include "QuadEncounter_Approached">> <<elseif _encounter.type === "catcall">> <<include "QuadEncounter_Catcall">> <<elseif _encounter.type === "recognize">> <<include "QuadEncounter_Recognize">> <<elseif _encounter.type === "fellowScholar">> <<include "QuadEncounter_FellowScholar">> <<elseif _encounter.type === "professorChat">> <<include "QuadEncounter_ProfessorChat">> <<elseif _encounter.type === "pheromones">> <<include "QuadEncounter_Pheromones">> <</if>> <</if>> <<divider "On Campus">> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Dorm Room: Hamilton Hall</span>' "DormRoom">><</link>> <<link '<span class="choice-btn">📚 Lecture Halls: Classes & Professors</span>' "LectureHalls">><</link>> <<link '<span class="choice-btn">📖 Library: Study & Research</span>' "Library">><</link>> <<link '<span class="choice-btn">💪 Gym & Locker Room</span>' "Gym">><</link>> <<link '<span class="choice-btn">🍽️ Cafeteria: Eat & Socialise</span>' "Cafeteria">><</link>> <<link '<span class="choice-btn">🏛️ Admin Building: Dean, Health Centre</span>' "AdminBuilding">><</link>> <<link '<span class="choice-btn">💼 Job Board: Employment</span>' "JobBoard">><</link>> <<link '<span class="choice-btn">🎭 Student Center: Clubs & Events</span>' "StudentCenter">><</link>> <<link '<span class="choice-btn">🏡 Greek Row: Fraternities & Sororities</span>' "GreekRow">><</link>> <<link '<span class="choice-btn">🚻 Campus Bathrooms</span>' "CampusBathrooms">><</link>> <<if $children.list.length > 0>> <<link '<span class="choice-btn">🚸 Campus Nursery</span>' "Children_Nursery">><</link>> <</if>> <<divider "Off Campus">> <<link '<span class="choice-btn">🛍️ Mall: Shopping</span>' "Mall">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">🍸 Bar District: Nightlife</span>' "BarDistrict">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">🖋️ Ink & Iron: Tattoo & Piercing</span>' "TattooShop">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">💇 Hair Salon</span>' "HairSalon">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">💊 Drugstore</span>' "Drugstore">> <<advanceTime 20>> <</link>> <<link '<span class="choice-btn">🏢 Downtown</span>' "Downtown">> <<advanceTime 40>> <</link>> <<divider "Phone">> <<link '<span class="choice-btn">📱 Phone</span>' "Phone_Home">><</link>> </div>
<<checkRoommateAwareness>> <<checkToysLeftOut>> <h2>🏠 Dorm Room: Hamilton Hall, Room 207</h2> <p>It's <<showTime>>. <<if $world.time < 420>> The room is dark. Moonlight filters through the window blinds. <<elseif $world.time < 600>> Morning light streams through the window. Campus is waking up. <<elseif $world.time < 720>> The room is bright with morning sun. You can hear students heading to class outside. <<elseif $world.time < 1020>> Midday. The dorm is quiet, most people being in class. Somebody two doors down is playing the same forty seconds of a song over and over. <<elseif $world.time < 1200>> Afternoon light fills the room. The campus is bustling outside. <<elseif $world.time < 1320>> Evening. The room feels cosy in the lamplight. <<else>> It's late. The building is winding down. You should probably sleep. <</if>> </p> /* Roommate presence */ <<if $roommate.name>> <<if XCLC.Roommate.isHome()>> <p><<print $roommate.name>> is <<print XCLC.Roommate.getActivity()>>.</p> <<else>> <p><<print $roommate.name>> is out.</p> <</if>> <</if>> /* Status warnings */ <<if $hygiene.cleanliness < 40>> <div class="alert alert--warning">⚠️ You're not exactly fresh. Hygiene: <<print $hygiene.cleanliness>>%</div> <</if>> <<if $pc.arousal > 70>> <div class="alert alert--warning">🔥 Your arousal is becoming distracting. <<print $pc.arousal>>%</div> <</if>> <<if $pc.energy < 20>> <div class="alert alert--warning">😫 You're exhausted. You need to sleep.</div> <</if>> <<checkLactation>> <<divider "Activities">> <div class="choice-group"> <<link '<span class="choice-btn">💤 Go to sleep</span>' "DormRoom_Sleep">> <<sleep>> <</link>> <<link '<span class="choice-btn">🚿 Take a shower</span>' "DormRoom_Shower">><</link>> <<link '<span class="choice-btn">🪞 Look in the mirror</span>' "DormRoom_Mirror">><</link>> <<link '<span class="choice-btn">📚 Study at your desk (1 hour)</span>' "DormRoom_Study">> <<advanceTime 60>> <<addXP "studying" 20>> <<addXP "intelligence" 10>> <<modStat "energy" -10 "Studying">> <<modStat "stress" 5 "Studying">> <</link>> <<link '<span class="choice-btn">📺 Relax (30 min)</span>' "DormRoom_Relax">> <<advanceTime 30>> <<modStat "energy" 10 "Resting">> <<modStat "mood" 8 "Relaxing">> <<modStat "stress" -8 "Relaxing">> <</link>> <<if $children.list.length > 0>> <<link '<span class="choice-btn">👶 Look after <<if $children.list.length > 1>>the children<<else>>the baby<</if>> (3 hours)</span>' "Children_Care">><</link>> <</if>> <<link '<span class="choice-btn">🔥 Masturbate</span>' "DormRoom_Masturbate">><</link>> <<link '<span class="choice-btn">📱 Check phone</span>' "Phone_Home">><</link>> <<link '<span class="choice-btn">👗 Change outfit (Wardrobe)</span>' "WardrobeMenu">><</link>> /* Online work happens where the equipment is, not at a noticeboard */ <<if $jobs.camGirl.active && $inventory.hasLaptop && $inventory.hasWebcam>> <<link '<span class="choice-btn">📷 Go live: cam show</span>' "Job_Cam_Start">><</link>> <</if>> <<if $jobs.fansOnly.active && $inventory.hasCamera>> <<link '<span class="choice-btn">💰 FansOnly: create content</span>' "Job_FansOnly_Hub">><</link>> <</if>> <<if ($jobs.camGirl.active && (!$inventory.hasLaptop || !$inventory.hasWebcam)) || ($jobs.fansOnly.active && !$inventory.hasCamera)>> <p style="opacity:0.55; font-size:0.85em;"><em>You need the right kit before you can work from in here. The electronics store downtown has it.</em></p> <</if>> /* Pregnancy test at home */ <<if $inventory.pregnancyTests > 0>> <<link '<span class="choice-btn">🤰 Take a pregnancy test (<<print $inventory.pregnancyTests>> remaining)</span>' "PregnancyTest">> <<set $inventory.pregnancyTests-->> <<advanceTime 5>> <</link>> <</if>> /* Grooming */ <<if $inventory.razors > 0 && ($pc.legHair > 0 || $pc.pubicHair > 0)>> <<divider "Grooming">> <<if $pc.legHair > 0>> <<link '<span class="choice-btn">🪒 Shave legs (Razors: <<print $inventory.razors>>)</span>' "DormRoom">> <<shaveLegs>> <</link>> <</if>> <<if $pc.pubicHair > 0>> <<link '<span class="choice-btn">🪒 Shave pubic area (Razors: <<print $inventory.razors>>)</span>' "DormRoom">> <<shavePubic>> <</link>> <</if>> <</if>> <<if $inventory.skincareUses > 0>> <<link '<span class="choice-btn">✨ Apply skincare (<<print $inventory.skincareUses>> uses)</span>' "DormRoom">> <<applySkincare>> <</link>> <</if>> /* Makeup */ <<divider "Makeup">> <<if $pc.makeupApplied>> <<link '<span class="choice-btn">💧 Remove makeup</span>' "DormRoom">> <<applyMakeup "none">> <</link>> <</if>> <<if !$pc.makeupApplied || $pc.makeupStyle !== "natural">> <<if $inventory.makeupUses.natural > 0>> <<link '<span class="choice-btn">🌿 Apply natural makeup (<<print $inventory.makeupUses.natural>> uses)</span>' "DormRoom">> <<applyMakeup "natural">> <</link>> <</if>> <</if>> <<if !$pc.makeupApplied || $pc.makeupStyle !== "glam">> <<if $inventory.makeupUses.glam > 0>> <<link '<span class="choice-btn">✨ Apply glam makeup (<<print $inventory.makeupUses.glam>> uses)</span>' "DormRoom">> <<applyMakeup "glam">> <</link>> <</if>> <</if>> /* Roommate */ <<if $roommate.name && XCLC.Roommate.isHome()>> <<divider "Social">> <<link '<span class="choice-btn">💬 Talk to <<print $roommate.name>></span>' "DormRoom_TalkToRoommate">><</link>> <</if>> <<divider "Navigation">> <<link '<span class="choice-btn">🗺️ Leave: Campus Map</span>' "CampusMap">><</link>> </div>
<<if $transformation.sideEffects.eroticDreams >= 1>> <<set _dreamLevel = $transformation.sideEffects.eroticDreams>> <<if _dreamLevel === 1>> <p>Your dreams are warm and strange. Soft hands, warm breath, the feeling of someone pressed against you. You stir restlessly.</p> <<elseif _dreamLevel === 2>> <p>You dream of bodies, tangled and urgent and never quite in focus. A mouth on yours. Hands that know where they are going. You make a sound into the pillow and your hips shift against the mattress without asking you first.</p> <<elseif _dreamLevel === 3>> <p>The dreams are vivid enough to taste. You're being taken, roughly, enthusiastically, and you're LOVING it. You wake mid-orgasm, gasping, the sheets soaked with sweat.</p> <<modStat "arousal" 20 "Vivid dreams">> <<else>> <p>The dream is so intense it feels real. Multiple partners, every hole filled, your body a conduit of pure sensation. You scream yourself awake, convulsing, your new body clenching around nothing.</p> <<modStat "arousal" 40 "Hallucinatory dreams">> <</if>> <</if>> /* ─── Dream Sequence (Phase 9) ─── */ <<checkDream>> <p>You <<if $pc.energy >= 80>>slept well. You feel refreshed and ready. <<elseif $pc.energy >= 50>>got some rest. Not amazing, but functional. <<elseif $pc.energy >= 25>>didn't sleep great. You feel groggy. <<else>>barely slept. Everything hurts and you want to die. <</if>></p> <p>It's <<showTime>> on <<showDate>>.</p> <div class="choice-group"> <<link '<span class="choice-btn">⚡ Quick morning routine</span>' "QuickRoutine_Setup">><</link>> <<link '<span class="choice-btn">🏠 Get up (do things individually)</span>' "MorningRoutine">><</link>> </div>
<<shower>> <p>The hot water cascades over your body. <<if $transformation.sideEffects.increasedSensitivity >= 1>> <<set _sensLevel = $transformation.sideEffects.increasedSensitivity>> <<if _sensLevel === 1>> Every droplet feels amplified on your skin. It's... pleasant. Very pleasant. <<modStat "arousal" 5 "Shower sensitivity">> <<elseif _sensLevel === 2>> The sensation is almost overwhelming. Your nipples harden instantly and each stream of water that hits them sends a jolt through you. <<modStat "arousal" 15 "Shower sensitivity">> <<elseif _sensLevel >= 3>> You have to brace yourself against the wall. The water on your skin is practically foreplay. Your breasts ache, your thighs press together, and you're breathing hard before you've even reached for the soap. <<modStat "arousal" 25 "Shower sensitivity">> <</if>> <</if>> </p> <<if $transformation.sideEffects.lactation >= 2>> <p>🍼 Milk runs from your nipples, mixing with the shower water. You cup your breasts and squeeze, expressing the pressure. It's surprisingly... satisfying.</p> <<set $temp.lastExpressed = $world.time>> <<modStat "arousal" 5 "Expressing milk">> <</if>> /* Roommate walk-in check */ <<set _walkIn = XCLC.Roommate.checkWalkIn('shower')>> <<if _walkIn.walkedIn>> <div class="card"> <div class="card__title">🚪 Interruption!</div> <p><<print _walkIn.text>></p> </div> <<modStat "confidence" -3 "Walked in on">> <</if>> <p>You step out feeling clean and fresh.</p> /* Suction-cup toy: the whole point of owning one */ <<set _showerToys = XCLC.Toys.ownedTagged("shower")>> <<if _showerToys.length > 0>> <p style="opacity:0.75;"><em>Your <<print XCLC.Toys.plain(_showerToys[0])>> is sitting in the shower caddy where you left it, entirely innocent-looking until you remember what it is for.</em></p> <</if>> <div class="choice-group"> <<if _showerToys.length > 0>> <<link '<span class="choice-btn">🚿 Actually: you are already in here <em>(Solo Performance)</em></span>' "Solo_Setup">> <<set $temp.soloShower = true>> <<advanceTime 30>> <</link>> <</if>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>> </div>
<p>You sit at your desk and open a textbook. <<if $transformation.sideEffects.bimbofication >= 2>> The words blur and swim. You read the same paragraph three times and still can't remember what it says. Was studying always this hard? You catch yourself doodling hearts in the margin instead of taking notes. <<elseif $transformation.sideEffects.bimbofication === 1>> Your concentration isn't what it used to be. Some concepts take longer to grasp than they should. <<else>> You manage to focus and get some productive studying done. <</if>> </p> <<if $transformation.sideEffects.eroticDreams >= 2>> <<if random(1,3) === 1>> <p>Your mind goes somewhere else. You are looking at the textbook and seeing none of it. Warmth. The ghost of a grip on your hips. The weight of hands where there are no hands.</p> <p>You shake your head. Focus, <<print $pc.femaleFirstName>>.</p> <<modStat "arousal" 10 "Daydream">> <</if>> <</if>> <<if $pc.arousal > 60>> <p>It's almost impossible to concentrate with this level of arousal. You keep shifting in your seat, thighs pressing together.</p> <</if>> <p>+20 Studying XP, +10 Intelligence XP</p> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
<div class="card"> <div class="card__title">🪞 Your Reflection</div> <<set _raceLabel = $pc.race.charAt(0).toUpperCase() + $pc.race.slice(1)>> <p>A <<print _raceLabel>> girl stares back at you. <<if $pc.bodyType === "athletic">>Toned and lean, with visible definition. <<elseif $pc.bodyType === "hourglass">>Curves in all the right places, a classic feminine silhouette. <<elseif $pc.bodyType === "slender">>Slim and delicate, with a model's frame. <<else>>Soft and inviting, with generous curves. <</if>> </p> <p><<print $pc.hairLength.charAt(0).toUpperCase() + $pc.hairLength.slice(1)>> <<print $pc.hairColour>> hair, <<print $pc.hairStyle>> style. <<print $pc.eyeColour.charAt(0).toUpperCase() + $pc.eyeColour.slice(1)>> eyes that are still unfamiliar every time you look.</p> <p><<print $pc.breastSize>> Cup breasts. <<print $pc.buttSize.charAt(0).toUpperCase() + $pc.buttSize.slice(1)>> ass. <<print $pc.height.charAt(0).toUpperCase() + $pc.height.slice(1)>> height.</p> /* ─── Pregnancy reflection ─── */ <<if $pregnancy.isPregnant>> <<set _pw = $pregnancy.weeksPregnant>> <<if _pw >= 28>> <p>🤰 <strong>Your belly owns the reflection now.</strong> Round, unmistakable, and heavy enough that it has moved your centre of gravity somewhere you have not finished learning. Your breasts are fuller and rest on the curve of it. Nothing in your wardrobe hides this any more, and you have stopped auditioning things that might. <<toneThink "I look like a stranger. Again." "Every week there's more of... us." "I'm HUGE and honestly? Kind of glowing. 🥹">></p> <<elseif _pw >= 20>> <p>🤰 <strong>You're showing. Properly showing.</strong> A firm, rounded bump pushing out against your top, and your breasts have gone up what feels like a full cup. Strangers' eyes drop to it before they find your face, every single time. <<toneThink "There's no hiding this anymore." "Hi, little one. We're in this together, I guess." "Bump era!! I need cuter maternity tops.">></p> <<elseif _pw >= 12>> <p>🤰 <strong>There's a curve to your lower belly now.</strong> Invisible under anything loose, perfectly obvious in anything fitted. Your breasts ache when you take your bra off. Anybody paying attention could tell you. <<if $pregnancy.discovered>><<toneThink "It's real. It's really real." "Twelve weeks. Decision time is running out." "My bump is showing!! 🤰">><<else>><em>You press a hand against it. That's not cafeteria food. You should take a test.</em><</if>></p> <<elseif _pw >= 4 && $pregnancy.discovered>> <p>🤰 <em>Nothing shows yet. Your body is still keeping it between the two of you. But you know, and your hand keeps going to your stomach when you are not thinking about it.</em></p> <</if>> <</if>> <p>Makeup: <<if $pc.makeupApplied>><<print $pc.makeupStyle.charAt(0).toUpperCase() + $pc.makeupStyle.slice(1)>><<else>>None<</if>> | Legs: <<if $pc.legHair === 0>>Smooth<<elseif $pc.legHair === 1>>Stubble<<else>>Needs shaving<</if>> | Hygiene: <<print $hygiene.cleanliness>>%</p> <p><strong>Wearing:</strong> <<print XCLC.Wardrobe.getSlotName('top') !== 'Empty' ? XCLC.Wardrobe.getSlotName('top') : (XCLC.Wardrobe.getSlotName('dress') !== 'Empty' ? XCLC.Wardrobe.getSlotName('dress') : 'Nothing')>>, <<print XCLC.Wardrobe.getSlotName('bottom') !== 'Empty' ? XCLC.Wardrobe.getSlotName('bottom') : ''>> | Shoes: <<print XCLC.Wardrobe.getSlotName('shoes')>> | Style: <<print $inventory.styleIdentity === 'none' ? 'Mixed' : $inventory.styleIdentity.charAt(0).toUpperCase() + $inventory.styleIdentity.slice(1)>></p> <<if $pc.piercings.length > 0>> <p><strong>Piercings:</strong> <<for _p = 0; _p < $pc.piercings.length; _p++>><<print $pc.piercings[_p].name>><<if _p < $pc.piercings.length - 1>>, <</if>><</for>></p> <</if>> <<if $pc.tattoos.length > 0>> <p><strong>Tattoos:</strong> <<for _t = 0; _t < $pc.tattoos.length; _t++>><<print $pc.tattoos[_t].name>> (<<print $pc.tattoos[_t].location>>)<<if _t < $pc.tattoos.length - 1>>, <</if>><</for>></p> <</if>> <<divider "">> <p><strong>Beauty:</strong> <<print $pc.beautyTotal>> (Base: <<print $pc.beautyBase>> + Grooming: <<print $pc.beautyGrooming>> + Makeup: <<print $pc.beautyMakeup>> + Clothing: <<print $pc.beautyClothing>> + Skincare: <<print $pc.beautySkincare>> + Fitness: <<print $pc.beautyFitness>>)</p> <p><strong>Stats:</strong> Energy <<print Math.round($pc.energy)>> | Mood <<print Math.round($pc.mood)>> | Stress <<print Math.round($pc.stress)>> | Arousal <<print Math.round($pc.arousal)>></p> <p>Confidence <<print Math.round($pc.confidence)>> | Willpower <<print Math.round($pc.willpower)>> | Intelligence <<print Math.round($pc.intelligence)>> | Femininity <<print Math.round($pc.femininity)>></p> </div> /* ─── Skills Display ─── */ <div class="card"> <div class="card__title">📋 Skills</div> <div class="card__subtitle">🔞 Sexual</div> <table class="wiki-table"> <tr><th>Skill</th><th>Level</th><th>XP</th></tr> <<for _sn range ["oral", "vaginal", "anal", "handjob", "stamina", "flexibility", "dirtyTalk", "deepThroat"]>> <<set _sk = $skills[_sn]>> <tr><td><<print _sk.icon>> <<print _sk.name>></td><td><<print _sk.level>></td><td><<print _sk.xp>>/<<print _sk.xpNext>></td></tr> <</for>> </table> <div class="card__subtitle">📚 Academic</div> <table class="wiki-table"> <tr><th>Skill</th><th>Level</th><th>XP</th></tr> <<for _sn range ["intelligence", "studying"]>> <<set _sk = $skills[_sn]>> <tr><td><<print _sk.icon>> <<print _sk.name>></td><td><<print _sk.level>></td><td><<print _sk.xp>>/<<print _sk.xpNext>></td></tr> <</for>> </table> <div class="card__subtitle">🎭 Social</div> <table class="wiki-table"> <tr><th>Skill</th><th>Level</th><th>XP</th></tr> <<for _sn range ["charm", "persuasion", "composure"]>> <<set _sk = $skills[_sn]>> <tr><td><<print _sk.icon>> <<print _sk.name>></td><td><<print _sk.level>></td><td><<print _sk.xp>>/<<print _sk.xpNext>></td></tr> <</for>> </table> <div class="card__subtitle">🎬 Performance</div> <table class="wiki-table"> <tr><th>Skill</th><th>Level</th><th>XP</th></tr> <<for _sn range ["camSkill", "dance", "cheerleading"]>> <<set _sk = $skills[_sn]>> <tr><td><<print _sk.icon>> <<print _sk.name>></td><td><<print _sk.level>></td><td><<print _sk.xp>>/<<print _sk.xpNext>></td></tr> <</for>> </table> </div> <<link '<span class="choice-btn">← Back</span>' "DormRoom">><</link>>
<<set _denial = $transformation.sideEffects.masturbationDenial || 0>> <<set _anyToy = XCLC.Toys.owned().length > 0>> <<set _wornPlug = XCLC.Toys.worn()>> <h2>🔥 Alone</h2> <p>You shut the door, check it twice out of a habit you did not used to have, and sit down on the edge of the bed.</p> <<if $pc.arousal >= 80>> <p>You are not going to be able to concentrate on anything else until this is dealt with. It has been like a hand on the back of your neck all day.</p> <<elseif _denial > 0>> <p>You already know how this is likely to go. You are going to try anyway.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">⚡ Quick: just take the edge off <em>(fast, modest relief)</em></span>' "DormRoom_MasturbateQuick">> <<advanceTime 20>> <</link>> <<link '<span class="choice-btn">🕯️ Take your time <em>(Solo Performance: pick a toy, edge for a bigger payoff)</em></span>' "Solo_Setup">> <<set $temp.soloShower = false>> <<advanceTime 45>> <</link>> <<if !_anyToy && !_wornPlug>> <p style="opacity:0.6; font-size:0.85em;"><em>You have no toys. After Dark, above the boutique on the high street, sells them.</em></p> <</if>> <<link '<span class="choice-btn">↩️ Never mind</span>' "DormRoom">><</link>> </div>
<<set _denialLevel = $transformation.sideEffects.masturbationDenial || 0>> <<set _hasVibe = XCLC.Toys.hasCat("vibe")>> <<set _hasDildo = XCLC.Toys.hasCat("dildo")>> <<set _hasToy = _hasVibe || _hasDildo>> <p>You lie back and let your hand go where it wants. The strange part is not the wanting, which you recognise perfectly well. It is that the map is different now, and every route on it takes longer and arrives harder than anything you remember.</p> <<if _hasToy>> <p>💗 You get your <<if _hasVibe && _hasDildo>>toys<<elseif _hasVibe>>vibrator<<else>>dildo<</if>> out of the bedside drawer. Your hand is fine. This is not fine, this is a different category of thing entirely.</p> <</if>> <<if $transformation.sideEffects.increasedSensitivity >= 2>> <p>You drag your fingertips across one nipple, barely making contact, and the sound you make is loud enough that you check the door.</p> <</if>> <<if _denialLevel === 0>> /* ── Level 0: Full orgasm ── */ <<set _satisfied = true>> <<if $transformation.sideEffects.orgasmDenial >= 1>> <<set _denyChance = $transformation.sideEffects.orgasmDenial * 20>> <<if random(1,100) <= _denyChance>> <<set _satisfied = false>> <p>You climb, and you keep climbing, and you get right up to the edge of it. Then it simply goes. Steps back out of reach like something that was never there. You try again. You try again after that. Every time, your body closes the door in the last half second.</p> <p>"Come ON!" you hiss. But it won't come. Neither will you.</p> <<modStat "arousal" -10 "Partial relief">> <<modStat "stress" 10 "Orgasm denied">> <<modStat "mood" -10 "Frustration">> <</if>> <</if>> <<if _satisfied>> <p>It builds low and slow, gathering somewhere behind your hips, and then it goes off through your whole body at once. <<if $transformation.sideEffects.strongOrgasms >= 2>> Your back comes off the mattress. Your toes curl hard enough to cramp, and you get a pillow over your face just in time, because the noise you make into it is not one you would want carrying through a dorm wall. For a second or two there is nothing in your head at all. <<modStat "energy" -10 "Overwhelming orgasm">> <</if>> </p> <<if $transformation.sideEffects.squirting >= 1>> <<if random(1,100) <= $transformation.sideEffects.squirting * 20>> <p>💧 You squirt, properly, enough to soak the sheet under you. You lie in the wet patch getting your breath back and decide to be embarrassed about it later.</p> <<modHygiene -10 "Squirting">> <</if>> <</if>> <<set $pc.arousal = 0>> <<modStat "stress" -15 "Post-orgasm relaxation">> <<modStat "mood" 10 "Release">> <<if _hasToy>> <<modStat "stress" -5 "Toy-assisted relief">> <<if _hasDildo>><<addXP "vaginal" 5>><</if>> <<if _hasVibe>><<addXP "stamina" 3>><</if>> <</if>> <p>You lie there afterwards with your heart going, one arm over your eyes, feeling every separate place your body is touching the bed.</p> <</if>> <<elseif _denialLevel === 1>> /* ── Level 1: No orgasm, 20% arousal reduction ── */ <<set _reduction = Math.round($pc.arousal * 0.20)>> <p>Your hand finds its way between your legs. It builds, warm and steady and completely genuine, right up until the point where it flattens out. Every time. The X-Change will take you to the edge all night and it will not let you over it.</p> <p>After several frustrating minutes, you give up. You're less wound up, but not satisfied. Not even close.</p> <<set $pc.arousal = Math.max(0, $pc.arousal - _reduction)>> <<modStat "stress" 5 "Incomplete relief">> <<modStat "mood" -5 "Frustrated">> <<elseif _denialLevel === 2>> /* ── Level 2: No orgasm, 15% arousal reduction ── */ <<set _reduction = Math.round($pc.arousal * 0.15)>> <p>You try. God, you try. Your fingers find every single place that ought to finish this, and none of them do, because the X-Change has put a wall between you and it. You can feel exactly where it is. You cannot get to it.</p> <p>You stop, panting, barely less turned on than when you started. Your body aches with need.</p> <<set $pc.arousal = Math.max(0, $pc.arousal - _reduction)>> <<modStat "stress" 8 "Denial frustration">> <<modStat "mood" -8 "Can't finish">> <<elseif _denialLevel === 3>> /* ── Level 3: No orgasm, 10% arousal reduction ── */ <<set _reduction = Math.round($pc.arousal * 0.10)>> <p>It is close to cruelty. Your body answers everything you do to it, nipples tight, thighs slick, breath coming in pieces, and none of that answering goes anywhere. It is not coming. It is never coming. The X-Change saw to that months ago and you signed for it.</p> <p>You pull your hand away, shaking with frustration. You're barely less aroused than before. This is torture.</p> <<set $pc.arousal = Math.max(0, $pc.arousal - _reduction)>> <<modStat "stress" 12 "Agonising denial">> <<modStat "mood" -10 "Tortured">> <<else>> /* ── Level 4+: No orgasm, 5% arousal reduction ── */ <<set _reduction = Math.round($pc.arousal * 0.05)>> <p>Your hand moves on its own. You know it won't work. It NEVER works. But you can't stop trying. The need is constant, overwhelming, and the X-Change has sealed you shut.</p> <p>Tears of frustration sting your eyes as you give up. You're barely less turned on than when you started. The denial is making you desperate enough to consider... other options.</p> <<set $pc.arousal = Math.max(0, $pc.arousal - _reduction)>> <<modStat "stress" 15 "Complete denial">> <<modStat "mood" -15 "Desperate">> <<modStat "willpower" -3 "Broken down">> <</if>> /* Roommate walk-in check */ <<set _walkIn = XCLC.Roommate.checkWalkIn('masturbate')>> <<if _walkIn.walkedIn>> <div class="card"> <div class="card__title">🚪 Oh no.</div> <p><<print _walkIn.text>></p> </div> <<modStat "confidence" -5 "Caught masturbating">> <<modStat "femininity" 3 "Embarrassment">> <</if>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
<p>You flop onto your bed and <<set _activity = random(1,4)>> <<if _activity === 1>> scroll through social media on your phone. Memes, drama, and an unsettling number of ads that seem to know about your transformation. <<elseif _activity === 2>> watch a show on your laptop. It's mindless but exactly what you need right now. <<elseif _activity === 3>> stare at the ceiling and think about your life. How did you end up here? Taking X-Change pills and living as a girl in a college dorm? <<if $pc.femininity > 40>>Honestly? It's not as bad as you expected. <<else>>It's still surreal. Every single day. <</if>> <<else>> take a short nap. Twenty minutes of blissful unconsciousness. <</if>> </p> <<if $roommate.name && XCLC.Roommate.isHome()>> <<if $roommate.personality === "supportive">> <p><<print $roommate.name>> notices you relaxing. "Want some tea?" she asks, already reaching for the kettle.</p> <<elseif $roommate.personality === "party">> <p>"Booooring," <<print $roommate.name>> says from across the room. "We should go DO something!"</p> <<elseif $roommate.personality === "mean">> <p><<print $roommate.name>> glances at you. "Must be nice to just lie around doing nothing."</p> <</if>> <</if>> <<arousalDrift>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>> /* ═══════════════════════════════════════════════════ STUB LOCATIONS: To be expanded in Phase 3+ ═══════════════════════════════════════════════════ */
<<run XCLC.Service.checkForNewRequest()>> <h2>📖 Library</h2> <div class="choice-group"><<whoIsAround>></div> <p>It's <<showTime>>. The Thornfield library is a grand old pile of a building: three floors of books, study carrels, and corners nobody has looked into since the seventies. <<if $world.time >= 420 && $world.time < 720>>Morning sunlight streams through the tall windows. It's quiet, just a few early studiers.<<elseif $world.time >= 720 && $world.time < 1080>>The library is comfortably busy. Students scattered across tables, the soft tap of keyboards.<<elseif $world.time >= 1080 && $world.time < 1380>>The evening crowd is settling in for study sessions. Every table has at least one occupant.<<else>>The library is nearly empty at this hour. Just you and the night owls.<</if>></p> <<if $scholarship.activeRequest>> <<set _req = $scholarship.activeRequest>> <<set _elapsed = $world.time - _req.createdAt>> <<set _remaining = 30 - _elapsed>> <div class="alert alert--info">📱 <strong>CampusHub Request!</strong> <<print _req.npc.firstName>> wants <<print _req.serviceType>> at <<print _req.locationName>>. (<<print _remaining>> min remaining)</div> <div class="choice-group"> <<link '<span class="choice-btn">✅ Accept request</span>' `($scholarship.activeRequest && $scholarship.activeRequest.isGroup) ? "GroupMeet" : "ServiceMeet"`>> <<run XCLC.Service.acceptRequest()>> <<advanceTime 10>> <</link>> </div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">📚 Quiet Study (1 hour): Intelligence XP</span>' "LibraryStudy">> <<set $temp.studyType = "quiet">> <</link>> <<link '<span class="choice-btn">👥 Group Study (1 hour): Intelligence + Charm XP</span>' "LibraryStudy">> <<set $temp.studyType = "group">> <</link>> <<link '<span class="choice-btn">🔬 Research (1 hour): boost next exam</span>' "LibraryStudy">> <<set $temp.studyType = "research">> <</link>> /* ─── Glory Hole (library bathroom) ─── */ <<if !$gloryHole.libraryDiscovered && $world.week >= 3 && random(1, 3) === 1>> <<link '<span class="choice-btn">🚻 Use the bathroom</span>' "GloryHole_LibraryDiscover">><</link>> <<elseif $gloryHole.libraryDiscovered>> <<link '<span class="choice-btn">🚻 Library bathroom...</span>' "GloryHole_Library">><</link>> <</if>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<<set _type = $temp.studyType>> <<set _se = $transformation.sideEffects>> <<if _type === "quiet">> <h2>📚 Quiet Study</h2> <p>You find an empty carrel on the third floor, spread out your notes, and get to work. The silence is almost meditative.</p> <<if _se.bimbofication >= 2>> <p>The words on the page keep blurring. You read the same paragraph three times. Anything with more than two moving parts slides straight out of your hands. You end up colour-coding the whole chapter with highlighters, which helps about as much as you would expect.</p> <<set _intXP = Math.max(5, 25 - _se.bimbofication * 5)>> <<else>> <<set _intXP = 25>> <</if>> <<advanceTime 60>> <<addXP "studying" _intXP>> <<addXP "intelligence" 15>> <<modStat "energy" -10 "Studying">> <<modRep "goodStudent" 2 "Library study">> <<elseif _type === "group">> <h2>👥 Group Study</h2> <p>You join a study group at one of the long tables. Four of them, two guys and two girls, shuffle their books along to make you a space.</p> <<if _se.pheromones >= 2>> <p>Within ten minutes, both guys have shifted their chairs closer. One of them keeps "accidentally" touching your arm. You try to focus on the material but your pheromones are making it difficult for everyone.</p> <<modStat "arousal" 5 "Pheromone attention">> <</if>> <<advanceTime 60>> <<addXP "studying" 20>> <<addXP "intelligence" 10>> <<addXP "charm" 10>> <<modStat "energy" -10 "Studying">> <<modStat "mood" 3 "Social studying">> <<modRep "goodStudent" 2 "Library study">> <<else>> <h2>🔬 Research</h2> <p>You dig into the stacks, pulling reference books for your upcoming classes. It's dry, dense material, but it'll help on the next exam.</p> <<advanceTime 60>> <<addXP "studying" 15>> <<modStat "energy" -15 "Intensive research">> <<modRep "goodStudent" 3 "Library research">> <<if $academic>><<set $academic.researchBonus = ($academic.researchBonus || 0) + 1>><</if>> <</if>> /* Common effects */ <<run XCLC.Toast.show('📚 Studied! +' + (_type === 'quiet' ? '25' : (_type === 'group' ? '20' : '15')) + ' study XP', 'success')>> /* Random event check (15% chance) */ <<if random(1, 100) <= 15>> <<set _libEvent = random(1, 4)>> <<if _libEvent === 1 && _se.bimbofication >= 2>> <p>You catch yourself doodling hearts in the margins of your textbook instead of taking notes. When did you become this person?</p> <<modStat "femininity" 1 "Doodling hearts">> <<elseif _libEvent === 2>> <<set _studyNpc = XCLC.NPC.generate('student')>> <p>A <<print _studyNpc.bodyType>> <<if _studyNpc.gender === "male">>guy<<else>>girl<</if>> with <<print _studyNpc.hairColour>> hair sits down next to you. "Hey. You're in <<if $academic && $academic.classes && $academic.classes.length > 0>><<print $academic.classes[0].name>><<else>>Professor Chen's class<</if>>, right? I'm <<print _studyNpc.firstName>>. Can I park here?"</p> <<modStat "mood" 3 "Social interaction">> <<elseif _libEvent === 3 && $pc.energy < 40>> <p>Your head drops. You come round with no idea how long you were gone and the ghost of a paragraph pressed into your cheek. The student opposite is trying very hard not to laugh and failing at it.</p> <<modStat "energy" 5 "Power nap">> <<modStat "confidence" -2 "Fell asleep in public">> <<else>> <p>You lose yourself in the material. When you look up, an hour has passed without you noticing. That's either dedication or dissociation.</p> <</if>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">📚 Study more</span>' "Library">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<<run XCLC.Service.checkForNewRequest()>> <h2>🍽️ Cafeteria</h2> <<set _mealTime = "closed">> <<if $world.time >= 420 && $world.time < 600>><<set _mealTime = "breakfast">> <<elseif $world.time >= 600 && $world.time < 720>><<set _mealTime = "brunch">> <<elseif $world.time >= 720 && $world.time < 900>><<set _mealTime = "quiet">> <<elseif $world.time >= 900 && $world.time < 1020>><<set _mealTime = "lunch">> <<elseif $world.time >= 1020 && $world.time < 1200>><<set _mealTime = "dinner">> <<elseif $world.time >= 1200 && $world.time < 1380>><<set _mealTime = "late">> <</if>> <p>It's <<showTime>>. <<if _mealTime === "breakfast">>The cafeteria smells like coffee and toast. A few bleary-eyed students shuffle through the breakfast line.<<elseif _mealTime === "brunch">>The breakfast rush has passed. A few late risers pick at cereal and fruit.<<elseif _mealTime === "lunch">>The lunch crowd is here in force. Every table is taken, the noise level is substantial, and the food line stretches to the door.<<elseif _mealTime === "dinner">>Dinner service. The cafeteria is warm and bustling, the smell of hot food filling the air.<<elseif _mealTime === "late">>The cafeteria is winding down. A few students nurse coffee over textbooks.<<elseif _mealTime === "quiet">>The cafeteria is between meals. Vending machines and leftover pastries only.<<else>>The cafeteria is closed. Lights off, chairs stacked on tables.<</if>></p> <<if $scholarship.activeRequest>> <<set _req = $scholarship.activeRequest>> <<set _elapsed = $world.time - _req.createdAt>> <<set _remaining = 30 - _elapsed>> <div class="alert alert--info">📱 <strong>CampusHub Request!</strong> <<print _req.npc.firstName>> wants <<print _req.serviceType>> at <<print _req.locationName>>. (<<print _remaining>> min remaining)</div> <div class="choice-group"> <<link '<span class="choice-btn">✅ Accept request</span>' `($scholarship.activeRequest && $scholarship.activeRequest.isGroup) ? "GroupMeet" : "ServiceMeet"`>> <<run XCLC.Service.acceptRequest()>> <<advanceTime 10>> <</link>> </div> <</if>> <<if _mealTime !== "closed">> <div class="choice-group"><<whoIsAround>></div> <</if>> <<if _mealTime === "closed" || _mealTime === "quiet">> <p><em><<if _mealTime === "closed">>The kitchen is closed. Come back during meal hours.<<else>>Between meals, so it is snacks or nothing.<</if>></em></p> <<if _mealTime === "quiet">> <div class="choice-group"> <<link '<span class="choice-btn">🍫 Grab a snack from the vending machine</span>' "Cafeteria">> <<advanceTime 5>> <<modStat "energy" 5 "Vending machine snack">> <</link>> <<link '<span class="choice-btn">☕ Get coffee</span>' "Cafeteria">> <<advanceTime 5>> <<modStat "energy" 10 "Coffee">> <<modStat "stress" -3 "Caffeine">> <</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div> <</if>> <<else>> <div class="choice-group"> <<if _mealTime === "breakfast" || _mealTime === "brunch">> <<link '<span class="choice-btn">🥞 Full breakfast (30 min)</span>' "CafeteriaEat">> <<set $temp.mealType = "full">> <<set $temp.mealName = "breakfast">> <</link>> <<link '<span class="choice-btn">☕ Just coffee and toast (10 min)</span>' "CafeteriaEat">> <<set $temp.mealType = "quick">> <<set $temp.mealName = "coffee">> <</link>> <<elseif _mealTime === "lunch">> <<link '<span class="choice-btn">🍔 Full lunch (30 min)</span>' "CafeteriaEat">> <<set $temp.mealType = "full">> <<set $temp.mealName = "lunch">> <</link>> <<link '<span class="choice-btn">🥗 Salad (15 min)</span>' "CafeteriaEat">> <<set $temp.mealType = "light">> <<set $temp.mealName = "salad">> <</link>> <<else>> <<link '<span class="choice-btn">🍝 Full dinner (30 min)</span>' "CafeteriaEat">> <<set $temp.mealType = "full">> <<set $temp.mealName = "dinner">> <</link>> <<link '<span class="choice-btn">🥗 Light meal (15 min)</span>' "CafeteriaEat">> <<set $temp.mealType = "light">> <<set $temp.mealName = "light meal">> <</link>> <</if>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div> <</if>>
/* Defaults so a stale link or reloaded save cannot throw */ <<set _type = $temp.mealType || "standard">> <<set _name = $temp.mealName || "lunch">> <<set _se = $transformation.sideEffects>> <h2>🍽️ <<print _name.charAt(0).toUpperCase()>><<print _name.slice(1)>></h2> /* ─── Morning sickness (pregnancy weeks 3-13) ─── */ <<if $pregnancy.isPregnant && $pregnancy.weeksPregnant >= 3 && $pregnancy.weeksPregnant <= 13 && random(1, 100) <= 35>> <p>You get two bites in before your stomach turns over. It is the smell that does it, not just yours but everybody's, the whole room's worth arriving at once.</p> <p>🤢 You barely make it to the bathroom. A few students watch you sprint past. When you emerge ten minutes later, pale and shaky, your appetite is gone and your tray has been cleared.</p> <<advanceTime 20>> <<modStat "energy" -5 "Couldn't keep food down">> <<modStat "stress" 5 "Morning sickness">> <<if !$pregnancy.discovered>> <p><em>Third time this week. Either something is wrong with you or something is very specifically right. You should take a test.</em></p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">😮💨 Give up on eating</span>' "CampusMap">><</link>> <<link '<span class="choice-btn">🍽️ Try again with something plain</span>' "Cafeteria">> <<modStat "energy" 5 "Crackers and water">> <</link>> </div> <<else>> <<if _type === "full">> <p>You load up a tray and find a seat. The food isn't gourmet, but it's hot and filling. You eat steadily, people-watching between bites.</p> <<advanceTime 30>> <<modStat "energy" 20 "Full meal">> <<modStat "mood" 5 "Good food">> <<elseif _type === "light">> <p>You grab a light plate and eat quickly, keeping an eye on the time.</p> <<advanceTime 15>> <<modStat "energy" 10 "Light meal">> <<modStat "mood" 3 "Ate something">> <<else>> <p>You grab coffee and a piece of toast, inhaling both at the counter. It's not a meal, but it'll do.</p> <<advanceTime 10>> <<modStat "energy" 8 "Quick bite">> <</if>> /* SE interactions */ <<if _se.bimbofication >= 3>> <p>You stare at the food on your tray. Are these calories going to make you fat? The thought arrives unbidden and unwelcome. You push the plate away half-finished, then pull it back. Then push it away again. God, when did eating get so complicated?</p> <<modStat "stress" 3 "Food anxiety">> <</if>> <<if _se.pheromones >= 2 && (_type === "full" || _type === "light")>> <p>You notice the table of guys two rows over has been staring at you since you sat down. One of them elbows his friend and nods in your direction. Your pheromones, carrying on the cafeteria air. You eat faster.</p> <<modStat "arousal" 3 "Attention in cafeteria">> <</if>> /* Random social event (20% chance) */ <<if random(1,100) <= 20>> <<set _cafeEvent = random(1,3)>> <<if _cafeEvent === 1>> <<set _cafeNPC = XCLC.NPC.generate('student')>> <p>"This seat taken?" A <<print _cafeNPC.bodyType>> <<if _cafeNPC.gender === "male">>guy<<else>>girl<</if>> with <<print _cafeNPC.hairColour>> hair sits down across from you without waiting for an answer. "<<print _cafeNPC.firstName>>. You're in the programme, right?"</p> <p>You talk through the rest of the meal and it is almost completely normal, provided neither of you says out loud what "the programme" involves.</p> <<modStat "mood" 5 "Social meal">> <<elseif _cafeEvent === 2 && _se.lactation >= 2>> <p>Mid-bite you feel it start: the warm prickling tightness, the pressure of milk with nowhere to go. You cross your arms over your <<print $pc.breastSize>>-cups and pray nothing shows through your shirt. <<if $pc.breastSize === "D" || $pc.breastSize === "DD">>It shows through your shirt.<</if>></p> <<modStat "stress" 3 "Lactation in public">> <<else>> <p>The table behind you is gossiping. "Did you hear about the CCUMDUP girl?" Then somebody kicks somebody, and the whole table goes quiet at once. You keep eating and pretend you have gone deaf.</p> <<modStat "mood" -3 "Gossip">> <</if>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🍽️ Eat more</span>' "Cafeteria">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div> <</if>>
<h2>🏛️ Admin Building</h2> <p>It's <<showTime>>. The admin building houses the Dean's office, registrar, and the Campus Health Centre.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏥 Health Centre</span>' "HealthCentre">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>🏥 Campus Health Centre</h2> <p>The health centre is clean, quiet, and mercifully private. A nurse in scrubs looks up from her desk.</p> <p>"Hi there. <<print $pc.femaleFirstName>>, right? What can we help with today?"</p> <<if $pregnancy && $pregnancy.riskFlag>> <div class="alert alert--warning">⚠️ You have an outstanding pregnancy risk. You should get tested.</div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔬 STD Test (Free, 30 min)</span>' "HealthService">> <<set $temp.healthService = "std_test">> <</link>> <<link '<span class="choice-btn">🤰 Pregnancy Test (Free, 15 min)</span>' "HealthService">> <<set $temp.healthService = "pregnancy_test">> <</link>> <<if $pregnancy.isPregnant && $pregnancy.discovered>> <<link '<span class="choice-btn">🩻 Prenatal Check-Up & Ultrasound (Free, 45 min)</span>' "HealthService">> <<set $temp.healthService = "prenatal">> <</link>> <<link '<span class="choice-btn">🗓️ Birth plan<<if $pregnancy.birthPlan>>: currently <<print $pregnancy.birthPlan>><<else>>: not yet decided<</if>></span>' "PregnancyBirthPlan">><</link>> <</if>> <<link '<span class="choice-btn">💊 Morning-After Pill ($25)</span>' "HealthService">> <<set $temp.healthService = "morning_after">> <</link>> <<link '<span class="choice-btn">🧠 Therapy Session ($30, 1 hour)</span>' "HealthService">> <<set $temp.healthService = "therapy">> <</link>> <<link '<span class="choice-btn">💊 Birth Control Prescription ($15/month)</span>' "HealthService">> <<set $temp.healthService = "birth_control">> <</link>> <<if !$inventory.hasIUD>> <<link '<span class="choice-btn">⚕️ IUD Insertion ($150, long-term)</span>' "HealthService">> <<set $temp.healthService = "iud">> <</link>> <<else>> <<link '<span class="choice-btn">⚕️ IUD Removal ($25)</span>' "HealthService">> <<set $temp.healthService = "iud_remove">> <</link>> <</if>> <<link '<span class="choice-btn">🩺 General Check-Up (Free, 30 min)</span>' "HealthService">> <<set $temp.healthService = "checkup">> <</link>> <<link '<span class="choice-btn">🩹 Injury Treatment ($20)</span>' "HealthService">> <<set $temp.healthService = "injury">> <</link>> <<link '<span class="choice-btn">⚗️ X-Change Adjustment (1 per semester)</span>' "HealthService">> <<set $temp.healthService = "xchange_adjust">> <</link>> /* ─── Dr. Crane: investigation storyline ─── */ <<if !$hypnosis.discovered>> <<link '<span class="choice-btn">📋 Notice Board: Stress Management Sessions</span>' "Hypnosis_Discover">><</link>> <<elseif !$hypnosis.resolved>> <<if ($world.day - $hypnosis.lastSessionDay >= 7 || $hypnosis.sessionsAttended === 0)>> <<link '<span class="choice-btn">🌀 Dr. Crane: Relaxation Session</span>' "Hypnosis_Session">><</link>> <</if>> <<if $hypnosis.suspicious>> <<link '<span class="choice-btn">🔍 Dr. Crane: keep building your file</span>' "Crane_Investigate">><</link>> <</if>> <<elseif $hypnosis.lingering>> <<link '<span class="choice-btn">🏥 Screening for lingering suggestion (free)</span>' "Crane_Deprogram">><</link>> <</if>> <<link '<span class="choice-btn">← Back</span>' "AdminBuilding">><</link>> </div>
<<set _service = $temp.healthService>> <<if _service === "std_test">> <h2>🔬 STD Test</h2> <<if $transformation.addons.stdProtection>> <p>The nurse checks your file. "You have the STD Protection add-on. You're immune to sexually transmitted infections. No test needed."</p> <p>She pauses. "Must be nice."</p> <<else>> <p>The nurse takes a swab and draws a small blood sample. "Results in a few minutes."</p> <<advanceTime 30>> <<if $health && $health.hasSTD>> <<set _std = XCLC.STD.def($health.stdType)>> <<set _stdDays = $world.day - ($health.stdDay || $world.day)>> <p>"I'm sorry. The test came back positive for <<print _std.name>>. It's treatable, and we'll treat it today, but I do need you to be more careful than you have been."</p> <<if !$health.stdSymptomatic && $health.stdSilent>> <p>"And before you ask: no, you wouldn't necessarily have known. This one stays quiet in a lot of people. That is exactly why we test."</p> <<elseif !$health.stdSymptomatic>> <p>"You caught this before it had anything to say for itself. Coming in on a hunch was the right call."</p> <</if>> <<if $health.stdComplication === "fertility">> <div class="alert alert--danger">🦠 Untreated for <<print _stdDays>> days. There is scarring. It will not undo itself, and your fertility has taken a permanent step down.</div> <<elseif $health.stdComplication === "health">> <div class="alert alert--danger">🔥 Untreated for <<print _stdDays>> days. It has spread beyond where it started and taken a real bite out of your health.</div> <</if>> <div class="alert alert--warning"><<print _std.icon>> <strong><<print _std.name>></strong>. <<print _std.blurb>> Treatment costs $<<print _std.treatment>>.</div> <<if $finance.money >= _std.treatment>> <<set _stdCost = _std.treatment>> <<link '<span class="choice-btn">💊 Get treatment ($<<print _std.treatment>>)</span>' "HealthCentre">> <<set $finance.money -= _stdCost>> <<run XCLC.STD.cure()>> <<run XCLC.Toast.show('🏥 Treated. You are clean.', 'success')>> <</link>> <<else>> <p><em>You can't afford treatment today. Come back with $<<print _std.treatment>>, because this will not clear up on its own and it does not get cheaper.</em></p> <</if>> <<else>> <p>"All clear. No infections detected." She smiles. "Keep being safe out there."</p> <</if>> <</if>> <<elseif _service === "pregnancy_test">> <h2>🤰 Pregnancy Test</h2> <p>The nurse hands you a cup. Fifteen minutes later, she returns with results.</p> <<advanceTime 15>> <<if $pregnancy && $pregnancy.isPregnant>> <p>Her face is carefully neutral. "The test is positive. You're pregnant."</p> <p>The word hangs in the air. Pregnant. You. In a body you've had for <<print $world.day>> days.</p> <<set $pregnancy.confirmed = true>> <<set $pregnancy.discovered = true>> <<set $pregnancy.confirmedDay = $world.day>> <<set $pregnancy.riskFlag = false>> <<modStat "stress" 20 "Pregnancy confirmed">> <div class="alert alert--warning">🤰 You are pregnant. You can terminate at this clinic ($200) within the first 12 weeks.</div> <<if $pregnancy.weeksPregnant <= 12 && $finance.money >= 200>> <<link '<span class="choice-btn">💊 Terminate pregnancy ($200)</span>' "HealthCentre">> <<set $finance.money -= 200>> <<set $pregnancy.isPregnant = false>> <<set $pregnancy.weeksPregnant = 0>> <<set $pregnancy.confirmed = false>> <<set $pregnancy.discovered = false>> <<set $pregnancy.terminated = true>> <<set $pregnancy.riskDay = 0>> <<run ($pregnancy.decisions = $pregnancy.decisions || []).push("abort")>> <<modStat "stress" -10 "Pregnancy terminated">> <<modStat "mood" -10 "Emotional impact">> <<run XCLC.Toast.show('🏥 Procedure complete.', 'info')>> <</link>> <</if>> <<else>> <p>"Negative. You're not pregnant." You let out a breath you didn't know you were holding.</p> <<set $pregnancy.riskFlag = false>> <<modStat "stress" -5 "Not pregnant - relief">> <</if>> <<elseif _service === "prenatal">> <h2>🩻 Prenatal Check-Up</h2> <<advanceTime 45>> <<if !$pregnancy.isPregnant>> <p>"There's no active pregnancy in your file," the nurse says gently. "No check-up needed."</p> <<else>> <<set _pw = $pregnancy.weeksPregnant>> <p>The nurse takes your blood pressure, weighs you, and asks about symptoms. Then she wheels over the ultrasound cart. "Let's have a look at you. The gel is cold and I have never once managed to warm it properly."</p> <p>The wand glides over your belly. The screen resolves into shifting grey static... and then a shape.</p> <div class="card"> <div class="card__title">🩻 Ultrasound: Week <<print _pw>></div> <<if _pw < 8>> <p>"Still very early. Everything is exactly where it ought to be. Come back in a few weeks and we'll get you a heartbeat."</p> <<else>> <p>💓 A rapid, watery thumping fills the room. <strong>A heartbeat.</strong> <<toneThink "That's... real. That's a real heartbeat." "Oh. Oh wow." "That's my baby!! 🥹">></p> <<if $pregnancy.babyCount === 2 && _pw >= 12>> <p>The nurse goes quiet. She moves the wand an inch, holds it, and then her whole face changes. "Well. There are <strong>two</strong> heartbeats in there. Congratulations. It's twins."</p> <<toneThink "Two. No. No no no." "Twins. Two of them. How am I supposed to do this twice over." "TWO BABIES?! Okay wow okay!! 😭💕">> <<elseif _pw >= 12>> <p>"One healthy baby, developing right on schedule."</p> <</if>> <<if _pw >= 20>> <p>"Would you like to know the sex?" You nod before you can think about it. <<if $pregnancy.babyCount === 2>>"Baby A is a <strong><<print $pregnancy.babyGenders[0]>></strong>... and Baby B is a <strong><<print $pregnancy.babyGenders[1]>></strong>."<<else>>"It's a <strong><<print $pregnancy.babyGenders[0]>></strong>."<</if>></p> <</if>> <</if>> <p><strong>Progress:</strong> Week <<print _pw>> of 36, due in roughly <<print Math.max(0, 36 - _pw)>> weeks<<if _pw >= 24>> (<<print XCLC.Time.monthName((($world.month - 1 + Math.ceil(Math.max(0, 36 - _pw) / 4)) % 12) + 1)>>)<</if>>.</p> <<if _pw >= 4 && _pw <= 13>> <p><strong>Symptoms:</strong> Morning sickness is normal at this stage. It should ease after week 13. Keep crackers by the bed.</p> <<elseif _pw >= 28>> <p><strong>Notes:</strong> Third trimester. Expect fatigue, backache, and increasingly personal questions from strangers.</p> <</if>> </div> <p>She wipes the gel off your stomach with a paper towel and hands you a printout. It is a grainy grey smudge and it is now, without any argument, the most important photograph you own. <<if $temp.pregnancyPlan === "adopt">>You look at it for a long time.<</if>></p> <<modStat "stress" -5 "Reassurance">> <<modStat "mood" 5 "Sonogram photo">> <</if>> <<elseif _service === "morning_after">> <h2>💊 Morning-After Pill</h2> <<if $finance.money < 25>> <p>"I'm sorry, that'll be $25." The nurse checks your file. "Your account doesn't have sufficient funds."</p> <<else>> <<if $pregnancy && $pregnancy.riskFlag && ($world.day - $pregnancy.riskDay) <= 2>> <p>The nurse hands you a pill and a glass of water. "Take it now. This works best within 48 hours of exposure."</p> <p>You swallow it. Relief washes over you. It's done.</p> <<set $finance.money -= 25>> <<set $pregnancy.riskFlag = false>> /* Undo a conception from this risk window (not yet discovered) */ <<if $pregnancy.isPregnant && !$pregnancy.discovered && $pregnancy.weeksPregnant === 0>> <<set $pregnancy.isPregnant = false>> <<set $pregnancy.totalPregnancies = Math.max(0, $pregnancy.totalPregnancies - 1)>> <</if>> <<modStat "stress" -10 "Morning-after pill">> <<run XCLC.Toast.show('💊 Morning-after pill taken. Risk cleared.', 'success')>> <<elseif $pregnancy && $pregnancy.riskFlag>> <p>"It's been more than 48 hours since exposure. The morning-after pill won't be effective. I'd recommend a pregnancy test instead."</p> <<else>> <p>"There's no current pregnancy risk in your file. You don't need this right now. Come back if you do."</p> <</if>> <</if>> <<elseif _service === "therapy">> <h2>🧠 Therapy Session</h2> <<if $finance.money < 30>> <p>"Sessions are $30. We can set up a payment plan if needed..." The nurse trails off sympathetically.</p> <<else>> <<set $finance.money -= 30>> <<advanceTime 60>> <p>You sit in a comfortable chair across from Dr. Park, the campus therapist. She has kind eyes and doesn't judge.</p> <p>"How are you adjusting to the programme?" she asks. "To... all of it?"</p> <p>You talk. About the body. About the expectations. About how some days you look in the mirror and don't recognize yourself, and other days you do and that's worse.</p> <p>Dr. Park listens. She doesn't have answers, but somehow you feel lighter when the hour is up.</p> <<modStat "stress" -25 "Therapy session">> <<modStat "mood" 15 "Talking to someone">> <<modStat "willpower" 10 "Therapy insight">> <<run XCLC.Toast.show('🧠 Therapy: Stress -25, Mood +15, Willpower +10', 'success')>> <</if>> <<elseif _service === "birth_control">> <h2>💊 Birth Control</h2> <<if $transformation.addons.birthControl>> <p>"You've already got the Birth Control add-on running. No prescription needed, you're covered."</p> <<elseif $finance.money < 15>> <p>"A monthly prescription is $15. Unfortunately, your funds are insufficient."</p> <<else>> <p>The nurse writes a prescription. "Take one pill daily. If you miss a day, you're not protected that day. Come back monthly for refills."</p> <<set $finance.money -= 15>> <<set $health.birthControlActive = true>> <<set $health.birthControlDays = 30>> <<run XCLC.Toast.show('💊 Birth control prescription: 30 days.', 'success')>> <</if>> <<elseif _service === "iud">> <h2>⚕️ IUD Insertion</h2> <<if $transformation.addons.birthControl>> <p>"You've already got the Birth Control add-on running. An IUD would be doing a job that's already done. Save your money."</p> <<elseif $finance.money < 150>> <p>"The insertion procedure is $150. Unfortunately, your account doesn't cover it."</p> <<else>> <p>The nurse walks you through it: a small T-shaped device, a few minutes of discomfort, and years of protection. "Ready?"</p> <p>It is quick and it is not pleasant. One deep cramp that folds you forward, a breath through your teeth, and it's in. "You'll cramp for a day or two. After that you're covered until somebody takes it out."</p> <<set $finance.money -= 150>> <<set $inventory.hasIUD = true>> <<advanceTime 45>> <<modStat "stress" 5 "Uncomfortable procedure">> <<modStat "health" -3 "Cramping">> <<run XCLC.Toast.show('⚕️ IUD inserted. Long-term pregnancy protection active.', 'success')>> <</if>> <<elseif _service === "iud_remove">> <h2>⚕️ IUD Removal</h2> <<if $finance.money < 25>> <p>"Removal is $25. Your account is short."</p> <<else>> <p>Removal is much faster than fitting it was. One short tug, a breath you had not noticed you were holding, and it's out.</p> <p>"You're no longer protected," the nurse reminds you, meeting your eyes. "Be careful out there."</p> <<set $finance.money -= 25>> <<set $inventory.hasIUD = false>> <<advanceTime 20>> <<run XCLC.Toast.show('⚕️ IUD removed. You are no longer protected.', 'warning')>> <</if>> <<elseif _service === "checkup">> <h2>🩺 General Check-Up</h2> <<advanceTime 30>> <p>The nurse takes your vitals, checks your file, and runs through a standard health assessment.</p> <div class="card"> <div class="card__title">📋 Health Report</div> <p><strong>Health:</strong> <<print $pc.health>>/100</p> <p><strong>Energy:</strong> <<print $pc.energy>>/100</p> <p><strong>Stress:</strong> <<print $pc.stress>>/100</p> <p><strong>Hygiene:</strong> <<print $hygiene.cleanliness>>/100</p> <p><strong>Breast Size:</strong> <<print $pc.breastSize>>-cup</p> <p><strong>Active Add-ons:</strong> <<if $transformation.addons.birthControl>>Birth Control, <</if>><<if $transformation.addons.stdProtection>>STD Protection, <</if>><<if $transformation.addons.wet>>Wet, <</if>><<if $transformation.addons.noHair>>No Body Hair<</if>></p> <p><strong>Contraception:</strong> <<if $transformation.addons.birthControl>>💊 X-Change add-on (permanent)<<elseif $inventory.hasIUD>>⚕️ IUD<<elseif $health.birthControlActive>>💊 Prescription (<<print $health.birthControlDays>> days left)<<elseif $inventory.onPill>>💊 Pill<<else>>None<</if>></p> <<oldNameNote>> <p><strong>STD Status:</strong> <<if $health.hasSTD && $health.stdSymptomatic>>🦠 Symptomatic: get tested and treated<<elseif $health.hasSTD>>🦠 Infection detected: treatable ($50)<<else>>✅ Clean<</if>></p> <<if !$transformation.addons.noPeriod>> <p><strong>Cycle:</strong> <<if $pregnancy.isPregnant>>Paused (pregnancy)<<elseif $health.cycleDay <= 4>>🩸 Period (day <<print $health.cycleDay>> of 4)<<else>>Day <<print $health.cycleDay>> of 28<</if>></p> <</if>> <p><strong>Pregnancy Risk:</strong> <<if $pregnancy && $pregnancy.isPregnant && $pregnancy.discovered>>🤰 Confirmed (week <<print $pregnancy.weeksPregnant>>)<<elseif $pregnancy && $pregnancy.riskFlag>>⚠️ Possible<<else>>None<</if>></p> </div> <p>"Everything looks normal for someone in the programme," the nurse says. "Well, as normal as it gets."</p> <<elseif _service === "injury">> <h2>🩹 Injury Treatment</h2> <<if $finance.money < 20>> <p>"Treatment is $20. Your account is a bit short."</p> <<elseif $pc.health >= 90>> <p>The nurse checks you over. "You seem fine. No injuries I can see. Come back if something hurts."</p> <<else>> <p>The nurse patches you up with brisk, unsentimental competence. Disinfectant, bandages, an ice pack she tells you to hold there and clearly means it.</p> <<set $finance.money -= 20>> <<set $pc.health = Math.min(100, $pc.health + 30)>> <<run XCLC.Toast.show('🩹 Injuries treated. Health +30.', 'success')>> <</if>> <<elseif _service === "xchange_adjust">> <h2>⚗️ X-Change Dosage Adjustment</h2> <<if $health && $health.adjustedThisSemester>> <p>"We can only do one X-Change adjustment per semester. You've already had yours. Come back next semester."</p> <<else>> <p>The nurse pulls up your transformation profile. "I can shift one side effect by a single level, up or down. Which one?"</p> <p><em>Choose a side effect to modify:</em></p> <<set _seList = Object.keys($transformation.sideEffects)>> <div class="choice-group"> <<for _i = 0; _i < _seList.length; _i++>> <<set _seName = _seList[_i]>> <<set _seVal = $transformation.sideEffects[_seName]>> <<if _seVal > 0>> <<capture _seName, _seVal>> <<link '<span class="choice-btn"><<print _seName>>: <<print _seVal>> → <<print Math.max(0, _seVal - 1)>> (decrease)</span>' "HealthCentre">> <<set $transformation.sideEffects[_seName] = Math.max(0, _seVal - 1)>> <<set $health.adjustedThisSemester = true>> <<run XCLC.Toast.show('⚗️ ' + _seName + ' reduced to ' + ($transformation.sideEffects[_seName]), 'success')>> <</link>> <</capture>> <</if>> <</for>> <<link '<span class="choice-btn">← Changed my mind</span>' "HealthCentre">><</link>> </div> <</if>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🏥 Other services</span>' "HealthCentre">><</link>> <<link '<span class="choice-btn">← Back</span>' "AdminBuilding">><</link>> </div> /* StudentCenter and GreekRow moved to 14_social.twee */
<<run XCLC.Service.checkForNewRequest()>> <h2>🚻 Campus Bathrooms</h2> <p>It's <<showTime>>. The communal bathrooms near the quad. Fluorescent lights, cracked tile, the faint smell of pine cleaner losing its battle against… everything else.</p> <p>There are three stalls. Two are ordinary. The third, in the back corner, has a hole cut through the partition wall at roughly waist height. Someone's written "CCUMDUP SERVICE STATION" above it in sharpie. Below that, in different handwriting: "$20."</p> <<if $scholarship.activeRequest>> <<set _req = $scholarship.activeRequest>> <<set _elapsed = $world.time - _req.createdAt>> <<set _remaining = 30 - _elapsed>> <div class="alert alert--info">📱 <strong>CampusHub Request!</strong> <<print _req.npc.firstName>> wants <<print _req.serviceType>> at <<print _req.locationName>>. (<<print _remaining>> min remaining)</div> <div class="choice-group"> <<link '<span class="choice-btn">✅ Accept request</span>' `($scholarship.activeRequest && $scholarship.activeRequest.isGroup) ? "GroupMeet" : "ServiceMeet"`>> <<run XCLC.Service.acceptRequest()>> <<advanceTime 10>> <</link>> </div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Freshen up at the sink (10 min)</span>' "BathroomFreshenUp">><</link>> <<if $pc.makeupApplied>> <<link '<span class="choice-btn">💄 Fix your makeup</span>' "BathroomMakeup">><</link>> <</if>> <<link '<span class="choice-btn">🕳️ The glory hole... ($20)</span>' "GloryHoleIntro">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>🚿 Freshen Up</h2> <p>You splash water on your face, wash your hands, and try to make yourself look presentable in the scratched bathroom mirror. It's not a shower, but it'll do.</p> <<advanceTime 10>> <<modHygiene 15 "Freshened up">> <<if $transformation.sideEffects.lactation >= 2>> <p>You take the opportunity to express some milk into the sink. The relief is immediate. You pray nobody walks in.</p> <</if>> <<run XCLC.Toast.show('🚿 Freshened up! Hygiene +15', 'success')>> <div class="choice-group"> <<link '<span class="choice-btn">🚻 Back to bathrooms</span>' "CampusBathrooms">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>💄 Fix Makeup</h2> <p>You lean close to the mirror and fix the smudges. A little water, some careful blending, and you look passable again. Not great, but passable.</p> <<advanceTime 5>> <<run XCLC.Toast.show('💄 Makeup touched up.', 'success')>> <div class="choice-group"> <<link '<span class="choice-btn">🚻 Back to bathrooms</span>' "CampusBathrooms">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<<set _se = $transformation.sideEffects>> <h2>🕳️ The Last Stall</h2> <p>You stand in front of the last stall. The hole is unmistakable, cut rough and worn smooth at the edges since. There's a price list on the wall in sharpie.</p> <div class="card"> <div class="card__title">💰 Price List</div> <p>👄 Oral · $20</p> <p>🍑 Vaginal · $35</p> <p>🔥 Anal · $50</p> </div> <p>Cash left on the toilet tank. Anonymous. No CampusHub, no ratings, no record.</p> <<if $pc.femininity < 30>> <p>Every instinct screams at you to walk away. This is degrading. This is beneath you. You were a man six weeks ago.</p> <<elseif $pc.femininity < 60>> <p>Part of you is horrified. Part of you is... curious? The anonymity is almost appealing. Nobody would know. Nobody could judge.</p> <<else>> <p>You've done worse for less, and this one is at least on your terms. More or less.</p> <</if>> <<if _se.sexualFluidAddiction >= 2>> <p>Your mouth waters, and you know exactly what that is. The craving is loud and it is not remotely subtle and it is still, in the end, only a craving. You stand there long enough to be sure the decision is yours. Then you make it.</p> <<modStat "arousal" 10 "Addiction craving">> <</if>> <<if _se.submissive >= 2>> <p>Something about how impersonal the whole arrangement is gets to you. On your knees for a man whose face you will never see, reduced to a service and a number written on a wall. It should do nothing for you. It does.</p> <<modStat "arousal" 5 "Submissive thrill">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">👄 Oral ($20)</span>' "GloryHoleEncounter">> <<set $temp.ghType = "oral">> <</link>> <<link '<span class="choice-btn">🍑 Vaginal: turn around ($35)</span>' "GloryHoleEncounter">> <<set $temp.ghType = "vaginal">> <</link>> <<link '<span class="choice-btn">🔥 Anal ($50)</span>' "GloryHoleEncounter">> <<set $temp.ghType = "anal">> <</link>> <<link '<span class="choice-btn">🚫 No. Walk away.</span>' "CampusBathrooms">> <<modStat "confidence" 2 "Resisted temptation">> <</link>> </div>
<<set _se = $transformation.sideEffects>> <<set _ghType = $temp.ghType || "oral">> /* Random cock size */ <<set _ghSize = random(1, 6)>> <<set _sizeDesc = "">> <<if _ghSize <= 1>><<set _sizeDesc = "small, manageable">> <<elseif _ghSize <= 2>><<set _sizeDesc = "average">> <<elseif _ghSize <= 3>><<set _sizeDesc = "above average">> <<elseif _ghSize <= 4>><<set _sizeDesc = "big">> <<elseif _ghSize <= 5>><<set _sizeDesc = "thick">> <<else>><<set _sizeDesc = "huge">> <</if>> /* ═══ ORAL ═══ */ <<if _ghType === "oral">> <h2>👄 Glory Hole: Oral</h2> <p>You lock the stall, kneel on the cold tile. Your <<print $pc.hairColour>> hair brushes the grimy floor. You tap the wall twice.</p> <p>Through the hole slides something <<print _sizeDesc>>.</p> <<set _dc = Math.min(6, 2 + Math.floor(_ghSize / 2))>> <<set _result = XCLC.Roll.doCheck("oral", _dc)>> <<if _result.outcome === "crit_success">> <p>You take him in and something clicks into place. Tongue, lips, throat, the whole thing working together without you having to think about any part of it. He finishes fast and you hear him gasp on the other side of the partition. A hand comes through afterwards and leaves thirty on the cistern. Ten over the asking price.</p> <<set _payment = 30>> <<modStat "confidence" 3 "Expert performance">> <<addXP "oral" 20>> <<elseif _result.outcome === "success">> <p>You wrap your lips around him and get to work. Bob, breathe, repeat. He groans. It doesn't take long. $20 appears on the tank.</p> <<set _payment = 20>> <<addXP "oral" 15>> <<elseif _result.outcome === "partial_fail">> <p>The angle is wrong from the start. Your jaw cramps and you gag twice, neither time gracefully. He gets there eventually on persistence rather than anything you did. Fifteen on the cistern. He shorted you and he knew he was doing it.</p> <<set _payment = 15>> <<modStat "confidence" -3 "Sloppy performance">> <<addXP "oral" 10>> <<else>> <p>You gag immediately, pull off, try again, gag worse. He pulls back through the hole. "Fuckin' amateur." $10 on the tank. Pity money.</p> <<set _payment = 10>> <<modStat "confidence" -5 "Humiliating failure">> <<modStat "stress" 5 "Glory hole failure">> <<addXP "oral" 5>> <</if>> <<modStat "energy" -10 "Oral exertion">> /* ═══ VAGINAL ═══ */ <<elseif _ghType === "vaginal">> <h2>🍑 Glory Hole: Vaginal</h2> <p>You lock the stall and turn around. Hiking up your skirt, you back up to the hole, bracing your hands on the far wall. This is surreal. This is happening.</p> <p>You feel him press up against you, <<print _sizeDesc>>. Then he pushes in.</p> <<set _dc = Math.min(7, 3 + Math.floor(_ghSize / 2))>> <<set _result = XCLC.Roll.doCheck("vaginal", _dc)>> <<if _result.outcome === "crit_success">> <p>The angle turns out to be unexpectedly perfect. He slides in <<if _ghSize >= 5>>with a stretch that pulls a sound out of you<<else>>smoothly<</if>> and you get your fist against your mouth to keep quiet. Your body takes the whole thing over inside a minute, hips rolling back against the partition to meet him. It is good. That is the part you will still be thinking about on the walk home.</p> <p>He finishes with a groan that comes back off the tiles. Fifty on the cistern. Generous.</p> <<set _payment = 50>> <<modStat "arousal" 25 "Amazing anonymous sex">> <<modStat "confidence" 3 "Great performance">> <<addXP "vaginal" 20>> <<elseif _result.outcome === "success">> <p>He gets in <<if _ghSize >= 4>>with some difficulty, being both big and badly angled<<else>>without much trouble<</if>>. You brace against the partition and let him set the pace. It is mechanical and it is impersonal and your body answers it anyway, warmth gathering low in your stomach without your permission.</p> <p>$35 on the tank.</p> <<set _payment = 35>> <<modStat "arousal" 15 "Anonymous vaginal">> <<addXP "vaginal" 15>> <<elseif _result.outcome === "partial_fail">> <p>The angle is wrong. He keeps slipping out. You adjust, he tries again, and it's just... awkward. <<if _ghSize >= 5>>He's too big for this position.<<else>>Neither of you can find a rhythm.<</if>> He finishes but it takes forever.</p> <p>$25 on the tank. Below rate.</p> <<set _payment = 25>> <<modStat "confidence" -3 "Clumsy performance">> <<addXP "vaginal" 10>> <<else>> <p>He pushes in and you cry out far too loudly. Somebody in the next stall says "Jesus." That is the end of that. He pulls out, swears under his breath, and you listen to him zip up and go.</p> <p>$15 on the tank. Pity rate.</p> <<set _payment = 15>> <<modStat "confidence" -5 "Glory hole disaster">> <<modStat "stress" 8 "Humiliation">> <<addXP "vaginal" 5>> <</if>> <<modStat "energy" -15 "Vaginal exertion">> /* Pregnancy risk */ <<pregnancyRisk "unknown">> <<if $pregnancy.isPregnant && $pregnancy.discovered>> <p><em>He didn't pull out. Not that it makes any difference now, given what you are already carrying.</em></p> <<elseif !$transformation.addons.birthControl && !$health.birthControlActive>> <p><em>He didn't pull out. You felt it. The familiar dread settles in your stomach.</em></p> <</if>> /* ═══ ANAL ═══ */ <<else>> <h2>🔥 Glory Hole: Anal</h2> <p>You lock the stall and turn around. You pull down your bottoms and back up to the hole, pressing your <<print $pc.buttSize>> ass against the partition. You try to relax. You fail.</p> <p>He presses against you, <<print _sizeDesc>>. Then pushes. <<if _ghSize >= 4>>Pain. Immediate, sharp pain.<<else>>Pressure. Discomfort. Then more.<</if>></p> <<set _dc = Math.min(8, 4 + Math.floor(_ghSize / 2))>> <<set _result = XCLC.Roll.doCheck("anal", _dc)>> <<if _result.outcome === "crit_success">> <p>You breathe through it the way you have learned to. The pain thins out and something else moves in underneath it, deep and low and not remotely respectable, and your toes curl inside your shoes. You push back against the partition and take him further. He groans. You bite down on your lip hard enough to taste it.</p> <p>$70 on the tank. He was impressed.</p> <<set _payment = 70>> <<modStat "arousal" 20 "Intense anonymous anal">> <<modStat "confidence" 3 "Endured and excelled">> <<addXP "anal" 25>> <<elseif _result.outcome === "success">> <p>It hurts, but you manage. <<if _ghSize >= 5>>He's big and every thrust is a negotiation with pain,<<else>>The angle isn't great but you find a way to brace,<</if>> and he finishes after a few minutes. You exhale, shaking.</p> <p>$50 on the tank.</p> <<set _payment = 50>> <<modStat "arousal" 10 "Anonymous anal">> <<addXP "anal" 20>> <<elseif _result.outcome === "partial_fail">> <p>Your body tenses up and won't relax. He pushes, you wince, he pushes harder. It's painful without being productive. He finishes but neither of you enjoyed it.</p> <p>$35 on the tank. He's being generous.</p> <<set _payment = 35>> <<modStat "stress" 8 "Painful anonymous anal">> <<modStat "confidence" -3 "Difficult performance">> <<addXP "anal" 10>> <<else>> <p>You tense up completely. He can barely get inside. After three agonizing attempts, he gives up. "This isn't working," he mutters through the wall. You hear him leave.</p> <p>$20 on the tank. Sympathy money for trying.</p> <<set _payment = 20>> <<modStat "stress" 12 "Humiliating anal failure">> <<modStat "confidence" -5 "Failed completely">> <<addXP "anal" 5>> <</if>> <<modStat "energy" -20 "Anal exertion">> <</if>> /* ═══ COMMON POST ═══ */ <<set $finance.money += _payment>> <<advanceTime 15>> <<modHygiene -10 "Glory hole">> <<if _se.sexualFluidAddiction >= 2 && _ghType === "oral">> <p>The taste lingers. Your addiction purrs, satisfied.</p> <<modStat "mood" 5 "Addiction satisfied">> <</if>> <<if _se.increasedSensitivity >= 2>> <p>Your hypersensitivity made that far more intense than it should have been. You're trembling.</p> <<modStat "arousal" 10 "Sensitive glory hole">> <</if>> <<modRep "slut" 3 "Glory hole">> <<modStat "femininity" 2 "Anonymous service">> /* Anonymous strangers: elevated STD risk */ <<stdRisk _ghType 2>> <p>You straighten up, pocket the cash, and try to steady your breathing. Your <<print $pc.breastSize>>-cups feel heavy as you stand.</p> <p><strong>+$<<print _payment>></strong></p> <div class="choice-group"> <<if $pc.energy > 15>> <<link '<span class="choice-btn">👄 Another round: Oral ($20)</span>' "GloryHoleEncounter">> <<set $temp.ghType = "oral">> <</link>> <<link '<span class="choice-btn">🍑 Another round: Vaginal ($35)</span>' "GloryHoleEncounter">> <<set $temp.ghType = "vaginal">> <</link>> <<link '<span class="choice-btn">🔥 Another round: Anal ($50)</span>' "GloryHoleEncounter">> <<set $temp.ghType = "anal">> <</link>> <<else>> <p><em>You're too exhausted for another round.</em></p> <</if>> <<link '<span class="choice-btn">🚿 Freshen up at the sink</span>' "BathroomFreshenUp">><</link>> <<link '<span class="choice-btn">🗺️ Leave</span>' "CampusMap">><</link>> </div> /* Mall, Drugstore, HairSalon, TattooShop now in 12_shops.twee */ /* WardrobeMenu now in 11_wardrobe.twee */ /* BarDistrict moved to 06_off_campus.twee */ /* Downtown moved to 15_jobs.twee (hooker passages): stub kept for non-job access */
<<checkStreetProposition>> <h2>🏢 Downtown</h2> <p>It's <<showTime>>. The downtown strip: restaurants, offices, and then past the main drag, where the lighting gets noticeably worse and stays that way.</p> <<set _period = XCLC.Time.getPeriod($world.time)>> <<if _period === "night" || _period === "late_night">> <p>The streetlights are dim here. Cars crawl by slowly. You can see silhouettes leaning against lamp posts.</p> <</if>> <div class="choice-group"> <<if $jobs.hooker.active && (_period === "night" || _period === "late_night")>> <<link '<span class="choice-btn">💋 Walk the street</span>' "Job_Hooker_Street">><</link>> <</if>> <<if $jobs.dealer.active>> <<link '<span class="choice-btn">📦 Visit Marco (restock)</span>' "Job_Dealer_Restock">><</link>> <</if>> /* ─── Sex work tiers ─── */ <<if $jobs.brothel.active>> <<if _period === "evening" || _period === "night" || _period === "late_night">> <<link '<span class="choice-btn">🏮 The Lantern: work your shift</span>' "Job_Brothel_Shift">><</link>> <<else>> <p><em>🏮 The Lantern · evening shifts only</em></p> <</if>> <<else>> <<link '<span class="choice-btn">🏮 The Lantern: ask about the rota</span>' "Job_Brothel_Apply">><</link>> <</if>> <<if !$jobs.escort.active>> <<link '<span class="choice-btn">💼 Aurelia Companions: enquire</span>' "Job_Escort_Apply">><</link>> <<else>> <p><em>💼 Aurelia · bookings arrive in the app on your phone</em></p> <</if>> <<divider "">> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><<advanceTime 30>><</link>> </div>
<h2>⚙️ Settings</h2> /* ── Save Game ── */ <div class="card"> <div class="card__title">💾 Save Game</div> <<for _slot = 1; _slot <= 5; _slot++>> <<capture _slot>> <<set _saveData = XCLC.SaveSystem.getSlotInfo(_slot)>> <<if _saveData>> <div style="margin-bottom: 0.5em;"> <p><strong>Slot <<print _slot>>:</strong> Day <<print _saveData.day>>, Week <<print _saveData.week>>, Sem <<print _saveData.semester>> · Fem <<print _saveData.femininity>></p> <<link '<span class="choice-btn" style="font-size:0.85em;">💾 Overwrite Slot <<print _slot>></span>' "SettingsMenu">> <<run XCLC.SaveSystem.saveToSlot(_slot)>> <<run XCLC.Toast.show("💾 Saved to Slot " + _slot + "!", "success")>> <</link>> </div> <<else>> <<link '<span class="choice-btn">💾 Save to Slot <<print _slot>> (empty)</span>' "SettingsMenu">> <<run XCLC.SaveSystem.saveToSlot(_slot)>> <<run XCLC.Toast.show("💾 Saved to Slot " + _slot + "!", "success")>> <</link>> <</if>> <</capture>> <</for>> </div> /* ── Load Game ── */ <div class="card"> <div class="card__title">📂 Load Game</div> <<set _hasAnySave = false>> <<for _slot = 1; _slot <= 5; _slot++>> <<capture _slot>> <<set _saveData = XCLC.SaveSystem.getSlotInfo(_slot)>> <<if _saveData>> <<set _hasAnySave = true>> <<link '<span class="choice-btn">📂 Load Slot <<print _slot>>: Day <<print _saveData.day>>, Sem <<print _saveData.semester>></span>' "SettingsMenu">> <<run XCLC.SaveSystem.loadFromSlot(_slot)>> <</link>> <</if>> <</capture>> <</for>> /* Check autosave */ <<set _autoData = XCLC.SaveSystem.getSlotInfo('auto')>> <<if !_autoData>> <<run (function() { var d = localStorage.getItem('xclc_autosave'); if (d) { try { State.temporary.autoMeta = JSON.parse(d).meta; } catch(e){} } })()>> <<set _autoData = _autoMeta>> <</if>> <<if !_hasAnySave && !_autoData>> <p style="opacity: 0.5;"><em>No saves found.</em></p> <</if>> </div> /* ── Export / Import ── */ <div class="card"> <div class="card__title">📤 Export / 📥 Import Save</div> <<link '<span class="choice-btn">📤 Export Save (JSON download)</span>' "SettingsMenu">> <<run XCLC.SaveSystem.exportSave()>> <</link>> <<link '<span class="choice-btn">📥 Import Save (JSON file)</span>'>> <<run XCLC.SaveSystem.importSave()>> <</link>> <p style="opacity:0.6; font-size:0.85em;">Importing loads the save immediately, so export your current game first if you want to keep it.</p> </div> /* ── Restart Game ── */ <div class="card"> <div class="card__title">🔄 Restart Game</div> <p style="opacity: 0.7;">This will start a brand new game. <strong>Unsaved progress will be lost.</strong></p> <<link '<span class="choice-btn" style="background: rgba(255,23,68,0.2); border-color: #ff1744;">🔄 Restart Game</span>' "SettingsMenu_ConfirmRestart">><</link>> </div> <div class="choice-group"> <<link '<span class="choice-btn">← Back</span>' `($ui.returnPassage || "CampusMap")`>><</link>> </div>
<h2>🔄 Are you sure?</h2> <div class="card"> <div class="card__title">⚠️ Restart Confirmation</div> <p>This will <strong>erase all progress</strong> and return to the start screen. Your save slots will remain intact.</p> </div> <div class="choice-group"> <<link '<span class="choice-btn" style="background: rgba(255,23,68,0.3); border-color: #ff1744;">🔄 Yes, restart the game</span>' "SettingsMenu_ConfirmRestart">> <<run Engine.restart()>> <</link>> <<link '<span class="choice-btn">← No, go back</span>' "SettingsMenu">><</link>> </div>
<h2>👤 Character Sheet</h2> <<include "DormRoom_Mirror">>
<h2>📋 Skills</h2> <<set _cats = [ {key: "sexual", name: "💗 Sexual", desc: "Improved through practice."}, {key: "academic", name: "🧠 Academic", desc: "Improved by studying and attending class."}, {key: "social", name: "🤝 Social", desc: "Improved through conversation and social events."}, {key: "performance", name: "🎭 Performance", desc: "Improved through jobs and performing."} ]>> <<set _keys = Object.keys($skills)>> <<for _ci = 0; _ci < _cats.length; _ci++>> <<set _cat = _cats[_ci]>> /* Count trained skills in this category */ <<set _trained = 0>><<set _total = 0>> <<for _ki = 0; _ki < _keys.length; _ki++>> <<if $skills[_keys[_ki]].category === _cat.key>> <<set _total++>> <<if $skills[_keys[_ki]].level > 0>><<set _trained++>><</if>> <</if>> <</for>> <div @class="'card skills-cat skills-cat--' + _cat.key"> <div class="card__title"><<print _cat.name>> <span class="skills-cat__meta"><<print _trained>>/<<print _total>> trained</span></div> <p style="opacity:0.6; font-size:0.85em; margin:0;"><<print _cat.desc>></p> <div class="skills-grid"> <<for _ki = 0; _ki < _keys.length; _ki++>> <<set _skill = $skills[_keys[_ki]]>> <<if _skill.category === _cat.key>> <<set _xpPct = Math.min(100, Math.max(0, Math.round((_skill.xp / Math.max(1, _skill.xpNext)) * 100)))>> <div @class="'skill-cell' + (_skill.level === 0 && _skill.xp === 0 ? ' untrained' : '')"> <div class="skill-cell__head"> <div class="skill-cell__icon"><<print _skill.icon>></div> <div class="skill-cell__name"><<print _skill.name>></div> <div class="skill-cell__level"><<if _skill.level === 0 && _skill.xp === 0>>Untrained<<else>>Lv <<print _skill.level>><</if>></div> </div> <div> <div class="skill-cell__bar"><div class="skill-cell__fill" @style="'width:' + _xpPct + '%'"></div></div> <div class="skill-cell__xp"><<print _skill.xp>> / <<print _skill.xpNext>> XP</div> </div> </div> <</if>> <</for>> </div> </div> <</for>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' `($ui.returnPassage || "CampusMap")`>><</link>> </div> /* JournalMenu moved to 24_journal.twee */ /* AchievementsMenu moved to 25_achievements.twee */ /* Graduation moved to 18_endings.twee */
<<set _shower = !!($temp.soloShower)>> <<set _vibes = XCLC.Toys.ownedIn("vibe")>> <<set _dildos = XCLC.Toys.ownedIn("dildo")>> <<set _plugs = XCLC.Toys.ownedIn("plug")>> <<set _worn = XCLC.Toys.worn()>> <<set _suction = XCLC.Toys.ownedTagged("shower")>> <<if _shower>> <h2>🚿 Nobody Is Waiting For This Bathroom</h2> <p>You reach past the shampoo and press the suction cup flat against the tile, testing it with the heel of your hand until it holds. It is an absurd object to own. It is a more absurd object to own and then use in a shared bathroom at eleven in the morning on a Tuesday. You lock the cubicle anyway.</p> <p>The water is loud enough to cover almost anything. Almost.</p> <<else>> <h2>💗 Time To Yourself</h2> <p>The door is shut. Your roommate is out, or asleep, or wearing headphones, and you have decided not to interrogate which. You lie back, let your shoulders drop into the mattress, and stop holding yourself the way you hold yourself in front of people.</p> <<if $pc.arousal >= 70>> <p>You have been carrying this around all day. It has been sitting under everything, every conversation and every stair climb and every accidental drag of fabric, and it is a relief to finally admit that this is where the day was always going.</p> <<elseif $pc.arousal <= 25>> <p>You are not desperate. That is almost the point. There is something deliberate about doing this because you decided to, rather than because your body ambushed you into it.</p> <</if>> <<if _worn>> <p>The <<print XCLC.Toys.plain(_worn)>> is still in. It has been in all day, a low steady presence you stopped consciously noticing hours ago and are noticing very consciously again now.</p> <</if>> <</if>> <p style="opacity:0.7; font-size:0.85em;"><em>Fill <strong>Build</strong> to 100 to finish. Past 85 you can hold yourself on the edge. Every edge you hold multiplies what the finish is worth, but it costs stamina and gets harder each time.</em></p> <h3>What are you using?</h3> <div class="choice-group"> <<if _shower>> <<for _si = 0; _si < _suction.length; _si++>> <<set _st = _suction[_si]>> <<capture _st>> <<link '<span class="choice-btn">🚿 <<print _st.name>>: <em>stuck to the tile, hands free</em></span>' "Solo_Round">> <<run XCLC.Solo.start({toy: _st.id, shower: true})>> <</link>> <</capture>> <</for>> <<link '<span class="choice-btn">🤲 Just your hands and the water</span>' "Solo_Round">> <<run XCLC.Solo.start({shower: true})>> <</link>> <<else>> <<link '<span class="choice-btn">🤲 Just your hands</span>' "Solo_Round">> <<run XCLC.Solo.start({})>> <</link>> <<for _vi = 0; _vi < _vibes.length; _vi++>> <<set _vt = _vibes[_vi]>> <<capture _vt>> <<link '<span class="choice-btn">〰️ <<print _vt.name>>: <em><<print _vt.desc>></em></span>' "Solo_Round">> <<run XCLC.Solo.start({toy: _vt.id})>> <</link>> <</capture>> <</for>> <<for _di = 0; _di < _dildos.length; _di++>> <<set _dt = _dildos[_di]>> <<capture _dt>> <<link '<span class="choice-btn">🕯️ <<print _dt.name>>: <em><<print _dt.desc>></em></span>' "Solo_Round">> <<run XCLC.Solo.start({toy: _dt.id})>> <</link>> <</capture>> <</for>> <<for _pi = 0; _pi < _plugs.length; _pi++>> <<set _pt = _plugs[_pi]>> <<capture _pt>> <<link '<span class="choice-btn">💎 <<print _pt.name>>: <em><<print _pt.desc>></em></span>' "Solo_Round">> <<run XCLC.Solo.start({toy: _pt.id})>> <</link>> <</capture>> <</for>> <</if>> <<if _shower>> <<link '<span class="choice-btn">↩️ Actually, just wash and get out</span>' "DormRoom">><</link>> <<else>> <<link '<span class="choice-btn">↩️ Actually, not right now</span>' "DormRoom">><</link>> <</if>> </div>
<<set _ctx = $temp.soloCtx>> <<set _shower = _ctx.shower>> <<if $temp.soloOutcome>> <<goto "Solo_Finish">> <</if>> <h2>Round <<print $temp.soloRound + 1>><<if _ctx.toyName>>: <<print _ctx.toyName>><<else>>: Hands Only<</if>></h2> <<if $temp.soloLastText>> <p><<print $temp.soloLastText>></p> <</if>> <p style="opacity:0.65;"><em><<print XCLC.Solo.ambient()>></em></p> /* ─── Meters ─── */ <<set _bPct = Math.round($temp.soloBuild)>> <<set _sPct = Math.round(($temp.soloStamina / $temp.soloStaminaMax) * 100)>> <<set _iPct = Math.min(100, Math.round(($temp.soloIntensity - 1) / 1.5 * 100))>> <div class="card" style="padding: 0.8em 1.2em;"> <div class="sex-meter-row"> <span class="stat-bar-icon">💗</span> <span class="sex-meter-label">Build</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _bPct + '%; background: var(--accent-pink);'"></div></div> <span class="sex-meter-val"><<print _bPct>></span> </div> <div class="sex-meter-row"> <span class="stat-bar-icon">💪</span> <span class="sex-meter-label">Stamina</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _sPct + '%; background: var(--accent-teal);'"></div></div> <span class="sex-meter-val"><<print Math.round($temp.soloStamina)>></span> </div> <div class="sex-meter-row"> <span class="stat-bar-icon">🔥</span> <span class="sex-meter-label">Intensity</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _iPct + '%; background: var(--accent-purple);'"></div></div> <span class="sex-meter-val">×<<print $temp.soloIntensity.toFixed(2)>></span> </div> </div> /* ─── Body state ─── */ <p style="opacity:0.75;"><em><<if $temp.soloBuild >= 85>>You are right at the edge. Thighs locked, breath in pieces, one wrong move from over. Everything past here is a decision.<<elseif $temp.soloBuild >= 60>>Your body has committed. The heat has stopped being something you are building and started being something that is happening to you.<<elseif $temp.soloBuild >= 30>>Warm all the way through now, hips shifting without instruction, breathing changed.<<else>>Still finding it. Your body takes a moment to agree that this is what you are doing.<</if>><<if $temp.soloEdges >= 2>> After <<print $temp.soloEdges>> refusals your nerves are screaming and every touch is arriving at twice the volume.<</if>></em></p> /* ─── Moves ─── */ <<set _moves = XCLC.Solo.available()>> <div class="choice-group"> <<for _mi = 0; _mi < _moves.length; _mi++>> <<set _mv = _moves[_mi]>> <<capture _mv>> <<link '<span class="choice-btn"><<print _mv.icon>> <<print _mv.name>> <em>(−<<print _mv.cost>> stamina)</em></span>' "Solo_Round">> <<run XCLC.Solo.doMove(_mv.id)>> <</link>> <</capture>> <</for>> <<if $temp.soloBuild >= 85>> <<set _edgeDC = 2 + Math.max(0, $temp.soloEdges - 1)>> <<link '<span class="choice-btn">🛑 Back off: hold yourself there <em>(Composure DC <<print _edgeDC>>, banks intensity)</em></span>' "Solo_Round">> <<run XCLC.Solo.edge()>> <</link>> <</if>> <<link '<span class="choice-btn">🌬️ Ease off for a minute <em>(+11 stamina)</em></span>' "Solo_Round">> <<run XCLC.Solo.breather()>> <</link>> <<if $temp.soloBuild >= 60>> <<link '<span class="choice-btn">💥 Let go <em>(finish now, at current intensity)</em></span>' "Solo_Round">> <<run XCLC.Solo.release()>> <</link>> <</if>> <<link '<span class="choice-btn">✋ Stop: this is not happening</span>' "Solo_Round">> <<run XCLC.Solo.giveUp()>> <</link>> </div>
<<set _res = XCLC.Solo.resolve()>> <<set _ctx = $temp.soloCtx>> <<set _shower = _ctx.shower>> <<set _out = _res.outcome>> <h2><<if _out === "climax">><<if _res.edges >= 3>>Worth Every Second<<elseif _res.edges >= 1>>Earned<<else>>Release<</if>><<elseif _out === "snatched">>Stolen<<elseif _out === "denied">>The Wall<<elseif _out === "spent">>Out Of Road<<else>>Not Tonight<</if>></h2> <<if _out === "climax">> <<if _res.tipped>> <<if _res.edges >= 1>> <p>You had every intention of holding on and your body filed a dissenting opinion. It goes over without asking, and because you had already refused it <<print _res.edges>> time<<if _res.edges > 1>>s<</if>>, it goes over <em>hard</em>: a chain reaction you set up yourself and then lost control of.</p> <<else>> <p>You go to stop and discover, with about half a second of warning, that the decision was made some time ago and nobody consulted you about it.</p> <</if>> <</if>> <<if _res.edges >= 3>> <p>By the time you finally let yourself have it there is nothing measured left in you. It does not arrive so much as detonate, everything you refused over the last however-many minutes cashing in at once, in one long unbroken wave that keeps not ending. Your back leaves the <<if _shower>>tile<<else>>mattress<</if>>. Sound comes out of you that you will think about later with your hands over your face. Your legs are still trembling a full minute afterwards and you make no attempt to stop them.</p> <p>You lie there afterwards, wrecked and grinning at nothing, and think: <em>so that is what all the fuss is about.</em></p> <<elseif _res.edges >= 1>> <p>You let go and it comes up to meet you properly. Deeper than the quick ones, slower to arrive and a great deal slower to leave, rolling through you in stages. You breathe through the last of it with one hand still pressed flat against yourself, unwilling to let it finish finishing.</p> <p>Patience, it turns out, has a return rate.</p> <<else>> <p>The build tips over and you go with it: a clean, sharp, uncomplicated finish that empties every wound-up thing out of you at once. Your hand slows and stops. Your breathing takes longer to get the message.</p> <</if>> <<if _res.strong>> <p>💥 It is <em>enormous</em>. The X-Change has done something to the wiring down there and the aftershocks keep arriving in waves for a good while after you would have expected them to stop.</p> <</if>> <<if _res.squirted>> <p>💧 You squirt, <<if _shower>>lost immediately in the water, which is the one mercy of doing this in here<<else>>soaking a genuinely unreasonable amount of your sheets<</if>>. Still new. Still faintly astonishing.</p> <<if !_shower>><<modHygiene -10 "Squirting">><</if>> <</if>> <div class="alert alert--success">💗 Stress −<<print _res.relief>> · Mood +<<print _res.mood>> · Arousal cleared<<if _res.edges > 0>> · <<print _res.edges>> edge<<if _res.edges > 1>>s<</if>> held (×<<print _res.intensity.toFixed(2)>>)<</if>></div> <<elseif _out === "snatched">> <p>You are there. You are <em>right there</em>, past the point where it should be automatic, and the orgasm simply does not arrive. Your body climbs to the top of the stairs and finds no last step. You keep going out of sheer disbelief, chasing it, and it recedes exactly as fast as you pursue.</p> <p>Eventually you stop, shaking with frustration, wound tighter than when you started and with nothing at all to show for it.</p> <div class="alert alert--warning">😖 Orgasm Denial stole it. Stress +10 · Mood −10</div> <<elseif _out === "denied">> <<if _res.denialLevel === 1>> <p>The pleasure plateaus and stays there: high, insistent, and going absolutely nowhere. Every time you get close the sensation flattens out like a road that stops climbing. After several increasingly determined minutes you take your hand away. Less wound up. Nowhere near satisfied.</p> <<elseif _res.denialLevel === 2>> <p>You try. You hit every spot that should end this, you use everything you have, and the X-Change has built a wall around the finish that you can see and feel and cannot get over. You stop, panting, barely less desperate than when you started.</p> <<elseif _res.denialLevel === 3>> <p>It is close to cruel. Your body answers every touch with genuine, urgent, unfaked need, and the release is not coming. It is never coming. You pull your hand away shaking, barely a fraction less aroused than when you began.</p> <<else>> <p>Your hand keeps moving even though you know how this ends. It never works. It has not worked in a long time. But the need is constant and enormous and you cannot make yourself stop trying, and when you finally do stop there are tears of pure frustration in your eyes.</p> <p>The denial is starting to make you consider things you would not otherwise consider.</p> <</if>> <div class="alert alert--warning">🚫 Masturbation Denial (level <<print _res.denialLevel>>): the finish is not available to you.</div> <<elseif _out === "spent">> <p>Your arms give out before your body does. Wrist aching, thighs burning, breathing hard and still <em>right there</em> without being able to close the distance. You let your hand fall onto your stomach and stare at the ceiling, defeated by your own stamina.</p> <div class="alert alert--info">😮💨 You ran out of steam before you got there.</div> <<else>> <p>You stop. Not because anything is wrong exactly. The head is just not in it, and forcing it would only make the whole thing feel like a chore. You pull the covers up and let the moment go.</p> <</if>> /* ─── Roommate walk-in ─── */ <<if !_shower>> <<set _walkIn = XCLC.Roommate.checkWalkIn("masturbate")>> <<else>> <<set _walkIn = XCLC.Roommate.checkWalkIn("shower")>> <</if>> <<if _walkIn.walkedIn>> <div class="card"> <div class="card__title">🚪 Oh no.</div> <p><<print _walkIn.text>></p> </div> <<modStat "confidence" -5 "Caught in the act">> <<modStat "femininity" 3 "Mortification">> <</if>> <div class="choice-group"> <<if _ctx.toy && !_shower>> <<goto_solo_tidy>> <<elseif _shower>> <<link '<span class="choice-btn">🚿 Rinse off and get out</span>' "DormRoom">> <<run XCLC.Toys.tidyUp()>> <</link>> <<else>> <<link '<span class="choice-btn">← Back to your room</span>' "DormRoom">><</link>> <</if>> </div>
/* Tidy-up choice after using a toy in the room. Leaving it out is what makes the roommate discovery event possible. */ <<widget "goto_solo_tidy">> <<set _tidyToy = XCLC.Toys.def($temp.soloCtx.toy)>> <<set _bimbo = $transformation.sideEffects.bimbofication || 0>> <<link '<span class="choice-btn">🧺 Clean it, put it away properly</span>' "DormRoom">> <<run XCLC.Toys.tidyUp()>> <<modStat "energy" -2 "Tidying up">> <</link>> <<capture _tidyToy>> <<link '<span class="choice-btn">😴 Leave it: deal with it later <em>(risk: someone finds it)</em></span>' "DormRoom">> <<run XCLC.Toys.leaveOut(_tidyToy.id)>> <<run XCLC.Toast.show("🙈 You left the " + XCLC.Toys.plain(_tidyToy) + " out.", "info", 4000)>> <</link>> <</capture>> <<if _bimbo >= 2>> <p style="opacity:0.6; font-size:0.85em;"><em>Putting things away has become genuinely difficult to care about lately.</em></p> <</if>> <</widget>>
/* Player wakes up: process morning SEs, show events, offer activities */ <<run XCLC.SE.processMorning()>> <h2>🌅 Good Morning</h2> <p>You wake up at <<showTime>> on <<showDate>>. <<if $pc.energy >= 80>>You feel refreshed and ready to face the day. <<elseif $pc.energy >= 50>>You feel okay. Not great, not terrible. <<elseif $pc.energy >= 25>>You feel groggy. Could really use some coffee. <<else>>You feel exhausted. Did you even sleep? <</if>> </p> /* Display morning SE events */ <<if $temp.morningEvents && $temp.morningEvents.length > 0>> <div class="card"> <div class="card__title">Morning Sensations</div> <<for _i = 0; _i < $temp.morningEvents.length; _i++>> <p><<print $temp.morningEvents[_i]>></p> <</for>> </div> <</if>> /* Roommate status */ <<if $roommate.name>> <<if XCLC.Roommate.isHome()>> <p><<print $roommate.name>> is <<print XCLC.Roommate.getActivity()>>.</p> <<else>> <p><<print $roommate.name>> is already out.</p> <</if>> <</if>> /* Status warnings */ <<if $hygiene.cleanliness < 50>> <div class="alert alert--warning">🚿 You could really use a shower. Hygiene: <<print $hygiene.cleanliness>>%</div> <</if>> <<if $pc.arousal > 60>> <div class="alert alert--warning">🔥 You're uncomfortably aroused. It's hard to concentrate.</div> <</if>> <<checkLactation>> <div class="choice-group"> <<link '<span class="choice-btn">⚡ Quick Routine (do your morning in one click)</span>' "QuickRoutine_Setup">><</link>> <<link '<span class="choice-btn">🏠 Go to your room (do things individually)</span>' "DormRoom">><</link>> </div>
<h2>⚡ Quick Morning Routine</h2> <p>Select what you want to do this morning. These will be performed in order and the time cost will be combined.</p> <div id="qr-setup"></div> <<run setTimeout(function(){ XCLC.QuickRoutine.render(); }, 50)>>
/* Execute the saved quick routine */ <<set _qr = $temp.quickRoutine || {}>> /* Shower */ <<if _qr.shower>> <<shower>> <p>🚿 You take a hot shower.</p> <<if $transformation.sideEffects.increasedSensitivity >= 1>> <p>⚡ The water cascading over your new body sends shivers of pleasure through you.</p> <<modStat "arousal" 10 "Shower sensitivity">> <</if>> <<if $transformation.sideEffects.lactation >= 2>> <p>🍼 Milk drips from your nipples into the shower drain. You cup your breasts and squeeze, expressing the pressure.</p> <<set $temp.lastExpressed = $world.time>> <</if>> <</if>> /* Shave legs */ <<if _qr.shaveLegs>> <<shaveLegs>> <p>🪒 You shave your legs smooth.</p> <</if>> /* Shave pubic */ <<if _qr.shavePubic>> <<shavePubic>> <p>🪒 You tidy up downstairs.</p> <</if>> /* Skincare */ <<if _qr.skincare>> <<applySkincare>> <p>✨ You apply your skincare routine.</p> <</if>> /* Makeup */ <<if _qr.makeup && _qr.makeup !== "none">> <<applyMakeup _qr.makeup>> <p>💄 You apply <<print _qr.makeup>> makeup.</p> <</if>> <p>Morning routine complete! Time: <<showTime>>.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Back to room</span>' "DormRoom">><</link>> <<link '<span class="choice-btn">🗺️ Head to campus</span>' "CampusMap">><</link>> </div>
/* Player returns to dorm late / chooses to go to bed */ <<run XCLC.SE.processNight()>> <h2>🌙 Winding Down</h2> <p>It's <<showTime>>. Time to call it a night.</p> /* Remove makeup if applied */ <<if $pc.makeupApplied>> <p>You remove your makeup at the bathroom sink.</p> <<applyMakeup "none">> <</if>> /* Night SE events */ <<if $temp.nightEvents && $temp.nightEvents.length > 0>> <div class="card"> <div class="card__title">Evening Thoughts</div> <<for _i = 0; _i < $temp.nightEvents.length; _i++>> <p><<print $temp.nightEvents[_i]>></p> <</for>> </div> <</if>> /* Roommate */ <<if $roommate.name && XCLC.Roommate.isHome()>> <p><<print $roommate.name>> is <<if $world.time >= 1380>>already asleep<<else>><<print XCLC.Roommate.getActivity()>><</if>>.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💤 Go to sleep</span>' "DormRoom_Sleep">><</link>> <<if $pc.arousal > 40 && $transformation.sideEffects.masturbationDenial === 0>> <<link '<span class="choice-btn">🔥 Take care of that arousal first...</span>' "DormRoom_Masturbate">><</link>> <</if>> <<link '<span class="choice-btn">🏠 Not tired yet (back to room)</span>' "DormRoom">><</link>> </div>
/* A guy approaches and hits on the player. Personality-reactive. */ <<set _npc = $temp.quadNPC || XCLC.NPC.generate({})>> <<set _p = _npc.personality>> <div class="card"> <div class="card__title">👤 Someone approaches...</div> <<if _p === "friendly" || _p === "sweet">> <p>A <<print _npc.bodyType>> <<print _npc.race>> guy with <<print _npc.hairColour>> hair walks over, hands in his pockets. He looks a little nervous.</p> <p>"Hey, sorry to bother you. I'm <<print _npc.firstName>>. I don't think we've met? You're in the CCUMDUP programme, right? I just thought... you seemed cool."</p> <<elseif _p === "cocky" || _p === "demanding">> <p>A <<print _npc.bodyType>> <<print _npc.race>> guy breaks away from a group of friends and intercepts you on the path. He's grinning like he already knows how this conversation ends.</p> <p>"Yo, I'm <<print _npc.firstName>>. You're one of those scholarship girls, right? Lucky me." He looks you up and down without even pretending to be subtle.</p> <<elseif _p === "shy">> <p>You notice a <<print _npc.bodyType>> guy hovering near the fountain, stealing glances at you. When you accidentally make eye contact, he panics and walks straight over, going red.</p> <p>"H-hi. I'm <<print _npc.firstName>>. I, uh. You dropped something. No, you didn't. Sorry. I just wanted to say hi."</p> <<elseif _p === "aggressive">> <p>A <<print _npc.bodyType>> <<print _npc.race>> guy cuts across your path, stepping too close. He smells like cheap cologne and confidence.</p> <p>"<<print _npc.firstName>>." He doesn't ask your name. "You're that new girl from Hamilton, right? I've been hearing things about you CCUMDUP girls."</p> <<elseif _p === "romantic">> <p>A tall <<print _npc.race>> guy with <<print _npc.eyeColour>> eyes falls into step beside you like he's been waiting for exactly this moment.</p> <p>"I'm <<print _npc.firstName>>. Forgive the interruption. I noticed you walking past and couldn't not say something. Are you always this beautiful or is today special?"</p> <<else>> <p>A <<print _npc.bodyType>> <<print _npc.race>> guy appears at your elbow with a weird smile. Something about his energy is... off.</p> <p>"Hey. I'm <<print _npc.firstName>>. I've seen you around. You live in Hamilton, right? Room 207?" How does he know your room number?</p> <</if>> </div> <div class="choice-group"> <<link '<span class="choice-btn">😊 Be friendly. "Nice to meet you."</span>' "CampusMap">> <<modStat "mood" 3 "Nice conversation">> <<modStat "femininity" 1 "Friendly with a guy">> <</link>> <<link '<span class="choice-btn">😏 Flirt back. "Well aren\'t you forward..."</span>' "CampusMap">> <<modStat "confidence" 3 "Flirting">> <<modStat "femininity" 2 "Flirting with a guy">> <<modStat "arousal" 5 "Flirting">> <</link>> <<link '<span class="choice-btn">❄️ Cold. "Not interested."</span>' "CampusMap">> <<modStat "confidence" 5 "Asserting boundaries">> <</link>> <<link '<span class="choice-btn">🚶 Keep walking. Ignore him.</span>' "CampusMap">> <</link>> </div>
/* Beauty-gated. Someone catcalls from across the quad. */ <div class="card"> <div class="card__title">📢 Catcall</div> <<set _catcalls = [ '"Daaaamn, girl!" from a group of guys on a bench.', '"Hey beautiful, where you going?" Someone yells from a passing car.', 'A wolf-whistle from a second-floor dorm window.', '"Yo shorty! Come sit with us!" from a group at a picnic table.', '"Looking good, scholarship girl!" Someone knows what CCUMDUP is.' ]>> <<set _cat = _catcalls[random(0, _catcalls.length - 1)]>> <p><<print _cat>></p> <<if $transformation.sideEffects.exhibitionist >= 1>> <p>You feel a little thrill. The attention is... flattering? No. Yes? You're confused about how you feel.</p> <<modStat "arousal" 5 "Enjoying attention">> <<else>> <p>Your face burns. You keep walking, eyes forward.</p> <</if>> </div> <<modStat "femininity" 1 "Catcalled">> <<modStat "confidence" -2 "Street harassment">>
/* Reputation-gated. Someone recognises you from a service encounter. */ <<set _npc = $temp.quadNPC || XCLC.NPC.generate({})>> <div class="card"> <div class="card__title">😰 Recognised...</div> <<set _recTexts = [ 'A guy you vaguely recognise does a double-take as you pass. He nudges his friend and whispers something. They both look at you. One of them grins.', 'Someone calls out: "Hey! You\'re that girl from CampusHub, right? 5 stars, bro." His friends laugh. Your stomach drops.', '"<<print $pc.femaleFirstName>>?" A guy jogs up. "We, uh... met last week? Through the programme? I just wanted to say... thanks." He looks embarrassed. You feel worse.' ]>> <p><<print _recTexts[random(0, _recTexts.length - 1)]>></p> </div> <<modStat "confidence" -5 "Recognised">> <<modStat "stress" 8 "Public recognition">> <<modRep "slut" 2 "Recognised in public">>
/* Meet another CCUMDUP girl. */ <<set _npc = $temp.quadNPC || XCLC.NPC.generate({})>> <div class="card"> <div class="card__title">👩 Fellow Scholar</div> <p>A <<print _npc.bodyType>> <<print _npc.race>> girl catches your eye near the fountain. Something about the way she carries herself, the same mixture of discomfort and determination, tells you she's one of you.</p> <p>"<<print _npc.firstName>>," she says quietly, sitting beside you. "Also CCUMDUP. Also used to be a guy. Fun, right?"</p> <<set _dialogue = [ '"How are you handling the... side effects?" She tugs at her bra strap self-consciously. "I got hit with the lactation thing. It\'s a nightmare."', '"Have you done many services yet? I\'ve done three. The first one was..." She trails off. "Well. You\'ll see."', '"My roommate doesn\'t know. Does yours? God, the lying is almost worse than the actual programme."', '"At least the credits are real, right? That\'s what I keep telling myself. Real degree, real career after this."', '"I heard there\'s a girl on the third floor who actually likes it now. Like, for real. Scary, right?"' ]>> <p><<print _dialogue[random(0, _dialogue.length - 1)]>></p> </div> <div class="choice-group"> <<link '<span class="choice-btn">💬 "Yeah. It\'s a lot. Nice to know I\'m not alone though."</span>' "CampusMap">> <<modStat "mood" 10 "Shared experience">> <<modStat "stress" -8 "Solidarity">> <</link>> <<link '<span class="choice-btn">😔 "I don\'t want to talk about it."</span>' "CampusMap">> <<modStat "stress" -3 "Avoidance">> <</link>> </div>
/* A professor stops you. Sets up academic relationship. */ <<set _npc = $temp.quadNPC || XCLC.NPC.generate({type: "professor"})>> <div class="card"> <div class="card__title">🎓 Professor <<print _npc.lastName>></div> <p>A <<print _npc.bodyType>> <<print _npc.race>> <<if _npc.gender === "male">>man<<else>>woman<</if>> in a tweed jacket stops you on the path.</p> <p>"Ah. You're one of our CCUMDUP scholars, aren't you? <<print _npc.firstName>> <<print _npc.lastName>>, <<print ['English', 'Psychology', 'Biology', 'Economics', 'Sociology', 'Art History'][random(0,5)]>> department."</p> <<if _npc.personality === "friendly" || _npc.personality === "sweet">> <p>"I just wanted to say that I know the programme has its challenges. My office hours are Tuesdays and Thursdays. Don't hesitate if you need anything."</p> <<elseif _npc.personality === "creepy">> <p><<if _npc.gender === "male">>His eyes linger a moment too long. "I've heard... interesting things about the programme. Perhaps we could discuss it in my office sometime? Privately."<<else>>"The programme is... well. Just be careful, dear. Some of the faculty have opinions."<</if>></p> <<else>> <p>"Keep your grades up. The scholarship has academic requirements too, you know. I don't give free passes."</p> <</if>> </div> <<modStat "stress" 3 "Professor interaction">>
/* Pheromones SE causes a scene. Level 2+ only. */ <div class="card"> <div class="card__title">🌸 Your pheromones are out of control</div> <<set _level = $transformation.sideEffects.pheromones>> <<if _level <= 2>> <p>As you walk through the quad, you notice an unusual number of heads turning. A guy on a bench follows you with his eyes, mouth slightly open. A girl walking past does a double-take and then looks confused about why she's staring.</p> <p>It's your pheromones. The X-Change chemical signature is designed to attract. And right now, it's working overtime.</p> <<elseif _level === 3>> <p>The effect is almost visible. People slow down as you pass, turning like sunflowers tracking the sun. A group of guys falls completely silent as you walk by. One of them actually stands up.</p> <p>"Excuse me," he says, but he clearly has no plan for what comes after that sentence.</p> <<else>> <p>It's getting ridiculous. You can't walk ten feet without someone approaching. A guy walks into a lamppost staring at you. Two girls start whispering furiously. A professor drops his briefcase.</p> <p>You need to get inside before you cause an actual scene.</p> <</if>> </div> <<modStat "arousal" 5 "Pheromone attention">> <<modStat "femininity" 2 "Centre of attention">> <<modStat "confidence" -3 "Unwanted attention">>
/* Link shown on any location with a roster */ <<widget "whoIsAround">> <<set _venue = XCLC.Presence.venue(passage())>> <<if _venue>> <<set $temp.presenceFrom = passage()>> <<link '<span class="choice-btn">👥 See who is around</span>' "Presence_Here">> <<advanceTime 5>> <</link>> <</if>> <</widget>>
<<set _from = $temp.presenceFrom || "CampusMap">> <<set _venue = XCLC.Presence.venue(_from)>> <<set _people = XCLC.Presence.here(_from)>> <h2>👥 Around <<print _venue ? _venue.label : "here">></h2> <<if _people.length === 0>> <p>Nobody worth crossing a room for.</p> <<else>> <p>You take a proper look at the room instead of moving through it, which is not something you used to do.</p> <div class="choice-group"> <<for _pi = 0; _pi < _people.length; _pi++>> <<set _p = _people[_pi]>> <<set _hist = XCLC.Presence.history(_p)>> <<set _tag = _p.gender === "male" ? "♂" : "♀">> <<set _btn = '<span class="choice-btn">' + _tag + ' <strong>' + _p.firstName + ' ' + _p.lastName + '</strong>: ' + XCLC.Presence.glance(_p) + (_hist ? '<br><em style="opacity:0.7;">' + _hist + '</em>' : '') + '</span>'>> <<capture _p, _btn>> <<link _btn "Presence_Talk">> <<set $temp.presenceNPCId = _p.id>> <</link>> <</capture>> <</for>> </div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">↩️ Get on with your day</span>' _from>><</link>> </div>
<<set _npc = XCLC.Presence.byId($temp.presenceNPCId)>> <<set _from = $temp.presenceFrom || "CampusMap">> <<if !_npc>> <p>They have gone.</p> <div class="choice-group"><<link '<span class="choice-btn">↩️ Back</span>' _from>><</link>></div> <<else>> <<set _known = (_npc.encounters || 0) > 0>> <<set _they = _npc.gender === "male" ? "he" : "she">> <<set _theyC = _npc.gender === "male" ? "He" : "She">> <<set _them = _npc.gender === "male" ? "him" : "her">> <h2><<print _npc.firstName>> <<print _npc.lastName>></h2> <<if _known>> <p><<print _theyC>> spots you first, which tells you something. There is a half-second of recalibration, the working out of which version of knowing each other this is going to be in public, and then <<print _they>> lifts a hand.</p> <p style="opacity:0.75;"><em><<print XCLC.Presence.history(_npc)>> Opinion of you: <<print Math.round(_npc.opinion)>>/100.</em></p> <<else>> <p><<print XCLC.Service.describeNPC(_npc)>></p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💬 Talk to <<print _them>></span>' "Presence_Chat">> <<advanceTime 20>> <</link>> <<if $pc.confidence >= 30>> <<link '<span class="choice-btn">😏 Flirt <em>(Charm)</em></span>' "Presence_Flirt">> <<advanceTime 15>> <</link>> <</if>> <<if _known && _npc.opinion >= 60 && (_npc.encounters || 0) >= 2>> <<link '<span class="choice-btn">📱 Ask if <<print _they>> wants to arrange something</span>' "Presence_Arrange">> <<advanceTime 10>> <</link>> <</if>> <<canAskOut _npc>> <<if $temp.canAskOut>> <<link '<span class="choice-btn">💞 Ask <<print _them>> out. Properly.</span>' "Relationship_Ask">> <<advanceTime 10>> <</link>> <</if>> <<link '<span class="choice-btn">↩️ Leave it</span>' "Presence_Here">><</link>> </div> <</if>>
<<set _npc = XCLC.Presence.byId($temp.presenceNPCId)>> <<set _from = $temp.presenceFrom || "CampusMap">> <<set _res = XCLC.Roll.doCheck("charm", 3)>> <<run XCLC.DicePopup.show()>> <<set _they = _npc.gender === "male" ? "he" : "she">> <<set _theyC = _npc.gender === "male" ? "He" : "She">> <h2>💬 Talking</h2> <<if _res === "crit_success">> <p>It goes unreasonably well. You find the thing <<print _they>> actually cares about within about ninety seconds and then simply let <<print _they === "he" ? "him" : "her">> talk, and by the end of it <<print _they>> is telling you something <<print _they>> clearly had not planned to tell anyone in a cafeteria.</p> <p>"Sorry," <<print _they>> says. "That was a lot." It was not, particularly. You say so.</p> <<run (function(){ var n = XCLC.Presence.byId(State.variables.temp.presenceNPCId); if(n){ n.opinion = Math.min(100, n.opinion + 12); } }())>> <<modStat "mood" 8 "Good conversation">> <<addXP "charm" 20>> <<elseif _res === "success">> <p>A decent conversation, the ordinary kind, about the term and the building works and somebody you both half know. <<print _theyC>> is easier with you at the end of it than at the start.</p> <<run (function(){ var n = XCLC.Presence.byId(State.variables.temp.presenceNPCId); if(n){ n.opinion = Math.min(100, n.opinion + 6); } }())>> <<modStat "mood" 4 "Pleasant company">> <<addXP "charm" 10>> <<elseif _res === "partial_fail">> <p>It never quite catches. Two dead ends and a joke that lands flat, and then the specific pause where you both consider whether to rescue it and independently decide not to.</p> <<addXP "charm" 4>> <<else>> <p>You misjudge it badly. Too familiar, too fast, on a subject <<print _they>> plainly did not want raised in public. <<print _theyC>> goes polite, which is worse than annoyed.</p> <<run (function(){ var n = XCLC.Presence.byId(State.variables.temp.presenceNPCId); if(n){ n.opinion = Math.max(0, n.opinion - 8); } }())>> <<modStat "confidence" -3 "That went badly">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">↩️ Back</span>' "Presence_Here">><</link>> <<link '<span class="choice-btn">🚶 Get on with your day</span>' _from>><</link>> </div>
<<set _npc = XCLC.Presence.byId($temp.presenceNPCId)>> <<set _from = $temp.presenceFrom || "CampusMap">> <<set _res = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<set _they = _npc.gender === "male" ? "he" : "she">> <<set _theyC = _npc.gender === "male" ? "He" : "She">> <<set _them = _npc.gender === "male" ? "him" : "her">> <h2>😏 Flirting</h2> <<orientationNote _npc.gender>> <<if _res === "crit_success">> <p>You are good at this now. That is the part that still catches you off guard: the timing of it, the half-beat pause before answering, the thing you have learned to do with your eyes that you could not have described a year ago.</p> <p><<print _theyC>> is thoroughly, visibly interested by the end of it, and makes sure you know <<print _they>> would say yes to something if something were offered.</p> <<run (function(){ var n = XCLC.Presence.byId(State.variables.temp.presenceNPCId); if(n){ n.opinion = Math.min(100, n.opinion + 10); n.attraction = Math.min(100, (n.attraction||30) + 25); } }())>> <<modStat "confidence" 6 "It worked">> <<addXP "charm" 22>> <<elseif _res === "success">> <p>Light, easy, unmistakably flirting, and returned, which is the part that matters. Nothing is arranged. Both of you know something could be.</p> <<run (function(){ var n = XCLC.Presence.byId(State.variables.temp.presenceNPCId); if(n){ n.opinion = Math.min(100, n.opinion + 5); n.attraction = Math.min(100, (n.attraction||30) + 14); } }())>> <<modStat "arousal" 8 "Flirting">> <<addXP "charm" 12>> <<elseif _res === "partial_fail">> <p><<print _theyC>> does not pick it up. Not a rejection, just genuinely does not register it, answers the surface of what you said, and moves on. You let it go rather than trying again more obviously.</p> <<addXP "charm" 5>> <<else>> <p><<print _theyC>> picks it up and puts it straight back down. "That's kind. And no, sorry. Not interested." Said kindly enough, and completely without ambiguity.</p> <p>You say of course, and mean it, and the two of you have a short conversation about something else so that neither of you has to leave on that.</p> <<run (function(){ var n = XCLC.Presence.byId(State.variables.temp.presenceNPCId); if(n){ n.attraction = Math.max(0, (n.attraction||30) - 10); } }())>> <<modStat "confidence" -4 "Turned down">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">↩️ Back</span>' "Presence_Here">><</link>> <<link '<span class="choice-btn">🚶 Get on with your day</span>' _from>><</link>> </div>
<<set _npc = XCLC.Presence.byId($temp.presenceNPCId)>> <<set _from = $temp.presenceFrom || "CampusMap">> <<set _they = _npc.gender === "male" ? "he" : "she">> <<set _theyC = _npc.gender === "male" ? "He" : "She">> <<set _them = _npc.gender === "male" ? "him" : "her">> <<set _wants = (_npc.opinion >= 70) || ((_npc.attraction || 30) >= 55)>> <h2>📱 Arranging It</h2> <p>You ask plainly, in a normal voice, the way you would ask about a lift home. It took you an embarrassingly long time to learn that the plain version works better than any of the alternatives.</p> <<if _wants>> <p>"Yeah," <<print _they>> says, and then, checking: "Through the app, or how do you want to do this?"</p> <p>Through the app. It is cleaner that way and you both know exactly where you are with it. <<print _theyC>> puts the request in while you are standing there, which saves everyone a day of waiting.</p> <div class="alert alert--success">📱 <<print _npc.firstName>> has put a request in. It will be waiting on CampusHub.</div> <<run (function(){ var sv = State.variables; var n = XCLC.Presence.byId(sv.temp.presenceNPCId); if (!n) return; var req = XCLC.Service.generateRequest(); req.npcId = n.id; req.requestedBy = n.firstName; sv.scholarship.activeRequest = req; sv.temp.serviceNPC = n; sv.temp.serviceRequest = req; n.opinion = Math.min(100, n.opinion + 4); }())>> <<else>> <p>"Ah. Not right now," <<print _they>> says. Not embarrassed about it, not making a thing of it. "Nothing to do with you. Just not where I am this week."</p> <p>"Fair enough," you say, and mean that too, and the conversation carries on being a conversation.</p> <div class="alert alert--info">🙂 Not this time. Ask again another week.</div> <</if>> <div class="choice-group"> <<if _wants>> <<link '<span class="choice-btn">📱 Open CampusHub</span>' "Phone_CampusHub">><</link>> <</if>> <<link '<span class="choice-btn">↩️ Back</span>' "Presence_Here">><</link>> <<link '<span class="choice-btn">🚶 Get on with your day</span>' _from>><</link>> </div>
/* ═══════════════════════════════════════════════════ THORNFIELD: BAR DISTRICT Four venues: Rusty Nail, Velvet, Pulse, Candy Bar ═══════════════════════════════════════════════════ */ <<set _period = XCLC.Time.getPeriod($world.time)>> <<if _period === "early_morning" || _period === "morning" || _period === "afternoon">> <h2>🍸 Bar District</h2> <p>The neon signs are off, the doors are locked. The bar district doesn't wake up until evening.</p> <p><em>Come back after 5 PM.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div> <<else>> <<checkStreetProposition>> <h2>🍸 Bar District</h2> <<showDrunkStatus>> <<if _period === "evening">> <p>The bar district is warming up. Neon signs flicker to life, bouncers take their posts, and the first crowds trickle in. Bass thumps from somewhere down the street.</p> <<elseif _period === "night">> <p>The bar district is alive. Music bleeds from every doorway, drunk students stumble between venues, and the air smells of cigarettes and regret. It's prime time.</p> <<else>> <p>The bar district is winding down. A few diehards remain, taxis idle at the kerb, and broken glass crunches underfoot.</p> <</if>> <<if $substances.drunkLevel >= 3>> <p><em>The world is... moving. A lot. You grab a lamp post for support.</em></p> <</if>> <<divider "Venues">> <div class="choice-group"> <<link '<span class="choice-btn">🍺 The Rusty Nail: Dive Bar</span>' "Bar_RustyNail">> <<advanceTime 10>> <</link>> <<link '<span class="choice-btn">🍸 Velvet: Cocktail Lounge</span>' "Bar_Velvet">> <<advanceTime 10>> <</link>> <<link '<span class="choice-btn">🎵 Pulse: Dance Club</span>' "Bar_Pulse">> <<advanceTime 10>> <</link>> <<link '<span class="choice-btn">💋 Candy Bar: Strip Club</span>' "Bar_CandyBar">> <<advanceTime 10>> <</link>> /* ─── Velvet Room (BDSM Club) ─── */ <<if $velvetRoom.discovered>> <<link '<span class="choice-btn">🖤 The Velvet Room</span>' "VelvetRoom_Hub">> <<advanceTime 10>> <</link>> <<elseif !$velvetRoom.discovered && ($reputation.slut >= 30 || ($transformation.sideEffects.submissive >= 2))>> <<link '<span class="choice-btn">🚪 An unmarked door...</span>' "VelvetRoom_Discover">><</link>> <</if>> /* ─── Glory Hole (bar bathroom) ─── */ <<if $gloryHole.barDiscovered>> <<link '<span class="choice-btn">🚻 Bar Bathroom (glory hole)</span>' "GloryHole_Bar">> <<advanceTime 10>> <</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">> <<advanceTime 30>> <<if $substances.drunkLevel >= 3>> <<set $temp.drunkTravel = true>> <</if>> <</link>> </div> <</if>>
<h2>🍺 The Rusty Nail</h2> <div class="choice-group"><<whoIsAround>></div> <<showDrunkStatus>> <p>A proper dive. The lighting is bad, the pool table has a rip in the felt, and the jukebox only plays classic rock. The bartender, a burly woman with sleeve tattoos and no discernible interest in anybody's ID, doesn't card a soul.</p> <<if $world.dayOfWeek >= 4>> <p>It's packed tonight. A group of construction workers occupy the corner booth. A few students huddle around the pool table.</p> <<else>> <p>Quiet tonight. A few regulars nurse their drinks. The TV plays sports on mute.</p> <</if>> <<set _dealer = random(1, 10) <= 3>> <<if _dealer>> <p>A thin guy in a hoodie leans against the cigarette machine, making eye contact with anyone who looks his way. <em>Dealer.</em></p> <</if>> <<divider "What do you do?">> <div class="choice-group"> <<link '<span class="choice-btn">🍺 Order a beer ($4)</span>' "Bar_RustyNail">> <<drink "beer">> <<advanceTime 20>> <</link>> <<link '<span class="choice-btn">🥃 Order a shot ($5)</span>' "Bar_RustyNail">> <<drink "shot">> <<advanceTime 15>> <</link>> <<link '<span class="choice-btn">🎱 Play pool</span>' "Bar_RustyNail">> <<advanceTime 30>> <<modStat "mood" 5 "Playing pool">> <<run XCLC.Toast.show("🎱 You play a few rounds. Not bad.", "info")>> <</link>> <<if _dealer>> <<link '<span class="choice-btn">🤫 Talk to the guy in the hoodie</span>' "Bar_DrugDeal">><</link>> <</if>> /* ─── Glory Hole (bar bathroom) ─── */ <<if !$gloryHole.barDiscovered && $substances.drunkLevel >= 2 && $reputation.slut >= 20>> <<link '<span class="choice-btn">🚻 Use the bathroom (you notice something...)</span>' "Bar_RustyNail">> <<set $gloryHole.barDiscovered = true>> <<run XCLC.Toast.show("🚻 You notice a hole in the bathroom stall wall...", "warning")>> <</link>> <<elseif $gloryHole.barDiscovered>> <<link '<span class="choice-btn">🚻 Bathroom (glory hole)</span>' "GloryHole_Bar">><</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">🚪 Leave</span>' "BarDistrict">><</link>> </div>
<h2>🍸 Velvet</h2> <<showDrunkStatus>> /* Bouncer check */ <<if $pc.beautyTotal < 50>> <<set _charmResult = XCLC.Roll.doCheck("charm", 4)>> <<if _charmResult === "crit_fail" || _charmResult === "partial_fail">> <p>The bouncer, a mountain of a man in a black suit, looks you up and down and takes his time about it. "Not tonight, sweetheart." He jerks a thumb toward the street.</p> <p><em>You're not dressed well enough for Velvet. Try improving your outfit or beauty.</em></p> <<run XCLC.DicePopup.show()>> <div class="choice-group"> <<link '<span class="choice-btn">😤 Walk away</span>' "BarDistrict">><</link>> </div> <<else>> <p>The bouncer gives you a once-over and nods. The velvet rope lifts.</p> <<run XCLC.DicePopup.show()>> <<include "Bar_Velvet_Interior">> <</if>> <<else>> <<include "Bar_Velvet_Interior">> <</if>>
<p>Inside, everything is dark wood, soft jazz, and candlelight. The cocktails come in crystal glasses. The clientele skews older: professionals, sugar daddies, women in designer dresses who arrived separately and will leave that way or not.</p> <p><<if $pc.beautyTotal >= 70>>Several heads turn as you walk in. You look good and everyone knows it.<<elseif $pc.beautyTotal >= 50>>You blend in well enough. A few appreciative glances.<<else>>You feel underdressed. Everyone looks more polished than you.<</if>></p> <<divider "What do you do?">> <div class="choice-group"> <<link '<span class="choice-btn">🍸 Order a cocktail ($12)</span>' "Bar_Velvet">> <<drink "cocktail">> <<advanceTime 20>> <</link>> <<link '<span class="choice-btn">🍷 Order wine ($9)</span>' "Bar_Velvet">> <<drink "wine">> <<advanceTime 20>> <</link>> <<link '<span class="choice-btn">💬 Mingle with the crowd</span>' "Bar_Velvet">> <<advanceTime 30>> <<set _charmResult = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _charmResult === "crit_success" || _charmResult === "success">> <<modStat "confidence" 5 "Good conversation">> <<modRep "popular" 2>> <<run XCLC.Toast.show("✨ You made a great impression.", "info")>> <<else>> <<modStat "confidence" -3 "Awkward conversation">> <</if>> <</link>> <<divider "">> <<link '<span class="choice-btn">🚪 Leave</span>' "BarDistrict">><</link>> </div>
<h2>🎵 Pulse</h2> <div class="choice-group"><<whoIsAround>></div> <<showDrunkStatus>> <<if $finance.money < 10>> <p>The bouncer points at the sign: "$10 cover." You check your pockets. Not enough.</p> <div class="choice-group"> <<link '<span class="choice-btn">😤 Can\'t afford the cover</span>' "BarDistrict">><</link>> </div> <<else>> <<set $finance.money -= 10>> <p>You pay the $10 cover and push through the heavy doors. The bass hits you like a wall. Strobe lights cut through fog machines. The dance floor is packed solid. Bodies grinding, hands in the air, sweat and perfume going the same way in the dark.</p> <p>A DJ booth towers over the floor. The VIP section is roped off upstairs. The bar glows neon blue.</p> <<set _dealer = random(1, 10) <= 5>> <<if _dealer>> <p>Near the bathrooms, a guy with glow sticks around his neck catches your eye and tilts his head toward the back hallway. <em>Dealer.</em></p> <</if>> <<divider "What do you do?">> <div class="choice-group"> <<link '<span class="choice-btn">🍸 Order a drink ($7)</span>' "Bar_Pulse">> <<drink "cocktail">> <<advanceTime 15>> <</link>> <<link '<span class="choice-btn">💃 Hit the dance floor</span>' "Bar_Dance">> <<advanceTime 30>> <</link>> <<if _dealer>> <<link '<span class="choice-btn">🤫 Follow the glow stick guy</span>' "Bar_DrugDeal">><</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">🚪 Leave</span>' "BarDistrict">><</link>> </div> <</if>>
<h2>💃 Dance Floor</h2> <<showDrunkStatus>> <<set _danceResult = XCLC.Roll.doCheck("dance", 4)>> <<run XCLC.DicePopup.show()>> <<if _danceResult === "crit_success">> <p>You lose yourself in the music. Your body moves with a confidence you did not know you had. Hips rolling, arms loose, feet finding every beat a fraction before you consciously hear it. A circle forms around you. People are watching, cheering.</p> <p><<if $substances.ecstasy.rolling>>The ecstasy makes every note feel like it's being played inside your body. You've never felt so alive.<<else>>The rhythm takes over. You're not thinking. Only feeling.<</if>></p> <<modStat "confidence" 10 "Amazing dancing">> <<modStat "mood" 15 "Dancing">> <<modRep "popular" 3>> <<addXP "dance" 25>> <<elseif _danceResult === "success">> <p>You find a rhythm and stick with it. Nothing flashy, but you're moving well. A few people dance near you, matching your energy. It feels good.</p> <<modStat "mood" 10 "Dancing">> <<addXP "dance" 15>> <<elseif _danceResult === "partial_fail">> <p>You try to dance but the beat keeps escaping you. Your arms don't know what to do. You bounce awkwardly, hyper-aware of everyone around you looking more natural than you.</p> <<modStat "mood" 3 "Tried to dance">> <<addXP "dance" 8>> <<else>> <p>You step onto the floor and immediately bump into someone, who spills their drink. "Watch it!" Someone laughs. You retreat to the edge, face burning.</p> <<modStat "confidence" -5 "Dance floor disaster">> <<addXP "dance" 5>> <</if>> /* NPC approach chance */ <<set _approached = random(1, 10) <= ($pc.beautyTotal > 60 ? 5 : 3)>> <<if _approached>> <<set _approachNPC = XCLC.NPC.generate({gender: random(1,10) <= 7 ? "male" : "female", type: "student"})>> <<set $temp.barNPC = _approachNPC>> <p><<if _approachNPC.gender === "male">>A <<print _approachNPC.bodyType>> guy<<else>>A <<print _approachNPC.bodyType>> girl<</if>> slides up behind you, <<if $substances.drunkLevel >= 2>>and through the beer goggles they look incredibly hot<<else>>matching your movement<</if>>. "You're a good dancer," <<if _approachNPC.gender === "male">>he<<else>>she<</if>> says close to your ear.</p> <div class="choice-group"> <<link '<span class="choice-btn">😏 Dance with them</span>' "Bar_Dance">> <<advanceTime 20>> <<modStat "arousal" 10 "Grinding">> <<modRep "popular" 1>> <</link>> <<link '<span class="choice-btn">👋 Smile and move away</span>' "Bar_Pulse">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">💃 Keep dancing</span>' "Bar_Dance">> <<advanceTime 20>> <</link>> <<link '<span class="choice-btn">🚪 Head back</span>' "Bar_Pulse">><</link>> </div> <</if>>
<h2>🤫 The Dealer</h2> <p>He's lean, mid-twenties, eyes scanning constantly. "What you need?" he asks, barely moving his lips.</p> <<divider "Available">> <div class="choice-group"> <<if $finance.money >= 15>> <<link '<span class="choice-btn">🌿 Weed: $15</span>' "Bar_DrugDeal">> <<set $finance.money -= 15>> <<set $substances.weed.doses++>><<set $substances.dealerBuys++>> <<run XCLC.Toast.show("🌿 Scored a bag.", "info")>> <<modRep "troublemaker" 1>> <</link>> <</if>> <<if $finance.money >= 30>> <<link '<span class="choice-btn">💊 Ecstasy: $30</span>' "Bar_DrugDeal">> <<set $finance.money -= 30>> <<set $substances.ecstasy.doses++>><<set $substances.dealerBuys++>> <<run XCLC.Toast.show("💊 Scored a pill.", "info")>> <<modRep "troublemaker" 2>> <</link>> <</if>> <<if $finance.money >= 50>> <<link '<span class="choice-btn">❄️ Cocaine: $50</span>' "Bar_DrugDeal">> <<set $finance.money -= 50>> <<set $substances.cocaine.doses++>><<set $substances.dealerBuys++>> <<run XCLC.Toast.show("❄️ Scored a gram.", "info")>> <<modRep "troublemaker" 3>> <</link>> <</if>> <<if $finance.money < 15>> <p><em>You can't afford anything he's selling.</em></p> <</if>> /* He floats the alternative once you are a known face, or once it is obvious you are short. Cash prices above stay on the board. */ <<set _tradeOpen = ($substances.dealerBuys >= 2 || $reputation.slut >= 30 || $substances.dealerTrades > 0)>> <<if _tradeOpen>> <<divider "">> <<if $substances.dealerTrades > 0>> <<link '<span class="choice-btn">💱 "Same arrangement as last time?"</span>' "Dealer_Offer_Rates">><</link>> <<else>> <<link '<span class="choice-btn">💱 He mentions he takes other kinds of payment...</span>' "Dealer_Offer">><</link>> <</if>> <</if>> <<divider "">> <<link '<span class="choice-btn">👋 Nevermind</span>' "BarDistrict">><</link>> </div>
<h2>💋 Candy Bar</h2> <<showDrunkStatus>> <p>The Candy Bar smells like body spray and desperation. Neon pink lights wash everything in a warm glow. A raised stage dominates the center, a pole gleaming under spotlights. Waitresses in lingerie weave between tables.</p> <<if $world.dayOfWeek === 2 || $world.dayOfWeek === 5>> <p>A chalkboard sign reads: <strong>🌟 AMATEUR NIGHT · Dance for Tips!</strong></p> <</if>> <<divider "What do you do?">> <div class="choice-group"> <<link '<span class="choice-btn">👀 Watch a show ($10)</span>' "Bar_StripShow">> <<if $finance.money >= 10>> <<set $finance.money -= 10>> <<advanceTime 30>> <</if>> <</link>> <<link '<span class="choice-btn">🍸 Order a drink ($6)</span>' "Bar_CandyBar">> <<drink "cocktail">> <<advanceTime 15>> <</link>> <<if $world.dayOfWeek === 2 || $world.dayOfWeek === 5>> <<link '<span class="choice-btn">💃 Sign up for Amateur Night</span>' "Bar_AmateurNight">><</link>> <</if>> <<link '<span class="choice-btn">🚪 VIP Back Rooms</span>' "Bar_BackRoom">> <<advanceTime 10>> <</link>> <<divider "">> <<link '<span class="choice-btn">🚪 Leave</span>' "BarDistrict">><</link>> </div>
<h2>👀 The Show</h2> <<if $finance.money < 10>> <p>You can't afford a show right now. The bouncer near the stage area shakes his head.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Bar_CandyBar">><</link>> </div> <<else>> <p>You settle into a plush seat near the stage. The lights dim, the music shifts to something slower, heavier.</p> <<set _dancer = XCLC.NPC.generate({gender: "female", type: "student"})>> <p>A <<print _dancer.bodyType>> woman with <<print _dancer.hairColour>> hair takes the stage. She moves like water. Every muscle controlled, every look deliberate, nothing wasted. The pole work is impressive.</p> <p><<if $pc.femininity >= 50>>You watch with a mix of admiration and something else. Could you do that?<<else>>It's mesmerizing. You can barely look away.<</if>></p> <<modStat "mood" 5 "Entertainment">> <<modStat "arousal" 10 "Strip show">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to the bar</span>' "Bar_CandyBar">><</link>> </div> <</if>>
<h2>💃 Amateur Night</h2> <p>The MC spots you near the sign-up sheet. "You wanna go up? Hundred bucks minimum for anyone who finishes a full routine. Tips on top. You in?"</p> <div class="choice-group"> <<link '<span class="choice-btn">💪 Let\'s do this</span>' "Bar_AmateurNight_Perform">><</link>> <<link '<span class="choice-btn">😰 Actually, never mind</span>' "Bar_CandyBar">><</link>> </div>
<h2>🌟 Your Performance</h2> <<advanceTime 30>> <p>The spotlight hits you. The crowd goes quiet, then someone whistles. The music starts: a deep, thumping beat.</p> /* Stage 1: Basic dance */ <<set _danceResult = XCLC.Roll.doCheck("dance", 4)>> <<run XCLC.DicePopup.show()>> <<set _tips = 20>> <<set _stripped = false>> <<if _danceResult === "crit_success" || _danceResult === "success">> <p>You find the rhythm immediately. Your hips move, your body rolls. The crowd leans in. Dollar bills flutter onto the stage.</p> <<set _tips += 30>> <<addXP "dance" 20>> /* Stage 2: Strip further? */ <div class="choice-group"> <<link '<span class="choice-btn">👕 Strip your top off (more tips)</span>' "Bar_AmateurNight_Strip">> <<set $temp.amateurTips = _tips>> <</link>> <<link '<span class="choice-btn">🎤 Finish the routine (keep clothes on)</span>' "Bar_AmateurNight_Finish">> <<set $temp.amateurTips = _tips>> <</link>> </div> <<else>> <p>You stumble on the first step. The pole is slippery, or your hands are. You try to recover, swaying to the beat, but it's not great. A few polite claps. Some uncomfortable looks.</p> <<set _tips = 20>> <<addXP "dance" 10>> <<set $temp.amateurTips = _tips>> <<modStat "confidence" -5 "Awkward performance">> <div class="choice-group"> <<link '<span class="choice-btn">😳 Get off stage</span>' "Bar_AmateurNight_Finish">><</link>> </div> <</if>>
<h2>💋 Going Further</h2> <<set _composureResult = XCLC.Roll.doCheck("composure", 5)>> <<run XCLC.DicePopup.show()>> <<if _composureResult === "crit_success" || _composureResult === "success">> <p>You pull your top off with a flourish. The crowd roars. You feel the spotlight hot on your <<print $pc.breastSize>>-cup breasts. Dollar bills rain down. Someone yells "Take it ALL off!"</p> <p><<if $pc.femininity >= 60>>Something about this feels... right. The attention, the power of it.<<else>>Your heart is pounding. But the money is good.<</if>></p> <<set $temp.amateurTips += 50>> <<modStat "confidence" 10 "Crowd goes wild">> <<modStat "arousal" 15 "Exhibitionism">> <<modRep "slut" 3>> <<modRep "popular" 2>> <<addXP "dance" 15>> <<else>> <p>You try to pull your top off seductively but your arms get tangled. Someone laughs. You manage to get it off but the moment is lost. A few bills land on stage. Mostly pity tips.</p> <<set $temp.amateurTips += 15>> <<modStat "confidence" -3 "Awkward strip">> <<modRep "slut" 2>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🎤 Finish the routine</span>' "Bar_AmateurNight_Finish">><</link>> </div>
<h2>💰 Results</h2> <<set _totalTips = $temp.amateurTips || 20>> <<set _totalTips += random(-10, 20)>> <<if _totalTips < 20>><<set _totalTips = 20>><</if>> <<set $finance.money += _totalTips>> <p>The music fades. You collect the bills scattered across the stage. The MC hands you the base pay.</p> <div class="card"> <div class="card__title">💰 Amateur Night Earnings</div> <p><strong>Tips + Base:</strong> $<<print _totalTips>></p> <<if _totalTips >= 80>> <p><em>The MC nods appreciatively. "Come back anytime, honey."</em></p> <<elseif _totalTips >= 40>> <p><em>"Not bad for a newbie."</em></p> <<else>> <p><em>The MC pats your shoulder sympathetically. "Practice makes perfect."</em></p> <</if>> </div> <<modRep "partyGirl" 2>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to Candy Bar</span>' "Bar_CandyBar">><</link>> </div>
<h2>🚪 VIP Back Rooms</h2> <p>A hallway lined with curtained booths. Muffled music from the main floor. A bored bouncer checks your ID and waves you through.</p> <p>"Private dances are $50. Anything else is between you and the customer."</p> <<set _clientNPC = XCLC.NPC.generate({gender: "male", type: "premium"})>> <<set $temp.backRoomNPC = _clientNPC>> <p>A <<print _clientNPC.bodyType>> <<print _clientNPC.personality>> man in an expensive suit gestures you over. "How much for a private dance, sweetheart?"</p> <div class="choice-group"> <<link '<span class="choice-btn">💃 Give him a private dance ($50)</span>' "Bar_BackRoom_Dance">><</link>> <<link '<span class="choice-btn">🚪 Just looking</span>' "Bar_CandyBar">><</link>> </div>
<h2>💃 Private Dance</h2> <<advanceTime 20>> <<set _npc = $temp.backRoomNPC>> <<set _danceResult = XCLC.Roll.doCheck("dance", 4)>> <<run XCLC.DicePopup.show()>> <<if _danceResult === "crit_success" || _danceResult === "success">> <p>You straddle his lap, moving to the beat. Your body rolls against him. He's captivated, both hands locked on the armrests, obeying the no-touching rule by the thinnest margin available to him. His breathing goes ragged.</p> <p>"Fuck... you're incredible." He peels off extra bills. "Can we... go further?"</p> <<set _basePay = 50 + random(20, 50)>> <<set $finance.money += _basePay>> <<addXP "dance" 15>> <<addXP "charm" 10>> <<modStat "arousal" 10 "Lap dance">> <<run XCLC.Toast.show("💰 +$" + _basePay + " for the dance", "info")>> <div class="choice-group"> <<link '<span class="choice-btn">😏 "How much further?" (escort)</span>' "Bar_BackRoom_Escort">> <<set $temp.escortPay = random(100, 200)>> <</link>> <<link '<span class="choice-btn">💅 Just the dance</span>' "Bar_CandyBar">><</link>> </div> <<else>> <p>The dance is... fine. Nothing special. He doesn't ask for more. You collect the standard $50 and leave the booth.</p> <<set $finance.money += 50>> <<addXP "dance" 8>> <<run XCLC.Toast.show("💰 +$50 for the dance", "info")>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Bar_CandyBar">><</link>> </div> <</if>>
<h2>💋 Going Further</h2> <<set _npc = $temp.backRoomNPC>> <<set _pay = $temp.escortPay || 150>> <p>"<<print _pay>> bucks," you say. He doesn't even blink. Bills appear on the table.</p> <<set $finance.money += _pay>> <<run XCLC.Toast.show("💰 +$" + _pay, "info")>> <p>The curtain closes. What happens in the back room stays in the back room.</p> /* Simplified service encounter */ <<set _result = XCLC.Roll.doCheck("oral", 4)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>It's quick, efficient, and he's generous afterwards. "You ever want steady work, talk to the manager," he says, straightening his tie.</p> <<modStat "confidence" 3 "Easy money">> <<else>> <p>It's awkward in the cramped booth. Functional. He leaves without a word.</p> <</if>> <<modStat "arousal" 15 "Back room">> <<modRep "slut" 3>> <<modHygiene -15 "Back room encounter">> <<advanceTime 20>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Clean up and go back</span>' "Bar_CandyBar">><</link>> </div>
<h2>🌃 Getting Home Wasted</h2> <<if $substances.drunkLevel >= 4>> /* Blackout */ <p>You... you don't remember leaving. The last thing you recall is the neon signs blurring together, then nothing.</p> <p><em>Fade to black.</em></p> <<set _badEvent = random(1, 10)>> <<if _badEvent <= 3>> <<set $temp.blackoutEvent = "woke up somewhere strange">> <p>You wake up in an unfamiliar bed. Your clothes are scattered on the floor. Someone is snoring next to you. You don't recognise them.</p> <<modStat "stress" 15 "Blackout mystery">> <<modHygiene -30 "Unknown night">> <<elseif _badEvent <= 6>> <p>You wake up on a bench outside the student union. It's 6 AM. Your wallet is lighter than it should be.</p> <<set $finance.money = Math.max(0, $finance.money - random(20, 50))>> <<modStat "stress" 10 "Woke up outside">> <<else>> <p>You wake up in your own bed. Thank god. You have no memory of how you got here. Your phone has 14 missed calls.</p> <<modStat "stress" 5 "Memory gap">> <</if>> <<elseif $substances.drunkLevel >= 3>> /* Wasted */ <p>You stumble toward campus, bouncing off walls and lampposts. A taxi driver honks at you as you wander into the road.</p> <<set _taxiMoney = random(10, 20)>> <<if $finance.money >= _taxiMoney>> <p>Somehow you flag down a taxi. It costs $<<print _taxiMoney>>. You make it home alive.</p> <<set $finance.money -= _taxiMoney>> <<else>> <p>You can't afford a taxi. You walk. It takes forever. Your feet hurt. You may have been sick behind a bush.</p> <<modStat "energy" -20 "Long drunk walk">> <</if>> <</if>> <<resetDrinking>> <<advanceTime 120>> <div class="choice-group"> <<link '<span class="choice-btn">😴 Pass out</span>' "DormRoom">> <<set $world.time = 420>> <<advanceDay>> <</link>> </div>
<<run XCLC.Service.checkForNewRequest()>> <h2>💪 Gym & Locker Room</h2> <div class="choice-group"><<whoIsAround>></div> <p>It's <<showTime>>. <<print XCLC.Gym.getAtmosphere()>></p> <<if $scholarship.activeRequest>> <<set _req = $scholarship.activeRequest>> <<set _elapsed = $world.time - _req.createdAt>> <<set _remaining = 30 - _elapsed>> <div class="alert alert--info">📱 <strong>CampusHub Request!</strong> <<print _req.npc.firstName>> wants <<print _req.serviceType>> at <<print _req.locationName>>. (<<print _remaining>> min remaining)</div> <div class="choice-group"> <<link '<span class="choice-btn">✅ Accept request</span>' `($scholarship.activeRequest && $scholarship.activeRequest.isGroup) ? "GroupMeet" : "ServiceMeet"`>> <<run XCLC.Service.acceptRequest()>> <<advanceTime 10>> <</link>> </div> <</if>> <<if $transformation.sideEffects.pheromones >= 2 && XCLC.Gym.getCrowdedness() === "packed">> <div class="alert alert--warning">🧪 The packed gym is making your pheromones go haywire. You can feel every pair of eyes on you.</div> <<modStat "arousal" 10 "Pheromones in packed gym">> <</if>> <<if $gym.workedOutToday>> <p><em>You've already worked out today. Your muscles need rest.</em></p> <</if>> /* Marcus the trainer */ <<if typeof $gym.metMarcus === 'undefined'>><<set $gym.metMarcus = false>><<set $gym.marcusRep = 0>><<set $gym.marcusTrainedToday = false>><</if>> <<if !$gym.metMarcus>> <p>A tall, muscular Black man in a staff polo approaches you. Late twenties, shaved head, easy grin. "Hey. Marcus." He puts out a hand. "One of the trainers here. Haven't seen you before. You on the X-Change programme?"</p> <p>You nod.</p> <p>"Thought so." He says it without any edge on it. "Listen. I run some off-the-books sessions for programme students. Endurance, flexibility, confidence, the physical side of it. Entirely your call, and I won't bring it up again if the answer's no. Interested?"</p> <<set $gym.metMarcus = true>> <</if>> <div class="choice-group"> <<if !$gym.workedOutToday>> <<link '<span class="choice-btn">🏋️ Weight Training (1 hour)</span>' "GymWorkout">> <<set $temp.gymActivity = "weights">> <</link>> <<link '<span class="choice-btn">🧘 Yoga Class (45 min)</span>' "GymWorkout">> <<set $temp.gymActivity = "yoga">> <</link>> <<link '<span class="choice-btn">🏃 Cardio (45 min)</span>' "GymWorkout">> <<set $temp.gymActivity = "cardio">> <</link>> <</if>> /* Marcus training */ <<if $gym.metMarcus && !$gym.marcusTrainedToday>> <<divider "Marcus's Training">> <<link '<span class="choice-btn">💋 Oral Technique Training (45 min)</span>' "MarcusTraining">> <<set $temp.marcusSkill = "oral">> <</link>> <<link '<span class="choice-btn">🤸 Flexibility & Positions (45 min)</span>' "MarcusTraining">> <<set $temp.marcusSkill = "flexibility">> <</link>> <<link '<span class="choice-btn">💪 Stamina & Endurance (45 min)</span>' "MarcusTraining">> <<set $temp.marcusSkill = "stamina">> <</link>> <<link '<span class="choice-btn">😮 Deep Throat Training (45 min)</span>' "MarcusTraining">> <<set $temp.marcusSkill = "deepThroat">> <</link>> <<link '<span class="choice-btn">🗣️ Dirty Talk Coaching (45 min)</span>' "MarcusTraining">> <<set $temp.marcusSkill = "dirtyTalk">> <</link>> <<elseif $gym.marcusTrainedToday>> <p><em>Marcus waves from across the gym. "Same time tomorrow." You've already trained with him today.</em></p> <</if>> <<link '<span class="choice-btn">🚿 Locker Room & Showers</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<<set _activity = $temp.gymActivity>> <<set _se = $transformation.sideEffects>> /* Apply workout effects */ <<if _activity === "weights">> <h2>🏋️ Weight Training</h2> <p>You take a pair of dumbbells to an open bench. They sit wrong in your hands, which are smaller than the hands that learned this, and your <<print $pc.bodyType>> frame argues with every rep. You do the set anyway.</p> <<if $pc.breastSize === "D" || $pc.breastSize === "DD">> <p>Your <<print $pc.breastSize>>-cups make bench presses awkward. Every rep, they shift and bounce. You catch someone staring and look away.</p> <</if>> <<advanceTime 60>> <<modStat "energy" -20 "Weight training">> <<modStat "mood" 10 "Exercise endorphins">> <<modStat "stress" -10 "Exercise">> <<addXP "stamina" 15>> <<set $pc.beautyFitness = Math.min(15, $pc.beautyFitness + 2)>> <<elseif _activity === "yoga">> <h2>🧘 Yoga Class</h2> <p>You roll out a mat near the back of the studio. The instructor, a whip-thin woman in her thirties who never once looks at her own reflection, walks the class through the sequence.</p> <p>Downward dog is... different with breasts. They hang toward your face. You try not to think about it.</p> <<if _se.increasedSensitivity >= 2>> <p>Every stretch sends tingles through your hypersensitive body. The yoga pants pressing against you in warrior pose makes you bite your lip. This is supposed to be relaxing.</p> <<modStat "arousal" 10 "Sensitive yoga">> <</if>> <<advanceTime 45>> <<modStat "energy" -10 "Yoga">> <<modStat "mood" 8 "Yoga calm">> <<modStat "stress" -15 "Yoga relaxation">> <<addXP "composure" 10>> <<set $pc.beautyFitness = Math.min(15, $pc.beautyFitness + 1)>> <<else>> <h2>🏃 Cardio</h2> <p>You climb onto a treadmill and start running. Your <<print $pc.breastSize>>-cup breasts bounce with every stride despite the sports bra. Your <<print $pc.hairColour>> ponytail whips back and forth.</p> <p>Within ten minutes you're drenched in sweat. But the endorphins hit and for a while, you don't think about anything except the burn.</p> <<advanceTime 45>> <<modStat "energy" -25 "Cardio">> <<modStat "mood" 5 "Runner's high">> <<modStat "stress" -5 "Cardio">> <<addXP "stamina" 20>> <<set $pc.beautyFitness = Math.min(15, $pc.beautyFitness + 2)>> <</if>> /* Common post-workout */ <<set $pc.lastGymDay = $world.day>> <<set $gym.totalVisits++>> <<set $gym.workedOutToday = true>> <<modHygiene -20 "Workout sweat">> <<run XCLC.Beauty.recalculate()>> <<run XCLC.Toast.show('💪 Workout complete! Beauty +' + (_activity === 'yoga' ? '1' : '2') + ' (fitness)', 'success')>> <p>You finish up, muscles aching pleasantly. You're sweaty and probably need a shower.</p> /* Roll for event */ <<set _event = XCLC.Gym.rollEvent(_activity)>> <<if _event>> <<set $temp.gymEvent = _event>> <<include "GymEventDispatch">> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Hit the showers</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">💪 Back to gym</span>' "Gym">><</link>> <<link '<span class="choice-btn">🗺️ Leave gym</span>' "CampusMap">><</link>> </div> <</if>>
<<set _evt = $temp.gymEvent>> <<if _evt.type === "mirror">><<include "GymEvent_Mirror">> <<elseif _evt.type === "wardrobe">><<include "GymEvent_Wardrobe">> <<elseif _evt.type === "spotter">><<include "GymEvent_Spotter">> <<elseif _evt.type === "yogaInstructor">><<include "GymEvent_YogaInstructor">> <<elseif _evt.type === "pheromones">><<include "GymEvent_Pheromones">> <<elseif _evt.type === "jockApproach">><<include "GymEvent_JockApproach">> <<elseif _evt.type === "lockerIntrusion">><<include "GymEvent_LockerIntrusion">> <<elseif _evt.type === "showerScene">><<include "GymEvent_ShowerScene">> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Hit the showers</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">🗺️ Leave gym</span>' "CampusMap">><</link>> </div> <</if>>
<p>On the way to the locker room, you pass the floor-to-ceiling mirror. You stop.</p> <<if $pc.femininity < 30>> <p>The girl in the reflection is flushed and sweating, <<print $pc.hairColour>> hair stuck to her neck, and she is still not you. You remember being broader than this. Taller. Harder to move. This body is soft in places you have no memory of having, and it surprises you every single time.</p> <p>You stare at your <<print $pc.breastSize>>-cup chest rising and falling. Those are yours now. That thought hasn't gotten any less strange.</p> <<modStat "stress" 3 "Dysphoria">> <<elseif $pc.femininity < 60>> <p>You catch your reflection and slow down. Flushed cheeks, <<print $pc.bodyType>> frame, <<print $pc.breastSize>>-cups held down by a sports bra. She is starting to look familiar. She is starting to look like you, which is a different thing.</p> <p>The thought is less terrifying than it used to be. You're not sure what that means.</p> <<modStat "femininity" 1 "Mirror acceptance">> <<else>> <p>You look good and you know it. Flushed from the work, your <<print $pc.bodyType>> body doing nothing to hide itself in gym clothes, <<print $pc.hairColour>> hair wrecked in the way people pay for. You catch yourself posing. Only slightly. Turning just far enough to get a proper look at your <<print $pc.buttSize>> ass.</p> <p>A guy walking past does a double-take. You feel a flush of warmth that has nothing to do with exercise.</p> <<modStat "confidence" 3 "Looking good">> <<modStat "femininity" 2 "Admiring yourself">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Hit the showers</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">🗺️ Leave gym</span>' "CampusMap">><</link>> </div>
<p>Mid-rep you feel the give. The band of your sports bra goes at the seam and your <<print $pc.breastSize>>-cup breasts drop loose under a tank top that was never intended to work alone. There is no disguising it and you have about four seconds.</p> <<set _composureCheck = XCLC.Roll.doCheck("composure", 3)>> <<if _composureCheck.outcome === "crit_success" || _composureCheck.outcome === "success">> <p>You fold your arms like you meant to, collect your towel on the way past, and have it over your chest before you reach the door. Nobody noticed. If anybody noticed, they will never be able to prove it.</p> <<modStat "confidence" 2 "Handled it">> <<else>> <p>You freeze. Your nipples are clearly visible through the thin fabric. The guy on the machine next to you stares openly. You grab your things and practically run to the locker room, face burning.</p> <<modStat "confidence" -5 "Public wardrobe malfunction">> <<modRep "slut" 2 "Wardrobe malfunction">> <<if $transformation.sideEffects.exhibitionist >= 2>> <p>The worst part is that you liked it. Your face is burning and not all of the heat is shame, and you will be turning that over on the walk home.</p> <<modStat "arousal" 10 "Exhibitionist thrill">> <</if>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Hit the showers</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">🗺️ Leave gym</span>' "CampusMap">><</link>> </div>
<<set _npc = XCLC.NPC.generate('student')>> <p>A <<print _npc.bodyType>> guy with <<print _npc.hairColour>> hair and <<print _npc.eyeColour>> eyes approaches your bench. "Need a spot?"</p> <p>He is already moving into position before you have answered, and he sets up standing over the bar with his hips at the height of your face. His hands go under the bar, which is where a spotter's hands belong, and then they start drifting outward along the bar towards your ribs, which is not.</p> <p>"Just keeping you safe," he says, with a smile that is doing something else entirely.</p> <div class="choice-group"> <<link '<span class="choice-btn">🤚 "Hands on the bar or get off my bench."</span>' "Gym">> <<modStat "confidence" 4 "Named it on the spot">> <<run XCLC.Toast.show('He puts his hands back on the bar and finds somewhere else to be after the set.', 'success')>> <</link>> <<link '<span class="choice-btn">🏋️ Rack it and end the set yourself</span>' "Gym">> <<modStat "confidence" 2 "Removed yourself">> <<run XCLC.Toast.show('You rack the bar mid-set and go and use the machines instead. He gets the message.', 'info')>> <</link>> <<link '<span class="choice-btn">😶 Say nothing and get through the set</span>' "Gym">> <<modStat "stress" 6 "Said nothing">> <<run XCLC.Toast.show('You finish the set. It stays with you longer than the workout does.', 'warning')>> <</link>> </div>
<p>The yoga instructor moves through the class, adjusting poses. When she reaches you, her hands linger on your hips, sliding you into a deeper stretch.</p> <p>"Open your hips," she says, pressing down on your lower back with the flat of her hand. The stretch is good. Then her other hand comes to your inner thigh, well above where an alignment cue needs to be, and stops there.</p> <<if $transformation.sideEffects.increasedSensitivity >= 2>> <p>Your body lights up under her hand before your opinion has been consulted. You get the sound back down into your throat, mostly. She notices, and holds your eyes a beat longer than she needs to.</p> <<modStat "arousal" 15 "Instructor's touch + sensitivity">> <<else>> <<modStat "arousal" 8 "Instructor's touch">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">✋ "That is not where the cue goes."</span>' "Gym">> <<modStat "confidence" 4 "Corrected an instructor">> <<run XCLC.Toast.show('She apologises, crisply and professionally, and keeps to your shoulders for the rest of the hour.', 'success')>> <</link>> <<link '<span class="choice-btn">🧘 Shift out of the pose and reset</span>' "Gym">> <<modStat "confidence" 2 "Moved yourself out of it">> <<run XCLC.Toast.show('You come out of the pose and set up again a foot further away. She takes the hint.', 'info')>> <</link>> <<link '<span class="choice-btn">😶🌫️ Hold the pose and say nothing</span>' "Gym">> <<modStat "stress" 5 "Held it in">> <<run XCLC.Toast.show('You hold the stretch until she moves on. The class finishes. You do not book the next one.', 'warning')>> <</link>> </div>
<p>The gym is packed and your pheromones are in overdrive. Within ten minutes of your workout, a semicircle of guys has materialized around your area of the gym. Two are pretending to use machines nearby. One is just standing there, not even pretending.</p> <p>"Can I help you?" you ask. None of them move.</p> <p>More of them drift over. You can feel the attention as an actual weight on your skin, and the infuriating part is that your body has decided to answer it, a low warmth spreading through your stomach while you are still trying to leave.</p> <<modStat "arousal" 15 "Pheromone gym swarm">> <<modStat "femininity" 2 "Centre of attention">> <<modStat "stress" 5 "Surrounded">> <div class="choice-group"> <<link '<span class="choice-btn">🏃 Escape to the locker room</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">🗺️ Leave the gym entirely</span>' "CampusMap">><</link>> </div>
<<ensureServiceContext>> <<set _jock = XCLC.NPC.generate('student')>> <p>A <<print _jock.height>>, <<print _jock.bodyType>> guy in a tank top approaches you. <<print _jock.hairColour.charAt(0).toUpperCase()>><<print _jock.hairColour.slice(1)>> hair, <<print _jock.eyeColour>> eyes, the kind of arms that suggest he lives here.</p> <p>"Hey. <<print _jock.firstName>>." He extends a hand. "You're in the programme, right? CCUMDUP?"</p> <p>You nod cautiously.</p> <p>"Cool. I'm a Premium Student. Was gonna request you on CampusHub, but since you're here..." He shrugs. "Want to skip the app and just... handle it now?"</p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Sure, let\'s do this</span>' "ServiceMeet">> /* Create a request object directly */ <<set $temp.serviceRequest = { npc: _jock, serviceType: _jock.preferredService || 'oral', location: 'locker_room', locationName: 'Locker Room', locationDesc: 'the gym locker room, steamy and echoing', locationPrivacy: 'medium', createdAt: $world.time, createdDay: $world.day, dc: XCLC.Service.getServiceDC(_jock, _jock.preferredService || 'oral'), credits: (_jock.preferredService === 'anal') ? 2 : 1, bonusCredits: 0 }>> <<set $temp.serviceNPC = _jock>> <<set $scholarship.inService = true>> <</link>> <<link '<span class="choice-btn">❌ No thanks, I\'m just here to work out</span>' "Gym">> <<run XCLC.Toast.show('He looks disappointed but shrugs. "Your loss."', 'info')>> <</link>> </div>
<h2>🚿 Locker Room</h2> <p>The women's locker room: rows of blue metal lockers, wooden benches worn pale in the middle, and a tiled shower area at the back with steam rolling out of it.</p> <<if $hygiene.cleanliness < 60>> <p>You definitely need a shower. You can smell yourself.</p> <</if>> /* Roll for locker event */ <<set _lockerEvent = XCLC.Gym.rollEvent('locker')>> <<if _lockerEvent>> <<set $temp.gymEvent = _lockerEvent>> <<include "GymEventDispatch">> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Take a shower (15 min)</span>' "GymShower">><</link>> <<link '<span class="choice-btn">💪 Back to gym</span>' "Gym">><</link>> <<link '<span class="choice-btn">🗺️ Leave</span>' "CampusMap">><</link>> </div> <</if>>
<h2>🚿 Shower</h2> <p>You strip and step into a stall. The water is hot enough to hurt for a second and then exactly right, and you hear yourself make a noise as the work of the last hour goes out of your shoulders.</p> <<if $transformation.sideEffects.increasedSensitivity >= 2>> <p>The pressure on skin this sensitive is close to obscene. Every drop registers separately. The spray crosses your breasts, your stomach, lower, and you end up with both palms flat against the tile, breathing carefully, waiting for it to stop being a problem.</p> <<modStat "arousal" 10 "Sensitive shower">> <</if>> <<if $transformation.sideEffects.lactation >= 2>> <p>The warm water triggers your milk. White streams run down your <<print $pc.breastSize>>-cup breasts and spiral down the drain. At least nobody can see in here.</p> <</if>> <<advanceTime 15>> <<modHygiene 30 "Gym shower">> <p>You towel off, feeling clean and refreshed.</p> <div class="choice-group"> <<link '<span class="choice-btn">💪 Back to gym</span>' "Gym">><</link>> <<link '<span class="choice-btn">🗺️ Leave</span>' "CampusMap">><</link>> </div>
<p>You are halfway through changing, bra unclasped and jeans round your ankles, when the door bangs open and a guy walks in.</p> <p>"Sorry, wrong." He gets that far and stops. He does not leave, and his eyes go from your face down and stay down.</p> <<set _composureCheck = XCLC.Roll.doCheck("composure", 3)>> <<if _composureCheck.outcome === "crit_success" || _composureCheck.outcome === "success">> <p>You grab your towel and cover up in one smooth motion. "Wrong room," you say flatly. "Out." He retreats, muttering apologies.</p> <<modStat "confidence" 3 "Handled it calmly">> <<else>> <p>You get a hand up and the towel across you a half second slower than you would have liked. "Out." It comes out louder than you meant and it works. Somebody in the corridor hauls him back by the shoulder. "Mate, that's the women's." The door bangs shut on him.</p> <p>You sit down on the bench with the towel still gripped in one fist and let your heart come back down.</p> <<modStat "confidence" -2 "Rattled">> <<modStat "stress" 5 "Locker room intrusion">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Take a shower to calm down</span>' "GymShower">><</link>> <<link '<span class="choice-btn">🗺️ Get dressed and leave</span>' "CampusMap">><</link>> </div>
<p>You're in the shower, eyes closed, water cascading over you, when you hear the stall curtain slide back. Your eyes fly open.</p> <<set _npc = XCLC.NPC.generate('student')>> <p>A <<print _npc.bodyType>> <<if _npc.gender === "male">>guy<<else>>girl<</if>> with <<print _npc.hairColour>> hair is standing there, naked, acting like this is completely normal.</p> <<if _npc.gender === "male">> <p>"Room for two?" <<print _npc.firstName>> asks, already stepping in. He's <<if _npc.cockSize === "large" || _npc.cockSize === "huge">>hard to miss<<else>>not shy about it<</if>>.</p> <<else>> <p>"Mind sharing?" <<print _npc.firstName>> says, sliding in beside you. "The other stalls are taken." They're clearly not, but she doesn't seem to care.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚫 Get out. Now.</span>' "GymShower">> <<modStat "confidence" 3 "Stood your ground">> <</link>> <<link '<span class="choice-btn">😶 ...Fine.</span>' "GymShower">> <<modStat "femininity" 2 "Accepting intimacy">> <<modStat "arousal" 15 "Shared shower">> <<if $transformation.sideEffects.submissive >= 2>> <<modStat "arousal" 10 "Submissive compliance">> <</if>> <</link>> </div>
/* Defaults so a stale link cannot throw */ <<set _skill = $temp.marcusSkill || "stamina">> <<set _skillObj = $skills[_skill] || $skills.stamina>> <<set _repBonus = Math.min(5, Math.floor($gym.marcusRep / 3))>> <<set _xpGain = 25 + _repBonus * 5>> <h2>💪 Training with Marcus</h2> <p>Marcus takes you to a private room at the back of the gym. It is small: mats down, a mirror along one wall, a bench. He locks the door and then tells you he has, which you notice he does every time.</p> <p>"Alright. <<print $pc.femaleFirstName>>. Today we're working on <<print _skillObj.name>>."</p> <<if _skill === "oral">> <p>He produces a set of training aids from a locked cabinet. "Technique is everything. Jaw, tongue, breathing. Most girls on the programme just wing it and get through it. You're going to be better than that."</p> <p>For forty-five minutes, he drills you through exercises. Jaw stretches that make your eyes water. Tongue isolation movements that feel ridiculous until you realise you can already feel the difference. Breathing patterns.</p> <<if $gym.marcusRep >= 5>> <p>"You're getting good at this," Marcus says with a nod. "Real good. Your rating's gonna climb."</p> <</if>> <<modStat "arousal" 8 "Oral training">> <<elseif _skill === "flexibility">> <p>"Positions are half the battle," Marcus says, dropping onto a mat. "If you can't hold a position, you lose control of the encounter. And control is how you get five stars."</p> <p>He takes you through a run of stretches and positions, some of them straight out of a yoga class and some of them very much not. Your <<print $pc.bodyType>> body complains for the first ten minutes. He is unhurried about it, squaring your hips, putting a hand between your shoulder blades and waiting until you drop.</p> <<if $transformation.sideEffects.increasedSensitivity >= 2>> <p>His hands on your body are electric. The stretches open you up in ways that send blood rushing to places that have nothing to do with flexibility.</p> <<modStat "arousal" 12 "Sensitive flexibility training">> <<else>> <<modStat "arousal" 5 "Physical contact">> <</if>> <<elseif _skill === "stamina">> <p>"Endurance," Marcus says, setting a timer. "Most encounters last five to fifteen minutes. Your muscles need to hold up. Your lungs need to hold up. And your mind needs to hold up."</p> <p>He puts you through a circuit built to hurt: planks, wall sits, hip thrusts, core work until your stomach is shaking. He counts you through every set and does not once let you stop early.</p> <p>"Halfway through, when you're tired and it's a lot, that's when technique falls apart. Stamina is what keeps the rest of it working."</p> <<modStat "energy" -15 "Stamina training">> <<elseif _skill === "deepThroat">> <p>Marcus pulls out training aids of escalating sizes. "Deep throat is about overriding your gag reflex. It's a physical skill, not a mental one. We're gonna train the muscle."</p> <p>It is uncomfortable and it is humiliating, kneeling on a gym mat with your eyes streaming, fighting your own throat while Marcus talks you through the breathing and the angle in the flattest voice imaginable.</p> <<if $gym.marcusRep < 3>> <p>"Don't fight it. Relax. Swallow. There you go." His voice is calm, professional. Like he's coaching a squat form. Somehow that makes it both better and worse.</p> <<else>> <p>"There. No gag at all. You've come a long way." There is real pride in it, and it lands somewhere you were not braced for.</p> <</if>> <<modStat "arousal" 10 "Deep throat training">> <<modStat "confidence" -2 "Humbling training">> <<elseif _skill === "dirtyTalk">> <p>"Communication," Marcus says, leaning against the wall. "Half of a five-star rating is making them feel like a god. Words are your best tool."</p> <p>He hands you a list of phrases and makes you practise them. Out loud. To his face. Looking him in the eye.</p> <<if $gym.marcusRep < 3>> <p>It is mortifying. Your face is on fire and you are stumbling through lines you would not say out loud alone in a locked room. Marcus does not laugh once. He corrects your tone, your timing, and where you put the pause.</p> <p>"More breathy. You're telling them what they want to hear, not reading a grocery list."</p> <<modStat "confidence" -3 "Embarrassing training">> <<else>> <p>You deliver the lines smoothly now. Some of them even feel natural. Marcus nods approvingly. "You could sell ice to Eskimos. They won't know what hit them."</p> <<modStat "confidence" 3 "Finding your voice">> <</if>> <<modStat "arousal" 5 "Dirty talk practice">> <</if>> /* Apply XP and effects */ <<advanceTime 45>> <<addXP _skill _xpGain>> <<set $gym.marcusRep++>> <<set $gym.marcusTrainedToday = true>> <<modStat "femininity" 1 "Marcus's training">> <p>Marcus claps you on the shoulder. "Good session. <<if $gym.marcusRep <= 3>>Keep at it and you'll be running circles around the other programme students.<<elseif $gym.marcusRep <= 8>>You're improving fast. I can tell.<<else>>Honestly? You're one of the best I've trained. Natural talent."<</if>>"</p> <div class="choice-group"> <<link '<span class="choice-btn">💪 Back to gym</span>' "Gym">><</link>> <<link '<span class="choice-btn">🚿 Hit the showers</span>' "GymLocker">><</link>> <<link '<span class="choice-btn">🗺️ Leave</span>' "CampusMap">><</link>> </div>
/* Player picks 5 classes from 8. Rendered via JS for toggle cards. */ <h2>📚 Class Registration</h2> <p>Before orientation ends, you need to register for your first semester classes. You'll take <strong>5 classes</strong>: three on Monday, Wednesday and Friday, and two on Tuesday and Thursday.</p> <p>Choose from the available courses:</p> <div id="class-picker"></div> <div id="class-confirm" style="margin-top:1em;"></div> <<run setTimeout(function(){ var pool = XCLC.Academic.CLASS_POOL; var selected = []; var picker = jQuery('#class-picker'); var html = '<div class="cc-grid" style="display:grid;grid-template-columns:repeat(2,1fr);gap:0.5em;">'; for (var i = 0; i < pool.length; i++) { html += '<div class="cc-option class-pick" data-idx="' + i + '" style="cursor:pointer;padding:0.8em;border-radius:8px;border:2px solid var(--surface-2);background:var(--surface-1);transition:all 0.2s;">' + '<div style="font-size:1.3em;">' + pool[i].icon + '</div>' + '<div style="font-weight:600;">' + pool[i].name + '</div>' + '<div style="font-size:0.8em;opacity:0.7;">' + pool[i].department + ' Department</div>' + '</div>'; } html += '</div>'; picker.html(html); picker.find('.class-pick').on('click', function(){ var idx = parseInt(jQuery(this).data('idx')); var pos = selected.indexOf(idx); if (pos >= 0) { selected.splice(pos, 1); jQuery(this).css({'border-color':'var(--surface-2)', 'background':'var(--surface-1)'}); } else if (selected.length < 5) { selected.push(idx); jQuery(this).css({'border-color':'var(--accent)', 'background':'rgba(139,92,246,0.15)'}); } /* Update confirm button */ var confirmEl = jQuery('#class-confirm'); if (selected.length === 5) { confirmEl.html('<span class="choice-btn" id="confirm-classes" style="cursor:pointer;">✅ Confirm ' + selected.length + '/5 classes</span>'); jQuery('#confirm-classes').off('click').on('click', function(){ XCLC.Academic.buildSchedule(selected); Engine.play('ClassSelection_Confirm'); }); } else { confirmEl.html('<p style="opacity:0.6;">Selected: ' + selected.length + '/5</p>'); } }); }, 50)>>
<h2>📚 Schedule Confirmed</h2> <p>Your first semester schedule:</p> <div class="card"> <div class="card__title">📋 Your Classes</div> <<for _i = 0; _i < $academic.classes.length; _i++>> <<set _cls = $academic.classes[_i]>> <<set _prof = $academic.professors[_cls.professorIndex]>> <p><<print _cls.icon>> <strong><<print _cls.name>></strong> · <<print _cls.days>> <<print _cls.timeLabel>><br> <em>Prof. <<print _prof.lastName>> (<<print _prof.profType>>)</em></p> <</for>> </div> <p>Classes start tomorrow. Don't be late.</p> <div class="choice-group"> <<link '<span class="choice-btn">📱 Got it. Let\'s go.</span>' "CampusMap">> <<set $world.time = 600>> <</link>> </div>
<h2>📚 Lecture Halls</h2> <<if !$academic.classesChosen>> <p>You haven't registered for classes yet. That happens during orientation.</p> <<link '<span class="choice-btn">← Back to campus</span>' "CampusMap">><</link>> <<else>> <<set _today = XCLC.Academic.getScheduleForDay()>> <<set _dayNames = ['', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']>> <<set _dayName = _dayNames[$world.dayOfWeek] || 'Weekend'>> <<if $world.dayOfWeek >= 6>> <p>It's <<print _dayName>>. No classes today.</p> <<link '<span class="choice-btn">← Back to campus</span>' "CampusMap">><</link>> <<else>> <p><<print _dayName>>'s schedule:</p> <div class="card"> <div class="card__title">📋 Today's Classes</div> <<for _i = 0; _i < _today.length; _i++>> <<set _cls = _today[_i]>> <<set _prof = $academic.professors[_cls.professorIndex]>> <<set _isNow = ($world.time >= _cls.startTime && $world.time < _cls.endTime)>> <<set _isPast = ($world.time >= _cls.endTime)>> <p><<if _isNow>>🟢<<elseif _isPast>>✅<<else>>⬜<</if>> <<print _cls.icon>> <strong><<print _cls.name>></strong> · <<print _cls.timeLabel>><br> <em>Prof. <<print _prof.lastName>></em> | Grade: <<print Math.round(_cls.grade)>>%</p> <</for>> </div> <<set _current = XCLC.Academic.getCurrentClass()>> <<if _current>> <<set _currentCls = _current.classObj>> <<set _currentProf = $academic.professors[_currentCls.professorIndex]>> <div class="alert alert--info">🔔 <<print _currentCls.name>> with Prof. <<print _currentProf.lastName>> is in session right now!</div> <div class="choice-group"> <<link '<span class="choice-btn">📖 Attend class</span>' "AttendClass">> <<set $temp.classIndex = _current.index>> <<set $temp.classEvent = XCLC.Academic.attendClass(_current.index)>> <<advanceTime 60>> <<addXP "intelligence" 10>> <<modStat "energy" -5 "Lecture">> <</link>> <<link '<span class="choice-btn">🚫 Skip it</span>' "CampusMap">> <<run XCLC.Academic.skipClass(_current.index)>> <<run XCLC.Toast.show('📚 Skipped ' + _currentCls.name + '. Grade will suffer.', 'warning')>> <</link>> </div> <<else>> <p>No class in session right now.<<set _next = null>><<for _j = 0; _j < _today.length; _j++>><<if !_next && _today[_j].startTime > $world.time>><<set _next = _today[_j]>><</if>><</for>><<if _next>> Next up: <<print _next.name>> at <<print _next.timeLabel>>.<</if>></p> <<if _next>> <div class="choice-group"> <<capture _next>> <<link '<span class="choice-btn">⏳ Wait here until class starts</span>' "LectureHalls">> <<advanceTime `Math.max(0, _next.startTime - $world.time)`>> <<modStat "energy" -2 "Waiting around">> <<run XCLC.Toast.show('⏳ You wait around until class starts.', 'info')>> <</link>> <</capture>> </div> <</if>> <</if>> /* ─── Exams ─── */ <<set _isMidtermWeek = ($world.week === 8)>> <<set _isFinalsWeek = ($world.week >= 15)>> <<if _isMidtermWeek || _isFinalsWeek>> <<set _examType = _isFinalsWeek ? "final" : "midterm">> <div class="card" style="border-left: 3px solid var(--accent-red);"> <div class="card__title">📝 <<if _isFinalsWeek>>FINALS WEEK<<else>>MIDTERM WEEK<</if>></div> <p><<if _isFinalsWeek>>Finals count for 40% of your grade. Fail 3 or more and you repeat the semester.<<else>>Midterms count for 30% of your grade.<</if>> Exams take 2 hours each.</p> <<set _pending = 0>> <<for _ei = 0; _ei < $academic.classes.length; _ei++>> <<set _ecls = $academic.classes[_ei]>> <<set _done = _isFinalsWeek ? _ecls.finalDone : _ecls.midtermDone>> <<if _done>> <p>✅ <<print _ecls.icon>> <strong><<print _ecls.name>></strong> · <<print XCLC.Academic.examLetter(_isFinalsWeek ? _ecls.finalScore : _ecls.midtermScore)>> (<<print _isFinalsWeek ? _ecls.finalScore : _ecls.midtermScore>>%)</p> <<else>> <<set _pending++>> <<capture _ei, _examType>> <<link '<span class="choice-btn">📝 Sit the <<print _ecls.name>> <<print _examType>> (DC <<print XCLC.Academic.examDC(_ei)>>)</span>' "AcademicExam">> <<set $temp.examClassIndex = _ei>> <<set $temp.examType = _examType>> <</link>> <</capture>> <</if>> <</for>> <<if _pending === 0>> <p><em>All <<print _examType>>s done. Breathe.</em></p> <</if>> </div> <</if>> <<if $academic.drakeCase.stage !== 0 && !$academic.drakeCase.resolved>> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Prof. <<print $academic.professors[$academic.drakeCase.profIndex].lastName>>: build your case</span>' "Drake_Investigate">><</link>> </div> <</if>> <<set _gpa = XCLC.Academic.getGPA()>> <p><strong>GPA:</strong> <<print _gpa>> / 4.0 <<if _gpa < 2.0>><span style="color:var(--danger);">⚠️ ACADEMIC PROBATION</span><</if>></p> <<link '<span class="choice-btn">← Back to campus</span>' "CampusMap">><</link>> <</if>> <</if>>
<<set _ci = $temp.examClassIndex || 0>> <<set _type = $temp.examType || "midterm">> <<set _cls = $academic.classes[_ci]>> <<if !_cls>> <p>No exam is scheduled for you right now.</p> <div class="choice-group"><<link '<span class="choice-btn">â©ï¸ Back</span>' "LectureHalls">><</link>></div> <<else>> <<set _prof = ($academic.professors || [])[_cls.professorIndex] || {lastName: "Whitlock", firstName: "A."}>> <h2>📝 <<print _cls.name>>: <<print _type.charAt(0).toUpperCase()>><<print _type.slice(1)>></h2> <<advanceTime 120>> <p>Prof. <<print _prof.lastName>> hands out the papers. The room is silent except for pencil scratches and the occasional despairing sigh.</p> <<if $transformation.sideEffects.bimbofication >= 3>> <p>You stare at question one. The words rearrange themselves into soup. You draw a heart next to it and move on.</p> <<elseif $pc.energy < 30>> <p>You're exhausted. The questions blur. You push through on stubbornness alone.</p> <</if>> <<set _result = XCLC.Academic.takeExam(_ci, _type)>> <<run XCLC.DicePopup.show()>> <<if _result.outcome === "crit_success">> <p>It clicks. Every question maps to something you actually studied. You finish early and double-check your answers, quietly smug.</p> <<elseif _result.outcome === "success">> <p>Solid. A couple of questions make you sweat, but you know this material better than you thought.</p> <<elseif _result.outcome === "partial_fail">> <p>Rough patches. You blank on a whole section and have to guess. You walk out not sure which way it went.</p> <<else>> <p>Disaster. Half the exam might as well be in another language. You write <em>something</em> for every question and hope for partial credit.</p> <<modStat "stress" 10 "Bombed an exam">> <<modStat "confidence" -5 "Bombed an exam">> <</if>> <div class="card"> <div class="card__title">📊 Result</div> <p><strong>Grade:</strong> <<print _result.letter>> (<<print _result.score>>%)</p> <p><strong>Class grade now:</strong> <<print Math.round(_cls.grade)>>%</p> </div> <<addXP "intelligence" 15>> <<modStat "energy" -15 "Exam">> <<modStat "stress" 5 "Exam pressure">> <<if _type === "final" && _result.score >= 60>> <<awardAchievement "surviveFinals">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">📚 Back to Lecture Halls</span>' "LectureHalls">><</link>> <<link '<span class="choice-btn">🗺️ Back to campus</span>' "CampusMap">><</link>> </div> <</if>>
/* Fallbacks so a stale link or reloaded save cannot throw */ <<set _evt = $temp.classEvent || {}>> <<set _cls = _evt.cls || $academic.classes[0] || {icon: "📚", name: "your next class", grade: 70}>> <<set _prof = _evt.prof || {lastName: "Whitlock", firstName: "A.", gender: "male"}>> <<set _evt = {cls: _cls, prof: _prof, type: _evt.type || "lecture"}>> <h2><<print _cls.icon>> <<print _cls.name>></h2> <p>You take your seat in the lecture hall. Prof. <<print _prof.lastName>> is already at the podium.</p> <<if _evt.type === "normal">> <p>The lecture proceeds normally. <<print _prof.firstName>> <<print _prof.lastName>> covers new material. You take notes, follow along, and actually learn something.</p> <<if $transformation.sideEffects.bimbofication >= 1>> <p>Some of the concepts are harder to grasp than they should be. But you manage.</p> <</if>> <<modStat "mood" 2 "Productive class">> <<elseif _evt.type === "bimbo">> <p>Prof. <<print _prof.lastName>> is explaining something, and then something else, and you have lost the thread of both. You stare at the whiteboard until the words come apart. You write a note, and when you look down at it properly it is three hearts and a spiral.</p> <p>The girl beside you catches sight of the page. You would rather she had not.</p> <<modStat "confidence" -3 "Can't follow lecture">> <<modStat "mood" -5 "Feeling stupid">> <<elseif _evt.type === "orgasm">> <p>It arrives mid-lecture with no warning at all. That familiar warmth, low down and spreading, and absolutely nothing you can do about the timing of it. Not here. Please, not here.</p> <p>You take hold of the edge of the desk hard enough to whiten your knuckles. A small sound gets out of you and you turn it into a cough, badly.</p> <<if random(1,100) <= 40>> <p>The student beside you glances across. "You okay?" You nod far too quickly, face going scarlet, and sit very still until it has finished with you.</p> <<modStat "confidence" -5 "Public orgasm in class">> <<modRep "slut" 2 "Suspicious behaviour in class">> <<else>> <p>Somehow you get through it without a single person turning round. Your notes for those five minutes are one unbroken line dragged across the page.</p> <</if>> <<modStat "arousal" -20 "Involuntary orgasm">> <<elseif _evt.type === "sensitivity">> <p>The wooden lecture seat is its own small torture. Every time you shift, something reports back, and none of it is helpful. It is a great deal more than you can comfortably ignore for an hour.</p> <p>You spend the whole lecture concentrating on not squirming and absorb precisely nothing.</p> <<modStat "arousal" 15 "Sensitivity in class">> <<modStat "stress" 5 "Uncomfortable">> <<elseif _evt.type === "lactation">> <p>Halfway through the lecture you feel it start: warm wetness spreading out across your chest. Your milk is letting down, and there are already two dark circles on your top.</p> <<if _prof.awarenessOfCCUMDUP>> <p>Prof. <<print _prof.lastName>> glances at you and quickly looks away. <<if _prof.profType === "sympathetic">>After class, they quietly say: "There are spare shirts in the health centre, if you need."<<elseif _prof.profType === "creepy">>You catch <<print _prof.firstName>> staring at your chest with an expression that makes your skin crawl.<</if>></p> <<else>> <p>You cross your arms and try to hide it. The guy in front of you turns around and stares. Great.</p> <</if>> <<modStat "confidence" -5 "Leaking in class">> <<elseif _evt.type === "daydream">> <p>Prof. <<print _prof.lastName>>'s voice thins out into background noise. Your mind goes elsewhere. Warm hands on your skin. A mouth at your neck. Someone standing close behind you.</p> <p>"<<print $pc.femaleFirstName>>?"</p> <p>You jolt awake. The entire class is looking at you. You have no idea what the question was.</p> <<modStat "arousal" 10 "Sexual daydream">> <<modStat "confidence" -3 "Caught daydreaming">> <<elseif _evt.type === "pheromones">> <p>The guy sitting next to you keeps inching closer. His friend on the other side is doing the same thing. Within twenty minutes you're surrounded by a semicircle of guys who all found reasons to sit near you.</p> <p>Prof. <<print _prof.lastName>> has to ask them to spread out. Twice.</p> <<modStat "femininity" 2 "Centre of attention">> <<modStat "arousal" 5 "Pheromone attention">> <<elseif _evt.type === "calledOn">> <p>"<<print $pc.femaleFirstName>>? Can you tell the class...?"</p> <p>Prof. <<print _prof.lastName>> is looking right at you. Everyone turns to stare.</p> <<if $pc.intelligence >= 60>> <p>You actually know this one. The answer comes out smoothly. <<print _prof.firstName>> nods, impressed.</p> <<modStat "confidence" 5 "Good answer">> <<if _prof.profType === "demanding">><<modStat "mood" 3 "Impressed the tough prof">><</if>> <<elseif $pc.intelligence >= 35>> <p>You stumble through a half-answer. It's not great. It's not terrible. Prof. <<print _prof.lastName>> moves on.</p> <<else>> <p>"I... um..." The silence stretches. Someone coughs. <<print _prof.firstName>> <<print _prof.lastName>> sighs and calls on someone else. You sink into your seat.</p> <<modStat "confidence" -5 "Couldn't answer">> <<modStat "stress" 5 "Public embarrassment">> <</if>> <</if>> /* ─── Professor notices the pregnancy (one-time) ─── */ <<if $pregnancy.isPregnant && $pregnancy.weeksPregnant >= 14 && !$pregnancy.profNoticed>> <<set $pregnancy.profNoticed = true>> <<if _prof.profType === "sympathetic">> <div class="alert alert--info">After the lecture, Prof. <<print _prof.lastName>> quietly catches you at the door. "I couldn't help noticing. If you need deadline flexibility this semester, or just someone who can put things in front of the Dean discreetly, my office is open." A kind nod, and <<if _prof.gender === "male">>he's<<else>>she's<</if>> gone.</div> <<modStat "mood" 5 "Someone was kind">> <<elseif _prof.profType === "creepy">> <div class="alert alert--warning">You catch Prof. <<print _prof.firstName>> staring at your bump during the lecture, twice. After class he murmurs, "Motherhood suits you," in a tone that makes you want a shower.</div> <<modStat "stress" 5 "Skin crawling">> <<elseif _prof.profType === "strict">> <div class="alert alert--info">Prof. <<print _prof.lastName>> pauses by your desk. "I trust your... condition won't affect your attendance. The material won't wait." A beat. "The front row has better chairs. Take one."</div> <<else>> <div class="alert alert--info">Prof. <<print _prof.lastName>> glances at your belly, opens <<if _prof.gender === "male">>his<<else>>her<</if>> mouth, thinks better of it, and moves on with the lecture.</div> <</if>> <</if>> <p>The lecture ends. Students pack up and file out.</p> /* ─── Prof. Drake: predation arc entry ─── */ <<set _dk = $academic.drakeCase>> <<set _ecOffered = false>> /* He selects: a CCUMDUP student whose grade is slipping, or who he has decided is already available. Cooldown so it never feels spammy. */ <<set _dkTarget = (_cls.grade < 75) || ($reputation.slut >= 35)>> <<if _prof.profType === "creepy" && _dk.stage >= 0 && _dk.stage < 3 && _dkTarget && ($world.day - _dk.lastOfferDay) >= 4 && random(1,100) <= 35>> <<set _ecOffered = true>> <<set $academic.drakeCase.lastOfferDay = $world.day>> <<set $academic.drakeCase.profIndex = _cls.professorIndex>> /* _cls is a clone from $temp.classEvent: match by code, not reference */ <<set _dkIdx = $academic.classes.findIndex(function(c) { return c.code === _cls.code; })>> <<if _dkIdx < 0>><<set _dkIdx = 0>><</if>> <<set $academic.drakeCase.classIndex = _dkIdx>> <<set $temp.ecProfIndex = _cls.professorIndex>> <<set $temp.ecClassIndex = _dkIdx>> <div class="alert alert--warning">As the room empties, Prof. <<print _prof.lastName>>'s voice cuts through the shuffle: "Miss <<print $pc.lastName>>? A moment, please." His eyes linger a beat too long.</div> <div class="choice-group"> <<link '<span class="choice-btn">🚪 Stay after class</span>' "Drake_Office">><</link>> <<link '<span class="choice-btn">🏃 Slip out with the crowd</span>' "LectureHalls">> <<run XCLC.Toast.show("You pretend not to hear. His eyes follow you out.", "info")>> <</link>> </div> <</if>> <<if !_ecOffered>> <div class="choice-group"> <<link '<span class="choice-btn">← Back to lecture halls</span>' "LectureHalls">><</link>> <<link '<span class="choice-btn">🗺️ Head to campus</span>' "CampusMap">><</link>> </div> <</if>>
/* Router. Stage 0-1 are the approach (built here). Stage 2+ hands off to the arrangement bodies. Investigation is available from stage 1 onward. */ /* No classes registered means there is no case to route to. */ <<if !$academic.classes || $academic.classes.length === 0>> <p>There is nothing on your timetable that this concerns.</p> <div class="choice-group"><<link '<span class="choice-btn">Back</span>' "LectureHalls">><</link>></div> <<else>> <<if typeof $academic.drakeCase.classIndex !== "number" || $academic.drakeCase.classIndex < 0 || $academic.drakeCase.classIndex >= $academic.classes.length>> <<set $academic.drakeCase.classIndex = 0>> <</if>> <<if typeof $academic.drakeCase.profIndex !== "number" || $academic.drakeCase.profIndex < 0>> <<set $academic.drakeCase.profIndex = ($academic.classes[$academic.drakeCase.classIndex] || {professorIndex: 0}).professorIndex>> <</if>> <<set $temp.ecClassIndex = $academic.drakeCase.classIndex>> <<set $temp.ecProfIndex = $academic.drakeCase.profIndex>> <<if $academic.drakeCase.stage === 0>> <<goto "Drake_Overture">> <<elseif $academic.drakeCase.stage === 1>> <<goto "Drake_Argument">> <<else>> <<goto "Professor_ExtraCredit">> <</if>> <</if>>
<<set _dk = $academic.drakeCase>> <<set _prof = ($academic.professors || [])[_dk.profIndex] || {lastName: "Whitlock", firstName: "A.", gender: "male"}>> <<set _cls = $academic.classes[_dk.classIndex] || {name: "your seminar", grade: 70}>> <h2>🚪 Prof. <<print _prof.lastName>>'s Office</h2> <<advanceTime 20>> <p>The office is smaller than you expected and colder. Filing cabinets, a dying plant, framed certificates hung slightly too high. He does not close the door, which you notice, and then notice yourself noticing.</p> <p>"Sit, sit." He does not sit. "You are in the programme. The scholarship." Not a question, and not said unkindly but said the way you would confirm someone's timetable.</p> <p>He taps a stack of marked papers. "Your work in <<print _cls.name>> is <<if _cls.grade < 60>>in trouble<<elseif _cls.grade < 75>>not where it wants to be<<else>>fine, which is not the same as good<</if>>. That matters more for you than for most of them, I imagine. Scholarships have conditions."</p> <p><em>Everything he has said is true. Everything he has said is something a concerned tutor might say. And still your shoulders have come up around your ears and you could not explain to anyone why.</em></p> <p>"I have time on Thursdays," he says. "Some students find it useful."</p> <<set $academic.drakeCase.stage = 1>> <div class="choice-group"> <<link '<span class="choice-btn">📚 "Thursdays could work."</span>' "LectureHalls">> <<run XCLC.Toast.show("You have agreed to nothing except a meeting. Probably.", "info", 5000)>> <</link>> <<link '<span class="choice-btn">🙂 Deflect: "I will manage, thanks."</span>' "LectureHalls">> <<modStat "willpower" 2 "Kept your distance">> <<run XCLC.Toast.show("He smiles and lets it go. For now.", "info")>> <</link>> <<link '<span class="choice-btn">🚪 Leave without answering</span>' "LectureHalls">><</link>> </div>
<<set _dk = $academic.drakeCase>> <<set _prof = $academic.professors[_dk.profIndex]>> <<set _cls = $academic.classes[_dk.classIndex]>> <h2>🚪 Thursday</h2> <<advanceTime 30>> <p>This time he closes the door. Not dramatically, he just nudges it shut with his heel while carrying two coffees, and hands you one, and it would be strange to make anything of it.</p> <p>He asks about the programme. Not leering, not coy. Clinical, almost sympathetic. How many a week. Whether they let you refuse. What happens to the stipend if your rating drops. You find yourself answering, because they are reasonable questions and nobody has ever asked them.</p> <p>Then he leans back and says the thing he has been walking toward for twenty minutes.</p> <div class="card" style="border-left:3px solid var(--accent-red);"> <p><em>"Here is what I find remarkable. This university takes a young person who cannot pay, puts a pill in their hand and a quota on their phone, and calls it a scholarship. There is a spreadsheet. There is a star rating. And everyone, the Dean, the faculty, your own mother if she knew. Everyone agrees to call that an education."</em></p> <p><em>He turns his cup a quarter turn on the desk.</em></p> <p><em>"So I have never understood the pearl-clutching. You are already doing the thing. The institution already decided what you are worth and wrote it into a contract. The only difference between them and me is that I am not going to lie to you about it."</em></p> </div> <p><em>The awful part is not that it is monstrous. The awful part is that some of it is true, and he has said it out loud, and you cannot immediately find the seam.</em></p> <<if $transformation.sideEffects.bimbofication >= 2>> <p><em>You reach for the counter-argument and it slides away from you. It is right there. You know it is right there.</em></p> <</if>> <<modStat "stress" 10 "That landed somewhere">> <<divider "What do you say?">> <div class="choice-group"> <<link '<span class="choice-btn">🧠 Find the seam and cut him with it</span>' "Drake_Argument_Rebut">><</link>> <<link '<span class="choice-btn">🎭 Let him think it worked: and start paying attention</span>' "Drake_Argument_Play">><</link>> <<link '<span class="choice-btn">🚪 "I think we are done." Leave.</span>' "Drake_Decline">><</link>> <<link '<span class="choice-btn">😶 Say nothing. See where he takes it.</span>' "Professor_ExtraCredit">> <<set $academic.drakeCase.stage = 2>> <<set $academic.extraCredit.stage = 0>> <</link>> </div>
<<set _dk = $academic.drakeCase>> <<set _prof = $academic.professors[_dk.profIndex]>> <h2>🧠 The Seam</h2> <<set _rebut = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _rebut === "crit_success" || _rebut === "success">> <p>"I signed something," you say.</p> <p>He waits, indulgent.</p> <p>"I read it first. I knew the terms before I agreed and I can turn down any request that comes through that app and take the hit on my rating, and none of it <em>none</em> of it touches my grades. You are not being honest about a thing I already agreed to. You are a man who marks my work, in an office, with the door shut, inventing a new deal I never heard of until twenty minutes ago." You put the coffee down. "That is not the same. You just need it to be."</p> <p>Something moves behind his face and then is put away. For a moment he is not warm at all, and you get a clean look at what has been sitting across the desk from you this whole time.</p> <p>"Well," he says. "You are brighter than your marks suggest."</p> <p><em>Which, you realise walking out, is a threat.</em></p> <<modStat "confidence" 12 "Took his argument apart">> <<modStat "willpower" 8 "Clear-eyed">> <<set $academic.drakeCase.stage = -1>> <<set $academic.drakeCase.declined = true>> <<set $academic.drakeCase.retaliating = true>> <<if $academic.drakeCase.earnedGrade === null>> <<set $academic.drakeCase.earnedGrade = $academic.classes[$academic.drakeCase.classIndex].grade>> <</if>> <div class="alert alert--warning">📉 Your marks in that class begin sliding the following week. You know exactly why, and you cannot prove it. Yet.</div> <<else>> <p>"That is..." you start, and stop. "That is not the same thing."</p> <p>"Why not?"</p> <p>You know why not. You know it the way you know a word you cannot retrieve. He watches you fail to produce it with an expression of genuine, patient interest, and the silence goes on long enough to become an answer.</p> <p>"Think about it," he says warmly. "Thursdays."</p> <<modStat "stress" 12 "Outmanoeuvred">> <<modStat "confidence" -5 "Lost for words">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "LectureHalls">><</link>> </div> <</if>> <<if _rebut === "crit_success" || _rebut === "success">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Start keeping receipts</span>' "LectureHalls">> <<run XCLC.Toast.show("🔍 You can build a case against him, check the Lecture Halls.", "info", 6000)>> <</link>> </div> <</if>>
<<set _dk = $academic.drakeCase>> <<set _prof = $academic.professors[_dk.profIndex]>> <h2>🎭 Noncommittal</h2> <p>You do not agree. You do not disagree. You tilt your head and say "I will think about it" in a voice that gives him nothing and lets him hear whatever he wants.</p> <p>He hears yes. Men like him always hear yes.</p> <p>And now you are paying attention properly to the door, to the way he schedules you last, to the fact that he asked how many a week and wrote nothing down. He is careful. He has done this before.</p> <<set $academic.drakeCase.stage = 1>> <<if $academic.drakeCase.evidence.indexOf("His own words, and how careful he is with them") === -1>> <<run $academic.drakeCase.evidence.push("His own words, and how careful he is with them")>> <</if>> <<modStat "willpower" 4 "Playing a longer game">> <div class="alert alert--info">🔍 <strong>Evidence:</strong> you know what he sounds like when he thinks nobody is recording.</div> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep building</span>' "LectureHalls">><</link>> <<link '<span class="choice-btn">🔙 Leave for now</span>' "LectureHalls">><</link>> </div>
/* Shared exit — she gets out. He makes it cost her, and that cost is the first thing she can actually prove. */ <<set _dk = $academic.drakeCase>> <<set _prof = ($academic.professors || [])[_dk.profIndex] || {lastName: "Whitlock", firstName: "A.", gender: "male"}>> <<set _cls = $academic.classes[_dk.classIndex] || {name: "your seminar", grade: 70}>> <h2>🚪 No</h2> <p>You say no. Not cleverly, not with a speech, you just say it, and then you keep saying it while he explains why you have misunderstood him.</p> <p>"I think you have got the wrong idea about this conversation," he says, and the warmth has gone out of his voice entirely. "I have been trying to help you."</p> <p>He holds the door. You walk out into a corridor full of people who have no idea.</p> <<set $academic.drakeCase.stage = -1>> <<set $academic.drakeCase.declined = true>> <<set $academic.drakeCase.retaliating = true>> <<if $academic.drakeCase.earnedGrade === null>> <<set $academic.drakeCase.earnedGrade = _cls.grade>> <</if>> <<modStat "confidence" 8 "Said no and meant it">> <<modStat "willpower" 6 "Held the line">> <div class="alert alert--warning">📉 Your marks in <<print _cls.name>> start slipping the following week. The comments on your work do not match the grades at the bottom of it.</div> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Start keeping receipts</span>' "LectureHalls">> <<run XCLC.Toast.show("🔍 You can build a case against him check the Lecture Halls.", "info", 6000)>> <</link>> <<link '<span class="choice-btn">🔙 Leave it</span>' "LectureHalls">><</link>> </div>
<<if typeof $temp.ecClassIndex !== "number" || $temp.ecClassIndex < 0 || $temp.ecClassIndex >= $academic.classes.length>><<set $temp.ecClassIndex = 0>><</if>> <<set _prof = ($academic.professors || [])[$temp.ecProfIndex] || {lastName: "Whitlock", firstName: "A.", gender: "male"}>> <<set _cls = $academic.classes[$temp.ecClassIndex] || {name: "your seminar", grade: 70}>> <<set _ec = $academic.extraCredit>> <h2>🚪 Prof. <<print _prof.lastName>>'s Office</h2> <<advanceTime 30>> <<if _ec.stage === 0>> /* ── Stage 1: The proposition ── */ <p>His office smells of old coffee and cologne applied with intent. He gestures at the chair across his desk and looks at you the way men look at menus.</p> <p>"Your grade in <<print _cls.name>> is... adequate. But 'adequate' doesn't get scholarships renewed, does it?" He leans back. "I offer certain students <em>extra credit</em> opportunities. Private assignments. Discretion required. Interested?"</p> <p><em>The way he says 'assignments' leaves very little to the imagination.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">😏 "What kind of assignments?"</span>' "LectureHalls">> <<set $academic.extraCredit.stage = 1>> <<run (function(){ var sv = State.variables; sv.academic.classes[sv.temp.ecClassIndex].grade = Math.min(100, sv.academic.classes[sv.temp.ecClassIndex].grade + 5); }())>> <<modCorruption 1 "Professor's game">> <<run XCLC.Toast.show("📈 He smiles. 'We'll start small.' Grade +5. He'll be in touch.", "info", 6000)>> <</link>> <<link '<span class="choice-btn">🧊 "I\'ll earn my grade the normal way."</span>' "LectureHalls">> <<set $academic.extraCredit.stage = -1>> <<run XCLC.Toast.show("His smile doesn't reach his eyes. 'As you wish.'", "info")>> <</link>> </div> <<elseif _ec.stage === 1>> /* ── Stage 2: Hands-on tutoring ── */ <p>"Ah, my favourite student." He locks the office door behind you casually, like it means nothing. "Today's assignment is a practical. Come here."</p> <p>What follows is twenty minutes of 'tutoring' with his hands doing most of the teaching, your waist, your hips, the small of your back as he stands far too close behind you, pointing at a textbook neither of you is reading.</p> <div class="choice-group"> <<link '<span class="choice-btn">😶 Let him (Grade +8)</span>' "LectureHalls">> <<set $academic.extraCredit.stage = 2>> <<run (function(){ var sv = State.variables; sv.academic.classes[sv.temp.ecClassIndex].grade = Math.min(100, sv.academic.classes[sv.temp.ecClassIndex].grade + 8); }())>> <<modCorruption 2 "Professor's hands">> <<modStat "stress" 5 "Compromised">> <<run XCLC.Toast.show("📈 Grade +8. 'Excellent progress,' he murmurs.", "info")>> <</link>> <<link '<span class="choice-btn">✋ Pull away: "This stops here."</span>' "Professor_ExtraCredit_Refuse">><</link>> </div> <<elseif _ec.stage === 2>> /* ── Stage 3: On your knees ── */ <p>The door locks. The blinds twist shut. He doesn't bother with the textbook pretence anymore.</p> <p>"Final component of the extra credit module," he says, unbuckling his belt. "Oral examination."</p> <div class="choice-group"> <<link '<span class="choice-btn">🧎 Complete the "examination" (Grade +12)</span>' "LectureHalls">> <<set $academic.extraCredit.stage = 3>> <<run (function(){ var sv = State.variables; sv.academic.classes[sv.temp.ecClassIndex].grade = Math.min(100, sv.academic.classes[sv.temp.ecClassIndex].grade + 12); }())>> <<addXP "oral" 15>> <<modCorruption 3 "Professor's examination">> <<modHygiene -10 "Office visit">> <<modStat "stress" 8 "In too deep">> <<stdRisk "oral" 1>> <<run XCLC.Toast.show("📈 Grade +12. He straightens his tie like nothing happened.", "info")>> <</link>> <<link '<span class="choice-btn">✋ Refuse: this has gone too far</span>' "Professor_ExtraCredit_Refuse">><</link>> </div> <<else>> /* ── Stage 4: The full arrangement ── */ <p>By now there's a routine to it. The lock. The blinds. The desk cleared with one sweep of his arm.</p> <p>"You've been an exemplary student," he says. "Time for your <em>final</em>. Pass this, and you'll never have to worry about <<print _cls.name>> again."</p> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Pass the "final" (Grade set to 95)</span>' "LectureHalls">> <<set $academic.extraCredit.stage = 4>> <<run (function(){ var sv = State.variables; sv.academic.classes[sv.temp.ecClassIndex].grade = 95; }())>> <<addXP "vaginal" 15>> <<modCorruption 4 "The full arrangement">> <<modHygiene -15 "Office desk">> <<modStat "stress" 10 "What have you become">> <<pregnancyRisk `_prof.race`>> <<stdRisk "vaginal" 1>> <<run XCLC.Toast.show("📈 " + State.variables.academic.classes[State.variables.temp.ecClassIndex].name + " grade set to 95. An A, bought and paid for.", "info", 6000)>> <</link>> <<link '<span class="choice-btn">✋ Walk away for good</span>' "Professor_ExtraCredit_Refuse">><</link>> </div> <</if>>
<<set _prof = $academic.professors[$temp.ecProfIndex]>> <<set _ec = $academic.extraCredit>> <h2>🚪 Walking Out</h2> <<if _ec.stage >= 2>> /* High involvement: he turns nasty */ <p>His expression flattens. "That's disappointing. Especially after everything we've... accomplished together." He taps his desk drawer meaningfully. "It would be a shame if the academic integrity board received an anonymous tip about how you've been earning your grades."</p> <p><em>He's threatening you with the thing HE did. And it would still be your word against tenure.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">😨 Back down: keep the arrangement</span>' "LectureHalls">> <<modStat "stress" 15 "Trapped">> <<modStat "willpower" -5 "Cornered">> <<run XCLC.Toast.show("He smiles. 'I thought so. Same time next week.'", "warning")>> <</link>> <<link '<span class="choice-btn">🔥 "Report me, and I report you." (Composure check)</span>' "LectureHalls">> <<set _standoff = XCLC.Roll.doCheck("composure", 5)>> <<run XCLC.DicePopup.show()>> <<set $academic.extraCredit.stage = -1>> <<if _standoff === "crit_success" || _standoff === "success">> <<modStat "confidence" 10 "Stood your ground">> <<run XCLC.Toast.show("😎 Mutually assured destruction. He never bothers you again.", "success", 6000)>> <<else>> <<run (function(){ var sv = State.variables; sv.academic.classes[sv.temp.ecClassIndex].grade = Math.max(0, sv.academic.classes[sv.temp.ecClassIndex].grade - 10); }())>> <<modStat "stress" 15 "Marked woman">> <<run XCLC.Toast.show("📉 He can't report you but he CAN grade you. Grade -10. Every assignment now comes back bleeding red ink.", "error", 7000)>> <</if>> <</link>> </div> <<else>> <p>You walk out. Behind you, he exhales through his nose — annoyed, but not surprised. Low stakes, nothing lost.</p> <<set $academic.extraCredit.stage = -1>> <<run XCLC.Toast.show("You're done with his 'extra credit.' Your grade is your own.", "info")>> <div class="choice-group"> <<link '<span class="choice-btn">📚 Back to lecture halls</span>' "LectureHalls">><</link>> </div> <</if>>
<<set _dk = $academic.drakeCase>> <<set _prof = $academic.professors[_dk.profIndex]>> <<set _cls = $academic.classes[_dk.classIndex]>> <<set _ev = _dk.evidence>> <<set _involved = (_dk.stage >= 2)>> <h2>🔍 Receipts</h2> <p>Tenure is armour. "He made me uncomfortable" bounces straight off it. You need the kind of thing a panel cannot politely set aside.</p> <<if _involved>> <div class="alert alert--warning">⚠️ You went along with it. That is going to come up and he knows it, which is most of why he is not worried.</div> <</if>> <div class="card"> <div class="card__title">📁 What You Have (<<print _ev.length>>)</div> <<if _ev.length === 0>> <p style="opacity:0.6;"><em>Nothing yet.</em></p> <<else>> <<for _e = 0; _e < _ev.length; _e++>> <p>✅ <<print _ev[_e]>></p> <</for>> <</if>> </div> <div class="choice-group"> <<if _ev.indexOf("A recording of him saying it plainly") === -1>> <<link '<span class="choice-btn">📱 Leave your phone recording in your bag</span>' "Drake_Ev_Record">><</link>> <</if>> <<if _ev.indexOf("Your marks against the class average") === -1>> <<link '<span class="choice-btn">📊 Pull your marked work and compare it</span>' "Drake_Ev_Grades">><</link>> <</if>> <<if _ev.indexOf("Two other students with the same Thursday") === -1>> <<link '<span class="choice-btn">💬 Find the others he has kept behind</span>' "Drake_Ev_Students">><</link>> <</if>> <<if _ev.indexOf("A staffing history nobody wrote down") === -1>> <<link '<span class="choice-btn">🗄️ Ask the department secretary about him</span>' "Drake_Ev_Secretary">><</link>> <</if>> <<if _ev.length >= 2>> <<link '<span class="choice-btn">🛑 Put it to him directly</span>' "Drake_Confront">><</link>> <<link '<span class="choice-btn">🏛️ Take it to Dean Harrison</span>' "Drake_Report">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Later</span>' "LectureHalls">><</link>> </div>
<<set _prof = $academic.professors[$academic.drakeCase.profIndex]>> <h2>📱 On The Record</h2> <<advanceTime 40>> <p>You start the voice memo out in the corridor, drop the phone into your bag with the top left open, and go and be agreeable for half an hour.</p> <p>He is not careless, he never names the trade. But he says the spreadsheet line again, and the one about not insulting you by pretending, and near the end he says <em>"nobody is going to take your word over mine, so let us not make this adversarial"</em> in a tone that needs no transcript.</p> <p>You listen to it twice that night. It is worse the second time, because you can hear yourself laughing politely in the background.</p> <<run $academic.drakeCase.evidence.push("A recording of him saying it plainly")>> <<modStat "stress" 10 "Hearing it back">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Drake_Investigate">><</link>> </div>
<<set _dk = $academic.drakeCase>> <<set _cls = $academic.classes[_dk.classIndex]>> <h2>📊 The Numbers</h2> <<advanceTime 50>> <p>You lay every piece of marked work out across the dorm floor in date order, and for once you read the comments instead of the grades.</p> <p>"Strong structure." 61. "Clear grasp of the material." 58. "Well argued, see me." 55.</p> <p><<if _dk.earnedGrade !== null>>Before that Thursday you were sitting at <<print Math.round(_dk.earnedGrade)>>. You are at <<print Math.round(_cls.grade)>> now, and nothing about the work has changed.<<else>>The comments describe one student. The numbers describe a different one.<</if>> You photograph all of it, in order, with the dates showing.</p> <<run $academic.drakeCase.evidence.push("Your marks against the class average")>> <<modStat "confidence" 5 "Proof, not a feeling">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Drake_Investigate">><</link>> </div>
<h2>💬 The Others</h2> <<advanceTime 60>> <p>It takes two weeks and three awkward coffees. The first girl says nothing for ten minutes and then will not stop talking. The second is a year above you, dropped his module in her second semester, and has never told anyone why.</p> <p>"He does the coffee thing," she says. "And the door with his foot. And he asks how many a week." She looks at the table. "I thought it was me being paranoid. Then I thought it was just me."</p> <p>Both will put their names to a statement. One asks whether she has to be in the room when it happens.</p> <<run $academic.drakeCase.evidence.push("Two other students with the same Thursday")>> <<modStat "confidence" 8 "Not imagining it">> <<modRep "sweetheart" 4>> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Drake_Investigate">><</link>> </div>
<<set _prof = ($academic.professors || [])[$academic.drakeCase.profIndex] || {lastName: "Whitlock", firstName: "A.", gender: "male"}>> <h2>🗄️ Housekeeping</h2> <<advanceTime 30>> <p>The departmental secretary has worked in this building for twenty-six years and has the flat, unbothered manner of a woman who has watched every kind of person come through it.</p> <p>You ask, casually, how long Prof. <<print _prof.lastName>> has been with the department.</p> <p>She does not look up from her screen. "Third department in nine years." A pause exactly one beat too long. "There was no finding. Nothing was upheld." Another pause. "Both times."</p> <p>Then she writes a name and an extension on a compliments slip, slides it across the desk, and carries on typing as though she has said nothing at all.</p> <<run $academic.drakeCase.evidence.push("A staffing history nobody wrote down")>> <<modStat "stress" -5 "Someone else knows">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Drake_Investigate">><</link>> </div>
<<set _dk = $academic.drakeCase>> <<set _prof = $academic.professors[_dk.profIndex]>> <h2>🛑 Office Hours</h2> <<advanceTime 30>> <p>You go on a Thursday and you stay standing, and you tell him exactly what you have.</p> <<set _dc = _dk.stage >= 2 ? 5 : 4>> <<set _stand = XCLC.Roll.doCheck("composure", _dc)>> <<run XCLC.DicePopup.show()>> <<if _stand === "crit_success" || _stand === "success">> <p>He reaches for the argument again, the spreadsheet, the honesty, the pearl-clutching and this time it has nowhere to land, because you are not arguing with him. You are reading out dates.</p> <p>"Third department in nine years," you finish. "Nothing upheld. Both times."</p> <p>The warmth goes out of his face and does not come back. "What is it you want."</p> <p>"The marks I earned. And I want you to understand that I have copies of everything, in more than one place."</p> <<set $academic.drakeCase.confronted = true>> <<set $academic.drakeCase.retaliating = false>> <<if _dk.earnedGrade !== null>> <<set $academic.classes[_dk.classIndex].grade = _dk.earnedGrade>> <</if>> <<modStat "confidence" 15 "Faced him down">> <<modStat "willpower" 10 "Unmoved">> <<run XCLC.Toast.show("📈 Your marks in that class are quietly corrected the following week.", "success", 6000)>> <<else>> <p>He lets you finish. Then he asks mildly, almost kindly whether you have thought about how it looks. A scholarship student on a service programme. A grade she was unhappy with. A recording she made in secret, without consent, in a private meeting.</p> <p>"I would think very carefully," he says, "about whose account a panel finds simpler."</p> <p>You leave with your hands shaking and nothing resolved.</p> <<modStat "stress" 18 "He is not frightened of you">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🏛️ Take it to the Dean anyway</span>' "Drake_Report">><</link>> <<link '<span class="choice-btn">🔙 Leave</span>' "LectureHalls">><</link>> </div>
<<set _dk = $academic.drakeCase>> <<set _prof = $academic.professors[_dk.profIndex]>> <<set _n = _dk.evidence.length>> <<set _involved = (_dk.stage >= 2)>> <h2>🏛️ Dean Harrison</h2> <<advanceTime 60>> <p>She listens the entire way through without interrupting once, and takes notes, which is more than you had let yourself expect.</p> <<if _n >= 4 || (_n >= 3 && !_involved)>> <p>When you finish she sets the pen down. "Third department," she repeats. "In nine years." She is not talking to you.</p> <p>"You will be hearing from an investigator, not from me. He will not be teaching while that happens." She holds your eye. "And for what it is worth being on the programme does not make you less credible. Some people in this building will behave as though it does. They will be wrong, and I will put that in writing."</p> <<set $academic.drakeCase.resolved = true>> <<set $academic.drakeCase.reported = true>> <<set $academic.drakeCase.retaliating = false>> <<if _dk.earnedGrade !== null>> <<set $academic.classes[_dk.classIndex].grade = _dk.earnedGrade>> <</if>> <<modStat "confidence" 15 "Believed">> <<modRep "sweetheart" 10>> <<modRep "goodStudent" 5>> <<run XCLC.Toast.show("🏛️ Suspended pending investigation. Your marks are corrected.", "success", 7000)>> <<elseif _n >= 2>> <p>"I believe you," she says, and you can hear the second half arriving. "And two accounts without a recording is a slower road than three accounts with one. It will move. It will move at the pace these things move."</p> <<if _involved>> <p>She hesitates. "You should also be ready for someone to ask why you continued. It is not a fair question. You will be asked it anyway."</p> <</if>> <p>His Thursdays stop. The investigation outlives your second year.</p> <<set $academic.drakeCase.resolved = true>> <<set $academic.drakeCase.reported = true>> <<set $academic.drakeCase.retaliating = false>> <<modStat "confidence" 8 "Did it anyway">> <<modRep "sweetheart" 5>> <<run XCLC.Toast.show("🏛️ Under review. His office hours are suspended.", "info", 7000)>> <<else>> <p>She is kind about it, and kind is not the same as able. "Bring me something I can put in front of a panel."</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "CampusMap">><</link>> </div>
/* Player travels to the location and meets the NPC */ /* A real CampusHub request always finishes through ServiceMainAct , clear any return passage a standalone venue left behind. */ <<run XCLC.Encounter.clear()>> /* Per-encounter: cleared so a previous scene's answer cannot carry over. */ <<set $temp.creepyResponse = "">> <<set _req = $temp.serviceRequest || {locationName: "the meeting point", locationDesc: "the address on your phone", serviceType: "oral", locationPrivacy: "medium"}>> <<set _npc = $temp.serviceNPC || XCLC.NPC.generate({})>> <h2>📍 <<print _req.locationName>></h2> <p>You make your way to <<print _req.locationDesc>>. Your CampusHub app pulses with the active request.</p> <p><<print XCLC.Goggles.describe(_npc)>></p> <<run XCLC.Goggles.remember(_npc)>> <<orientationNote _npc.gender>> <<if _npc.encounters > 0>> <p><em>You know <<if _npc.gender === "male">>him<<else>>her<</if>>. <<print _npc.firstName>>, <<if _npc.encounters === 1>>you've done this once before<<elseif _npc.isRecurring>>one of your regulars, encounter #<<print _npc.encounters + 1>><<else>>this is round <<print _npc.encounters + 1>><</if>>. <<if _npc.opinion >= 70>><<if _npc.gender === "male">>He<<else>>She<</if>> requested you by name.<</if>></em></p> <</if>> <<if $pregnancy.isPregnant && $pregnancy.weeksPregnant >= 12>> <p><<if _npc.personality === "creepy">>His eyes go straight to your bump and stay there. "Pregnant," he says, like he's reading a menu. "Even better."<<elseif _npc.personality === "sweet" || _npc.personality === "romantic">>His eyes flick to your belly. "Oh. Are you... is this still okay? We can keep it gentle." The concern seems genuine.<<elseif _npc.personality === "aggressive" || _npc.personality === "demanding">>He clocks the bump, shrugs. "Not my problem. Not mine, anyway." Charming.<<elseif _npc.personality === "shy">>He notices your belly and turns scarlet. "I, um, congratulations? Is that the right thing to say right now?"<<else>>His gaze catches on your rounded belly for a moment. He decides not to comment. Most of them do.<</if>></p> <</if>> <<if _npc.personality === "shy">> <p>"H-hi. You're <<print $pc.femaleFirstName>>, right? From the programme?" He shuffles his feet. "I've, um, never done this before."</p> <<elseif _npc.personality === "aggressive">> <p>He doesn't bother with introductions. "You the girl from CampusHub? Good. Let's not waste time."</p> <<elseif _npc.personality === "romantic">> <p>"<<print $pc.femaleFirstName>>? You're even prettier in person." He actually smiles, warmly, not predatorily. "I'm <<print _npc.firstName>>. Can I get you anything first?"</p> <<elseif _npc.personality === "friendly">> <p>"Hey! You must be <<print $pc.femaleFirstName>>. I'm <<print _npc.firstName>>." He extends a hand. It's almost... normal? Like meeting someone for coffee, except for the reason you're here.</p> <<elseif _npc.personality === "demanding">> <p>"<<print $pc.femaleFirstName>>. <<print _npc.firstName>>." He checks his watch. "I have a class in ninety minutes, so let's be efficient about this."</p> <<elseif _npc.personality === "creepy">> <p>He's been watching you approach. There's a phone in his hand. Was he filming? "<<print $pc.femaleFirstName>>. I've seen your profile. You're <<print $pc.breastSize>>-cup, right? Perfect."</p> <<elseif _npc.personality === "sweet">> <p>"Hi. I'm <<print _npc.firstName>>." He looks almost apologetic. "Is this okay? The location, I mean. We can go somewhere else if you'd prefer."</p> <<else>> <p>"<<print _npc.firstName>>." He nods. You get the sense this isn't his first time using the programme.</p> <</if>> <<if $transformation.sideEffects.pheromones >= 2>> <p>You notice his nostrils flare slightly. Your pheromones are doing their thing, his pupils dilate and he takes a half-step closer.</p> <</if>> <p>He wants: <strong><<print _req.serviceType.charAt(0).toUpperCase()>><<print _req.serviceType.slice(1)>></strong></p> <<set $temp.condomUsed = false>> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Let\'s do this.</span>' "ServiceForeplay_Entry">><</link>> <<if _req.serviceType === "vaginal" && _npc.gender === "male" && $inventory.condoms > 0>> <<link '<span class="choice-btn">💊 "Sure, but you\'re wearing a condom." (<<print $inventory.condoms>> left)</span>' "ServiceCondomAsk">><</link>> <</if>> <<link '<span class="choice-btn">🏃 Actually, I can\'t do this. (Flee: -0.3 rating)</span>' "CampusMap">> <<run XCLC.Service.fleeEncounter()>> <</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <h2>💊 The Condition</h2> <p>You pull the little foil square from your bag and hold it up. "House rule."</p> <<if _npc.personality === "aggressive" || _npc.personality === "demanding" || _npc.personality === "creepy">> <<set _refuses = (random(1,100) <= 50)>> <<if _refuses>> <p><<if _npc.personality === "aggressive">>"Not happening." <<print _npc.firstName>> doesn't even pretend to consider it. "Raw or nothing. That's the deal."<<elseif _npc.personality === "demanding">>"I don't do condoms." He checks his watch, unbothered. "Your call. But decide fast."<<else>>He smiles in a way you don't like. "But then I wouldn't <em>feel</em> you. No. Take it or leave it."<</if>></p> /* Compelled-choice reference implementation. internalHeat leans on the player here. The walk-away stays clickable at every level: it is dimmed and costs stats. */ <<set _ihLvl = ($transformation.sideEffects.internalHeat || 0)>> <<set _ihOn = (_ihLvl >= 2)>> <<if _ihOn>><<compelNote "internalHeat" _ihLvl>><</if>> <<set _ihStay = _ihOn ? '<span class="choice-btn choice-btn--urged">😤 Fine. No condom.</span>' : '<span class="choice-btn">😤 Fine. No condom.</span>'>> <<set _ihGo = _ihOn ? '<span class="choice-btn choice-btn--compelled">🏃 Then we are done here. (Flee: -0.3 rating)</span>' : '<span class="choice-btn">🏃 Then we are done here. (Flee: -0.3 rating)</span>'>> <div class="choice-group"> <<link _ihStay "ServiceForeplay_Entry">><</link>> <<link _ihGo "CampusMap">> <<if _ihOn>> <<modStat "willpower" `-(_ihLvl * 2)` "Walked out on a craving">> <<modStat "stress" `_ihLvl * 3` "Walked out on a craving">> <</if>> <<run XCLC.Service.fleeEncounter()>> <</link>> </div> <<else>> <p>He exhales through his nose, annoyed. <<if _npc.personality === "aggressive">>"Whatever. Give it here."<<elseif _npc.personality === "demanding">>"Fine. It's coming out of your rating." He probably can't actually do that.<<else>>"If that's what it takes." His smile doesn't reach his eyes.<</if>> He takes it.</p> <<set $temp.condomUsed = true>> <<set $inventory.condoms-->> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Good. Let\'s go.</span>' "ServiceForeplay_Entry">><</link>> </div> <</if>> <<else>> <p><<if _npc.personality === "sweet" || _npc.personality === "romantic">>"Of course." He takes it without hesitation. "You didn't even need to ask."<<elseif _npc.personality === "shy">>"O-oh. Yeah! Yes. Obviously." He fumbles with the wrapper, ears bright red.<<elseif _npc.personality === "friendly">>"Smart girl." He grins and pockets it for the moment. "No arguments here."<<else>>He shrugs and takes it. "Fine by me."<</if>></p> <<set $temp.condomUsed = true>> <<set $inventory.condoms-->> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Let\'s do this.</span>' "ServiceForeplay_Entry">><</link>> </div> <</if>>
/* Router. Creepy NPCs get a boundary beat first; everyone else passes through. */ <<set _npc = $temp.serviceNPC || XCLC.NPC.generate({})>> <<if _npc.personality === "creepy" && !$temp.creepyResponse>> <<goto "ServiceForeplay_Boundary">> <<else>> <<goto "ServiceForeplay">> <</if>>
<<set _npc = $temp.serviceNPC || XCLC.NPC.generate({})>> <h2>Ground Rules</h2> <p><<print _npc.firstName>> moves in before you have finished putting your bag down, close enough that you can smell his aftershave, and reaches for you without asking anything first.</p> <p>You catch his wrist.</p> <div class="choice-group"> <<link '<span class="choice-btn">✋ "Ask me first. Every time."</span>' "ServiceForeplay">> <<set $temp.creepyResponse = "stopped">> <<addXP "composure" 5>> <<modStat "confidence" 4 "Held a boundary">> <</link>> <<link '<span class="choice-btn">🧭 "Slow down. My pace, or we are done."</span>' "ServiceForeplay">> <<set $temp.creepyResponse = "redirected">> <<modStat "confidence" 2 "Set the terms">> <</link>> <<link '<span class="choice-btn">😑 Let it go. Get it over with.</span>' "ServiceForeplay">> <<set $temp.creepyResponse = "allowed">> <<modStat "stress" 5 "Let it slide">> <</link>> <<link '<span class="choice-btn">🚪 "No. I am leaving." <em>(ends the booking)</em></span>' "CampusMap">> <<set $temp.creepyResponse = "left">> <<run XCLC.Service.fleeEncounter()>> <<modStat "confidence" 6 "Walked out">> <</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _se = $transformation.sideEffects>> <h2><<print _req.serviceType.charAt(0).toUpperCase()>><<print _req.serviceType.slice(1)>>: Foreplay</h2> <<if _npc.personality === "aggressive" || _npc.personality === "demanding">> <p>There is no buildup. <<print _npc.firstName>> gets a hand under your jaw and puts you against the wall hard enough to empty your lungs, and his mouth is on your throat before you have finished deciding how you feel about it. His thigh comes between yours. He is already hard against your hip and he is not being subtle about wanting you to know it.</p> <p>"I didn't come here for romance," he says into your skin. His palm flattens on your stomach and starts downward. "Tell me now if that's a problem."</p> <p>It is not a problem. That is the part you will turn over later, on the walk back.</p> <<elseif _npc.personality === "romantic">> <p><<print _npc.firstName>> takes your face in both hands and kisses you slowly, like the kissing is the point rather than the toll on the way to something else. It is so unhurried that it catches you completely off guard. His thumb moves along your cheekbone. When he finally pulls back your mouth follows his without being told to, which you had not authorised.</p> <p>"Relax," he says. "We have got all night."</p> <p>The awful thing is that you do.</p> <<modStat "mood" 3 "Gentle foreplay">> <<elseif _npc.personality === "shy">> <p><<print _npc.firstName>> reaches for you and misses, grabbing air. He goes red. "Sorry. I just, can I?" He gestures vaguely at your body. You take his hand and place it on your waist. He lets out a shaky breath.</p> <<elseif _npc.personality === "sweet">> <p>"Can I kiss you?" <<print _npc.firstName>> asks. You nod. It's soft, careful. His hands stay on your waist, not wandering without permission. You feel something you don't want to name.</p> <<modStat "mood" 2 "Sweet foreplay">> <<elseif _npc.personality === "creepy">> <<if $temp.creepyResponse === "stopped">> <p>He holds both hands up, palms out, and gives you a smile with nothing behind it. "Sure. Whatever you want." He asks before the next thing, and the one after that, and every time he asks he makes it sound like a favour he is doing you. It is still better than the alternative, and you notice that you got it by asking for it.</p> <<modStat "stress" 2 "He complied, grudgingly">> <<elseif $temp.creepyResponse === "redirected">> <p>"Your pace." He repeats it back like a word in a language he is not fluent in. But he waits, and he keeps waiting, and when he moves again it is slow enough that you are the one deciding what happens next.</p> <<modStat "stress" 3 "Kept him on a leash">> <<else>> <p>You let go of his wrist. He takes that for the permission it is and does not ask about anything else for the rest of the evening, and you spend the whole of it a half step behind your own body, filing it under things to think about later.</p> <<modStat "stress" 5 "Let it slide">> <</if>> <<else>> <p><<print _npc.firstName>> pulls you in and works through it in order, the way you would warm up an engine: mouth, neck, hands at your hips, a thumb testing under the waistband to see whether you will stop him. You do not. He nods slightly, to himself, and moves on to the next item.</p> <p>Business. You have done enough of these now to recognise a man following a routine, and to notice that you have one too.</p> <</if>> /* Wet addon check */ <<if $transformation.addons.wet>> <p>Your body is already responding. The Wet add-on means you're practically dripping before anything's even started. <<print _npc.firstName>> notices. <<if _npc.personality === "cocky">>"Damn, you're ready to go." He grins.<<elseif _npc.personality === "shy">>His eyes go wide. "Oh. Wow. Okay."<<else>>"Good," he says simply.<</if>></p> <<modStat "arousal" 15 "Wet addon">> <<else>> <<modStat "arousal" 10 "Foreplay">> <</if>> /* Sensitivity SE */ <<if _se.increasedSensitivity >= 2>> <p>Every touch sends electricity through your skin. Your hypersensitivity means even his fingertips trailing along your arm makes you shiver and gasp. This is going to be intense.</p> <<modStat "arousal" 10 "Sensitivity">> <</if>> /* Pheromones SE */ <<if _se.pheromones >= 2>> <p><<print _npc.firstName>> is breathing harder, pupils blown. Your pheromones are making him almost desperate. "God, you smell amazing," he mutters, pressing his face into your neck.</p> <</if>> /* Now determine positions */ <<set $temp.positionData = XCLC.Service.getPositions(_npc, _req.serviceType)>> <<if $temp.positionData.playerChooses>> <<goto "ServicePositionSelect">> <<else>> <<set $temp.chosenPosition = $temp.positionData.forcedPosition>> <p><<if _npc.personality === "aggressive">>He doesn't give you a choice. <<print $temp.chosenPosition.name>>. <<print $temp.chosenPosition.desc>>.<<elseif _npc.personality === "demanding">>He positions you exactly how he wants. <<print $temp.chosenPosition.name>>. <<print $temp.chosenPosition.desc>>.<<else>>"Let's do <<print $temp.chosenPosition.name.toLowerCase()>>," he says, already moving you into position.<</if>></p> <<goto "ServiceAct_Choose">> <</if>>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _positions = $temp.positionData.positions>> <h2>Choose Position</h2> <<if _npc.personality === "shy">> <p>"Whatever you want," <<print _npc.firstName>> says quietly. "You're the expert."</p> <<elseif _npc.personality === "friendly">> <p>"What works for you?" <<print _npc.firstName>> asks.</p> <<else>> <p><<print _npc.firstName>> lets you take the lead.</p> <</if>> <div class="choice-group"> <<for _i = 0; _i < _positions.length; _i++>> <<set _pos = _positions[_i]>> <<capture _pos>> <<link '<span class="choice-btn"><<print _pos.name>>: <<print _pos.desc>></span>' "ServiceAct_Choose">> <<set $temp.chosenPosition = _pos>> <</link>> <</capture>> <</for>> </div>
<<ensureServiceContext>> /* ═══ Mode select: full interactive encounter or quick resolve ═══ */ <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _pos = $temp.chosenPosition>> <<set $temp.actDcMod = 0>> <<set $temp.actFlair = 0>> <<set $temp.sexMinigameOutcome = null>> <h2><<print _pos.name>></h2> <p>Clothes hit the floor. <<print _npc.firstName>>'s hands are on you, and the next part is about to begin. How much of yourself are you going to put into this one?</p> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Take your time: give a real performance <em>(interactive)</em></span>' "ServiceSex_Start">><</link>> <<link '<span class="choice-btn">⚡ Just take care of <<print _npc.gender === "male" ? "him" : "her">> <em>(quick resolve)</em></span>' "ServiceAct_Technique">><</link>> </div>
<<ensureServiceContext>> <<run XCLC.Sex.start()>> <<set _npc = $temp.serviceNPC>> <<set _req = $temp.serviceRequest>> <<set _known = _npc.knownPrefs && _npc.knownPrefs.length > 0>> <h2>The Performance Begins</h2> <p>The last of the clothes are gone and the world narrows to skin, breath, and heat. <<print _npc.firstName>>'s body is <<print _npc.bodyType>>, warm under your hands, <<print _npc.gender === "male" ? "his" : "her">> pulse visible at the throat, already quick, already wanting. <<if _req.locationPrivacy === "low">>You're barely hidden here; every distant footstep sharpens the edge of it.<<elseif _req.locationPrivacy === "high">>The door is locked, the world shut out. You have all the time you decide to take.<<else>>The privacy is imperfect, enough to work with, thin enough to keep your heart rate honest.<</if>></p> <p>You take one slow breath and let this body do what it's frighteningly good at. This is a craft now, pace, pressure, attention, the reading of small signals. Every partner is an instrument with its own tuning<<if _known>>, and with <<print _npc.firstName>>, you already know some of the notes<</if>>.</p> <p style="opacity:0.7; font-size:0.85em;"><em>Fill <<print _npc.gender === "male" ? "his" : "her">> Pleasure before your Stamina runs out. Moves marked 💖 are a known favourite. You can finish <<print _npc.gender === "male" ? "him" : "her">> off any time past 70 Pleasure.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">Begin →</span>' "ServiceSex_Round">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _se = $transformation.sideEffects>> /* ─── End state reached? ─── */ <<if $temp.sexOutcome>> <<goto "ServiceSex_Finish">> <</if>> /* ─── Mid-scene orgasm at maxed arousal ─── */ <<if $pc.arousal >= 100 && !$temp.sexCameAlready>> <<set $temp.sexCameAlready = true>> <<if _se.orgasmDenial >= 2 && random(1,100) <= 40>> <p>💥 The climax rushes up on you mid-motion, and slams into the wall of the Orgasm Denial effect. Your body locks, trembling on the edge of a release that will not come. You have to keep working through the frustration screaming under your skin.</p> <<set $pc.arousal = 90>> <<modStat "stress" 8 "Denied mid-scene">> <<else>> <p>💥 It ambushes you mid-motion. Your own orgasm, sudden and enormous, tearing through you while you're supposed to be working. You shake through it, gasping, and <<print _npc.firstName>> <<if _npc.personality === "aggressive" || _npc.personality === "demanding">>smirks. "Focus."<<else>>watches with open delight. "That," <<if _npc.gender === "male">>he<<else>>she<</if>> breathes, "was the hottest thing I've ever seen."<</if>></p> <<set $pc.arousal = 30>> <<modStat "mood" 10 "Release">> <<modStat "energy" -8 "Orgasm">> <<if _npc.personality !== "aggressive" && _npc.personality !== "demanding">> <<set $temp.actFlair += 2>> <<run (function(){ var sv = State.variables; sv.temp.sexPleasure = Math.min(100, sv.temp.sexPleasure + 12); }())>> <</if>> <</if>> <</if>> <h2>Round <<print $temp.sexRound + 1>>: <<print $temp.chosenPosition.name>></h2> /* ─── Last move result ─── */ <<if $temp.sexLastText>> <p><<print $temp.sexLastText>></p> <</if>> /* ─── Ambient scene texture ─── */ <p style="opacity:0.65;"><em><<print XCLC.Sex.ambient()>></em></p> /* ─── Meters ─── */ <<set _plPct = Math.round($temp.sexPleasure)>> <<set _stPct = Math.round(($temp.sexStamina / $temp.sexStaminaMax) * 100)>> <<set _arPct = Math.round($pc.arousal)>> <div class="card" style="padding: 0.8em 1.2em;"> <div class="sex-meter-row"> <span class="stat-bar-icon">💗</span> <span class="sex-meter-label"><<print _npc.gender === "male" ? "His" : "Her">> Pleasure</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _plPct + '%; background: var(--accent-pink);'"></div></div> <span class="sex-meter-val"><<print _plPct>></span> </div> <div class="sex-meter-row"> <span class="stat-bar-icon">💪</span> <span class="sex-meter-label">Stamina</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _stPct + '%; background: var(--accent-teal);'"></div></div> <span class="sex-meter-val"><<print Math.round($temp.sexStamina)>></span> </div> <div class="sex-meter-row"> <span class="stat-bar-icon">🔥</span> <span class="sex-meter-label">Arousal</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _arPct + '%; background: var(--accent-purple);'"></div></div> <span class="sex-meter-val"><<print _arPct>></span> </div> </div> /* ─── Partner state flavour ─── */ <p style="opacity:0.75;"><em><<if $temp.sexPleasure >= 85>><<print _npc.firstName>> is right on the edge, shaking, incoherent, one good push from finished.<<elseif $temp.sexPleasure >= 60>><<print _npc.firstName>>'s control is slipping fast, flushed skin, ragged breathing, hands that can't stay still.<<elseif $temp.sexPleasure >= 30>><<print _npc.firstName>> is fully into it now, responding to everything you do.<<else>>You're just getting started. <<print _npc.firstName>> watches you with hungry anticipation.<</if>></em></p> /* ─── Moves ─── */ <<set _moves = XCLC.Sex.available()>> <div class="choice-group"> <<for _mi = 0; _mi < _moves.length; _mi++>> <<set _mv = _moves[_mi]>> <<set _isKnownPref = _npc.knownPrefs && _npc.knownPrefs.indexOf(_mv.id) !== -1>> <<set _hasSyn = XCLC.Sex.hasSynergy(_mv)>> <<capture _mv, _isKnownPref, _hasSyn>> <<link '<span class="choice-btn"><<print _mv.icon>> <<print _mv.name>> <<if _isKnownPref>>💖<</if>><<if _hasSyn>>⚡<</if>> <em>(−<<print _mv.cost>> stamina<<if _hasSyn>>, position bonus<</if>>)</em></span>' "ServiceSex_Round">> <<run XCLC.Sex.doMove(_mv.id)>> <</link>> <</capture>> <</for>> <<link '<span class="choice-btn">🗣️ Dirty talk <em>(−5 stamina, Dirty Talk check)</em></span>' "ServiceSex_Round">> <<run XCLC.Sex.doMove('u_dirty')>> <</link>> <<if XCLC.Sex.switchOptions().length > 0>> <<link '<span class="choice-btn">🔄 Switch position <em>(−6 stamina, keeps things fresh)</em></span>' "ServiceSex_Switch">><</link>> <</if>> <<link '<span class="choice-btn">🌬️ Slow down: catch your breath <em>(+12 stamina)</em></span>' "ServiceSex_Round">> <<run XCLC.Sex.doMove('u_breather')>> <</link>> <<if $temp.sexPleasure >= 70>> <<link '<span class="choice-btn">🏁 Finish <<print _npc.gender === "male" ? "him" : "her">> off now <em>(bank a solid result)</em></span>' "ServiceSex_Round">> <<run XCLC.Sex.cashOut()>> <</link>> <</if>> </div>
<<ensureServiceContext>> <<set _npc = $temp.serviceNPC>> <<set _opts = XCLC.Sex.switchOptions()>> <h2>🔄 Switch It Up</h2> <p>You slow to a stop, a hand on <<print _npc.gender === "male" ? "his" : "her">> chest, a breathless half-smile, and take stock. <<print _npc.firstName>> watches you, chest heaving, waiting to see what you'll do with <<print _npc.gender === "male" ? "him" : "her">> next. Moves marked ⚡ will hit harder in the right position.</p> <div class="choice-group"> <<for _oi = 0; _oi < _opts.length; _oi++>> <<set _op = _opts[_oi]>> <<capture _op>> <<link '<span class="choice-btn">🔄 <<print _op.name>>: <<print _op.desc>></span>' "ServiceSex_Round">> <<run XCLC.Sex.switchPosition(_op.id)>> <</link>> <</capture>> <</for>> <<link '<span class="choice-btn">↩️ Actually, stay right where you are</span>' "ServiceSex_Round">><</link>> </div>
<<ensureServiceContext>> <<set _npc = $temp.serviceNPC>> <<set _outcome = $temp.sexOutcome>> <h2><<if _outcome === "crit_success">>Masterpiece<<elseif _outcome === "success">>Well Played<<elseif _outcome === "partial_fail">>Running on Empty<<else>>Out of Gas<</if>></h2> <<if _outcome === "crit_success">> <p>You bring <<print _npc.firstName>> to the very peak and hold <<if _npc.gender === "male">>him<<else>>her<</if>> there a cruel extra moment before letting go, total control, start to finish. Whatever <<if _npc.gender === "male">>he<<else>>she<</if>> expected from a campus app, it wasn't <em>this</em>.</p> <<elseif _outcome === "success">> <p>You read the moment and closed it out cleanly. A strong, satisfying finish. The kind that earns good reviews.</p> <<elseif _outcome === "partial_fail">> <p>Your body gives out before the job is quite done. Thighs shaking, jaw aching, lungs burning. <<print _npc.firstName>> has to take over and finish the last stretch alone. Not a disaster. Not your best work either.</p> <<modStat "confidence" -3 "Ran out of gas">> <<else>> <p>You hit the wall hard. Completely spent with the job barely half done. The last few minutes are a limp, apologetic shuffle to an unsatisfying end. <<print _npc.firstName>>'s expression says everything.</p> <<modStat "confidence" -6 "Couldn't deliver">> <<modStat "stress" 8 "Failed performance">> <</if>> <<set $temp.sexMinigameOutcome = _outcome>> <<modStat "energy" `-Math.max(5, Math.round(($temp.sexStaminaMax - $temp.sexStamina) / 8))` "Exertion">> <<set _finishTarget = XCLC.Encounter.finishPassage()>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' _finishTarget>><</link>> </div>
<<ensureServiceContext>> /* ═══ Beat 1 (quick resolve): How do you approach it? ═══ */ <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _pos = $temp.chosenPosition>> <<set $temp.actDcMod = 0>> <<set $temp.actFlair = 0>> <h2><<print _pos.name>></h2> <p><<if _req.serviceType === "oral">>You're on your knees, <<print _npc.firstName>> in front of you, and the next few minutes are yours to shape.<<elseif _req.serviceType === "anal">>You brace yourself against <<print _req.locationDesc>>. He's behind you, patient for exactly as long as you make him be.<<else>>Skin against skin, his breath on your neck. How this goes is, partly, up to you.<</if>></p> <div class="choice-group"> <<if _req.serviceType === "oral">> <<link '<span class="choice-btn">🐢 Steady and careful: don\'t overreach <em>(easier check)</em></span>' "ServiceAct_Round1">> <<set $temp.actDcMod = -1>> <<set $temp.actBeatText = "You keep it controlled, steady rhythm, no heroics. Reliable beats flashy.">> <</link>> <<link '<span class="choice-btn">🔥 Go all in: give <<print _npc.gender === "male" ? "him" : "her">> a show <em>(harder check, better rating)</em></span>' "ServiceAct_Round1">> <<set $temp.actDcMod = 1>> <<set $temp.actFlair += 2>> <<set $temp.actBeatText = "You commit completely, eye contact, enthusiasm, zero hesitation. If you pull this off, " + (State.temporary.npc.gender === "male" ? "he" : "she") + " will never forget it.">> <</link>> <<link '<span class="choice-btn">👀 Watch <<print _npc.gender === "male" ? "his" : "her">> reactions and adapt <em>(Composure check)</em></span>' "ServiceAct_Read">><</link>> <<elseif _req.serviceType === "anal">> <<link '<span class="choice-btn">😮💨 Breathe and relax into it <em>(easier check)</em></span>' "ServiceAct_Round1">> <<set $temp.actDcMod = -1>> <<set $temp.actBeatText = "You focus on your breathing and let your body adjust at its own pace. Slow is smooth.">> <</link>> <<link '<span class="choice-btn">🍑 Push back and match him <em>(harder check, better rating)</em></span>' "ServiceAct_Round1">> <<set $temp.actDcMod = 1>> <<set $temp.actFlair += 2>> <<set $temp.actBeatText = "You don't just take it, you meet him halfway, setting a pace that makes him swear under his breath.">> <</link>> <<link '<span class="choice-btn">🗣️ Tell him exactly how to go <em>(Persuasion check)</em></span>' "ServiceAct_Read">><</link>> <<else>> <<link '<span class="choice-btn">🎯 Let him set the pace <em>(easier check)</em></span>' "ServiceAct_Round1">> <<set $temp.actDcMod = -1>> <<set $temp.actBeatText = "You follow his lead, matching his rhythm instead of fighting it. Easier on you, even if it gives him all the control.">> <</link>> <<link '<span class="choice-btn">🐎 Take control <em>(harder check, better rating)</em></span>' "ServiceAct_Round1">> <<set $temp.actDcMod = 1>> <<set $temp.actFlair += 2>> <<set $temp.actBeatText = "You flip the script, your pace, your angle, your show. His eyes go wide. Now you just have to deliver.">> <</link>> <<link '<span class="choice-btn">👀 Read his body and adapt <em>(Charm check)</em></span>' "ServiceAct_Read">><</link>> <</if>> </div>
<<ensureServiceContext>> /* ═══ Beat 1b: the adaptive gamble: a social sub-check that swings the DC ═══ */ <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _readSkill = _req.serviceType === "anal" ? "persuasion" : (_req.serviceType === "oral" ? "composure" : "charm")>> <<set _readResult = XCLC.Roll.doCheck(_readSkill, 3)>> <<run XCLC.DicePopup.show()>> <<set _him = _npc.gender === "male" ? "him" : "her">> <<set _his = _npc.gender === "male" ? "his" : "her">> <<set _hes = _npc.gender === "male" ? "he's" : "she's">> <h2>Reading <<print _him.charAt(0).toUpperCase() + _him.slice(1)>></h2> <<if _readResult === "crit_success" || _readResult === "success">> <p>You pay attention, every hitch of breath, every twitch, every reflexive grip of <<print _his>> hands. Within a minute you know exactly what works on <<print _him>>, and you use all of it.</p> <<set $temp.actDcMod = -2>> <<set $temp.actFlair += 1>> <<set $temp.actBeatText = "You've cracked " + _his + " code. Everything you do lands.">> <<else>> <p>You try to read <<print _him>>, but <<print _hes>> a closed book, or you're distracted, second-guessing every move. You lose your own rhythm hunting for <<print _his>>.</p> <<set $temp.actDcMod = 1>> <<set $temp.actBeatText = "Overthinking it cost you your flow. You scramble to recover.">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "ServiceAct_Round1">><</link>> </div>
<<ensureServiceContext>> /* ═══ Round 1: the beginning: extended scene prose + pace choice ═══ */ <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _pos = $temp.chosenPosition>> <<set _se = $transformation.sideEffects>> <h2><<print _pos.name>></h2> <p><em><<print $temp.actBeatText>></em></p> <<if _npc.gender === "female">> /* ─── Female NPC (oral) ─── */ <p>She settles back, thighs parting for you, and there's a heartbeat where she just looks at you, flushed, expectant, her <<print _npc.breastSize>>-cup chest rising and falling. You lower your mouth to her and she exhales like she's been holding that breath all day.</p> <p>You learn her by sound. The soft hitch when your tongue moves slow and flat. The sharper gasp when you focus, precise, right where she needs it. Her fingers slide into your <<print $pc.hairColour>> hair, not pushing, just holding on. "God," she whispers to the ceiling. "The app reviews did not do you justice."</p> <<elseif _req.serviceType === "oral">> /* ─── Oral, male ─── */ <<set _sizeDesc = {small: 'modest, you can take all of him without thinking', below_avg: 'unintimidating, comfortable', average: 'a solid, warm weight on your tongue', above_avg: 'big enough that your jaw already knows it', large: 'thick enough that your lips stretch around him', huge: 'genuinely intimidating, your fingers don\'t close around the base'}>> <p>You sink down onto your knees<<if _req.locationPrivacy === "low">>, hyper-aware that anyone could walk past<<if _se.exhibitionist >= 2>>, and God help you, that thought makes it better<</if>><</if>>. Up close he's <<print _sizeDesc[_npc.cockSize] || 'a solid, warm weight'>>. You wrap a hand around him, feel the heat of him, the pulse. Above you, <<print _npc.firstName>> goes very still, waiting.</p> <p>You start slow, a long, flat lick from base to tip, watching his stomach muscles jump. Then your lips close over him and the taste of him spreads across your tongue, salt and skin, and the small broken sound he makes goes straight through you. You take him deeper, cheeks hollowing, one hand working what your mouth can't cover, and set a rhythm that has his thighs trembling inside a minute.</p> <<if _se.oralLover >= 2>> <p><em>The Oral Lover effect hums under your skin, this isn't a job right now, your body genuinely wants this, mouth watering, pulse quick. That eagerness leaks into every movement and he can tell.</em></p> <</if>> <<elseif _req.serviceType === "anal">> /* ─── Anal ─── */ <p>You brace yourself, breathing slow, as he lines up behind you. There's pressure first, insistent, patient, and then the stretch, inch by careful inch, your body yielding around him with a fullness that borders on too much. Your knuckles go white on <<print _req.locationDesc>>. "Breathe," he says<<if _npc.personality === "aggressive">>, though he doesn't slow down<<else>>, and actually waits until you do<</if>>.</p> <p>Then he starts to move, and the too-much becomes something else. Deep and dark and shockingly intense, every slow thrust dragging sensation up your spine. Small sounds keep escaping you, sounds you'd be embarrassed by if you had any spare attention left to be embarrassed with.</p> <<if _se.analLover >= 2>> <p><em>The Anal Lover effect turns the burn to honey almost immediately. Your body arches back to meet him without consulting you first.</em></p> <</if>> <<if $transformation.addons.stretchy>> <p><em>The Stretchy add-on does its quiet work, no pain, just pressure and fullness and heat.</em></p> <</if>> <<else>> /* ─── Vaginal ─── */ <<set _entryDesc = {small: 'easily, almost gently', below_avg: 'smoothly', average: 'with a stretch that makes you exhale hard', above_avg: 'with a slow, relentless stretch', large: 'with a fullness that borders on overwhelming', huge: 'in slow, careful increments that leave you gasping'}>> <p><<if _pos.id === "cowgirl">>You push him down and climb astride him, taking his weight between your thighs. You line him up and sink down <<print _entryDesc[_npc.cockSize] || 'with a stretch'>>, controlling every inch of it, watching his face come apart beneath you as your body takes him in.<<elseif _pos.id === "doggy">>You go down on your forearms and he takes your hips in both hands. He enters you from behind <<print _entryDesc[_npc.cockSize] || 'with a stretch'>>, and the angle steals the air out of your lungs, deep, immediate, no adjustment period at all.<<elseif _pos.id === "rough">>He doesn't ask. He pins your wrists, kicks your feet apart, and drives into you <<print _entryDesc[_npc.cockSize] || 'with a stretch'>>. Your cry bounces off the walls of <<print _req.locationDesc>>.<<else>>He settles over you, his weight pressing you down, and pushes inside <<print _entryDesc[_npc.cockSize] || 'with a stretch'>>. For a moment neither of you moves, just his breath at your ear and your body adjusting around him, heartbeat by heartbeat.<</if>></p> <p><<if $transformation.addons.wet>>The Wet add-on means there's no friction, no resistance, just slick, obscene ease, and the sound of it fills the room. He groans at how ready you are.<<else>>Your body warms to it by degrees, each movement smoother than the last.<</if>> He finds a rhythm and your breath starts keeping time with it, little punched-out sounds you couldn't suppress if you tried.</p> <<if $pregnancy.isPregnant && $pregnancy.weeksPregnant >= 12>> <p><em>He's careful around your bump<<if _npc.personality === "aggressive" || _npc.personality === "demanding">>, or careless, rather, and you adjust your own angle to protect it<</if>>. Pregnancy has made everything more sensitive; you feel him everywhere.</em></p> <</if>> <</if>> <<if _se.increasedSensitivity >= 2>> <p><em>Your hypersensitivity turns every point of contact incandescent. It's building too fast. Staying in control takes real effort.</em></p> <<modStat "arousal" 10 "Hypersensitivity">> <</if>> <<if _se.internalHeat >= 2 && _req.serviceType !== "oral">> <p><em>The Internal Heat effect purrs in satisfaction. THIS is what your body has been demanding for days. The relief of it is almost as strong as the pleasure.</em></p> <</if>> <<if _npc.gender === "male">> <<divider "How do you want it?">> <div class="choice-group"> <<link '<span class="choice-btn">🕯️ Slow and deep: draw it out, savour it</span>' "ServiceAct_Round2">> <<set $temp.actPace = "slow">> <<set $temp.actFlair += 1>> <<modStat "arousal" 10 "Slow burn">> <</link>> <<link '<span class="choice-btn">🔥 Hard and fast: take him for a ride</span>' "ServiceAct_Round2">> <<set $temp.actPace = "hard">> <<set $temp.actFlair += 1>> <<modStat "arousal" 15 "Intensity">> <<modStat "energy" -5 "Exertion">> <<addXP "stamina" 5>> <</link>> <<link '<span class="choice-btn">🫦 Surrender completely: let him do what he wants</span>' "ServiceAct_Round2">> <<set $temp.actPace = "surrender">> <<modStat "arousal" 20 "Giving in">> <<modStat "femininity" 2 "Total surrender">> <<if $transformation.sideEffects.submissive >= 2>><<set $temp.actFlair += 2>><<else>><<set $temp.actFlair += 1>><</if>> <</link>> </div> <<else>> /* Female NPCs skip the pace round: her scene builds to its own finish */ <p>Her thighs start to tremble against your ears. She's close, you can taste it, feel it in the way her whole body draws tight as a bowstring.</p> <<divider "Bring her home">> <div class="choice-group"> <<link '<span class="choice-btn">🎯 Stay exactly where you are: steady, relentless</span>' "ServiceMainAct">> <<set $temp.actFlair += 2>> <<addXP "oral" 5>> <</link>> <<link '<span class="choice-btn">🗣️ Murmur something filthy against her <em>(Dirty Talk check)</em></span>' "ServiceAct_DirtyTalk">><</link>> <<link '<span class="choice-btn">💗 Slide a hand between your own legs too</span>' "ServiceMainAct">> <<modStat "arousal" 15 "Touching yourself">> <<modStat "femininity" 1 "Shameless">> <<set $temp.actFlair += 1>> <</link>> </div> <</if>>
<<ensureServiceContext>> /* ═══ Round 2: building: pace consequences, then escalation choices ═══ */ <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _pos = $temp.chosenPosition>> <<set _se = $transformation.sideEffects>> <<set _pace = $temp.actPace || "slow">> <h2>Deeper</h2> <<if _pace === "slow">> <p>You slow everything down to a syrup crawl, long, deliberate movements that make each second stretch. <<if _req.serviceType === "oral">>Your mouth becomes patient, thorough, taking him to the root and holding there until his breath shakes, then off again slow enough to feel every vein against your tongue.<<else>>Every thrust lands full and unhurried, deep enough to make you both feel all of it, no rush toward anywhere.<</if>> It's torture, and it's exquisite, and <<print _npc.firstName>> is coming undone by degrees.</p> <p><<if _npc.personality === "demanding">>"You're doing this on purpose," he grits out. You absolutely are.<<elseif _npc.personality === "romantic">>"Like that," he breathes. "Exactly like that. Don't change a thing."<<else>>His hands flex against you, caught between wanting more and never wanting this to end.<</if>></p> <<elseif _pace === "hard">> <p>You crank the pace until the world blurs at the edges. <<if _req.serviceType === "oral">>Fast, wet, relentless, your jaw burns and you don't care, chasing his sounds, your hand and mouth in overdrive.<<else>>Skin on skin, sharp and rhythmic, the obscene percussion of it filling <<print _req.locationDesc>>. Sweat gathers along your spine. Your thighs scream. You don't slow down.<</if>></p> <p><<if _npc.personality === "aggressive">>"FUCK. Yes." He matches you, and it becomes a contest neither of you wants to win quickly.<<elseif _npc.personality === "shy">>He makes a sound like the air's been knocked out of him. "I. You're. <em>Oh my god</em>."<<else>><<print _npc.firstName>> swears, low and reverent, hands gripping hard enough to leave prints.<</if>></p> <<modStat "arousal" 10 "Relentless pace">> <<else>> <p>You let go of everything, control, pretence, self-consciousness, and let him move you how he wants. Your body becomes something he plays: repositioned, angled, used. There's a strange, floating freedom in it, in having no decisions left to make, nothing to do but feel.</p> <p><<if _npc.personality === "aggressive" || _npc.personality === "demanding">>He takes the surrender as his due, thorough, unhurried, absolute. "Good girl," he says, and the words land somewhere deep and traitorous that glows at the praise.<<elseif _npc.personality === "sweet" || _npc.personality === "romantic">>He handles the gift of it with unexpected care, murmuring your name against your skin like it means something.<<else>><<print _npc.firstName>> exhales like he's won something, and maybe he has.<</if>></p> <<if _se.submissive >= 2>> <p><em>The Submissive effect sings. This, exactly this, is the shape your altered brain wants the world to be.</em></p> <<modStat "arousal" 10 "Submission">> <</if>> <</if>> /* ─── Escalation: NPC demand or player-driven ─── */ <<set _demand = random(1, 100) <= 45>> <<if _demand>> <<divider "He wants more">> <<if _npc.personality === "aggressive" || _npc.personality === "demanding">> <p>Abruptly he stops, grips you, and moves you where he wants you, <<if _req.serviceType === "oral">>both hands in your hair now, angling your head back. "Open. Stay still."<<else>>hauling you into a new angle entirely, deeper, sharper. "Like this."<</if>> Not a question.</p> <div class="choice-group"> <<link '<span class="choice-btn">😮 Take everything he gives</span>' "ServiceMainAct">> <<set $temp.actFlair += 2>> <<modStat "arousal" 15 "Used hard">> <<modStat "stress" 3 "Intense">> <<addXP "stamina" 8>> <</link>> <<link '<span class="choice-btn">✋ Set a boundary: "Easy. My pace."</span>' "ServiceMainAct">> <<set _boundary = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _boundary === "crit_success" || _boundary === "success">> <<set $temp.actFlair += 1>> <<modStat "confidence" 5 "Held your ground">> <<else>> <<set $temp.actFlair -= 1>> <<modStat "stress" 5 "Ignored">> <</if>> <</link>> </div> <<elseif _npc.personality === "romantic" || _npc.personality === "sweet">> <p>He slows, cradles your face, makes you meet his eyes. "Tell me what you want," he says quietly. "Not what the app says. What <em>you</em> want."</p> <div class="choice-group"> <<link '<span class="choice-btn">💬 Tell him the truth</span>' "ServiceMainAct">> <<set $temp.actFlair += 2>> <<modStat "mood" 5 "Being asked">> <<modStat "femininity" 2 "Honest wanting">> <<modStat "arousal" 10 "Getting what you asked for">> <</link>> <<link '<span class="choice-btn">😶 Deflect: "This is about you."</span>' "ServiceMainAct">> <<set $temp.actFlair += 1>> <<modStat "willpower" 2 "Walls up">> <</link>> </div> <<else>> <p>"Turn around," he says suddenly<<if _req.serviceType === "oral">>, he wants a different angle, wants to watch himself disappear between your lips<<else>>, he wants you a new way, wants variety, wants everything<</if>>.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔄 Give him the variety he wants</span>' "ServiceMainAct">> <<set $temp.actFlair += 2>> <<addXP "flexibility" 8>> <<modStat "arousal" 10 "New angle">> <</link>> <<link '<span class="choice-btn">😏 "No. You\'ll finish exactly like this."</span>' "ServiceMainAct">> <<set _tease = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _tease === "crit_success" || _tease === "success">> <<set $temp.actFlair += 3>> <<modStat "confidence" 5 "Delicious control">> <<else>> <<set $temp.actFlair -= 1>> <</if>> <</link>> </div> <</if>> <<else>> <<divider "The edge is getting closer">> <p><<if _npc.personality === "creepy">>"Look at me while you do it," he says. You fix your <<print $pc.eyeColour>> eyes on his and something in his expression makes you feel like a photograph being taken.<<else>><<print _npc.firstName>> is close now. You can feel it in the changed rhythm, hear it in his breathing. And your own body is climbing right alongside his, whether you invited it to or not.<</if>></p> <div class="choice-group"> <<link '<span class="choice-btn">🗣️ Talk dirty to him <em>(Dirty Talk check: big rating swing)</em></span>' "ServiceAct_DirtyTalk">><</link>> <<if $pc.arousal >= 70 && _se.masturbationDenial < 2>> <<link '<span class="choice-btn">💥 Stop holding back: let yourself come</span>' "ServiceMainAct">> <<set $temp.actFlair += 2>> <<modStat "arousal" -35 "Mid-scene orgasm">> <<modStat "mood" 10 "Release">> <<modStat "femininity" 2 "Came for him">> <<run XCLC.Toast.show("💥 You come apart around him, and he FELT it. Flair +2.", "success", 5000)>> <</link>> <</if>> <<link '<span class="choice-btn">💗 Touch yourself while he works</span>' "ServiceMainAct">> <<modStat "arousal" 15 "Your own hand">> <<modStat "femininity" 1 "Shameless">> <<set $temp.actFlair += 1>> <</link>> <<link '<span class="choice-btn">🎯 Stay focused: bring him home like a professional</span>' "ServiceMainAct">> <<set $temp.actFlair += 1>> <<addXP `_req.serviceType === "mixed" ? "oral" : _req.serviceType` 5>> <</link>> </div> <</if>>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _dtResult = XCLC.Roll.doCheck("dirtyTalk", 3)>> <<run XCLC.DicePopup.show()>> <h2>🗣️ Saying It Out Loud</h2> <<if _dtResult === "crit_success">> <p>The words come out low and filthy and perfectly timed, and <<print _npc.firstName>> nearly loses it on the spot. "Where the hell did THAT come from?" You have no idea. You're a little shocked at yourself.</p> <<set $temp.actFlair += 3>> <<modStat "arousal" 15 "Your own words">> <<addXP "dirtyTalk" 20>> <<elseif _dtResult === "success">> <p>You murmur something you'd never repeat sober. It works, <<if _npc.gender === "male">>his rhythm stutters, his grip tightens<<else>>her breath catches, her thighs clamp tighter<</if>>. Noted.</p> <<set $temp.actFlair += 2>> <<modStat "arousal" 10 "Saying it out loud">> <<addXP "dirtyTalk" 15>> <<else>> <p>"Yeah, you... like that... thing." It comes out flat and awkward, like a bad actor reading a script. <<print _npc.firstName>> actually snorts. You want to dissolve.</p> <<set $temp.actFlair -= 1>> <<modStat "confidence" -3 "Dirty talk disaster">> <<addXP "dirtyTalk" 8>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "ServiceMainAct">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _pos = $temp.chosenPosition>> <<set _se = $transformation.sideEffects>> <<if $temp.sexMinigameOutcome>> /* ═══ Minigame path: outcome already earned round by round: no extra roll ═══ */ <<set _result = $temp.sexMinigameOutcome>> <<set $temp.serviceOutcome = _result>> <<set $temp.sexMinigameOutcome = null>> <<else>> /* Calculate final DC: base + position modifier + technique choices */ <<set _dc = _req.dc + (_pos.dc || 0) + ($temp.actDcMod || 0)>> /* ─── Add-on DC Modifiers ─── */ /* No Gag Reflex: -2 DC on oral */ <<if $transformation.addons.gagReflex && _req.serviceType === "oral">> <<set _dc = Math.max(1, _dc - 2)>> <</if>> /* Stretchy: -1 DC with large/huge partners */ <<if $transformation.addons.stretchy && (_npc.cockSize === "large" || _npc.cockSize === "huge")>> <<set _dc = Math.max(1, _dc - 1)>> <</if>> /* ─── Side Effect DC Modifiers ─── */ /* Oral Lover: -1 DC on oral per level (max -2) */ <<if _se.oralLover > 0 && _req.serviceType === "oral">> <<set _dc = Math.max(1, _dc - Math.min(2, _se.oralLover))>> <</if>> /* Anal Lover: -1 DC on anal per level (max -2) */ <<if _se.analLover > 0 && _req.serviceType === "anal">> <<set _dc = Math.max(1, _dc - Math.min(2, _se.analLover))>> <</if>> /* Submissive: +willingness but no DC change (handled in processEffects) */ /* Exhibitionist: arousal bonus if location is public */ <<if _se.exhibitionist >= 2 && _req.isPublic>> <<modStat "arousal" 10 "Exhibitionist thrill">> <</if>> /* Perform the skill check */ <<set _skill = _req.serviceType>> <<if _skill === "mixed">><<set _skill = "oral">><</if>> <<set _result = XCLC.Roll.doCheck(_skill, _dc)>> <<set $temp.serviceOutcome = _result>> <<set $temp.serviceRoll = $lastRoll>> /* Show the roll modal */ <<run XCLC.DicePopup.showService()>> <</if>> <h2><<print _pos.name>></h2> /* ═══ ORAL ═══ */ <<if _req.serviceType === "oral">> <<if _npc.gender === "male">> <<set _sizeWord = {small: 'manageable', below_avg: 'modest', average: 'average', above_avg: 'big', large: 'thick', huge: 'enormous'}>> <<set _sw = _sizeWord[_npc.cockSize] || 'average'>> <<if _result === "crit_success">> <p>You sink to your knees on the cold floor. <<print _npc.firstName>> is <<print _sw>>, <<if _npc.cockSize === "huge">>intimidating, but you open wide and take him in. Your jaw aches instantly but you don't care.<<elseif _npc.cockSize === "small">>easy to take. You work the full length without effort.<<else>>a comfortable mouthful.<</if>></p> <p><<if _pos.id === "deepthroat">>You relax your throat and take him to the base. His hands clutch at your <<print $pc.hairColour>> hair as you swallow around him. "Holy fuck," he whispers.<<elseif _pos.id === "facefuck">>He grabs fistfuls of your <<print $pc.hairColour>> hair and thrusts. You breathe through your nose, taking it, eyes watering but never gagging. He looks down at you with something like awe.<<else>>Your tongue works the underside, your hand covers what your mouth can't reach. You look up at him through your lashes with your <<print $pc.eyeColour>> eyes. He moans.<</if>></p> <p>You're good at this. Better than you should be. The thought is disturbing and thrilling in equal measure.</p> <<modStat "confidence" 5 "Amazing performance">> <<elseif _result === "success">> <p>You kneel and take him in your mouth. He's <<print _sw>>, <<if _npc.cockSize === "large" || _npc.cockSize === "huge">>a stretch, your jaw already aching, but you manage.<<else>>manageable.<</if>></p> <p><<if _pos.id === "deepthroat">>You work your way deeper, gagging once before finding the right angle. It's not elegant but it works. <<print _npc.firstName>> groans appreciation.<<elseif _pos.id === "facefuck">>He grips your <<print $pc.hairColour>> hair and thrusts. You try to keep up, eyes streaming. It's brutal but you hang on.<<else>>Your head bobs steadily. You find a rhythm, tongue, lips, hand. <<print _npc.firstName>> leans back and lets you work.<</if>></p> <<elseif _result === "partial_fail">> <p>You kneel and wrap your lips around him. He's <<print _sw>>. <<if _npc.cockSize === "large" || _npc.cockSize === "huge">>TOO big. You gag immediately, pulling back with strings of saliva.<<else>>You try to find a rhythm but your jaw cramps and your technique is off.<</if>></p> <p><<if _pos.id === "deepthroat">>You try to go deep but your gag reflex kicks in hard. You pull off coughing. <<print _npc.firstName>> sighs.<<elseif _pos.id === "facefuck">>He pushes too deep and you choke. He pulls back but the mood is broken. "Sorry," you gasp.<<else>>Your hand keeps slipping. Your mouth is dry then too wet. It's messy and awkward.<</if>></p> <<modStat "confidence" -3 "Sloppy performance">> <<else>> <p>You kneel. He's <<print _sw>>. The first attempt goes badly, your teeth scrape him and he hisses. "Watch it!"</p> <p><<if _pos.id === "deepthroat">>You try to go deep, gag violently, and have to pull off completely. Your eyes are streaming, mascara running. <<print _npc.firstName>> looks annoyed.<<elseif _pos.id === "facefuck">>He grabs your head and you panic, shoving him away. He stumbles. "What the fuck?"<<else>>Nothing works. Your jaw locks, your technique is nonexistent. This is humiliating.<</if>></p> <<modStat "confidence" -8 "Terrible performance">> <<modStat "stress" 10 "Humiliation">> <</if>> <<else>> /* Female NPC oral */ <<if _result === "crit_success">> <p>You bury your face between her thighs. She tastes clean, her <<print _npc.skinTone>> skin soft against your cheeks. Your tongue finds her clit and she gasps, fisting the sheets.</p> <p>"Don't stop. Right there." Her <<print _npc.bodyType>> body arches. You don't stop.</p> <<modStat "confidence" 5 "Amazing performance">> <<elseif _result === "success">> <p>You settle between her legs. It takes a moment to find what works but her sounds guide you, soft moans when you're close, frustrated huffs when you drift off target. Her <<print _npc.breastSize>>-cup chest heaves.</p> <<elseif _result === "partial_fail">> <p>This is harder than it looks. You're not sure where to focus and she keeps shifting. "Higher. No, left. No." It's awkward.</p> <<modStat "confidence" -3 "Uncertain performance">> <<else>> <p>You have no idea what you're doing. She's patient for about thirty seconds before pushing your head away. "Never mind," she says flatly.</p> <<modStat "confidence" -8 "Terrible performance">> <</if>> <</if>> /* ═══ VAGINAL ═══ */ <<elseif _req.serviceType === "vaginal">> <<set _sizeWord = {small: 'easily', below_avg: 'smoothly', average: 'with a stretch', above_avg: 'with a groan', large: 'with difficulty', huge: 'painfully'}>> <<set _sw = _sizeWord[_npc.cockSize] || 'with a stretch'>> <<if _result === "crit_success">> <p><<if _pos.id === "missionary">><<print _npc.firstName>> pushes inside you <<print _sw>>. You feel every inch. Your back arches off the surface, your <<print $pc.breastSize>>-cup breasts pressing against his <<print _npc.bodyType>> chest. Your <<print $pc.hairColour>> hair fans out beneath you.<<elseif _pos.id === "doggy">>You brace yourself on all fours. He enters you from behind <<print _sw>> and your arms nearly give out. The angle is perfect, he's hitting spots you didn't know you had.<<elseif _pos.id === "cowgirl">>You lower yourself onto him <<print _sw>>, controlling the depth. Your <<print $pc.bodyType>> body rolls in a rhythm that makes him grip the sheets. You look down at his face, he's gone.<<else>>He pins you down and enters hard. <<print _sw>>. No warmup, no warning. Your cry echoes in <<print _req.locationDesc>>.<</if>></p> <p>Your body responds in ways that should terrify you. The pleasure builds, overwhelming, undeniable. This feels good. It feels really good. You hate that it feels good.</p> <<modStat "arousal" 30 "Amazing sex">> <<modStat "confidence" 5 "Great performance">> <<elseif _result === "success">> <p><<if _pos.id === "missionary">>He pushes inside <<print _sw>>. It's not comfortable at first, the stretch, the fullness, but your body adjusts. His weight on you, his <<print _npc.hairColour>> hair brushing your forehead.<<elseif _pos.id === "doggy">>On all fours, he enters from behind. <<print _sw>>. The angle is deep. Your <<print $pc.breastSize>>-cups sway with each thrust.<<elseif _pos.id === "cowgirl">>You sink down on him <<print _sw>>. It takes a moment to find a rhythm, but once you do, his hands find your hips and hold on.<<else>>Hard and fast. <<print _sw>>. You grip whatever's nearest and hold on.<</if>></p> <p>It's... not terrible. Your body is responding whether you want it to or not.</p> <<modStat "arousal" 20 "Sex">> <<elseif _result === "partial_fail">> <p><<if _pos.id === "missionary">>He pushes in <<print _sw>> and you wince. You try to angle your hips but nothing feels right.<<elseif _pos.id === "doggy">>On all fours, he enters and immediately goes too hard. You cry out, not in pleasure. "Slow down!"<<elseif _pos.id === "cowgirl">>You try to ride him but your thighs burn after thirty seconds. The rhythm is off. He looks underwhelmed.<<else>>It's rough without being good-rough. Just painful. You grit your teeth.<</if>></p> <<modStat "arousal" 10 "Mediocre sex">> <<modStat "confidence" -3 "Clumsy performance">> <<else>> <p><<if _pos.id === "missionary">>He tries to push inside and you tense up. It takes three attempts. When he finally enters, you're too tense for either of you to enjoy it.<<else>>Nothing works. The angle is wrong, you're too dry<<if !$transformation.addons.wet>>, your body isn't cooperating<<else>> despite the Wet add-on<</if>>. <<print _npc.firstName>> is visibly frustrated.<</if>></p> <<modStat "confidence" -8 "Terrible sex">> <<modStat "stress" 10 "Humiliation">> <</if>> /* ═══ ANAL ═══ */ <<elseif _req.serviceType === "anal">> <<set _sizeWord = {small: 'with discomfort', below_avg: 'with a sharp intake of breath', average: 'with a moan you can\'t suppress', above_avg: 'with a cry', large: 'with a scream', huge: 'it takes three tries and you see stars'}>> <<set _sw = _sizeWord[_npc.cockSize] || 'with a gasp'>> <<if _result === "crit_success">> <p><<if _pos.id === "anal_doggy">>On all fours, you breathe deep as he presses against you. He enters <<print _sw>>. You expected pain, and there is some, but the pleasure that follows is shocking. Your <<print $pc.bodyType>> body shudders.<<elseif _pos.id === "prone_bone">>Face down, you bite the pillow. He enters <<print _sw>>. The fullness is overwhelming. Your <<print $pc.breastSize>>-cup breasts are crushed against the surface. Every thrust sends sparks through you.<<elseif _pos.id === "reverse_cowgirl">>You lower yourself onto him backwards <<print _sw>>. The control is yours, you set the pace, the depth. He watches your <<print $pc.buttSize>> ass with glazed eyes.<<else>>Pressed against the wall, he lifts one of your legs and pushes in <<print _sw>>. The position is precarious but the angle is deep.<</if>></p> <p>You'd never have imagined this could feel good. But it does. It really, undeniably does.</p> <<modStat "arousal" 25 "Amazing anal">> <<modStat "confidence" 5 "Great performance">> <<elseif _result === "success">> <p>He enters <<print _sw>>. It's intense, the stretch, the burn, but you manage. <<if _pos.id === "prone_bone">>Face down, you breathe through it.<<elseif _pos.id === "reverse_cowgirl">>You control the pace, going slow.<<else>>Your hands grip whatever's nearest.<</if>></p> <p>It gets easier after the first minute. Not exactly pleasurable, but not the nightmare you feared.</p> <<modStat "arousal" 15 "Anal">> <<elseif _result === "partial_fail">> <p>He enters <<print _sw>>. You cry out, too loud, too sharp. He pauses. "You okay?" <<if _npc.personality === "sweet">>He actually looks concerned.<<else>>He doesn't wait for an answer before continuing.<</if>></p> <p>Every thrust is a negotiation between pain and tolerance. Your body never fully adjusts.</p> <<modStat "stress" 8 "Painful anal">> <<modStat "confidence" -3 "Difficult performance">> <<else>> <p>He tries to enter and you tense up completely. "Relax," he says. You can't. <<if _npc.cockSize === "large" || _npc.cockSize === "huge">>He's too big, there's no way.<<else>>Your body won't cooperate.<</if>></p> <p>After several painful attempts, he manages to push inside, but it's a disaster. You're white-knuckling through every second.</p> <<modStat "stress" 15 "Terrible anal">> <<modStat "confidence" -8 "Humiliating failure">> <</if>> <</if>> /* ═══ MID-ACT SE TRIGGERS ═══ */ <<if _se.randomOrgasm >= 1 && random(1,100) <= _se.randomOrgasm * 8>> <p>It hits you without warning, an orgasm crashing through you mid-act. Your whole body clenches, your back arches, a moan tears out of you that you can't suppress. <<print _npc.firstName>> <<if _npc.personality === "cocky">>"That good, huh?" He grins.<<elseif _npc.personality === "shy">>freezes. "Did you just...?"<<else>>doesn't stop.<</if>></p> <<modStat "arousal" -20 "Mid-act orgasm">> <</if>> <<if _se.lactation >= 2 && random(1,100) <= 30>> <p>Your breasts are leaking. Milk beads on your <<print $pc.breastSize>>-cup nipples and runs down your chest. <<print _npc.firstName>> <<if _npc.personality === "creepy">>stares, then squeezes one. Milk sprays. He grins. "Kinky."<<elseif _npc.personality === "sweet">>looks alarmed. "Is that, are you okay?"<<else>>notices but doesn't comment.<</if>></p> <</if>> <<if _se.increasedSensitivity >= 3>> <p>Your hypersensitivity makes every sensation ten times more intense. The friction, the pressure, the heat of his body against yours. It's almost too much to bear. You're trembling, overstimuated, barely holding it together.</p> <<modStat "arousal" 15 "Hypersensitivity">> <</if>> <<goto "ServiceClimax">>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _outcome = $temp.serviceOutcome>> <<set _se = $transformation.sideEffects>> <h2>Climax</h2> <<if _npc.gender === "male">> <<if _req.serviceType === "oral">> /* Oral climax: no pregnancy risk */ <<set _swallow = (random(1,100) <= 60) || _npc.personality === "aggressive" || _npc.personality === "demanding">> <<if _swallow>> <p><<print _npc.firstName>>'s hand tightens in your <<print $pc.hairColour>> hair, holding you in place as he finishes. You feel him pulse against your tongue, there's nowhere to go but swallow.</p> <p>"Fuck," he breathes, finally letting go.</p> <<set _req.bonusCredits = 1>> <<else>> <p><<print _npc.firstName>> pulls back at the last second, finishing across your <<if random(1,2) === 1>>lips<<else>>cheek<</if>>. <<if _outcome === "crit_success">>"God damn," he says reverently.<<elseif _outcome === "crit_fail">>He looks disappointed even as he finishes.<<else>>He catches his breath, leaning back.<</if>></p> <</if>> <<elseif _req.serviceType === "anal">> /* Anal climax: no pregnancy risk */ <p><<print _npc.firstName>> grips your hips and drives deep one final time. You feel him pulse inside you, hot, filling, unmistakable. He groans against your <<print $pc.hairColour>> hair.</p> <p>"Fuck," he breathes. He doesn't pull out for a long moment.</p> <<set _req.bonusCredits = 1>> <<elseif $temp.condomUsed>> /* Vaginal with condom: small failure chance, higher when rough */ <<set _breakChance = 4>> <<if ($temp.chosenPosition && $temp.chosenPosition.id === "rough") || _npc.personality === "aggressive">><<set _breakChance = 9>><</if>> <<if _npc.cockSize === "large" || _npc.cockSize === "huge">><<set _breakChance += 4>><</if>> <<if random(1, 100) <= _breakChance>> <p><<print _npc.firstName>> grips your hips and drives deep one final time, and you both feel it go. A sudden change in sensation, unmistakable, a beat before either of you can react.</p> <p>He pulls out. The latex is split along one side. "...Ah," he says, with the particular flatness of a man doing arithmetic. <<toneThink "No. No no no." "Well. That is a problem for future me." "Oops. 🙈">></p> <div class="alert alert--warning">💔 The condom failed.</div> <<pregnancyRisk `_npc.race`>> <<stdRisk "vaginal" 1>> <<modStat "stress" 12 "Condom failure">> <<else>> <p><<print _npc.firstName>> grips your hips and drives deep one final time, groaning as he finishes. The condom catches everything, you feel the pulse of it, but none of the heat.</p> <p>He pulls out, ties it off, and tosses it in the trash. <<if _npc.personality === "aggressive" || _npc.personality === "demanding">>"Happy?" he mutters. You are, actually.<<else>>No dread. No mental math about dates. Just done.<</if>></p> <</if>> <<else>> /* Vaginal: internal or external? */ <<set _internal = false>> <<if $transformation.addons.birthControl>> <<set _internal = (random(1,100) <= 60)>> <<else>> <<set _internal = (random(1,100) <= 30)>> <</if>> <<if _npc.personality === "aggressive" || _npc.personality === "demanding">> <<set _internal = true>> <</if>> <<if _internal>> <p><<print _npc.firstName>> grips your hips and drives deep one final time. You feel him pulse inside you, hot, filling, unmistakable. He groans against your <<print $pc.hairColour>> hair.</p> <p>"Fuck," he breathes. He doesn't pull out for a long moment.</p> <<if $pregnancy.isPregnant && $pregnancy.discovered>> <p><em>He came inside you. A few months ago that thought would have landed like a stone. Now there's a strange, dark comedy to it. That particular ship has long since sailed.</em></p> <<elseif !$transformation.addons.birthControl && !$health.birthControlActive>> <p><em>He came inside you. The thought lands like a stone. You're not on birth control.</em></p> <</if>> <<pregnancyRisk `_npc.race`>> <<set _req.bonusCredits = 1>> <<else>> <p><<print _npc.firstName>> pulls out at the last second, finishing on your <<if random(1,2) === 1>>stomach<<else>>thighs<</if>>. <<if _outcome === "crit_success">>"God damn," he says reverently.<<elseif _outcome === "crit_fail">>He looks disappointed even as he finishes.<<else>>He catches his breath, leaning back.<</if>></p> <</if>> <</if>> <<else>> /* Female NPC climax */ <p><<print _npc.firstName>>'s thighs clamp around your head as she finishes. Her <<print _npc.bodyType>> body shudders, hands clutching at the surface beneath her. A breathless moan escapes her lips.</p> <</if>> /* Player's own reaction */ <<if _se.strongOrgasms >= 2 && $pc.arousal >= 70>> <p>Your own orgasm hits like a freight train. It's not subtle. Your whole body spasms, you cry out, and for a few seconds you can't see or think. When it passes, you're shaking.</p> <<modStat "arousal" -40 "Strong orgasm">> <<modStat "mood" 5 "Intense pleasure">> <<elseif $pc.arousal >= 80 && _se.masturbationDenial <= 1>> <p>You come too. It happens almost against your will. A wave of pleasure cresting and breaking. You press your face into whatever's nearest and ride it out.</p> <<modStat "arousal" -30 "Orgasm">> <<elseif _se.masturbationDenial >= 2 && $pc.arousal >= 70>> <p>You're right on the edge. SO close. But it won't come. The denial SE keeps you hovering at the peak, never tipping over. It's maddening. You whimper in frustration.</p> <<modStat "stress" 5 "Denial frustration">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "ServiceAftermath">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _outcome = $temp.serviceOutcome>> <h2>Aftermath</h2> /* NPC reaction based on outcome */ <<if _outcome === "crit_success">> <p><<print _npc.firstName>> looks at you with genuine admiration. <<if _npc.personality === "shy">>"That was... wow. Thank you. I mean." He goes red again.<<elseif _npc.personality === "aggressive">>"Not bad." From him, that's a five-star review.<<elseif _npc.personality === "romantic">>"You're incredible." He brushes a strand of <<print $pc.hairColour>> hair from your face. "Can I see you again?"<<else>>"That was amazing." He's smiling. Actually smiling.<</if>></p> <<elseif _outcome === "success">> <p><<print _npc.firstName>> nods, satisfied. <<if _npc.personality === "shy">>"T-thanks." He avoids eye contact.<<elseif _npc.personality === "friendly">>"That was good. Thanks, <<print $pc.femaleFirstName>>."<<else>>"Solid." He starts getting dressed.<</if>></p> <<elseif _outcome === "partial_fail">> <p><<print _npc.firstName>> finishes but doesn't look impressed. <<if _npc.personality === "demanding">>"I've had better." Ouch.<<elseif _npc.personality === "sweet">>"It's okay. You're still learning, right?"<<else>>He shrugs. "It was fine."<</if>></p> <<else>> <p><<print _npc.firstName>> looks annoyed. <<if _npc.personality === "aggressive">>"What a waste of time." He doesn't look at you as he leaves.<<elseif _npc.personality === "cocky">>"Wow. That was... bad. Like, really bad." Thanks, <<print _npc.firstName>>.<<else>>He gets dressed quickly, making minimal eye contact. The silence is worse than anything he could say.<</if>></p> <</if>> /* Stat effects are handled in ServiceRating after selfie */ <<advanceTime 30>> <p>You clean up as best you can in <<print _req.locationDesc>>. <<if $hygiene.cleanliness < 30>>You desperately need a shower.<<else>>You feel grimy but functional.<</if>></p> <p><em>Time for the selfie.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">📸 Take the verification selfie</span>' "ServiceSelfie">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _outcome = $temp.serviceOutcome>> <h2>📸 Verification Selfie</h2> <p>CampusHub requires a post-service selfie for verification. You pull out your phone.</p> <p>You look in the phone camera. <<if $pc.makeupApplied>>Your makeup is <<if _outcome === "crit_fail">>completely ruined. Mascara streaks, lipstick smeared to your chin.<<else>>a little smudged but salvageable.<</if>><<else>>No makeup to ruin, at least.<</if>> Your <<print $pc.hairColour>> hair is <<if _outcome === "crit_success">>tousled in that "just had amazing sex" way.<<else>>a mess.<</if>></p> <p>How do you want to take this selfie?</p> <div class="choice-group"> <<link '<span class="choice-btn">🧘 Composed: look presentable (Composure check)</span>' "ServiceSelfieResult">> <<set $temp.selfieMode = "composed">> <<set $temp.selfieResult = XCLC.Roll.doCheck("composure", (_outcome === "crit_fail") ? 4 : 2)>> <</link>> <<link '<span class="choice-btn">😈 Slutty: lean into it (Charm check)</span>' "ServiceSelfieResult">> <<set $temp.selfieMode = "slutty">> <<set $temp.selfieResult = XCLC.Roll.doCheck("charm", (100 - $pc.femininity) / 20)>> <</link>> <<link '<span class="choice-btn">📱 Quick: just snap it, no fuss</span>' "ServiceSelfieResult">> <<set $temp.selfieMode = "quick">> <<set $temp.selfieResult = {outcome: "success"}>> <</link>> </div>
<<set _mode = $temp.selfieMode>> <<set _check = $temp.selfieResult>> /* doCheck() returns a string; the "quick" path stores an object. Normalise both, tolerate null. */ <<set _outcomeStr = (typeof _check === "string") ? _check : ((_check && _check.outcome) ? _check.outcome : "")>> <<set _passed = (_outcomeStr === "crit_success" || _outcomeStr === "success")>> <h2>📸 Selfie Uploaded</h2> <p><<print XCLC.Service.generateSelfieText(_mode, _passed)>></p> /* Apply selfie bonuses */ <<if _mode === "composed" && _passed>> <<set $temp.selfieBonus = 0.2>> <p><em>+0.2 rating bonus for looking presentable.</em></p> <<elseif _mode === "slutty" && _passed>> <<set $temp.selfieBonus = 0.3>> <<modRep "slut" 3 "Slutty selfie">> <p><em>+0.3 rating bonus for the provocative pose. (+3 slut rep)</em></p> <<elseif _mode === "slutty" && !_passed>> <<set $temp.selfieBonus = 0>> <<modRep "slut" 1 "Attempted slutty selfie">> <p><em>Nice try. No bonus. (+1 slut rep for trying)</em></p> <<else>> <<set $temp.selfieBonus = 0>> <</if>> <p>Selfie uploaded to CampusHub. ✅</p> <div class="choice-group"> <<link '<span class="choice-btn">⭐ See your rating</span>' "ServiceRating">><</link>> </div>
<<ensureServiceContext>> <<relationshipStrain>> <<set _req = $temp.serviceRequest>> <<set _npc = $temp.serviceNPC>> <<set _outcome = $temp.serviceOutcome>> <<set _selfieBonus = $temp.selfieBonus || 0>> /* Apply stat effects + credits + quota via existing widget */ <<completeService _req.serviceType _npc _outcome>> /* Apply selfie bonus on top */ <<if _selfieBonus > 0>> <<set $scholarship.rating = Math.min(5, $scholarship.rating + _selfieBonus)>> <<set $scholarship.rating = Math.round($scholarship.rating * 100) / 100>> <</if>> <<set _target = $scholarship.isFinalsWeek ? $scholarship.finalsQuota : $scholarship.weeklyQuota>> <<set _totalCredits = $temp.lastServiceCredits || 1>> <<if isNaN(_totalCredits)>><<set _totalCredits = 1>><</if>> <<if isNaN($scholarship.rating)>><<set $scholarship.rating = 5.0>><</if>> <<set _dispRating = $temp.lastServiceRating>> <<if typeof _dispRating !== 'number' || isNaN(_dispRating)>><<set _dispRating = 3.5>><</if>> <h2>⭐ Service Complete</h2> <div class="card"> <div class="card__title">📊 Results</div> <p><strong>NPC:</strong> <<print _npc.firstName>> <<print _npc.lastName>> (<<print _npc.personality>>)</p> <p><strong>Service:</strong> <<print _req.serviceType.charAt(0).toUpperCase()>><<print _req.serviceType.slice(1)>> · <<print $temp.chosenPosition.name>></p> <p><strong>Rating:</strong> ⭐ <<print _dispRating.toFixed(1)>> <<if _selfieBonus > 0>>(+<<print _selfieBonus>> selfie bonus)<</if>></p> <p><strong>Credits:</strong> +<<print _totalCredits>></p> <p><strong>Overall Rating:</strong> <<print $scholarship.rating.toFixed(2)>></p> <p><strong>Weekly Quota:</strong> <<print $scholarship.currentWeekServiced>>/<<print _target>></p> <<if $scholarship.mercyActive>> <p><em>🛡️ Mercy Rule still active (<<print 5 - $scholarship.totalServices>> encounters remaining)</em></p> <</if>> </div> /* Clean up service state */ <<set $scholarship.inService = false>> <<set $temp.serviceRequest = null>> <<set $temp.serviceNPC = null>> <<set $temp.chosenPosition = null>> <<set $temp.serviceOutcome = null>> <<set $temp.selfieMode = null>> <<set $temp.selfieResult = null>> <<set $temp.selfieBonus = null>> <div class="choice-group"> <<link '<span class="choice-btn">🗺️ Return to campus</span>' "CampusMap">><</link>> </div>
<<ensureServiceContext>> <<run XCLC.Encounter.clear()>> <<set _req = $temp.serviceRequest>> <<set _all = XCLC.GroupService.all(_req)>> <<set _names = XCLC.GroupService.names(_req)>> <<set _n = _req.groupSize>> <h2>📍 <<print _req.locationName>></h2> <p>You make your way to <<print _req.locationDesc>>. The app said two names<<if _n > 2>>, then three<</if>>, and it is one thing to read that on a phone and another to walk into a room and find them all already there.</p> <div class="card"> <div class="card__title">👥 <<print _names>></div> <<for _gi = 0; _gi < _all.length; _gi++>> <<set _g = _all[_gi]>> <p><strong><<print _g.firstName>> <<print _g.lastName>></strong> · <<print XCLC.Presence.glance(_g)>></p> <</for>> </div> <p>They have clearly discussed this beforehand, which is oddly reassuring. Nobody is improvising. The one who booked it does the talking.</p> <p>"So. Same as the app said. And you say stop, we stop, and that's the end of it, no argument. Everyone good with that?"</p> <p>Everyone is good with that. It is said plainly and without ceremony, the way you would confirm a delivery slot, and you find you believe it.</p> <div class="alert alert--info">💳 <<print _req.credits>> credits · DC <<print _req.dc>> · <<print _n>> clients</div> <p style="opacity:0.7;font-size:0.85em;"><em>You can walk out now, or at any point once it starts.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Go ahead</span>' "GroupAct">> <<set $scholarship.inService = true>> <</link>> <<link '<span class="choice-btn">🚫 Change your mind: leave now</span>' "GroupDecline">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <h2>🚫 Not This One</h2> <p>"Sorry, no. I thought I would be up for it and I'm not."</p> <p>There is a beat of disappointment and then a shrug, and somebody says "fair enough, thanks for saying rather than just not turning up," which is a lower bar than it sounds and you are grateful for it anyway.</p> <p>You are outside in under a minute.</p> <<set $scholarship.inService = false>> <<set $scholarship.activeRequest = null>> <<modStat "confidence" 4 "Left when you wanted to">> <<addXP "composure" 15>> <div class="choice-group"> <<link '<span class="choice-btn">🚶 Go</span>' "CampusMap">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _all = XCLC.GroupService.all(_req)>> <<set _n = _req.groupSize>> <<set $temp.groupRound = 0>> <<set $temp.groupScore = 0>> <<set $temp.groupStamina = 45 + ($skills.stamina.level * 8)>> <<set $temp.groupLog = "">> <h2>👥 <<print _n>> At Once</h2> <p>The practical problem with more than one person is attention, there is only so much of you, and somebody is always waiting. The skill is in making the waiting feel deliberate rather than accidental.</p> <p style="opacity:0.7;font-size:0.85em;"><em>Work through the rounds. Stamina is the limit. You can stop at any point and still be paid for what you did.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">Begin →</span>' "GroupRound">><</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _all = XCLC.GroupService.all(_req)>> <<set _n = _req.groupSize>> <<set _target = 3 * _n>> <<if $temp.groupRound >= _target || $temp.groupStamina <= 0>> <<goto "GroupFinish">> <</if>> <h2>Round <<print $temp.groupRound + 1>> / <<print _target>></h2> <<if $temp.groupLog>> <p><<print $temp.groupLog>></p> <</if>> <<set _sPct = Math.max(0, Math.round(($temp.groupStamina / (45 + $skills.stamina.level * 8)) * 100))>> <<set _pPct = Math.round(($temp.groupRound / _target) * 100)>> <div class="card" style="padding:0.8em 1.2em;"> <div class="sex-meter-row"> <span class="stat-bar-icon">💗</span><span class="sex-meter-label">Progress</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _pPct + '%; background: var(--accent-pink);'"></div></div> <span class="sex-meter-val"><<print $temp.groupRound>>/<<print _target>></span> </div> <div class="sex-meter-row"> <span class="stat-bar-icon">💪</span><span class="sex-meter-label">Stamina</span> <div class="stat-bar-track"><div class="stat-bar-fill" @style="'width:' + _sPct + '%; background: var(--accent-teal);'"></div></div> <span class="sex-meter-val"><<print Math.round($temp.groupStamina)>></span> </div> </div> <div class="choice-group"> <<link '<span class="choice-btn">🎯 Focus on one of them properly <em>(−12 stamina, best value)</em></span>' "GroupRound">> <<set _r = XCLC.Roll.doCheck($temp.serviceRequest.serviceType === "anal" ? "anal" : $temp.serviceRequest.serviceType === "vaginal" ? "vaginal" : "oral", $temp.serviceRequest.dc)>> <<set $temp.groupStamina -= (12 + XCLC.GroupService.staminaTax())>> <<set $temp.groupRound++>> <<if _r === "crit_success" || _r === "success">> <<set $temp.groupScore += 2>> <<set $temp.groupLog = "You give one of them your entire attention and let the others watch, which turns out to be its own kind of currency. Nobody minds waiting when the waiting is part of it.">> <<else>> <<set $temp.groupLog = "You commit to one of them and lose the thread of the room entirely. Somebody checks their phone. You feel it happen.">> <</if>> <</link>> <<link '<span class="choice-btn">🔄 Split your attention <em>(−9 stamina, safer)</em></span>' "GroupRound">> <<set _r = XCLC.Roll.doCheck("stamina", $temp.serviceRequest.dc - 1)>> <<set $temp.groupStamina -= (9 + XCLC.GroupService.staminaTax())>> <<set $temp.groupRound++>> <<if _r === "crit_success" || _r === "success">> <<set $temp.groupScore += 1>> <<set $temp.groupLog = "You keep all of them in play at once, a hand here, your mouth there, eye contact with whoever is currently getting the least. It is administrative in a way nobody warns you about, and you are good at it.">> <<else>> <<set $temp.groupLog = "You try to cover everyone and manage to shortchange all of them equally. The rhythm never arrives.">> <</if>> <</link>> <<link '<span class="choice-btn">🌬️ Slow it right down <em>(+14 stamina)</em></span>' "GroupRound">> <<set $temp.groupStamina = Math.min(45 + $skills.stamina.level * 8, $temp.groupStamina + 14)>> <<set $temp.groupRound++>> <<set $temp.groupLog = "You call a pause, water, a breath, somebody laughing at something off to the side. The temperature drops a little and your arms stop shaking.">> <</link>> <<link '<span class="choice-btn">✋ Stop. You are done. <em>(paid for what you did)</em></span>' "GroupFinish">> <<set $temp.groupStopped = true>> <</link>> </div>
<<ensureServiceContext>> <<set _req = $temp.serviceRequest>> <<set _n = _req.groupSize>> <<set _target = 3 * _n>> <<set _stopped = !!$temp.groupStopped>> <<set _done = $temp.groupRound>> <<set _frac = Math.min(1, _done / _target)>> <<set _quality = $temp.groupScore / Math.max(1, _target)>> <<set _credits = Math.max(0.5, Math.round(_req.credits * _frac * 10) / 10)>> <h2><<if _stopped>>Called It<<elseif $temp.groupStamina <= 0>>Spent<<else>>Finished<</if>></h2> <<if _stopped>> <p>"I'm done," you say, and sit up, and that is the whole negotiation. One of them starts to say something and the one who booked it cuts across with "she said she's done, mate," in a tone that closes the subject.</p> <p>You get dressed while they sort out the money between themselves. Nobody is rude to you. You had half expected otherwise and you notice that you had.</p> <<modStat "confidence" 6 "Stopped when you wanted to">> <<addXP "composure" 25>> <<elseif $temp.groupStamina <= 0>> <p>Your body gives out before the room does. You say so, honestly, and they take it about as well as could be expected, which is to say with some visible disappointment and no argument at all.</p> <<modStat "confidence" -3 "Ran out">> <<else>> <<if _quality >= 1.4>> <p>You run the room from beginning to end. Three people, or two, and not one of them at any point feels like the spare, that is the trick of it, and you have apparently learned the trick.</p> <<modStat "confidence" 10 "Handled it">> <<else>> <p>It gets done. Not elegantly in places, and there was a stretch in the middle where you lost track of who had had what, but it gets done and everyone leaves satisfied.</p> <<modStat "confidence" 4 "Got through it">> <</if>> <</if>> <div class="alert alert--info">💳 <<print _credits>> credits of <<print _req.credits>><<if _frac < 1>>, <<print Math.round(_frac * 100)>>% of the booking<</if>>.</div> <<set $scholarship.currentWeekCredits += _credits>> <<set $scholarship.totalCredits += _credits>> <<set $scholarship.currentWeekServiced++>> <<set $scholarship.totalServiced++>> <<set $scholarship.lastServiceDay = $world.day>> <<set $scholarship.inService = false>> <<set $scholarship.activeRequest = null>> <<modStat "energy" -30 "Group booking">> <<modRep "slut" 5>> <<modCorruption 4 "Group booking">> <<addXP `_req.serviceType === "anal" ? "anal" : _req.serviceType === "vaginal" ? "vaginal" : "oral"` `Math.round(30 * _frac)`>> <<addXP "stamina" `Math.round(25 * _frac)`>> <<if _req.serviceType !== "oral">> <<for _si = 0; _si < _n; _si++>> <<stdRisk `_req.serviceType` 1.3>> <</for>> <<if _req.npc.gender === "male">> <<pregnancyRisk `_req.npc.race`>> <</if>> <</if>> <<set $temp.groupStopped = false>> <div class="choice-group"> <<link '<span class="choice-btn">🚶 Head off</span>' "CampusMap">><</link>> </div>
<h2>👗 Wardrobe</h2> <<run setTimeout(function(){ var inv = State.variables.inventory; var outfit = inv.currentOutfit; var W = XCLC.Wardrobe; var hasDress = !!outfit.dress; var slots = [ {key: 'top', label: 'Top', icon: '👕', blocked: hasDress}, {key: 'bottom', label: 'Bottom', icon: '👖', blocked: hasDress}, {key: 'dress', label: 'Dress', icon: '👗', blocked: false}, {key: 'bra', label: 'Bra', icon: '👙', blocked: false}, {key: 'underwear', label: 'Underwear', icon: '🩲', blocked: false}, {key: 'shoes', label: 'Shoes', icon: '👟', blocked: false} ]; var html = '<div class="wardrobe-container">'; /* Style identity display */ var styleLabel = inv.styleIdentity === 'none' ? 'Mixed' : inv.styleIdentity.charAt(0).toUpperCase() + inv.styleIdentity.slice(1); var beautyBonus = W.getOutfitBeauty(); html += '<div class="wardrobe-style-bar"><span>Style: <strong>' + styleLabel + '</strong></span><span>Outfit Beauty: <strong>+' + beautyBonus + '</strong></span></div>'; /* Equipment slots */ html += '<div class="wardrobe-slots">'; for (var i = 0; i < slots.length; i++) { var s = slots[i]; var itemName = s.blocked ? '🔒 Blocked (dress equipped)' : W.getSlotName(s.key); var equipped = !s.blocked && outfit[s.key]; html += '<div class="wardrobe-slot' + (equipped ? ' equipped' : '') + (s.blocked ? ' blocked' : '') + '" data-slot="' + s.key + '">'; html += '<div class="wardrobe-slot-icon">' + s.icon + '</div>'; html += '<div class="wardrobe-slot-info">'; html += '<div class="wardrobe-slot-label">' + s.label + '</div>'; html += '<div class="wardrobe-slot-item">' + itemName + '</div>'; html += '</div>'; if (!s.blocked) { html += '<button class="wardrobe-change-btn" data-slot="' + s.key + '">Change</button>'; } html += '</div>'; } /* Accessories */ var accNames = W.getSlotName('accessories'); html += '<div class="wardrobe-slot" data-slot="accessories">'; html += '<div class="wardrobe-slot-icon">💍</div>'; html += '<div class="wardrobe-slot-info"><div class="wardrobe-slot-label">Accessories</div><div class="wardrobe-slot-item">' + accNames + '</div></div>'; html += '<button class="wardrobe-change-btn" data-slot="accessory">Change</button>'; html += '</div>'; /* Worn plug: only appears once you own something wearable */ var wearables = XCLC.Toys.wearable(); if (wearables.length > 0) { var wornDef = XCLC.Toys.worn(); html += '<div class="wardrobe-slot' + (wornDef ? ' equipped' : '') + '" data-slot="plug">'; html += '<div class="wardrobe-slot-icon">💎</div>'; html += '<div class="wardrobe-slot-info"><div class="wardrobe-slot-label">Worn Under</div><div class="wardrobe-slot-item">' + (wornDef ? wornDef.name : 'Nothing') + '</div></div>'; html += '<button class="wardrobe-plug-btn">Change</button>'; html += '</div>'; } html += '</div>'; /* end slots */ /* Item picker area (populated on click) */ html += '<div id="wardrobe-picker" class="wardrobe-picker"></div>'; html += '</div>'; jQuery('#wardrobe-display').html(html); /* Wire up change buttons */ jQuery('.wardrobe-change-btn').off('click').on('click', function(){ var slot = jQuery(this).data('slot'); var items = W.getItemsBySlot(slot); var pickerHtml = '<h4>Select ' + slot.charAt(0).toUpperCase() + slot.slice(1) + ':</h4>'; pickerHtml += '<div class="wardrobe-item-list">'; /* Unequip option */ pickerHtml += '<div class="wardrobe-pick-item unequip-option" data-action="unequip" data-slot="' + slot + '"><span>❌</span><span>Remove</span></div>'; for (var j = 0; j < items.length; j++) { var itm = items[j]; var isEquipped = (outfit[slot] === itm.id) || (slot === 'accessory' && outfit.accessories.indexOf(itm.id) >= 0); pickerHtml += '<div class="wardrobe-pick-item' + (isEquipped ? ' current' : '') + '" data-action="equip" data-item="' + itm.id + '">'; pickerHtml += '<span class="pick-name">' + itm.name + '</span>'; pickerHtml += '<span class="pick-stats">🔥' + itm.sexy + ' ✨' + itm.beauty + '</span>'; pickerHtml += '</div>'; } pickerHtml += '</div>'; jQuery('#wardrobe-picker').html(pickerHtml); /* Wire up picks */ jQuery('.wardrobe-pick-item').off('click').on('click', function(){ var action = jQuery(this).data('action'); if (action === 'unequip') { var uSlot = jQuery(this).data('slot'); if (uSlot === 'accessory') { W.unequip('accessories'); } else { W.unequip(uSlot); } } else { var itemId = jQuery(this).data('item'); W.equip(itemId); } /* Refresh the page */ Engine.play('WardrobeMenu'); }); }); /* Worn plug picker */ jQuery('.wardrobe-plug-btn').off('click').on('click', function(){ var wl = XCLC.Toys.wearable(); var cur = State.variables.inventory.wornPlug; var p = '<h4>Wear under your clothes:</h4><div class="wardrobe-item-list">'; p += '<div class="wardrobe-plug-pick unequip-option" data-plug=""><span>❌</span><span>Nothing</span></div>'; for (var k = 0; k < wl.length; k++) { p += '<div class="wardrobe-plug-pick' + (cur === wl[k].id ? ' current' : '') + '" data-plug="' + wl[k].id + '">'; p += '<span class="pick-name">' + wl[k].name + '</span>'; p += '<span class="pick-stats">' + wl[k].desc + '</span>'; p += '</div>'; } p += '</div><p style="opacity:0.6;font-size:0.85em;">Wearing one out of the house is its own kind of risk. Some things show.</p>'; jQuery('#wardrobe-picker').html(p); jQuery('.wardrobe-plug-pick').off('click').on('click', function(){ var pid = jQuery(this).data('plug'); if (!pid) { XCLC.Toys.removeWorn(); State.variables.inventory.plugWornSince = 0; } else if (XCLC.Toys.wear(pid)) { State.variables.inventory.plugWornSince = State.variables.world.day; State.variables.inventory.plugSpotted = 0; XCLC.Toast.show('💎 In. You are going to be aware of that all day.', 'info', 4000); } Engine.play('WardrobeMenu'); }); }); }, 50)>> <div id="wardrobe-display"><p style="opacity:0.5;">Loading wardrobe...</p></div> <<link '<span class="choice-btn">🔙 Back</span>' `($ui.returnPassage || "DormRoom")`>><</link>>
/* CSS for wardrobe is injected via style.css */
<h2>🛍️ Thornfield Mall</h2> <p>The mall sits just off campus, three storeys of shops, food courts, and questionable fashion choices. Students stream through the automatic doors, shopping bags in hand, the hum of pop music drifting from every storefront.</p> <div class="location-choices"> <<link '<span class="choice-btn">👕 Campus Basics</span>' "Shop_CampusBasics">><</link>> <<link '<span class="choice-btn">🖤 Hot Topic Noir</span>' "Shop_HotTopic">><</link>> <<link '<span class="choice-btn">💖 Candy Pink</span>' "Shop_CandyPink">><</link>> <<link '<span class="choice-btn">🔥 Spice</span>' "Shop_Spice">><</link>> <<link '<span class="choice-btn">🏃 Nike Athletics</span>' "Shop_Nike">><</link>> <<link '<span class="choice-btn">🔞 After Dark (Adult Store)</span>' "Shop_AfterDark">><</link>> <<link '<span class="choice-btn">💻 Electronics Store</span>' "Shop_Electronics">><</link>> </div> <div class="nav-back"> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>👕 Campus Basics</h2> <<run setTimeout(function(){ var html = XCLC.Shop.renderClothingShop('campus_basics', 'Campus Basics', 'Your one-stop shop for everyday college wear. Nothing flashy, just reliable, affordable basics that won\'t embarrass you in lecture.'); jQuery('#shop-display').html(html); jQuery('.shop-buy-btn').not('.disabled').off('click').on('click', function(){ var shop = jQuery(this).data('shop'); var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyClothing(shop, idx)) { Engine.play('Shop_CampusBasics'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>🖤 Hot Topic Noir</h2> <<run setTimeout(function(){ var html = XCLC.Shop.renderClothingShop('hot_topic', 'Hot Topic Noir', 'Dark walls, darker music. The air smells like incense and rebellion. Everything here is black, spiked, or laced, preferably all three.'); jQuery('#shop-display').html(html); jQuery('.shop-buy-btn').not('.disabled').off('click').on('click', function(){ var shop = jQuery(this).data('shop'); var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyClothing(shop, idx)) { Engine.play('Shop_HotTopic'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>💖 Candy Pink</h2> <<run setTimeout(function(){ var html = XCLC.Shop.renderClothingShop('candy_pink', 'Candy Pink', 'Everything is pink. The walls, the carpet, the staff uniforms, even the air freshener. If Barbie had a clothing store, this would be it. The shopgirl beams at you with impossibly white teeth.'); jQuery('#shop-display').html(html); jQuery('.shop-buy-btn').not('.disabled').off('click').on('click', function(){ var shop = jQuery(this).data('shop'); var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyClothing(shop, idx)) { Engine.play('Shop_CandyPink'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>🔥 Spice</h2> <<run setTimeout(function(){ var html = XCLC.Shop.renderClothingShop('spice', 'Spice', 'Dim lighting, throbbing bass, and mannequins wearing things that barely qualify as clothing. The kind of shop where the changing room mirrors have flattering lighting and the sales associate gives you a knowing look.'); jQuery('#shop-display').html(html); jQuery('.shop-buy-btn').not('.disabled').off('click').on('click', function(){ var shop = jQuery(this).data('shop'); var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyClothing(shop, idx)) { Engine.play('Shop_Spice'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>🏃 Nike Athletics</h2> <<run setTimeout(function(){ var html = XCLC.Shop.renderClothingShop('nike', 'Nike Athletics', 'Clean lines, motivational slogans, and that new-sneaker smell. Everything here is designed to make you look athletic even if the most exercise you get is walking to the cafeteria.'); jQuery('#shop-display').html(html); jQuery('.shop-buy-btn').not('.disabled').off('click').on('click', function(){ var shop = jQuery(this).data('shop'); var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyClothing(shop, idx)) { Engine.play('Shop_Nike'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>🔞 After Dark</h2> <<if $pc.femininity < 30>> <p><em>You hesitate at the entrance. The neon sign glows suggestively above frosted glass doors. A composure check crosses your mind...</em></p> <</if>> <<run setTimeout(function(){ var html = XCLC.Shop.renderClothingShop('after_dark', 'After Dark', 'Tucked away on the second floor, behind a discreet frosted glass entrance. Inside: silk, lace, leather, and things that make you blush. The lighting is warm and flattering. A well-dressed saleswoman approaches with a knowing smile.'); /* Add sex toys section */ html += '<div class="shop-header" style="margin-top:2em;"><h3>Toys & Equipment</h3><p style="opacity:0.7;margin:0.3em 0;">For personal use or... professional purposes.</p></div>'; html += '<div class="shop-grid">'; var toys = XCLC.Shop.TOYS.concat([ {id:'equip_ringlight', name:'Ring Light', price:40, cat:'equip', tags:[], desc:'Professional lighting for content creation.'}, {id:'equip_backdrop', name:'Backdrop Kit', price:30, cat:'equip', tags:[], desc:'A simple backdrop for cam shows and photos.'} ]); var sv = State.variables; for (var i = 0; i < toys.length; i++) { var t = toys[i]; var owned = false; if (t.id.indexOf('toy_') === 0) { owned = sv.inventory.sexToys.indexOf(t.id) !== -1; } else if (t.id === 'equip_ringlight') { owned = sv.inventory.hasRingLight; } else if (t.id === 'equip_backdrop') { owned = sv.inventory.hasBackdrop; } var canBuy = !owned && sv.finance.money >= t.price; html += '<div class="shop-item' + (owned ? ' owned' : '') + '">'; html += '<div class="shop-item-name">' + t.name + '</div>'; html += '<div class="shop-item-desc">' + (t.desc || '') + '</div>'; if (owned) { html += '<div class="shop-item-owned">Owned</div>'; } else { html += '<button class="shop-buy-toy' + (canBuy ? '' : ' disabled') + '" data-toy="' + t.id + '" data-price="' + t.price + '">$' + t.price + '</button>'; } html += '</div>'; } html += '</div>'; jQuery('#shop-display').html(html); /* Wire clothing buys */ jQuery('.shop-buy-btn').not('.disabled').off('click').on('click', function(){ var shop = jQuery(this).data('shop'); var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyClothing(shop, idx)) { Engine.play('Shop_AfterDark'); } }); /* Wire toy buys */ jQuery('.shop-buy-toy').not('.disabled').off('click').on('click', function(){ var toyId = jQuery(this).data('toy'); var price = parseInt(jQuery(this).data('price')); var svv = State.variables; if (svv.finance.money < price) return; svv.finance.money -= price; if (toyId.indexOf('toy_') === 0) { svv.inventory.sexToys.push(toyId); } else if (toyId === 'equip_ringlight') { svv.inventory.hasRingLight = true; } else if (toyId === 'equip_backdrop') { svv.inventory.hasBackdrop = true; } XCLC.Toast.show('🛍️ Purchased!', 'success'); Engine.play('Shop_AfterDark'); }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>💻 Electronics Store</h2> <p>A bright, clean electronics shop filled with the latest gadgets. Rows of laptops, cameras, and accessories line the walls.</p> <<run setTimeout(function(){ var sv = State.variables; var items = XCLC.Shop.ELECTRONICS; var html = '<div class="shop-grid">'; for (var i = 0; i < items.length; i++) { var item = items[i]; var owned = sv.inventory[item.flag]; var canBuy = !owned && sv.finance.money >= item.price; html += '<div class="shop-item' + (owned ? ' owned' : '') + '">'; html += '<div class="shop-item-name">' + item.name + '</div>'; html += '<div class="shop-item-desc">' + item.description + '</div>'; if (owned) { html += '<div class="shop-item-owned">Owned</div>'; } else { html += '<button class="shop-buy-elec' + (canBuy ? '' : ' disabled') + '" data-idx="' + i + '">$' + item.price + '</button>'; } html += '</div>'; } html += '</div>'; jQuery('#shop-display').html(html); jQuery('.shop-buy-elec').not('.disabled').off('click').on('click', function(){ var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyElectronics(idx)) { Engine.play('Shop_Electronics'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🛍️ Back to Mall</span>' "Mall">><</link>>
<h2>💊 Drugstore</h2> <p>A clean, fluorescent-lit pharmacy with neatly organised shelves. The pharmacist behind the counter gives you a friendly nod. Everything from razors to birth control, all under one roof.</p> <<run setTimeout(function(){ var sv = State.variables; var items = XCLC.Shop.DRUGSTORE; var html = '<div class="shop-grid">'; for (var i = 0; i < items.length; i++) { var item = items[i]; var canBuy = sv.finance.money >= item.price; var stock = ''; if (item.type === 'consumable') { stock = ' (Have: ' + sv.inventory[item.field] + ')'; } else if (item.type === 'makeup') { stock = ' (Have: ' + sv.inventory.makeupUses[item.field] + ' uses)'; } else if (item.type === 'special' && item.field === 'onPill') { stock = sv.inventory.onPill ? ' (Active)' : ''; } html += '<div class="shop-item">'; html += '<div class="shop-item-name">' + item.name + stock + '</div>'; html += '<div class="shop-item-desc">' + item.description + '</div>'; html += '<button class="shop-buy-drug' + (canBuy ? '' : ' disabled') + '" data-idx="' + i + '">$' + item.price + '</button>'; html += '</div>'; } html += '</div>'; jQuery('#shop-display').html(html); jQuery('.shop-buy-drug').not('.disabled').off('click').on('click', function(){ var idx = parseInt(jQuery(this).data('idx')); if (XCLC.Shop.buyDrugstore(idx)) { Engine.play('Drugstore'); } }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading shop...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>>
<h2>💇 Luxe Locks Hair Salon</h2> <p>A stylish salon with exposed brick walls and vintage mirrors. Your stylist, <strong>Jade</strong>, a woman with impeccable purple hair and a laugh you can hear from the escalator, beckons you into a chair.</p> <p>"Hey gorgeous! What are we doing today?" She runs her fingers through your <<= $pc.hairColour>> <<= $pc.hairLength>> hair appraisingly.</p> <div class="location-choices"> /* Haircut */ <<if $finance.money >= 25>> <<link '<span class="choice-btn">✂️ Haircut ($25, 45min)</span>'>> <<run setTimeout(function(){ var opts = ['short', 'medium', 'long']; var html = '<h4>Choose a length:</h4><div class="cc-grid" style="display:grid;grid-template-columns:repeat(3,1fr);gap:0.5em;">'; for (var i = 0; i < opts.length; i++) { html += '<div class="cc-option hair-pick" data-val="' + opts[i] + '" style="cursor:pointer;padding:1em;border-radius:8px;border:2px solid var(--surface-2);background:var(--surface-1);text-align:center;text-transform:capitalize;">' + opts[i] + '</div>'; } html += '</div>'; jQuery('#salon-picker').html(html); jQuery('.hair-pick').off('click').on('click', function(){ var val = jQuery(this).data('val'); State.variables.pc.hairLength = val; State.variables.finance.money -= 25; Engine.play('HairSalon_Done'); }); }, 50)>> <</link>> <<else>> <span class="choice-btn disabled">✂️ Haircut ($25): Can't afford</span> <</if>> /* Colour */ <<if $finance.money >= 40>> <<link '<span class="choice-btn">🎨 Hair Colour ($40, 60min)</span>'>> <<run setTimeout(function(){ var colours = ['blonde', 'brunette', 'black', 'red', 'auburn', 'pink', 'purple', 'blue', 'platinum', 'strawberry blonde']; var html = '<h4>Choose a colour:</h4><div class="cc-grid" style="display:grid;grid-template-columns:repeat(2,1fr);gap:0.5em;">'; for (var i = 0; i < colours.length; i++) { html += '<div class="cc-option colour-pick" data-val="' + colours[i] + '" style="cursor:pointer;padding:0.8em;border-radius:8px;border:2px solid var(--surface-2);background:var(--surface-1);text-transform:capitalize;">' + colours[i] + '</div>'; } html += '</div>'; jQuery('#salon-picker').html(html); jQuery('.colour-pick').off('click').on('click', function(){ var val = jQuery(this).data('val'); State.variables.pc.hairColour = val; State.variables.finance.money -= 40; Engine.play('HairSalon_Done'); }); }, 50)>> <</link>> <<else>> <span class="choice-btn disabled">🎨 Hair Colour ($40): Can't afford</span> <</if>> /* Style */ <<if $finance.money >= 15>> <<link '<span class="choice-btn">💁 Hair Style ($15, 30min)</span>'>> <<run setTimeout(function(){ var styles = ['straight', 'wavy', 'curly', 'braids', 'ponytail', 'pigtails', 'messy bun', 'bob']; var html = '<h4>Choose a style:</h4><div class="cc-grid" style="display:grid;grid-template-columns:repeat(2,1fr);gap:0.5em;">'; for (var i = 0; i < styles.length; i++) { html += '<div class="cc-option style-pick" data-val="' + styles[i] + '" style="cursor:pointer;padding:0.8em;border-radius:8px;border:2px solid var(--surface-2);background:var(--surface-1);text-transform:capitalize;">' + styles[i] + '</div>'; } html += '</div>'; jQuery('#salon-picker').html(html); jQuery('.style-pick').off('click').on('click', function(){ var val = jQuery(this).data('val'); State.variables.pc.hairStyle = val; State.variables.finance.money -= 15; Engine.play('HairSalon_Done'); }); }, 50)>> <</link>> <<else>> <span class="choice-btn disabled">💁 Hair Style ($15): Can't afford</span> <</if>> /* Extensions */ <<if $finance.money >= 60>> <<link '<span class="choice-btn">✨ Hair Extensions ($60, 90min)</span>'>> <<set $pc.hairLength = "long">> <<set $finance.money -= 60>> <<goto "HairSalon_Done">> <</link>> <<else>> <span class="choice-btn disabled">✨ Extensions ($60): Can't afford</span> <</if>> </div> <div id="salon-picker"></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>>
<h2>💇 Salon Visit Complete</h2> <p>Jade spins your chair around with a flourish. "There we go! What do you think?"</p> <p>You admire your <<= $pc.hairColour>> <<= $pc.hairLength>> hair, now styled in a <<= $pc.hairStyle>> look. It suits you.</p> <<advanceTime 45>> <<link '<span class="choice-btn">💇 Do more</span>' "HairSalon">><</link>> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>>
<h2>🖋️ Ink & Iron: Tattoo & Piercing</h2> <p>A surprisingly clean parlour with exposed brick and framed flash art covering every wall. The artist, <strong>Razor</strong>, a heavily tattooed woman with kind eyes and very steady hands, looks up from her sketch pad.</p> <p>"Welcome to Ink and Iron, sweetheart. What'll it be?"</p> <div class="location-choices"> <<link '<span class="choice-btn">💎 Piercings</span>' "TattooShop_Piercings">><</link>> <<link '<span class="choice-btn">🎨 Tattoos</span>' "TattooShop_Tattoos">><</link>> </div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>>
<h2>💎 Piercings</h2> <<run setTimeout(function(){ var sv = State.variables; var piercings = [ {id: 'ears_studs', name: 'Ear Studs', price: 20, beauty: 1, sexy: 0, desc: 'Classic ear studs. Simple and elegant.'}, {id: 'ears_hoops', name: 'Ear Hoops', price: 25, beauty: 2, sexy: 1, desc: 'Silver hoop earrings. A bit more daring.'}, {id: 'nose_stud', name: 'Nose Stud', price: 30, beauty: 1, sexy: 2, desc: 'A tiny diamond stud on your nostril.'}, {id: 'lip_ring', name: 'Lip Ring', price: 35, beauty: 1, sexy: 3, desc: 'A small ring on your lower lip. Oral skill bonus.'}, {id: 'tongue', name: 'Tongue Piercing', price: 40, beauty: 0, sexy: 4, desc: 'A barbell through your tongue. +10% oral skill.'}, {id: 'belly', name: 'Belly Button', price: 35, beauty: 2, sexy: 3, desc: 'A sparkling belly button ring. Visible with crop tops.'}, {id: 'nipples', name: 'Nipple Piercings', price: 50, beauty: 0, sexy: 5, desc: 'Both nipples pierced with small barbells. Sensitivity SE interaction.'}, {id: 'clit', name: 'Clit Piercing', price: 60, beauty: 0, sexy: 6, desc: 'An intimate piercing. Sensitivity SE interaction, arousal triggers.'} ]; var html = '<div class="shop-grid">'; for (var i = 0; i < piercings.length; i++) { var p = piercings[i]; var owned = false; for (var j = 0; j < sv.pc.piercings.length; j++) { if (sv.pc.piercings[j].id === p.id) { owned = true; break; } } var canBuy = !owned && sv.finance.money >= p.price; html += '<div class="shop-item' + (owned ? ' owned' : '') + '">'; html += '<div class="shop-item-name">' + p.name + '</div>'; html += '<div class="shop-item-stats"><span>✨+' + p.beauty + '</span><span>🔥+' + p.sexy + '</span></div>'; html += '<div class="shop-item-desc">' + p.desc + '</div>'; if (owned) { html += '<div class="shop-item-owned">Pierced</div>'; } else { html += '<button class="shop-buy-pierce' + (canBuy ? '' : ' disabled') + '" data-idx="' + i + '">$' + p.price + '</button>'; } html += '</div>'; } html += '</div>'; jQuery('#shop-display').html(html); jQuery('.shop-buy-pierce').not('.disabled').off('click').on('click', function(){ var idx = parseInt(jQuery(this).data('idx')); var pierce = piercings[idx]; sv.finance.money -= pierce.price; sv.pc.piercings.push({id: pierce.id, name: pierce.name, beauty: pierce.beauty, sexy: pierce.sexy}); Engine.play('TattooShop_Piercings'); }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🖋️ Back to Ink & Iron</span>' "TattooShop">><</link>>
<h2>🎨 Tattoos</h2> <<run setTimeout(function(){ var sv = State.variables; var tattoos = [ {id: 'flower_ankle', name: 'Small Flower', location: 'Ankle', price: 40, sexy: 1, desc: 'A delicate flower on your ankle. Subtle and feminine.'}, {id: 'butterfly_hip', name: 'Butterfly', location: 'Hip', price: 50, sexy: 2, desc: 'A butterfly on your hip. Visible in low-rise clothing.'}, {id: 'stars_wrist', name: 'Star Cluster', location: 'Wrist', price: 40, sexy: 1, desc: 'A trail of tiny stars across your wrist.'}, {id: 'rose_arm', name: 'Rose Vine', location: 'Arm', price: 60, sexy: 2, desc: 'A climbing rose vine wrapping around your forearm.'}, {id: 'tramp_stamp', name: 'Tramp Stamp', location: 'Lower Back', price: 80, sexy: 5, desc: 'A tribal-style design on your lower back. Adds slut reputation.'}, {id: 'sleeve', name: 'Full Sleeve', location: 'Arm', price: 150, sexy: 3, desc: 'A full arm sleeve. Intricate and striking. Takes 2 visits.'}, {id: 'heart_chest', name: 'Heart', location: 'Chest', price: 70, sexy: 4, desc: 'A heart design on your chest. Visible in low-cut tops.'}, {id: 'script_ribs', name: 'Script Text', location: 'Ribs', price: 90, sexy: 3, desc: 'Elegant script text along your ribcage.'} ]; var html = '<div class="shop-grid">'; for (var i = 0; i < tattoos.length; i++) { var t = tattoos[i]; var owned = false; for (var j = 0; j < sv.pc.tattoos.length; j++) { if (sv.pc.tattoos[j].id === t.id) { owned = true; break; } } var canBuy = !owned && sv.finance.money >= t.price; html += '<div class="shop-item' + (owned ? ' owned' : '') + '">'; html += '<div class="shop-item-name">' + t.name + ' <span style="opacity:0.6;">(' + t.location + ')</span></div>'; html += '<div class="shop-item-stats"><span>🔥+' + t.sexy + '</span></div>'; html += '<div class="shop-item-desc">' + (t.desc || '') + '</div>'; if (owned) { html += '<div class="shop-item-owned">Inked</div>'; } else { html += '<button class="shop-buy-tattoo' + (canBuy ? '' : ' disabled') + '" data-idx="' + i + '">$' + t.price + '</button>'; } html += '</div>'; } html += '</div>'; jQuery('#shop-display').html(html); jQuery('.shop-buy-tattoo').not('.disabled').off('click').on('click', function(){ var idx = parseInt(jQuery(this).data('idx')); var tat = tattoos[idx]; sv.finance.money -= tat.price; sv.pc.tattoos.push({id: tat.id, name: tat.name, location: tat.location, sexy: tat.sexy}); /* Tramp stamp adds slut rep */ if (tat.id === 'tramp_stamp') { if (!sv.reputation) sv.reputation = {}; sv.reputation.slut = (sv.reputation.slut || 0) + 5; } Engine.play('TattooShop_Tattoos'); }); }, 50)>> <div id="shop-display"><p style="opacity:0.5;">Loading...</p></div> <p style="margin-top:1em;opacity:0.7;">💰 Cash: $<<= $finance.money>></p> <<link '<span class="choice-btn">🖋️ Back to Ink & Iron</span>' "TattooShop">><</link>>
/* ═══════════════════════════════════════════════════ THORNFIELD: GREEK ROW Sororities, frat houses, parties ═══════════════════════════════════════════════════ */ <<set _period = XCLC.Time.getPeriod($world.time)>> <h2>🏡 Greek Row</h2> <div class="choice-group"><<whoIsAround>></div> <<showDrunkStatus>> <<if _period === "earlyMorning" || _period === "morning">> <p>Greek Row is quiet in the morning. Sorority houses sit like pastel-painted mansions along a tree-lined street. A few hungover students shuffle to class clutching coffee cups. Red cups and beer cans litter the frat house lawns.</p> <<elseif _period === "afternoon">> <p>Sorority sisters sunbathe on their front lawns. A shirtless frat guy tosses a football. Someone's playing music from an upstairs window. The Greek life billboard near the entrance lists upcoming events.</p> <<elseif _period === "evening">> <p>Greek Row comes alive. Lights blaze from every house. Pre-game music thumps from the frat houses. Groups of dressed-up students migrate between buildings, red cups already in hand.</p> <<else>> <p>The street is chaos. Music from three different houses competes for dominance. Students spill across lawns, drinks in hand, shouting over the noise. Someone just set off a firework.</p> <</if>> <<divider "Sorority Houses">> <div class="choice-group"> <<if $greekLife.member || $greekLife.pledging>> <<link '<span class="choice-btn">🏡 <<print $greekLife.sorority>> House</span>' "SororityCommon">><</link>> <<else>> <<if $greekLife.rushAvailable && !$greekLife.rushDeclined>> <<link '<span class="choice-btn">🌟 Rush Week: Check Out the Sororities!</span>' "SororityRush">><</link>> <<else>> <p><em>Sorority houses are members-only. Rush week happens in Week 2 of each year.</em></p> <</if>> <</if>> </div> <<divider "Frat Row">> <div class="choice-group"> <<if ($world.dayOfWeek >= 4) && (_period === "evening" || _period === "night" || _period === "lateNight")>> <<link '<span class="choice-btn">🎉 Frat Party: Sigma Chi House</span>' "FratParty">> <<advanceTime 10>> <</link>> <<else>> <p><em>The frat houses are quiet. Parties happen Friday and Saturday evenings.</em></p> <</if>> </div> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>🌟 Rush Week</h2> <p>It's Rush Week! Three sororities are accepting pledges. Each house has set up a table on Greek Row with banners, cookies, and overly enthusiastic sisters trying to recruit you.</p> <<divider "Choose a Sorority">> <div class="card"> <div class="card__title">ΑΦΕ: Alpha Phi Epsilon</div> <p>The hot ones. Their table is staffed by girls in crop tops and short skirts. The banner reads: "WORK HARD, PARTY HARDER." They're known for throwing the wildest parties and having the strongest connections to the frat houses.</p> <p><em>Vibe: Party girl / slutty. Hazing involves sexual dares.</em></p> </div> <div class="card"> <div class="card__title">ΔΓΝ: Delta Gamma Nu</div> <p>Their table is warm and inviting: fairy lights, hot chocolate, matching sweaters. The sisters greet everyone with genuine hugs. "We're a family," one says. "Sisterhood above everything."</p> <p><em>Vibe: Deep sisterhood bonding. Hazing focuses on intimacy and trust between sisters.</em></p> </div> <div class="card"> <div class="card__title">ΚΚΧ: Kappa Kappa Chi</div> <p>Professional. Crisp blazers, pearl necklaces, a printed brochure with alumni success stories. Their GPA average is the highest on campus. "We produce leaders," their president says with a perfectly practised smile.</p> <p><em>Vibe: Academic / prestige. Traditional hazing: drinking, discipline, no sexual content.</em></p> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Pledge Alpha Phi Epsilon</span>' "SororityPledge_APE_1">> <<set $greekLife.pledging = true>> <<set $greekLife.sorority = "Alpha Phi Epsilon">> <<set $greekLife.pledgeStage = 1>> <<set $greekLife.rank = "pledge">> <</link>> <<link '<span class="choice-btn">💜 Pledge Delta Gamma Nu</span>' "SororityPledge_DGN_1">> <<set $greekLife.pledging = true>> <<set $greekLife.sorority = "Delta Gamma Nu">> <<set $greekLife.pledgeStage = 1>> <<set $greekLife.rank = "pledge">> <</link>> <<link '<span class="choice-btn">📚 Pledge Kappa Kappa Chi</span>' "SororityPledge_KKC_1">> <<set $greekLife.pledging = true>> <<set $greekLife.sorority = "Kappa Kappa Chi">> <<set $greekLife.pledgeStage = 1>> <<set $greekLife.rank = "pledge">> <</link>> <<link '<span class="choice-btn">🚫 Not interested this year</span>' "GreekRow">> <<set $greekLife.rushDeclined = true>> <</link>> </div> /* ═══════════════════════════════════════════════════ ALPHA PHI EPSILON — SEXUAL HAZING (5 stages) ═══════════════════════════════════════════════════ */
<h2>ΑΦΕ Pledge: Stage 1: Flash Dare</h2> <p>Your first night as a pledge. The sisters gather in the living room, music low, candles lit. The pledge class six of you stands in a line. The president, a stunning brunette named Megan, paces in front of you.</p> <p>"Tonight is about proving you're not shy. Alpha Phi sisters don't hide." She points at the living room window, which faces the frat house across the street. "Flash them. Tits out. Five seconds minimum."</p> <p>The window is open. You can see frat guys on their porch, beers in hand.</p> <<rollButton "composure" 3 "Flash dare" "SororityPledge_APE_1_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You pull up your top without hesitation. The frat guys across the street erupt in cheers and whistles. Your <<print $pc.breastSize>>-cup breasts catch the lamplight. Five seconds. Six. Seven. You drop your shirt and the sisters scream approval.</p> <p>"YES, girl!" Megan high-fives you. "She's got what it takes!"</p> <<modStat "confidence" 5 "Flash dare passed">> <<modRep "slut" 2>> <<set $greekLife.pledgeStage = 2>> <<else>> <p>You hesitate. Your hands grip the hem of your shirt but you can't make them pull. The other pledges are already flashing. Megan's smile tightens.</p> <p>"Maybe next time, pledge." The disappointment in her voice stings.</p> <<modStat "confidence" -5 "Chickened out">> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 2>> <<link '<span class="choice-btn">✅ Next challenge</span>' "SororityPledge_APE_2">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Try again tomorrow</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΑΦΕ Pledge: Stage 2: Body Shots</h2> <p>A joint mixer with Sigma Chi. The sisters and frat guys are packed into the common room. Megan points at you. "Pledge! On the table. Now."</p> <p>You climb onto the beer-sticky table. Someone squeezes lime juice onto your stomach. Salt is sprinkled on your collarbone. A frat guy with a shit-eating grin leans in with a shot glass.</p> <p>"Hold still. Don't flinch."</p> <<rollButton "stamina" 4 "Endure body shots" "SororityPledge_APE_2_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You lie perfectly still as tongue after tongue traces salt from your skin. Three different guys do shots off your body. You don't flinch, don't squirm. The room chants your name.</p> <<modStat "confidence" 5 "Body shots champion">> <<modRep "popular" 3>> <<set $substances.alcoholTolerance = Math.min(10, $substances.alcoholTolerance + 1)>> <<set $greekLife.pledgeStage = 3>> <<else>> <p>The second guy's tongue is cold and you jolt, sending tequila everywhere. Laughter erupts. Your face burns. Megan sighs.</p> <<modStat "confidence" -5 "Flinched">> <<modRep "slut" 1>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 3>> <<link '<span class="choice-btn">✅ Next challenge</span>' "SororityPledge_APE_3">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Try again</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΑΦΕ Pledge: Stage 3: Lap Dance</h2> <p>Megan's boyfriend sits in a chair in the centre of the room. He's the Sigma Chi president tall, built, amused. Megan crosses her arms.</p> <p>"Give him a lap dance. A real one. Make him hard. If you can't turn on my boyfriend, you can't handle Alpha Phi."</p> <p>Music starts. The sisters watch from the couches. His hands are behind his head, legs spread. Waiting.</p> <<rollButton "dance" 5 "Lap dance" "SororityPledge_APE_3_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You straddle his lap. Your hips roll to the beat. You lean in close, <<print $pc.hairColour>> hair brushing his face, your <<print $pc.breastSize>>-cups pressed against his chest. His hands grip the chair. You can feel him getting hard through his jeans.</p> <p>"Well, well." Megan grins. "She's got talent." The sisters applaud.</p> <<addXP "dance" 15>> <<modStat "confidence" 5 "Great lap dance">> <<modRep "slut" 3>> <<set $greekLife.pledgeStage = 4>> <<else>> <p>You try to be sexy but you're stiff, awkward. You accidentally knee him. He winces. The room goes quiet. Megan covers her eyes.</p> <<modStat "confidence" -5 "Bad lap dance">> <<addXP "dance" 5>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 4>> <<link '<span class="choice-btn">✅ Next challenge</span>' "SororityPledge_APE_4">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Practice and try again</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΑΦΕ Pledge: Stage 4: The Blowjob Dare</h2> <p>The pledge class gathers in the chapter room. Three frat pledges nervous, shirtless sit on folding chairs. Megan paces.</p> <p>"Here's how it works. You blow one of them. The sisters watch. This is about confidence owning your sexuality. No hiding. No shame."</p> <p>She pairs you with a nervous-looking guy named Jake. He's cute, at least. His cock is average, already half-hard from anticipation.</p> <p>"On your knees, pledge."</p> <<rollButton "oral" 5 "Blowjob dare" "SororityPledge_APE_4_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You sink to your knees in front of Jake. The sisters watch from the circle. You take him in your mouth, working steadily, confidently. Jake groans. Your <<print $pc.eyeColour>> eyes flick up to meet Megan's approving gaze.</p> <p>It doesn't take long. Jake grips the chair, gasping. The sisters cheer.</p> <p>"That's an Alpha Phi girl right there," Megan says proudly.</p> <<addXP "oral" 20>> <<modStat "confidence" 5 "Performed under pressure">> <<modRep "slut" 5>> <<modHygiene -10 "Blowjob dare">> <<set $greekLife.pledgeStage = 5>> <<else>> <p>You kneel, open your mouth, and... freeze. The eyes on you. The judging. Jake shifts uncomfortably. You manage a few awkward strokes before pulling away, face burning.</p> <p>"It's okay," Megan says, though she clearly expected more. "You can try again."</p> <<modStat "confidence" -8 "Couldn't finish">> <<addXP "oral" 8>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 5>> <<link '<span class="choice-btn">✅ Final challenge</span>' "SororityPledge_APE_5">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Come back when ready</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΑΦΕ Pledge: Stage 5: The Train</h2> <p>Initiation night. The chapter room is candlelit. You're the last pledge standing. Three frat guys wait on a large bed pushed against the wall. Megan stands by the door.</p> <p>"This is it. The final test. Three guys, back to back. You finish all three, you're an Alpha Phi sister for life." She pauses. "Or you can walk away. No judgement. Well... some judgement."</p> <<rollButton "stamina" 6 "The train" "SororityPledge_APE_5_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>Three guys. Back to back. It's intense, overwhelming, exhausting but you take every one. Your body aches, your jaw hurts, but when the last guy finishes, you're still standing. Sweating, shaking, but standing.</p> <p>The sisters erupt. Megan wraps a silk robe around your shoulders. "Welcome to Alpha Phi Epsilon, sister."</p> <<set $greekLife.pledging = false>> <<set $greekLife.member = true>> <<set $greekLife.rank = "member">> <<set $greekLife.hazingComplete = true>> <<set $greekLife.sisterhood += 30>> <<modStat "confidence" 15 "Alpha Phi initiation">> <<modRep "slut" 10>> <<modRep "popular" 5>> <<addXP "stamina" 30>> <<addXP "oral" 15>> <<modHygiene -40 "Train">> <<modStat "arousal" 40 "Train">> <<modStat "energy" -30 "Exhausting initiation">> <<run XCLC.Toast.show("🎉 You're an Alpha Phi sister!", "info")>> <<else>> <p>You make it through the first guy, barely. The second is too much. You tap out, gasping. The room goes quiet. Megan's face is unreadable.</p> <p>"Come back next year, pledge." The door closes behind you.</p> <<modStat "confidence" -10 "Couldn't finish">> <<modStat "stress" 15 "Failed initiation">> <<addXP "stamina" 15>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🏡 <<if $greekLife.member>>Go to your new room<<else>>Go home<</if>></span>' `($greekLife.member ? "SororityCommon" : "GreekRow")`>><</link>> </div> /* ═══════════════════════════════════════════════════ DELTA GAMMA NU — LESBIAN BONDING HAZING (5 stages) ═══════════════════════════════════════════════════ */
<h2>ΔΓΝ Pledge: Stage 1: Trust Fall & Massage</h2> <p>The DGN house is warm, string lights, incense, soft music. The sisters sit in a circle on cushions. Your "big sister" mentor, a gentle girl named Ava with dark curls, places a blindfold over your eyes.</p> <p>"This is about trust," Ava whispers. "Let go of control. Let us take care of you."</p> <p>Hands guide you down onto a massage table. Multiple hands begin working warm oil into your shoulders, your back, your legs. It's intimate, careful.</p> <<rollButton "composure" 3 "Trust and relax" "SororityPledge_DGN_1_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You sink into it. The hands are gentle, knowing. Ava's voice murmurs encouragement. The tension drains from your muscles. You feel safe, held, cared for. When the blindfold comes off, you're surrounded by warm smiles.</p> <p>"Welcome to the beginning," Ava says, kissing your forehead.</p> <<modStat "stress" -15 "Deep relaxation">> <<set $greekLife.sisterhood += 10>> <<set $greekLife.pledgeStage = 2>> <<else>> <p>You tense up under the unfamiliar hands. Can't relax. Can't let go. Ava senses it. "It's okay. We'll try again." The session ends early. You feel frustrated with yourself.</p> <<modStat "stress" -5 "Tried to relax">> <<set $greekLife.sisterhood += 3>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 2>> <<link '<span class="choice-btn">✅ Next bonding session</span>' "SororityPledge_DGN_2">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Come back tomorrow</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΔΓΝ Pledge: Stage 2: Skinny Dipping</h2> <p>Midnight. Ava drives you and the other pledges to Crystal Lake, twenty minutes from campus. The water is silver under moonlight. The sisters are already there naked, laughing, splashing.</p> <p>"Strip. Swim. Feel the water on your real skin. No hiding behind clothes." Ava drops her dress. She's beautiful confident, natural.</p> <p>The other pledges hesitate. You all look at each other.</p> <<rollButton "composure" 4 "Strip and swim" "SororityPledge_DGN_2_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You peel off your clothes under the stars. The cool air prickles your skin. You wade into the lake it's cold at first, then perfect. The sisters swim around you, laughing, splashing. Ava floats beside you, moonlight on her wet skin.</p> <p>"See? Nothing to be afraid of." She takes your hand under the water. For a moment, everything is peaceful.</p> <<modStat "confidence" 10 "Skinny dipping">> <<modStat "mood" 15 "Beautiful night">> <<set $greekLife.sisterhood += 15>> <<set $greekLife.pledgeStage = 3>> <<else>> <p>You can't do it. You stand at the water's edge, arms crossed over your chest. Ava swims over. "It's okay. Not tonight." But you can see the other pledges in the water, bonding without you.</p> <<modStat "confidence" -3 "Couldn't strip">> <<set $greekLife.sisterhood += 5>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 3>> <<link '<span class="choice-btn">✅ Next bonding session</span>' "SororityPledge_DGN_3">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Try again next time</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΔΓΝ Pledge: Stage 3: Seven Minutes in Heaven</h2> <p>Pledge night social. Candles, wine, soft music. The sisters and pledges sit in a circle. Ava spins the bottle. It lands on you and a senior sister named Jade. She's athletic, confident, with knowing eyes.</p> <p>"Closet. Seven minutes. Whatever feels right." Jade stands, offers you her hand. The closet is small, dark. Warm. You can smell her perfume.</p> <p>"Relax," Jade whispers. "Just feel."</p> <<rollButton "charm" 4 "Seven minutes" "SororityPledge_DGN_3_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>Jade's lips find yours in the dark. The kiss is soft at first, exploratory. Then deeper. Her hands slide to your waist, pulling you close. You kiss back, hesitant, then hungry. Her fingers trace your jaw, your neck, the curve of your breast.</p> <p>Seven minutes. It feels like seven seconds. When the door opens, you're both flushed, breathing hard, smiling.</p> <<modStat "arousal" 20 "Kissing Jade">> <<modStat "confidence" 8 "Intimate connection">> <<set $greekLife.sisterhood += 15>> <<set $greekLife.pledgeStage = 4>> <<else>> <p>In the darkness, Jade leans in. You freeze. She pulls back. "It's okay. We don't have to." You stand in awkward silence for seven very long minutes.</p> <<modStat "stress" 5 "Awkward closet">> <<set $greekLife.sisterhood += 3>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 4>> <<link '<span class="choice-btn">✅ Next bonding session</span>' "SororityPledge_DGN_4">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Try again</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΔΓΝ Pledge: Stage 4: Sister Worship</h2> <p>Late evening at the DGN house. Ava, your big sister leads you to her private room. Rose petals on the bed. Candles. She sits on the edge, wearing a silk robe.</p> <p>"This is the deepest trust exercise. Every pledge gives this to their big sister. It's about devotion, vulnerability, closeness." She parts the robe. Her legs are bare. "Show me you're ready to be my sister."</p> <<rollButton "oral" 5 "Go down on Ava" "SororityPledge_DGN_4_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You kneel between Ava's thighs. She's gentle, her fingers thread through your <<print $pc.hairColour>> hair, guiding but never forcing. You find your rhythm, reading her body. Her breath quickens, her hips shift.</p> <p>"Oh god... right there..." She arches. When she comes, she pulls you up and kisses you, tasting herself on your lips. "My perfect little sister."</p> <<addXP "oral" 20>> <<modStat "arousal" 25 "Going down on Ava">> <<set $greekLife.sisterhood += 20>> <<modStat "confidence" 8 "Intimate trust">> <<set $greekLife.pledgeStage = 5>> <<else>> <p>You're willing but uncertain. Your technique is off too fast, then too slow. Ava is patient, encouraging, but eventually gently lifts your chin. "Not quite. But the willingness means everything." She kisses your forehead.</p> <<addXP "oral" 10>> <<set $greekLife.sisterhood += 8>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 5>> <<link '<span class="choice-btn">✅ Final initiation</span>' "SororityPledge_DGN_5">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Come back when ready</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΔΓΝ Pledge: Stage 5: Initiation Night</h2> <p>The chapter room is transformed. Silk sheets cover the floor. Candles line every surface. The entire pledge class and their big sisters gather in a circle. Ava holds your hand.</p> <p>"The daisy chain is our most sacred tradition. Every sister, connected to every other. No beginning, no end. Just... us."</p> <p>The sisters begin to undress. The pledges follow. Bodies intertwine mouths finding skin, hands finding warmth.</p> <<rollButton "stamina" 5 "Daisy chain initiation" "SororityPledge_DGN_5_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You lose yourself in the chain. Giving and receiving, connected to the women around you. Ava is above you, her dark curls falling against your skin. Someone else's mouth is between your thighs. You're doing the same for another sister. It's overwhelming, beautiful, sacred.</p> <p>When it's over, you're all tangled together, breathing hard, laughing softly. Ava presses her forehead to yours. "Welcome home, sister."</p> <<set $greekLife.pledging = false>> <<set $greekLife.member = true>> <<set $greekLife.rank = "member">> <<set $greekLife.hazingComplete = true>> <<set $greekLife.sisterhood += 30>> <<modStat "arousal" 40 "Daisy chain">> <<modStat "mood" 20 "Deep connection">> <<modStat "stress" -20 "Acceptance">> <<addXP "oral" 15>> <<addXP "stamina" 15>> <<run XCLC.Toast.show("💜 You're a Delta Gamma Nu sister!", "info")>> <<else>> <p>The intimacy overwhelms you. You try, but can't quite give yourself over to it. Ava sees. She holds you. "It's okay. We'll try again." The chain continues around you while you catch your breath.</p> <<modStat "stress" 10 "Overwhelmed">> <<addXP "stamina" 8>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🏡 <<if $greekLife.member>>Your new home<<else>>Go home<</if>></span>' `($greekLife.member ? "SororityCommon" : "GreekRow")`>><</link>> </div> /* ═══════════════════════════════════════════════════ KAPPA KAPPA CHI: TRADITIONAL HAZING (5 stages) ═══════════════════════════════════════════════════ */
<h2>ΚΚΧ Pledge: Stage 1: House Rules Quiz</h2> <p>The Kappa house library. Wood panelling, leather chairs, portraits of alumni on the walls. The pledge class sits at desks like an exam. The house president, Victoria, drops a 30-page booklet on your desk.</p> <p>"Memorise this. House history, founding principles, alumni achievements, chapter rules. I'll quiz you in one hour."</p> <<rollButton "intelligence" 3 "Study and recite" "SororityPledge_KKC_1_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You nail every question. Founded in 1887. The motto is "Per Aspera Ad Astra." The most famous alum is a Supreme Court justice. Victoria raises an eyebrow, impressed despite herself.</p> <p>"Competent. Good."</p> <<addXP "intelligence" 15>> <<set $greekLife.sisterhood += 5>> <<set $greekLife.pledgeStage = 2>> <<else>> <p>You blank on the founding date and mix up two alumni. Victoria makes you stand in the corner wearing a paper dunce hat. The seniors take photos. It's a long afternoon.</p> <<modStat "confidence" -5 "Dunce hat">> <<addXP "intelligence" 5>> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 2>> <<link '<span class="choice-btn">✅ Next challenge</span>' "SororityPledge_KKC_2">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Study more and retry</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΚΚΧ Pledge: Stage 2: Drinking Challenge</h2> <p>Friday night. The pledge class is lined up in the basement. Ten shot glasses each, filled with cheap vodka. Victoria clicks a stopwatch.</p> <p>"Relay. Each pledge takes one, passes to the next. Last pledge standing wins. We don't breed lightweights."</p> <<rollButton "stamina" 4 "Chug relay" "SororityPledge_KKC_2_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>Shot after shot. The vodka burns. Your eyes water. But you keep going. Slam, pass, slam, pass. The other pledges drop one by one. You're the last one standing, swaying but upright.</p> <p>"Impressive." Victoria almost smiles. Almost.</p> <<set $substances.alcoholTolerance = Math.min(10, $substances.alcoholTolerance + 1)>> <<set $greekLife.sisterhood += 10>> <<set $greekLife.pledgeStage = 3>> <<drink "shot">><<drink "shot">><<drink "shot">> <<else>> <p>The fourth shot comes back up. Spectacularly. The seniors jump back. You ruin someone's shoes. Victoria hands you a mop.</p> <<modStat "confidence" -5 "Vomited">> <<drink "shot">><<drink "shot">> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 3>> <<link '<span class="choice-btn">✅ Next challenge</span>' "SororityPledge_KKC_3">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Recover and retry</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΚΚΧ Pledge: Stage 3: Servant Day</h2> <p>You're assigned to Victoria for the entire day. Carry her books. Fetch her coffee. Iron her blazer. She's demanding, exacting, and treats you like furniture.</p> <p>"The latte should be 140 degrees. This is at least 150. Again."</p> <p>By afternoon, you're exhausted and your patience is razor-thin.</p> <<rollButton "composure" 5 "Endure the day" "SororityPledge_KKC_3_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You endure. Every unreasonable request, every snide comment, every "didn't I say TWO sugars?", and you handle it with a smile. By evening, Victoria nods.</p> <p>"Discipline is the foundation of leadership. You have it."</p> <<set $greekLife.sisterhood += 10>> <<modRep "sweetheart" 3>> <<set $greekLife.pledgeStage = 4>> <<else>> <p>"The LATTE." "I KNOW ABOUT THE FUCKING LATTE!" You snap. The room goes silent. Victoria's eyes narrow. "Get out. Come back when you can control yourself."</p> <<modStat "composure" -5 "Snapped at senior">> <<modStat "stress" 10 "Humiliation">> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 4>> <<link '<span class="choice-btn">✅ Next challenge</span>' "SororityPledge_KKC_4">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Apologize and retry</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΚΚΧ Pledge: Stage 4: Walk of Shame</h2> <p>6 AM. Victoria wakes the pledge class. "Strip to your underwear. You're walking from the Kappa house to the library and back. Through the quad. Past the dorms. During morning rush."</p> <p>Students are already heading to early classes. The quad is busy. You're in your <<if $pc.breastSize === "DD" || $pc.breastSize === "E">>struggling-to-contain<<else>>modest<</if>> bra and panties.</p> <p>"Chin up. Walk with dignity. A Kappa woman is never ashamed."</p> <<rollButton "composure" 6 "Walk of shame" "SororityPledge_KKC_4_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>You walk. Chin up, shoulders back, like Victoria said. Phone cameras flash. People stare. A frat guy whistles. But you keep walking steady, controlled, dignified.</p> <p>By the time you reach the library, you feel... powerful. Like nothing can touch you.</p> <<modStat "confidence" 15 "Walked with dignity">> <<modRep "popular" 5>> <<set $greekLife.pledgeStage = 5>> <<else>> <p>Three steps in, a group of guys start laughing. You try to cover yourself. You speed-walk, then run. By the time you reach the library you're in tears. Victoria texts: "Try again when you're ready."</p> <<modStat "confidence" -10 "Ran in shame">> <<modStat "stress" 20 "Public humiliation">> <</if>> <div class="choice-group"> <<if $greekLife.pledgeStage >= 5>> <<link '<span class="choice-btn">✅ Final exam</span>' "SororityPledge_KKC_5">><</link>> <<else>> <<link '<span class="choice-btn">🔄 Try again when ready</span>' "GreekRow">><</link>> <</if>> </div>
<h2>ΚΚΧ Pledge: Stage 5: Final Exam</h2> <p>The Kappa chapter room. Blindfolded. The entire sorority watches. Victoria reads questions from the house manual. You must answer perfectly. Then recite the oath.</p> <p>This is it. Months of discipline, study, and humiliation come down to this.</p> <<rollButton "intelligence" 5 "Final examination" "SororityPledge_KKC_5_Result">>
<<set _outcome = $lastRoll.outcome>> <<if _outcome === "crit_success" || _outcome === "success">> <p>Every question: correct. The oath: flawless. When the blindfold comes off, Victoria is smiling, genuinely smiling. The sisters applaud.</p> <p>"Per Aspera Ad Astra. Through hardship, to the stars." She pins a golden K to your blazer. "Welcome to Kappa Kappa Chi."</p> <<set $greekLife.pledging = false>> <<set $greekLife.member = true>> <<set $greekLife.rank = "member">> <<set $greekLife.hazingComplete = true>> <<set $greekLife.sisterhood += 20>> <<modStat "confidence" 15 "Kappa initiation">> <<modRep "goodStudent" 5>> <<addXP "intelligence" 25>> <<run XCLC.Toast.show("📚 You're a Kappa Kappa Chi sister!", "info")>> <<else>> <p>You blank on question seven. The oath comes out garbled. Victoria's face is stone. "You're not ready. Study. Come back next year."</p> <<modStat "confidence" -8 "Failed finals">> <<modStat "stress" 10 "Failed initiation">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🏡 <<if $greekLife.member>>Your new chapter house<<else>>Go home<</if>></span>' `($greekLife.member ? "SororityCommon" : "GreekRow")`>><</link>> </div> /* ═══════════════════════════════════════════════════ SORORITY COMMON ROOM (all sororities) ═══════════════════════════════════════════════════ */
<h2>🏡 <<print $greekLife.sorority>> House</h2> <p><<if $greekLife.sorority === "Alpha Phi Epsilon">>The Alpha Phi house is always buzzing. Loud music, girls getting ready for tonight's party, someone doing shots in the kitchen at 3 PM. The fridge is stocked with mixers and the closet is a communal wardrobe of slutty dresses.<<elseif $greekLife.sorority === "Delta Gamma Nu">>The DGN house is cozy. Fairy lights everywhere, someone baking in the kitchen, sisters braiding each other's hair on the common room floor. Ava waves you over to the couch.<<else>>The Kappa house is pristine. Hardwood floors, fresh flowers, a study schedule posted on the fridge. Victoria reviews flashcards at the dining table. The coffee machine is professional-grade.<</if>></p> <p><strong>Sisterhood:</strong> <<print $greekLife.sisterhood>>/100</p> <<divider "Activities">> <div class="choice-group"> <<link '<span class="choice-btn">💬 Hang out with sisters</span>' "SororityCommon">> <<advanceTime 60>> <<set $greekLife.sisterhood = Math.min(100, $greekLife.sisterhood + 3)>> <<modStat "mood" 5 "Sisterhood">> <<modRep "popular" 1>> <</link>> <<if $greekLife.sorority === "Alpha Phi Epsilon">> <<link '<span class="choice-btn">👗 Borrow party clothes</span>' "SororityCommon">> <<set $pc.beautyClothing = Math.min(20, $pc.beautyClothing + 5)>> <<run XCLC.Toast.show("👗 Borrowed a hot outfit from the closet.", "info")>> <</link>> <<elseif $greekLife.sorority === "Delta Gamma Nu">> <<link '<span class="choice-btn">💆 Sister spa night</span>' "SororityCommon">> <<advanceTime 60>> <<modStat "stress" -15 "Spa night">> <<modStat "mood" 10 "Bonding">> <<set $greekLife.sisterhood = Math.min(100, $greekLife.sisterhood + 5)>> <</link>> <<elseif $greekLife.sorority === "Kappa Kappa Chi">> <<link '<span class="choice-btn">📚 Join study group</span>' "SororityCommon">> <<advanceTime 90>> <<addXP "intelligence" 15>> <<addXP "studying" 15>> <<run XCLC.Toast.show("📚 Great study session with the sisters.", "info")>> <</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">🏡 Back to Greek Row</span>' "GreekRow">><</link>> </div> /* ═══════════════════════════════════════════════════ FRAT PARTIES ═══════════════════════════════════════════════════ */
<h2>🎉 Frat Party: Sigma Chi House</h2> <<showDrunkStatus>> <<set $greekLife.fratPartiesAttended++>> <<set $greekLife.lastPartyDay = $world.day>> <<modRep "partyGirl" 2>> <p>The Sigma Chi house is wall-to-wall bodies. Red cups, blaring hip-hop, a beer pong table in the living room, and a dance floor in the cleared-out dining room. The air is thick with sweat and cologne.</p> <<if $pc.beautyTotal >= 60>> <p>Heads turn as you walk in. A few guys elbow each other. A girl gives you the once-over.</p> <<else>> <p>Nobody notices your entrance. Just another body in the crowd.</p> <</if>> <<if $substances.drunkLevel >= 2>> <p><em>Everything looks <<if $substances.drunkLevel >= 3>>really really<<else>>slightly<</if>> better than it probably is.</em></p> <</if>> /* Gangbang trigger check */ /* Gated on reputation alone. Intoxication colours the scene, it does not unlock it. */ <<set _gangbangAvailable = ($reputation.slut >= 40)>> <<divider "What do you do?">> <div class="choice-group"> <<link '<span class="choice-btn">🍺 Get a drink</span>' "FratParty_Drink">><</link>> <<link '<span class="choice-btn">💃 Hit the dance floor</span>' "FratParty_Dance">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">🏓 Beer pong</span>' "FratParty_GameRoom">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">💬 Mingle</span>' "FratParty">> <<advanceTime 20>> <<addXP "charm" 5>> <<modStat "mood" 3 "Socialising">> <</link>> <<if _gangbangAvailable>> <<link '<span class="choice-btn">🔥 Go upstairs with the group</span>' "FratParty_Gangbang">><</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">🚪 Leave the party</span>' "GreekRow">> <<if $substances.drunkLevel >= 3>> <<set $temp.drunkTravel = true>> <</if>> <</link>> </div>
<h2>🍺 The Keg</h2> <<showDrunkStatus>> <p>A keg sits in the corner, surrounded by red cups. A frat guy works the tap. Free beer, the universal college currency.</p> <div class="choice-group"> <<link '<span class="choice-btn">🍺 Beer (free)</span>' "FratParty">> <<set $substances.drinksToday += 1>> <<checkDrunkState>> <<advanceTime 15>> <<run XCLC.Toast.show("🍺 Free beer!", "info")>> <</link>> <<link '<span class="choice-btn">🥃 Jungle juice (strong)</span>' "FratParty">> <<set $substances.drinksToday += 2>> <<checkDrunkState>> <<advanceTime 15>> <<run XCLC.Toast.show("🥃 That jungle juice hits HARD.", "warning")>> <</link>> <<link '<span class="choice-btn">🚰 Water (smart choice)</span>' "FratParty">> <<advanceTime 10>> <</link>> <<divider "">> <<link '<span class="choice-btn">🔙 Back to the party</span>' "FratParty">><</link>> </div>
<h2>💃 Dance Floor</h2> <<showDrunkStatus>> <<set _danceResult = XCLC.Roll.doCheck("dance", 3)>> <<run XCLC.DicePopup.show()>> <<if _danceResult === "crit_success" || _danceResult === "success">> <p>You lose yourself in the music. Bodies press against you. Someone's hands find your hips. You don't pull away. The beat takes over.</p> <<modStat "mood" 10 "Dancing">> <<addXP "dance" 10>> <<modRep "popular" 1>> <<else>> <p>You try to dance but the floor is too crowded and sticky. Someone steps on your foot. You mostly sway in place.</p> <<addXP "dance" 5>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to the party</span>' "FratParty">><</link>> </div>
<h2>🏓 Beer Pong</h2> <<showDrunkStatus>> <p>A crowd gathers around the beer pong table. Someone challenges you.</p> <<set _composureResult = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _composureResult === "crit_success" || _composureResult === "success">> <p>You sink cup after cup. The crowd chants your name. Your opponent looks devastated. You're the beer pong queen.</p> <<modStat "confidence" 5 "Beer pong champion">> <<modRep "popular" 2>> <<modRep "partyGirl" 2>> <<else>> <p>You miss every shot. You have to drink the penalty cups. The crowd laughs good-naturedly.</p> <<set $substances.drinksToday += 2>> <<checkDrunkState>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to the party</span>' "FratParty">><</link>> </div> /* ═══════════════════════════════════════════════════ FRAT PARTY GANGBANG ═══════════════════════════════════════════════════ */
<h2>🔥 Upstairs</h2> <<showDrunkStatus>> <<set _numGuys = random(2, 5)>> <<set $temp.gangbangGuys = _numGuys>> <<set $temp.gangbangRound = 0>> <<set $temp.gangbangCompleted = 0>> <p><<print _numGuys>> guys and a bedroom, and none of them are pretending to be here for the conversation.<<if $substances.drunkLevel >= 2>> The room has a soft edge on it and you are aware you are not at your sharpest.<</if>> The one nearest the door stops with his hand on the handle. "You sure about this?"</p> <p><<if _numGuys >= 4>>This is a lot. Even for you.<<elseif _numGuys >= 3>>Three guys. Your mouth goes dry.<<else>>Two guys. Manageable.<</if>></p> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Let\'s do this</span>' "FratParty_Gangbang_Act">><</link>> <<link '<span class="choice-btn">😰 Actually, no</span>' "FratParty">> /* No is no at every level. It was never conditional on being sober enough. */ <<run XCLC.Toast.show("You said no. Somebody groaned. You went back downstairs.", "info")>> <</link>> </div>
<h2>🔥 Round <<print $temp.gangbangRound + 1>></h2> <<showDrunkStatus>> <<set $temp.gangbangRound++>> <<set _round = $temp.gangbangRound>> <<set _totalGuys = $temp.gangbangGuys>> /* DC increases each round */ <<set _dc = 3 + _round>> <<set _staminaResult = XCLC.Roll.doCheck("stamina", _dc)>> <<run XCLC.DicePopup.show()>> <<if _staminaResult === "crit_success" || _staminaResult === "success">> <<set $temp.gangbangCompleted++>> <p><<if _round === 1>>The first guy pushes you onto the bed. It's rough, fast, intense. You take it <<if $transformation.sideEffects.wet>>your enhanced wetness helps<<else>>gritting your teeth through the initial shock<</if>>. He finishes with a grunt.<<elseif _round === 2>>The second one is bigger. Harder. Your body is already sore but adrenaline carries you. <<if $transformation.sideEffects.sensitive>>Every nerve ending is on fire it's almost too much.<</if>><<elseif _round === 3>>Number three. You're exhausted. Sweat-soaked. But you're still going. Something primal has taken over.<<elseif _round === 4>>Four. Your legs are shaking. You're running on willpower alone. The room is spinning.<<else>>Five. You barely know where you are anymore. It's pure endurance. Survival. Some twisted badge of honour.<</if>></p> <<addXP "stamina" 10>> <<modStat "arousal" 15 "Gangbang round">> <<else>> <p><<if _round <= 2>>It's too much. Your body gives out. You push him off, gasping.<<else>>Your arms buckle. You collapse onto the mattress. "Done... I'm done," you manage.<</if>></p> <<modStat "energy" -10 "Overwhelmed">> <</if>> /* Check if more rounds or done */ <<if $temp.gangbangCompleted < _totalGuys && (_staminaResult === "crit_success" || _staminaResult === "success")>> <div class="choice-group"> <<link '<span class="choice-btn">💪 Next round</span>' "FratParty_Gangbang_Act">><</link>> <<link '<span class="choice-btn">✋ Tap out</span>' "FratParty_Gangbang_End">><</link>> </div> <<else>> <<goto "FratParty_Gangbang_End">> <</if>>
<h2>🔥 Aftermath</h2> <<set _completed = $temp.gangbangCompleted>> <<set _total = $temp.gangbangGuys>> <<set _allRounds = (_completed >= _total)>> <p><<if _allRounds>>You did it. All <<print _total>>. You lie on the ruined bedsheets, chest heaving, body wrecked. <<if $substances.drunkLevel >= 3>>The details are already fuzzy. Did that really just happen?<<else>>You stare at the ceiling. That just happened.<</if>><<else>>You tapped out after <<print _completed>> of <<print _total>>. <<if _completed >= 2>>Not bad, all things considered.<<else>>It was too much.<</if>><</if>></p> /* Apply consequences */ <<modHygiene -40 "Gangbang">> <<modStat "arousal" 50 "Gangbang">> <<modStat "energy" `(_completed * -10)` "Exhaustion">> /* STD risk scales with how many you took */ <<stdRisk "vaginal" `Math.max(1, _completed)`>> <<if _allRounds>> <<addXP "stamina" 30>> <<addXP "oral" 15>> <<modStat "confidence" 10 "Completed gangbang">> <<modRep "slut" 10>> <<else>> <<addXP "stamina" `(_completed * 8)`>> <<modStat "confidence" -3 "Tapped out">> <<modRep "slut" `(_completed * 3)`>> <</if>> /* Filming chance */ <<set _filmed = random(1, 10) <= ($substances.drunkLevel >= 3 ? 4 : 2)>> <<if _filmed>> <p><em>Someone had their phone out. You're pretty sure you saw a flash...</em></p> <<modRep "slut" 15>> <<run XCLC.Toast.show("📱 Someone might have filmed that...", "warning")>> <</if>> /* Service credit */ <<if _completed >= 2>> <p><em>+<<print Math.min(3, _completed)>> service credits applied to your quota.</em></p> <<set $scholarship.currentWeekServiced += Math.min(3, _completed)>> <<set $scholarship.totalServiced += Math.min(3, _completed)>> <</if>> <<advanceTime 60>> <div class="choice-group"> <<link '<span class="choice-btn">🚿 Clean up and leave</span>' "FratParty">> <<modHygiene 10 "Quick cleanup">> <</link>> </div> /* ═══════════════════════════════════════════════════ STUDENT CENTER ═══════════════════════════════════════════════════ */
<h2>🎭 Student Center</h2> <div class="choice-group"><<whoIsAround>></div> <p>The student center is the social heart of campus. Cork boards covered in flyers, a lounge with worn couches, vending machines humming in the corner, and the muffled sounds of club meetings behind closed doors.</p> <<if $world.dayOfWeek === 0>> <p>It's quiet on Sunday. A few students study in the lounge.</p> <<elseif $world.dayOfWeek >= 4>> <p>It's buzzing today. Students cluster around the events board, debating weekend plans.</p> <<else>> <p>A steady stream of students passes through between classes.</p> <</if>> <<divider "Activities">> <div class="choice-group"> <<link '<span class="choice-btn">📋 Events Board</span>' "EventsBoard">><</link>> <<link '<span class="choice-btn">🛋️ Hang out in the lounge</span>' "StudentCenter_Lounge">> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">🎭 Club Rooms</span>' "StudentCenter_Club">><</link>> <<link '<span class="choice-btn">🍫 Vending Machines</span>' "StudentCenter_Vending">><</link>> <<divider "">> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>📋 Events Board</h2> <<set _weekNum = Math.floor($world.day / 7) + 1>> <<set _events = [ {name: "📖 Study Group · Library", desc: "Collaborative studying with other students.", skill: "studying", xp: 15, rep: "goodStudent", repVal: 2}, {name: "🎬 Movie Night · Auditorium", desc: "Free popcorn and a classic film.", skill: "composure", xp: 5, rep: "popular", repVal: 2}, {name: "🎤 Open Mic Night", desc: "Poetry, music, comedy. Brave souls only.", skill: "charm", xp: 15, rep: "popular", repVal: 3}, {name: "🎪 Club Fair", desc: "All campus clubs recruiting new members.", skill: "charm", xp: 10, rep: "popular", repVal: 2}, {name: "🧁 Charity Bake Sale", desc: "Buy cupcakes, support a cause.", skill: "charm", xp: 5, rep: "sweetheart", repVal: 3}, {name: "🧘 Free Yoga Class", desc: "Destress and stretch. Mat provided.", skill: "stamina", xp: 10, rep: "popular", repVal: 1}, {name: "🎤 Karaoke Night", desc: "Embarrass yourself for fun.", skill: "composure", xp: 15, rep: "partyGirl", repVal: 2} ]>> /* Pick 3 based on week */ <<set _e1 = _events[_weekNum % _events.length]>> <<set _e2 = _events[(_weekNum + 2) % _events.length]>> <<set _e3 = _events[(_weekNum + 4) % _events.length]>> <p>This week's events:</p> <div class="card"> <div class="card__title"><<print _e1.name>></div> <p><<print _e1.desc>></p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Attend (2 hours)</span>' "StudentCenter">> <<advanceTime 120>> <<addXP _e1.skill _e1.xp>> <<modRep _e1.rep _e1.repVal>> <<modStat "mood" 5 "Social event">> <<set $social.eventsAttended++>> <<run XCLC.Toast.show("🎉 Attended " + _e1.name, "info")>> <</link>> </div> </div> <div class="card"> <div class="card__title"><<print _e2.name>></div> <p><<print _e2.desc>></p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Attend (2 hours)</span>' "StudentCenter">> <<advanceTime 120>> <<addXP _e2.skill _e2.xp>> <<modRep _e2.rep _e2.repVal>> <<modStat "mood" 5 "Social event">> <<set $social.eventsAttended++>> <<run XCLC.Toast.show("🎉 Attended " + _e2.name, "info")>> <</link>> </div> </div> <div class="card"> <div class="card__title"><<print _e3.name>></div> <p><<print _e3.desc>></p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Attend (2 hours)</span>' "StudentCenter">> <<advanceTime 120>> <<addXP _e3.skill _e3.xp>> <<modRep _e3.rep _e3.repVal>> <<modStat "mood" 5 "Social event">> <<set $social.eventsAttended++>> <<run XCLC.Toast.show("🎉 Attended " + _e3.name, "info")>> <</link>> </div> </div> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to Student Center</span>' "StudentCenter">><</link>> </div>
<h2>🛋️ The Lounge</h2> <<set _encounter = random(1, 10)>> <<if _encounter <= 3>> <<set _loungeNPC = XCLC.NPC.generate({gender: random(1,10) <= 5 ? "male" : "female", type: "student"})>> <p>A <<print _loungeNPC.bodyType>> <<if _loungeNPC.gender === "male">>guy<<else>>girl<</if>> with <<print _loungeNPC.hairColour>> hair is sitting alone, scrolling their phone. They look up as you sit down.</p> <p>"Hey. You look bored too." They smile. You end up chatting for a while about classes, campus drama, and questionable cafeteria food.</p> <<addXP "charm" 8>> <<modStat "mood" 5 "Good conversation">> <<modRep "popular" 1>> <<elseif _encounter <= 5>> <p>A few students are debating something heated politics? Philosophy? You catch fragments. "No, that's EXACTLY why." "You're wrong, and here's why."</p> <p>You settle into a couch and people-watch. It's oddly relaxing.</p> <<modStat "mood" 3 "People watching">> <<else>> <p>The lounge is mostly empty. You sink into a couch, close your eyes for a moment, and just... breathe. Campus life is exhausting.</p> <<modStat "stress" -5 "Quiet moment">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to Student Center</span>' "StudentCenter">><</link>> </div>
<h2>🎭 Club Rooms</h2> <p>Doors line the hallway, each with a hand-made sign. Some are meeting now, others are quiet.</p> <<set _clubs = [ {id: "drama", name: "🎭 Drama Club", desc: "Acting, improv, semester play. Trains composure and charm.", skill1: "composure", skill2: "charm"}, {id: "debate", name: "🗣️ Debate Society", desc: "Argue about everything. Trains persuasion and intelligence.", skill1: "persuasion", skill2: "intelligence"}, {id: "art", name: "🎨 Art Club", desc: "Painting, sketching, creative expression. Reduces stress.", skill1: "composure", skill2: null}, {id: "gaming", name: "🎮 Gaming Club", desc: "Board games, video games, social gaming. Fun but unproductive.", skill1: null, skill2: null} ]>> <<for _i = 0; _i < _clubs.length; _i++>> <<set _c = _clubs[_i]>> <<set _isMember = $social.clubsMember.includes(_c.id)>> <<capture _c>> <div class="card"> <div class="card__title"><<print _c.name>> <<if _isMember>>✅ Member<</if>></div> <p><<print _c.desc>></p> <div class="choice-group"> <<if _isMember>> <<link '<span class="choice-btn">📅 Attend meeting (1.5 hrs)</span>' "StudentCenter">> <<advanceTime 90>> <<if _c.skill1>><<addXP _c.skill1 10>><</if>> <<if _c.skill2>><<addXP _c.skill2 5>><</if>> <<modStat "mood" 5 "Club meeting">> <<modRep "popular" 1>> <<run XCLC.Toast.show("🎭 Good club meeting!", "info")>> <</link>> <<else>> <<link '<span class="choice-btn">✋ Join this club</span>' "StudentCenter_Club">> <<run $social.clubsMember.push(_c.id)>> <<run XCLC.Toast.show("🎉 Joined " + _c.name + "!", "info")>> <<modRep "popular" 2>> <</link>> <</if>> </div> </div> <</capture>> <</for>> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to Student Center</span>' "StudentCenter">><</link>> </div>
<h2>🍫 Vending Machines</h2> <p>Two vending machines hum against the wall. One for snacks, one for drinks.</p> <div class="choice-group"> <<if $finance.money >= 2>> <<link '<span class="choice-btn">🍫 Candy bar ($2)</span>' "StudentCenter">> <<set $finance.money -= 2>> <<modStat "energy" 10 "Sugar rush">> <<run XCLC.Toast.show("🍫 Sugar rush! +10 energy", "info")>> <</link>> <</if>> <<if $finance.money >= 2>> <<link '<span class="choice-btn">☕ Coffee ($2)</span>' "StudentCenter">> <<set $finance.money -= 2>> <<modStat "energy" 15 "Caffeine">> <<run XCLC.Toast.show("☕ Caffeine boost! +15 energy", "info")>> <</link>> <</if>> <<if $finance.money >= 3>> <<link '<span class="choice-btn">🥤 Energy drink ($3)</span>' "StudentCenter">> <<set $finance.money -= 3>> <<modStat "energy" 25 "Energy drink">> <<run XCLC.Toast.show("🥤 ENERGY! +25 energy", "info")>> <</link>> <</if>> <<if $finance.money < 2>> <p><em>You can't afford anything. Check the couch cushions?</em></p> <</if>> <<divider "">> <<link '<span class="choice-btn">🔙 Back to Student Center</span>' "StudentCenter">><</link>> </div>
/* ═══════════════════════════════════════════════════ THORNFIELD: JOB SYSTEM WIDGETS ═══════════════════════════════════════════════════ */ /* ─── Check if player can take a new job ─── */ <<widget "canHireCheck">> /* Cam work and FansOnly are casual, with no shifts and no employer, so they don't count toward the 3-job limit. */ <<set _casual = ["camGirl", "fansOnly", "escort"]>> <<set _formalJobs = $jobs.current.filter(function(j){ return _casual.indexOf(j) === -1; })>> <<if _formalJobs.length >= 3>> <<run XCLC.Toast.show("❌ You already have 3 scheduled jobs. Quit one first. (Cam work and FansOnly don't count.)", "error")>> <<set _canHire = false>> <<else>> <<set _canHire = true>> <</if>> <</widget>> /* ─── Activate a job ─── */ <<widget "hireJob">> <<set _jobId = _args[0]>> <<set $jobs[_jobId].active = true>> <<run $jobs.current.push(_jobId)>> <<run XCLC.Toast.show("🎉 You got the job!", "info")>> <</widget>> /* ─── Quit a job ─── */ <<widget "quitJob">> <<set _jobId = _args[0]>> <<set $jobs[_jobId].active = false>> <<set $jobs.current = $jobs.current.filter(function(j) { return j !== _jobId; })>> <<run XCLC.Toast.show("👋 You quit your " + _jobId + " job.", "info")>> <</widget>> /* ─── Pay the player ─── */ <<widget "payPlayer">> <<set _amount = Number(_args[0]) || 0>> <<set _reason = _args[1] || "Work">> <<set $finance.money += _amount>> <<if _amount > 0>> <<set $finance.totalEarned += _amount>> <<else>> <<set $finance.totalSpent += Math.abs(_amount)>> <</if>> /* Bank app transaction log (capped) */ <<run (function(){ var sv = State.variables; if (!Array.isArray(sv.finance.transactions)) sv.finance.transactions = []; sv.finance.transactions.push({day: sv.world.day, amount: State.temporary.amount, reason: State.temporary.reason}); if (sv.finance.transactions.length > 20) sv.finance.transactions.shift(); }())>> <<run XCLC.Toast.show("💰 " + (State.temporary.amount >= 0 ? "+" : "-") + "$" + Math.abs(State.temporary.amount) + " (" + State.temporary.reason + ")", "info")>> <</widget>> /* Log a purchase/expense to the Bank app without changing money (call after the money has already been deducted). Usage: <<logExpense 50 "STD treatment">> */ <<widget "logExpense">> <<set _amount = Number(_args[0]) || 0>> <<set _reason = _args[1] || "Purchase">> <<set $finance.totalSpent += _amount>> <<run (function(){ var sv = State.variables; if (!Array.isArray(sv.finance.transactions)) sv.finance.transactions = []; sv.finance.transactions.push({day: sv.world.day, amount: -State.temporary.amount, reason: State.temporary.reason}); if (sv.finance.transactions.length > 20) sv.finance.transactions.shift(); }())>> <</widget>>
/* ═══════════════════════════════════════════════════ JOB BOARD: Central hub for all employment ═══════════════════════════════════════════════════ */ <h2>💼 Job Board</h2> <p>Your employment status. You can hold up to <strong>3 jobs</strong> at once.</p> <<if $jobs.current.length > 0>> <div class="card"> <div class="card__title">📋 Active Jobs (<<print $jobs.current.length>>/3)</div> <<for _i = 0; _i < $jobs.current.length; _i++>> <<set _jid = $jobs.current[_i]>> <<set _names = {barista: "☕ Barista", bartender: "🍸 Bartender", tutor: "📚 Tutor", cheerleader: "📣 Cheerleader", camGirl: "📷 Cam Girl", fansOnly: "💰 FansOnly", stripper: "💃 Stripper", hooker: "💋 Escort", dealer: "🧪 Dealer"}>> <<capture _jid>> <p><<print _names[_jid] || _jid>> · <<print $jobs[_jid].shifts || $jobs[_jid].shows || $jobs[_jid].sessions || $jobs[_jid].clients || $jobs[_jid].posts || 0>> sessions <<link '<span class="choice-btn choice-btn--small">❌ Quit</span>' "JobBoard">><<quitJob _jid>><</link>> </p> <</capture>> <</for>> </div> <</if>> <<divider "Available Positions">> <<set _period = XCLC.Time.getPeriod($world.time)>> /* === Non-Sexual Jobs === */ <div class="card"> <div class="card__title">🏢 Regular Employment</div> <div class="choice-group"> <<if $jobs.barista.active>> <<if _period === "early_morning" || _period === "morning" || _period === "afternoon">> <<link '<span class="choice-btn">☕ Work a barista shift</span>' "Job_Barista_Shift">><</link>> <<else>> <p><em>☕ Barista · Café is closed (morning/afternoon only)</em></p> <</if>> <<else>> <<link '<span class="choice-btn">☕ Apply: Barista: Bean There, Done That Café</span>' "Job_Barista_Apply">><</link>> <</if>> <<if $jobs.bartender.active>> <<if _period === "evening" || _period === "night" || _period === "late_night">> <<link '<span class="choice-btn">🍸 Work a bartender shift</span>' "Job_Bartender_Shift">><</link>> <<else>> <p><em>🍸 Bartender · Bar is closed (evening/night only)</em></p> <</if>> <<else>> <<if $skills.charm.level >= 3>> <<link '<span class="choice-btn">🍸 Apply: Bartender: Bar District</span>' "Job_Bartender_Apply">><</link>> <<else>> <p><em>🍸 Bartender · Requires Charm ≥ 3</em></p> <</if>> <</if>> <<if $jobs.tutor.active>> <<if _period === "afternoon">> <<link '<span class="choice-btn">📚 Run a tutoring session</span>' "Job_Tutor_Session">><</link>> <<else>> <p><em>📚 Tutor · Learning center is afternoon only</em></p> <</if>> <<else>> <<if $skills.intelligence.level >= 4 && $skills.studying.level >= 3>> <<link '<span class="choice-btn">📚 Apply: Campus Tutor</span>' "Job_Tutor_Apply">><</link>> <<else>> <p><em>📚 Tutor · Requires Intelligence ≥ 4, Studying ≥ 3</em></p> <</if>> <</if>> </div> </div> /* === Performance Jobs === */ <div class="card"> <div class="card__title">🎭 Performance & Content</div> <div class="choice-group"> <<if $jobs.cheerleader.active>> <<link '<span class="choice-btn">📣 Cheerleader Schedule</span>' "Job_Cheer_Hub">><</link>> <<else>> <<if $skills.dance.level >= 2 && $skills.stamina.level >= 2>> <<link '<span class="choice-btn">📣 Try out: Thornfield Wildcats Cheerleading</span>' "Job_Cheer_Tryout">><</link>> <<else>> <p><em>📣 Cheerleader · Requires Dance ≥ 2, Stamina ≥ 2</em></p> <</if>> <</if>> <<if $jobs.camGirl.active>> <<if $inventory.hasLaptop && $inventory.hasWebcam>> <p><em>📷 Cam Girl · active. You stream from your dorm room, not from a noticeboard.</em></p> <<else>> <p><em>📷 Cam Girl · Need laptop + webcam (Electronics Store)</em></p> <</if>> <<else>> <<if $inventory.hasLaptop && $inventory.hasWebcam>> <<link '<span class="choice-btn">📷 Set up: Cam Girl account</span>' "Job_Cam_Apply">><</link>> <<else>> <p><em>📷 Cam Girl · Need laptop + webcam (Electronics Store)</em></p> <</if>> <</if>> <<if $jobs.fansOnly.active>> <<link '<span class="choice-btn">💰 Create FansOnly content</span>' "Job_FansOnly_Hub">><</link>> <<else>> <<if $inventory.hasCamera>> <<link '<span class="choice-btn">💰 Set up: FansOnly account</span>' "Job_FansOnly_Apply">><</link>> <<else>> <p><em>💰 FansOnly · Need camera (Electronics Store)</em></p> <</if>> <</if>> <<if $jobs.stripper.active>> <<if _period === "evening" || _period === "night" || _period === "late_night">> <<link '<span class="choice-btn">💃 Work a stripper shift</span>' "Job_Stripper_Shift">><</link>> <<else>> <p><em>💃 Stripper · Club opens in the evening</em></p> <</if>> <<else>> <<if $skills.dance.level >= 2>> <<link '<span class="choice-btn">💃 Apply: Candy Bar dancer</span>' "Job_Stripper_Apply">><</link>> <<else>> <p><em>💃 Stripper · Requires Dance ≥ 2</em></p> <</if>> <</if>> </div> </div> /* === Criminal Jobs === */ <div class="card"> <div class="card__title">⚠️ Underground</div> <div class="choice-group"> <<if $jobs.hooker.active>> <<if _period === "night" || _period === "late_night">> <<link '<span class="choice-btn">💋 Walk the street</span>' "Job_Hooker_Street">><</link>> <</if>> <<if $jobs.hooker.phoneUnlocked && (_period === "evening" || _period === "night")>> <<link '<span class="choice-btn">📱 Check for phone clients</span>' "Job_Hooker_Phone">><</link>> <</if>> <<if _period !== "night" && _period !== "late_night" && _period !== "evening">> <p><em>💋 Escort · Night work only</em></p> <</if>> <<else>> <<link '<span class="choice-btn">💋 Start: Street walking</span>' "Job_Hooker_Apply">><</link>> <</if>> <<if $jobs.dealer.active>> <<link '<span class="choice-btn">🧪 Deal drugs</span>' "Job_Dealer_Hub">><</link>> <<else>> <<link '<span class="choice-btn">🧪 Start: Drug dealing</span>' "Job_Dealer_Apply">><</link>> <</if>> </div> </div> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ ☕ BARISTA: Bean There, Done That Café With coffee-making minigame ═══════════════════════════════════════════════════ */
<h2>☕ Bean There, Done That Café</h2> <p>A cozy campus café with exposed brick, chalkboard menus, and the constant hiss of an espresso machine. The manager, a cheerful woman named Rosa, looks you up and down.</p> <p>"You ever made coffee before? Doesn't matter. I'll train you. Minimum wage plus tips. Shifts are mornings and afternoons, three hours each. You in?"</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">☕ Take the job</span>' "JobBoard">> <<hireJob "barista">> <<run XCLC.Toast.show("☕ Rosa hands you an apron. 'Don't burn the milk.'", "info")>> <</link>> <<link '<span class="choice-btn">🚫 Not right now</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>☕ Barista Shift</h2> <<advanceTime 180>> <<set $jobs.barista.shifts++>> <p>You tie your apron and take your place behind the counter. The morning rush is starting.</p> /* Coffee Minigame: 3 customers */ <<set $temp.coffeeScore = 0>> <<set $temp.coffeeRound = 0>> <<set $temp.coffeeTotalRounds = 3>> <<goto "Job_Barista_Order">>
<<set $temp.coffeeRound++>> <<set _round = $temp.coffeeRound>> /* Generate a random order */ <<set _orders = [ {name: "Latte", steps: ["espresso", "steam", "pour"], desc: "a latte"}, {name: "Cappuccino", steps: ["espresso", "foam", "dust"], desc: "a cappuccino"}, {name: "Americano", steps: ["espresso", "water", "stir"], desc: "an americano"}, {name: "Mocha", steps: ["espresso", "chocolate", "steam"], desc: "a mocha"}, {name: "Flat White", steps: ["espresso", "microfoam", "pour"], desc: "a flat white"}, {name: "Espresso Shot", steps: ["grind", "tamp", "pull"], desc: "a double espresso"} ]>> <<set _order = _orders[random(0, _orders.length - 1)]>> <<set $temp.currentOrder = _order>> <<set $temp.coffeeStep = 0>> <<set _customerDescs = ["A sleepy professor", "A frantic student with three textbooks", "A woman in gym clothes", "A guy on his phone who won't make eye contact", "A chatty girl with too much energy", "An impatient businessman"]>> <<set $temp.customerDesc = _customerDescs[random(0, _customerDescs.length - 1)]>> <<goto "Job_Barista_Step">>
<<set $temp.coffeeStep++>> <<set _step = $temp.coffeeStep>> <<set _order = $temp.currentOrder>> <<set _correctStep = _order.steps[_step - 1]>> <<set _totalSteps = _order.steps.length>> <h3>☕ Customer <<print $temp.coffeeRound>> of <<print $temp.coffeeTotalRounds>></h3> <p><<print $temp.customerDesc>> orders <strong><<print _order.desc>></strong>.</p> <<if $temp.coffeeFeedback>><p><<print $temp.coffeeFeedback>></p><<set $temp.coffeeFeedback = "">><</if>> <p><strong>Making: <<print _order.name>> · Step <<print _step>> of <<print _totalSteps>>:</strong></p> /* Shuffle options: correct + 2 wrong */ <<set _allOptions = ["espresso", "steam", "pour", "foam", "dust", "water", "stir", "chocolate", "microfoam", "grind", "tamp", "pull"]>> <<set _wrong = _allOptions.filter(function(o) { return o !== _correctStep; })>> /* Shuffle wrong options */ <<set _w1 = _wrong[random(0, _wrong.length - 1)]>> <<set _wrong = _wrong.filter(function(o) { return o !== _w1; })>> <<set _w2 = _wrong[random(0, _wrong.length - 1)]>> /* Build choice array and shuffle */ <<set _choices = [_correctStep, _w1, _w2]>> <<set _choices = _choices.sort(function() { return Math.random() - 0.5; })>> /* Display name mapping */ <<set _displayNames = {espresso: "☕ Pull espresso shot", steam: "🌡️ Steam the milk", pour: "🥛 Pour milk", foam: "☁️ Froth the milk (thick foam)", dust: "🍫 Dust with cocoa", water: "💧 Add hot water", stir: "🥄 Stir", chocolate: "🍫 Add chocolate syrup", microfoam: "☁️ Microfoam the milk", grind: "⚙️ Grind the beans", tamp: "👊 Tamp the portafilter", pull: "☕ Pull the shot"}>> <div class="choice-group"> <<for _c = 0; _c < _choices.length; _c++>> <<capture _choices[_c]>> <<link '<span class="choice-btn"><<print _displayNames[_choices[_c]]>></span>' "Job_Barista_StepResult">> <<set $temp.coffeeChoice = _choices[_c]>> <</link>> <</capture>> <</for>> </div>
<<set _choice = $temp.coffeeChoice>> <<set _order = $temp.currentOrder>> <<set _step = $temp.coffeeStep>> <<set _correct = _order.steps[_step - 1]>> <<if _choice === _correct>> <<set $temp.coffeeFeedback = "✅ <strong>Correct!</strong> " + (_step === 1 ? "Perfect start." : (_step === 2 ? "Looking good." : "Nailed it."))>> <<set $temp.coffeeScore++>> <<else>> <<set _displayNames = {espresso: "Pull espresso shot", steam: "Steam the milk", pour: "Pour milk", foam: "Froth the milk", dust: "Dust with cocoa", water: "Add hot water", stir: "Stir", chocolate: "Add chocolate syrup", microfoam: "Microfoam the milk", grind: "Grind the beans", tamp: "Tamp the portafilter", pull: "Pull the shot"}>> <<set $temp.coffeeFeedback = "❌ <strong>Wrong!</strong> You should have: " + _displayNames[_correct] + ". " + (_step === 1 ? "The customer sighs." : (_step === 2 ? "You try to recover." : "The drink looks... off."))>> <</if>> /* More steps or next customer? */ <<if _step < _order.steps.length>> <<goto "Job_Barista_Step">> <<elseif $temp.coffeeRound < $temp.coffeeTotalRounds>> <p><<print $temp.coffeeFeedback>></p> <<set $temp.coffeeFeedback = "">> <p>The customer takes their drink<<if _choice === _correct>> with a smile<</if>>. Another one steps up to the counter.</p> <div class="choice-group"> <<link '<span class="choice-btn">☕ Next customer</span>' "Job_Barista_Order">><</link>> </div> <<else>> <<goto "Job_Barista_Results">> <</if>>
<h2>☕ Shift Results</h2> <<if $temp.coffeeFeedback>><p><<print $temp.coffeeFeedback>></p><<set $temp.coffeeFeedback = "">><</if>> <<set _score = $temp.coffeeScore>> <<set _maxScore = 9>> <<set _pct = Math.round((_score / _maxScore) * 100)>> <<set _basePay = 25 + ($jobs.barista.tier * 5)>> <<set _tipMultiplier = _pct / 100>> <<set _tips = Math.round(20 * _tipMultiplier)>> <<set _total = _basePay + _tips>> <<set $jobs.barista.tips += _tips>> <div class="card"> <div class="card__title">💰 Shift Complete</div> <p><strong>Orders correct:</strong> <<print _score>>/<<print _maxScore>> steps (<<print _pct>>%)</p> <p><strong>Base pay:</strong> $<<print _basePay>></p> <p><strong>Tips:</strong> $<<print _tips>></p> <p><strong>Total:</strong> $<<print _total>></p> </div> <<payPlayer _total "Barista shift">> <<addXP "charm" 10>> <<addXP "composure" 5>> /* Progression check */ <<if $jobs.barista.shifts >= 25 && $jobs.barista.tier < 2>> <<set $jobs.barista.tier = 2>> <<run XCLC.Toast.show("⭐ Promoted to Shift Lead! +$10/shift", "info")>> <<elseif $jobs.barista.shifts >= 10 && $jobs.barista.tier < 1>> <<set $jobs.barista.tier = 1>> <<run XCLC.Toast.show("⭐ Promoted to Senior Barista! +$5/shift", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 🍸 BARTENDER: Bar District With cocktail-making minigame ═══════════════════════════════════════════════════ */
<h2>🍸 Bartender Position</h2> <p>The Rusty Nail's manager, a grizzled man named Frank, squints at you. "Can you pour drinks without spilling? Can you handle drunks?" He slides a cocktail recipe book across the bar.</p> <p>"Evening shifts, four hours. Forty bucks base plus whatever you charm out of tips. Deal?"</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">🍸 Take the job</span>' "JobBoard">> <<hireJob "bartender">> <<run XCLC.Toast.show("🍸 Frank tosses you a bar towel. 'Don't fuck up the martinis.'", "info")>> <</link>> <<link '<span class="choice-btn">🚫 Not right now</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>🍸 Bartender Shift</h2> <<advanceTime 240>> <<set $jobs.bartender.shifts++>> <p>You step behind the bar. The neon signs glow. Music thumps. Time to make drinks.</p> /* Cocktail Minigame: 3 customers */ <<set $temp.cocktailScore = 0>> <<set $temp.cocktailRound = 0>> <<set $temp.cocktailTotalRounds = 3>> <<goto "Job_Bartender_Order">>
<<set $temp.cocktailRound++>> <<set _round = $temp.cocktailRound>> <<set _cocktails = [ {name: "Margarita", ingredients: ["tequila", "lime", "salt"], desc: "a margarita"}, {name: "Mojito", ingredients: ["rum", "mint", "lime"], desc: "a mojito"}, {name: "Martini", ingredients: ["gin", "vermouth", "olive"], desc: "a dry martini"}, {name: "Old Fashioned", ingredients: ["bourbon", "bitters", "sugar"], desc: "an old fashioned"}, {name: "Cosmopolitan", ingredients: ["vodka", "cranberry", "lime"], desc: "a cosmopolitan"}, {name: "Long Island", ingredients: ["vodka", "rum", "tequila"], desc: "a Long Island iced tea"}, {name: "Whiskey Sour", ingredients: ["whiskey", "lemon", "sugar"], desc: "a whiskey sour"}, {name: "Daiquiri", ingredients: ["rum", "lime", "sugar"], desc: "a daiquiri"} ]>> <<set _cocktail = _cocktails[random(0, _cocktails.length - 1)]>> <<set $temp.currentCocktail = _cocktail>> <<set $temp.cocktailStep = 0>> <<set _custDescs = ["A woman in a little black dress", "A burly guy with tattoos", "Two girls celebrating a birthday", "A nervous first-date couple", "A regular who's already three deep", "A professor who clearly doesn't want to be recognized"]>> <<set $temp.cocktailCustomerDesc = _custDescs[random(0, _custDescs.length - 1)]>> <<goto "Job_Bartender_Step">>
<<set $temp.cocktailStep++>> <<set _step = $temp.cocktailStep>> <<set _cocktail = $temp.currentCocktail>> <<set _correct = _cocktail.ingredients[_step - 1]>> <<set _total = _cocktail.ingredients.length>> <h3>🍸 Customer <<print $temp.cocktailRound>> of <<print $temp.cocktailTotalRounds>></h3> <p><<print $temp.cocktailCustomerDesc>> orders <strong><<print _cocktail.desc>></strong>.</p> <<if $temp.cocktailFeedback>><p><<print $temp.cocktailFeedback>></p><<set $temp.cocktailFeedback = "">><</if>> <p><strong>Mixing: <<print _cocktail.name>> · Ingredient <<print _step>> of <<print _total>>:</strong></p> <<set _allIngredients = ["tequila", "lime", "salt", "rum", "mint", "gin", "vermouth", "olive", "bourbon", "bitters", "sugar", "vodka", "cranberry", "whiskey", "lemon"]>> <<set _wrong = _allIngredients.filter(function(o) { return o !== _correct; })>> <<set _w1 = _wrong[random(0, _wrong.length - 1)]>> <<set _wrong = _wrong.filter(function(o) { return o !== _w1; })>> <<set _w2 = _wrong[random(0, _wrong.length - 1)]>> <<set _choices = [_correct, _w1, _w2]>> <<set _choices = _choices.sort(function() { return Math.random() - 0.5; })>> <<set _displayNames = {tequila: "🥃 Tequila", lime: "🍋 Lime juice", salt: "🧂 Salt rim", rum: "🍹 White rum", mint: "🌿 Fresh mint", gin: "🍸 Gin", vermouth: "🍷 Dry vermouth", olive: "🫒 Olive garnish", bourbon: "🥃 Bourbon", bitters: "💧 Angostura bitters", sugar: "🍬 Sugar syrup", vodka: "🍸 Vodka", cranberry: "🍒 Cranberry juice", whiskey: "🥃 Whiskey", lemon: "🍋 Lemon juice"}>> <div class="choice-group"> <<for _c = 0; _c < _choices.length; _c++>> <<capture _choices[_c]>> <<link '<span class="choice-btn"><<print _displayNames[_choices[_c]]>></span>' "Job_Bartender_StepResult">> <<set $temp.cocktailChoice = _choices[_c]>> <</link>> <</capture>> <</for>> </div>
<<set _choice = $temp.cocktailChoice>> <<set _cocktail = $temp.currentCocktail>> <<set _step = $temp.cocktailStep>> <<set _correct = _cocktail.ingredients[_step - 1]>> <<if _choice === _correct>> <<set $temp.cocktailFeedback = "✅ <strong>Correct!</strong> " + (_step === 1 ? "Good base." : (_step === 2 ? "Mix it in." : "Perfect finish."))>> <<set $temp.cocktailScore++>> <<else>> <<set _displayNames = {tequila: "Tequila", lime: "Lime juice", salt: "Salt rim", rum: "White rum", mint: "Fresh mint", gin: "Gin", vermouth: "Dry vermouth", olive: "Olive garnish", bourbon: "Bourbon", bitters: "Angostura bitters", sugar: "Sugar syrup", vodka: "Vodka", cranberry: "Cranberry juice", whiskey: "Whiskey", lemon: "Lemon juice"}>> <<set $temp.cocktailFeedback = "❌ <strong>Wrong!</strong> Should have been: " + _displayNames[_correct] + ". The customer frowns.">> <</if>> <<if _step < _cocktail.ingredients.length>> <<goto "Job_Bartender_Step">> <<elseif $temp.cocktailRound < $temp.cocktailTotalRounds>> <p><<print $temp.cocktailFeedback>></p> <<set $temp.cocktailFeedback = "">> <p>The customer takes their drink. Another one waves you down.</p> <div class="choice-group"> <<link '<span class="choice-btn">🍸 Next customer</span>' "Job_Bartender_Order">><</link>> </div> <<else>> <<goto "Job_Bartender_Results">> <</if>>
<h2>🍸 Shift Results</h2> <<if $temp.cocktailFeedback>><p><<print $temp.cocktailFeedback>></p><<set $temp.cocktailFeedback = "">><</if>> <<set _score = $temp.cocktailScore>> <<set _maxScore = 9>> <<set _pct = Math.round((_score / _maxScore) * 100)>> <<set _basePay = 40 + ($jobs.bartender.tier * 15)>> <<set _tips = Math.round(40 * (_pct / 100))>> <<set _total = _basePay + _tips>> <<set $jobs.bartender.tips += _tips>> /* Bartender event */ <<set _event = random(1, 10)>> <<if _event <= 2>> <p>A drunk guy refused to leave. You had to handle it with composure.</p> <<set _composure = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _composure === "crit_success" || _composure === "success">> <p>You talked him down smoothly. Frank nodded approvingly. <em>Bonus $20.</em></p> <<set _total += 20>> <<else>> <p>It got messy. Frank had to step in. Awkward.</p> <<modStat "stress" 5 "Bar fight">> <</if>> <<elseif _event === 3>> <p>A VIP dropped a $50 tip just for being pretty. Lucky night.</p> <<set _total += 50>> <</if>> <<set $substances.alcoholTolerance = Math.min(10, $substances.alcoholTolerance + 0.2)>> <div class="card"> <div class="card__title">💰 Shift Complete</div> <p><strong>Cocktails correct:</strong> <<print _score>>/<<print _maxScore>> ingredients (<<print _pct>>%)</p> <p><strong>Base pay:</strong> $<<print _basePay>></p> <p><strong>Tips:</strong> $<<print _tips>></p> <p><strong>Total:</strong> $<<print _total>></p> </div> <<payPlayer _total "Bartender shift">> <<addXP "charm" 12>> <<addXP "persuasion" 8>> <<if $jobs.bartender.shifts >= 15 && $jobs.bartender.tier < 1>> <<set $jobs.bartender.tier = 1>> <<run XCLC.Toast.show("⭐ Promoted to Head Bartender! +$15/shift", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 📚 TUTOR: Campus Learning Center ═══════════════════════════════════════════════════ */
<h2>📚 Campus Tutor Position</h2> <p>The Learning Center director reviews your transcript. "Your grades are strong. We need tutors for intro courses. Thirty dollars per session, two-hour blocks in the afternoon. Interested?"</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">📚 Take the position</span>' "JobBoard">> <<hireJob "tutor">> <<modRep "goodStudent" 3>> <</link>> <<link '<span class="choice-btn">🚫 Not right now</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>📚 Tutoring Session</h2> <<advanceTime 120>> <<set $jobs.tutor.sessions++>> <<set _student = XCLC.NPC.generate({gender: random(1,10) <= 5 ? "male" : "female", type: "student"})>> <p>Your student today is a <<print _student.bodyType>> <<if _student.gender === "male">>guy<<else>>girl<</if>> who clearly didn't read the textbook.</p> <<set _teachResult = XCLC.Roll.doCheck("intelligence", 4)>> <<run XCLC.DicePopup.show()>> <<set _basePay = 30 + ($jobs.tutor.tier * 15)>> <<if _teachResult === "crit_success" || _teachResult === "success">> <p>"Oh my god, you're amazing! It finally makes sense!" Your student beams. They get it.</p> <<modStat "mood" 5 "Good teaching">> <<modRep "goodStudent" 2>> /* Event chance */ <<set _event = random(1, 10)>> <<if _event <= 2 && _student.gender === "male">> <p>After the session, he lingers. "Hey, uh... would you want to grab coffee sometime? Like, not as a study thing." He's blushing.</p> <div class="choice-group"> <<link '<span class="choice-btn">😊 Sure, why not</span>' "Job_Tutor_Done">> <<modStat "mood" 5 "Date invitation">> <<modRep "popular" 1>> <</link>> <<link '<span class="choice-btn">📚 I keep things professional</span>' "Job_Tutor_Done">><</link>> </div> <<else>> <<goto "Job_Tutor_Done">> <</if>> <<else>> <p>The session is rough. Your student stares blankly no matter how you explain it. By the end, you're both frustrated.</p> <<modStat "stress" 5 "Difficult student">> <<goto "Job_Tutor_Done">> <</if>>
<<set _basePay = 30 + ($jobs.tutor.tier * 15)>> <<payPlayer _basePay "Tutoring session">> <<addXP "intelligence" 15>> <<addXP "studying" 10>> <<if $jobs.tutor.sessions >= 10 && $jobs.tutor.tier < 1>> <<set $jobs.tutor.tier = 1>> <<run XCLC.Toast.show("⭐ Promoted to Premium Tutor! $45/session", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 📣 CHEERLEADER: Thornfield Wildcats With routine minigame ═══════════════════════════════════════════════════ */
<h2>📣 Cheerleader Tryouts</h2> <p>The gym is set up for tryouts. Captain Brittany, blonde and terrifyingly fit with a clipboard already in hand, surveys the nervous line of girls.</p> <p>"Alright ladies. Show me what you've got. Full routine: opening, stunts, tumbling, closing. Don't fall on your face."</p> <<canHireCheck>> <<if _canHire>> <<set _danceCheck = XCLC.Roll.doCheck("dance", 4)>> <<set _staminaCheck = XCLC.Roll.doCheck("stamina", 4)>> <<run XCLC.DicePopup.show()>> <<if (_danceCheck === "crit_success" || _danceCheck === "success") && (_staminaCheck === "crit_success" || _staminaCheck === "success")>> <p>You nail every move. The jumps are clean, the tumbling is tight, and you finish with a split. Brittany circles something on her clipboard. "Welcome to the Wildcats."</p> <p>She hands you a bag. Inside: the official cheerleading uniform. A crop top and skirt in school colors, pom-poms, and white sneakers. "Don't lose it."</p> <<hireJob "cheerleader">> <<set $jobs.cheerleader.hasOutfit = true>> <<modRep "popular" 5>> <<else>> <p>You stumble on the tumbling and the timing is off. Brittany shakes her head. "Practice more and try again next week."</p> <<modStat "confidence" -5 "Failed tryout">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>📣 Wildcats Schedule</h2> <p><strong>Practices missed:</strong> <<print $jobs.cheerleader.practicesMissed>>/3 (kicked at 3)</p> <p><strong>Games cheered:</strong> <<print $jobs.cheerleader.gamesAttended>></p> <<set _period = XCLC.Time.getPeriod($world.time)>> <<set _dow = $world.dayOfWeek>> <<set _isPracticeDay = (_dow === 1 || _dow === 3 || _dow === 5)>> <<set _isGameDay = (_dow === 6 && ($world.day % 14 < 7))>> <div class="choice-group"> <<if _isPracticeDay && _period === "afternoon">> <<link '<span class="choice-btn">📣 Go to practice</span>' "Job_Cheer_Practice">><</link>> <<elseif _isPracticeDay>> <p><em>Practice is this afternoon (MWF, 2 PM)</em></p> <<else>> <p><em>No practice today</em></p> <</if>> <<if _isGameDay && _period === "afternoon">> <<link '<span class="choice-btn">🏟️ Cheer at the game!</span>' "Job_Cheer_Game">><</link>> <<elseif _isGameDay>> <p><em>Game day! Show up this afternoon.</em></p> <</if>> <<divider "">> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div>
<h2>📣 Cheerleading Practice</h2> <<advanceTime 120>> <p>The squad assembles in the gym. Brittany blows her whistle. "New routine, ladies. Follow my lead."</p> /* Routine Minigame: pick the right move 4 times */ <<set $temp.cheerScore = 0>> <<set $temp.cheerRound = 0>> <<set $temp.cheerTotalRounds = 4>> <<goto "Job_Cheer_Move">>
<<set $temp.cheerRound++>> <<set _round = $temp.cheerRound>> <<set _moves = [ {name: "High V", correct: "highV", desc: "Arms up in a V!"}, {name: "Toe Touch", correct: "toeTouch", desc: "Jump and touch your toes!"}, {name: "Herkie", correct: "herkie", desc: "One leg forward, one bent back!"}, {name: "Back Tuck", correct: "backTuck", desc: "Backflip tuck!"}, {name: "Pike Jump", correct: "pike", desc: "Legs straight out front!"}, {name: "Liberty", correct: "liberty", desc: "One foot up, arms in a T!"}, {name: "Round Off", correct: "roundOff", desc: "Cartwheel into both feet!"}, {name: "Front Walkover", correct: "walkover", desc: "Forward into a bridge and over!"} ]>> <<set _move = _moves[random(0, _moves.length - 1)]>> <<set $temp.currentMove = _move>> <p><strong>Move <<print _round>>:</strong> Brittany calls out: "<em><<print _move.desc>></em>"</p> /* Generate options */ <<set _allMoves = ["highV", "toeTouch", "herkie", "backTuck", "pike", "liberty", "roundOff", "walkover"]>> <<set _wrong = _allMoves.filter(function(m) { return m !== _move.correct; })>> <<set _w1 = _wrong[random(0, _wrong.length - 1)]>> <<set _wrong = _wrong.filter(function(m) { return m !== _w1; })>> <<set _w2 = _wrong[random(0, _wrong.length - 1)]>> <<set _choices = [_move.correct, _w1, _w2]>> <<set _choices = _choices.sort(function() { return Math.random() - 0.5; })>> <<set _moveNames = {highV: "🙌 High V", toeTouch: "🦵 Toe Touch", herkie: "💃 Herkie", backTuck: "🔄 Back Tuck", pike: "🦵 Pike Jump", liberty: "🗽 Liberty", roundOff: "🤸 Round Off", walkover: "🤸♀️ Front Walkover"}>> <div class="choice-group"> <<for _c = 0; _c < _choices.length; _c++>> <<capture _choices[_c]>> <<link '<span class="choice-btn"><<print _moveNames[_choices[_c]]>></span>' "Job_Cheer_MoveResult">> <<set $temp.cheerChoice = _choices[_c]>> <</link>> <</capture>> <</for>> </div>
<<set _choice = $temp.cheerChoice>> <<set _move = $temp.currentMove>> <<if _choice === _move.correct>> <p>✅ <strong>Perfect!</strong> You nail <<print _move.name>>. The squad flows together.</p> <<set $temp.cheerScore++>> <<else>> <p>❌ <strong>Wrong move!</strong> You do the wrong thing and crash into another cheerleader. "Focus, pledge!" Brittany snaps.</p> <</if>> <<if $temp.cheerRound < $temp.cheerTotalRounds>> <<goto "Job_Cheer_Move">> <<else>> <<goto "Job_Cheer_PracticeResult">> <</if>>
<h2>📣 Practice Results</h2> <<set _score = $temp.cheerScore>> <<if _score >= 3>> <p>"Good work today." Brittany almost sounds impressed. The squad high-fives you.</p> <<modStat "mood" 8 "Good practice">> <<modRep "popular" 2>> <<else>> <p>"We need to work on that." Brittany's tone says more than her words. You slink to the showers.</p> <<modStat "confidence" -3 "Rough practice">> <</if>> <<addXP "dance" 15>> <<addXP "stamina" 10>> <<addXP "flexibility" 5>> <<set $jobs.cheerleader.practiceDay = $world.day>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "CampusMap">><</link>> </div>
<h2>🏟️ Game Day!</h2> <<advanceTime 180>> <<set $jobs.cheerleader.gamesAttended++>> <p>The stadium is packed. The crowd roars. You're front and center in your cheerleading uniform, pom-poms ready.</p> <<set _danceResult = XCLC.Roll.doCheck("dance", 5)>> <<run XCLC.DicePopup.show()>> <<if _danceResult === "crit_success">> <p>You absolutely CRUSH the routine. The crowd chants your name. A camera crew catches your splits. Your phone blows up after the game.</p> <<modStat "confidence" 15 "Game day star">> <<modRep "popular" 5>> <<addXP "dance" 25>> <<elseif _danceResult === "success">> <p>Solid performance. The routine goes well, the crowd loves it, and the team wins. Good day.</p> <<modStat "mood" 10 "Game day">> <<modRep "popular" 3>> <<addXP "dance" 15>> <<else>> <p>You stumble during the big number. A few people in the crowd laugh. Brittany shoots you a look.</p> <<modStat "confidence" -5 "Game stumble">> <<modRep "popular" 1>> <<addXP "dance" 8>> <</if>> /* Featured dancer check */ <<if $jobs.cheerleader.gamesAttended >= 5 && $jobs.cheerleader.teamRank < 1>> <<set $jobs.cheerleader.teamRank = 1>> <<run XCLC.Toast.show("⭐ You're now a Featured Dancer! More attention, more fans.", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 📷 CAM GIRL: Dorm Room Shows ═══════════════════════════════════════════════════ */
<h2>📷 Cam Girl Setup</h2> <p>You set up your laptop and webcam on your desk. The lighting is... okay. You create an account on StreamLive under a pseudonym.</p> <p>"<<print $pc.firstName>>_Cam". No, too obvious. You settle on a stage name. The site approves your account instantly. You're live whenever you want to be.</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">📷 Set up account</span>' "JobBoard">> <<hireJob "camGirl">> <</link>> <<link '<span class="choice-btn">🚫 Not ready yet</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>📷 Going Live</h2> <<set _period = XCLC.Time.getPeriod($world.time)>> <<set _baseViewers = $jobs.camGirl.viewers>> <<if _period === "night" || _period === "late_night">> <<set _viewers = Math.round(_baseViewers * (1 + Math.random() * 0.5))>> <<elseif _period === "evening">> <<set _viewers = Math.round(_baseViewers * (0.7 + Math.random() * 0.3))>> <<else>> <<set _viewers = Math.round(_baseViewers * (0.3 + Math.random() * 0.3))>> <</if>> <<if $jobs.camGirl.hasRingLight || $inventory.hasRingLight>><<set _viewers = Math.round(_viewers * 1.2)>><</if>> <<if $inventory.hasBackdrop>><<set _viewers = Math.round(_viewers * 1.1)>><</if>> <<set $temp.camViewers = _viewers>> <<set $temp.camTokens = 0>> <p>You hit the "Go Live" button. The red light blinks. <<print _viewers>> viewers trickle in. The chat starts scrolling.</p> <p><em>"hey cutie" · "show feet" · "hi from texas" · "you're hot"</em></p> <<divider "Choose your show type">> <p><em>Higher tiers = higher DCs but more tokens. Anyone can try anything.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">😊 Tease Show (DC 3): Chat, flirt, light strip</span>' "Job_Cam_Show">> <<set $temp.camShowType = "tease">> <<set $temp.camDC = 3>> <<set $temp.camBaseTokens = 20>> <</link>> <<link '<span class="choice-btn">👙 Strip Show (DC 4): Full strip, posing</span>' "Job_Cam_Show">> <<set $temp.camShowType = "strip">> <<set $temp.camDC = 4>> <<set $temp.camBaseTokens = 40>> <</link>> <<link '<span class="choice-btn">🎀 Toy Show (DC 5): Vibrator, dildo play</span>' "Job_Cam_Show">> <<set $temp.camShowType = "toy">> <<set $temp.camDC = 5>> <<set $temp.camBaseTokens = 70>> <</link>> <<link '<span class="choice-btn">🔥 Explicit Show (DC 6): Full performance</span>' "Job_Cam_Show">> <<set $temp.camShowType = "explicit">> <<set $temp.camDC = 6>> <<set $temp.camBaseTokens = 100>> <</link>> </div>
<<if !$temp.camShowType>><<set $temp.camShowType = "tease">><</if>> <h2>📷 Live Show: <<print $temp.camShowType.charAt(0).toUpperCase() + $temp.camShowType.slice(1)>></h2> <<advanceTime 90>> <<set $jobs.camGirl.shows++>> /* Phase 1: Chat engagement */ <<set _charmResult = XCLC.Roll.doCheck("charm", 3)>> <<run XCLC.DicePopup.show()>> <<if _charmResult === "crit_success" || _charmResult === "success">> <p>You work the chat like a pro. Flirty, funny, playful. The viewer count climbs. People are tipping just for conversation.</p> <<set $temp.camTokens += 15>> <<set $temp.camViewers = Math.round($temp.camViewers * 1.3)>> <<else>> <p>The chat is slow. You struggle to keep people engaged. A few viewers leave.</p> <<set $temp.camViewers = Math.round($temp.camViewers * 0.8)>> <</if>> /* Phase 2: Performance */ <<set _camResult = XCLC.Roll.doCheck("camSkill", $temp.camDC)>> <<run XCLC.DicePopup.show()>> <<if _camResult === "crit_success">> <p>You're a natural. Every angle, every expression, every movement is perfect. The token counter goes berserk. Someone drops a 500-token bomb. The chat explodes with hearts and fire emojis.</p> <<set $temp.camTokens += Math.round($temp.camBaseTokens * 2.5)>> <<modStat "confidence" 10 "Amazing show">> <<elseif _camResult === "success">> <p>Good show. You hit your marks, the lighting works, the audience is into it. Steady stream of tokens.</p> <<set $temp.camTokens += Math.round($temp.camBaseTokens * 1.5)>> <<elseif _camResult === "partial_fail">> <p>It's... okay. The camera angle is weird, you fumble with props. Some viewers leave. A few sympathetic tips.</p> <<set $temp.camTokens += Math.round($temp.camBaseTokens * 0.7)>> <<else>> <p>Technical disaster. Your webcam freezes mid-show. When it comes back, you've lost half your audience. Someone screenshots the frozen frame of your weird face.</p> <<set $temp.camTokens += Math.round($temp.camBaseTokens * 0.3)>> <<modStat "confidence" -5 "Tech disaster">> <</if>> /* Event check */ <<set _event = random(1, 10)>> <<if _event <= 2>> <p><em>💬 Chat message: "Wait... do you go to Thornfield? I think I've seen you in class..." 😰</em></p> <<modRep "camGirl" 5>> <<modStat "stress" 8 "Recognized on cam">> <<elseif _event === 3>> <p><em>🐋 A whale drops $100 worth of tokens. "You're my new favorite."</em></p> <<set $temp.camTokens += 100>> <</if>> /* Calculate earnings: tokens * 0.5 = dollars */ <<set _earnings = Math.round($temp.camTokens * 0.5)>> <<set $jobs.camGirl.tokens += $temp.camTokens>> /* Viewer growth */ <<set $jobs.camGirl.viewers = Math.min(500, Math.round($jobs.camGirl.viewers * 1.05 + random(2, 8)))>> <div class="card"> <div class="card__title">📷 Show Results</div> <p><strong>Viewers:</strong> <<print $temp.camViewers>></p> <p><strong>Tokens earned:</strong> <<print $temp.camTokens>></p> <p><strong>Cash earned:</strong> $<<print _earnings>></p> </div> <<payPlayer _earnings "Cam show">> <<addXP "camSkill" 20>> <<modRep "camGirl" 2>> <<modStat "arousal" 15 "Exhibitionism">> /* Progression */ <<if $jobs.camGirl.shows >= 50 && $jobs.camGirl.tier < 3>> <<set $jobs.camGirl.tier = 3>> <<run XCLC.Toast.show("👑 Top Cam Girl! Maximum viewer base.", "info")>> <<elseif $jobs.camGirl.shows >= 25 && $jobs.camGirl.tier < 2>> <<set $jobs.camGirl.tier = 2>> <<set $jobs.camGirl.viewers = Math.min(500, $jobs.camGirl.viewers * 2)>> <<run XCLC.Toast.show("⭐ Popular Streamer! Viewers doubled.", "info")>> <<elseif $jobs.camGirl.shows >= 10 && $jobs.camGirl.tier < 1>> <<set $jobs.camGirl.tier = 1>> <<set $jobs.camGirl.viewers = Math.round($jobs.camGirl.viewers * 1.5)>> <<run XCLC.Toast.show("⭐ Established Streamer! +50% base viewers.", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 End stream</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ 💰 FANSONLY: Content Creation ═══════════════════════════════════════════════════ */
<h2>💰 FansOnly Setup</h2> <p>You download the FansOnly app and create a creator profile. Username, bio, profile pic. Subscription price: $5/month. Easy money... in theory.</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">💰 Create account</span>' "JobBoard">> <<hireJob "fansOnly">> <<set $jobs.fansOnly.lastPostDay = $world.day>> <</link>> <<link '<span class="choice-btn">🚫 Not yet</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>💰 FansOnly Dashboard</h2> /* Sub decay check */ <<set _daysSincePost = $world.day - $jobs.fansOnly.lastPostDay>> <<if _daysSincePost > 5 && $jobs.fansOnly.subs > 0>> <<set _decayDays = _daysSincePost - 5>> <<set _decayPct = Math.min(0.25, _decayDays * 0.05 * XCLC.FansOnly.churnMult())>> <<set _lost = Math.max(1, Math.round($jobs.fansOnly.subs * _decayPct))>> <<set $jobs.fansOnly.subs = Math.max(0, $jobs.fansOnly.subs - _lost)>> <div class="alert alert--warning">⚠️ You haven't posted in <<print _daysSincePost>> days. Lost <<print _lost>> subscribers.<<if $jobs.fansOnly.rating >= 4>> Your rating is holding some of them.<<elseif $jobs.fansOnly.rating > 0 && $jobs.fansOnly.rating < 3>> A weak rating means they leave faster.<</if>></div> <</if>> <<set _perSub = XCLC.FansOnly.perSub()>> <div class="card"> <div class="card__title">📊 Stats</div> <p><strong>Subscribers:</strong> <<print $jobs.fansOnly.subs>> ($<<print $jobs.fansOnly.subs * _perSub>>/week at $<<print _perSub>>/sub)</p> <p><strong>Total posts:</strong> <<print $jobs.fansOnly.posts>></p> <p><strong>Days since last post:</strong> <<print _daysSincePost>></p> <<if $jobs.fansOnly.ratingCount > 0>> <p><strong>Rating:</strong> <<print $jobs.fansOnly.rating>>/5.0 <span style="opacity:0.6;">(<<print $jobs.fansOnly.ratingCount>> posts rated)</span></p> <p style="opacity:0.7;font-size:0.85em;"><em><<if $jobs.fansOnly.rating >= 4.5>>Word of mouth is doing your marketing for you.<<elseif $jobs.fansOnly.rating >= 4>>A genuinely well-regarded account.<<elseif $jobs.fansOnly.rating >= 3.5>>Solid. People stay subscribed.<<elseif $jobs.fansOnly.rating >= 3>>Middling. It pays, but nobody is recommending it.<<else>>The comments are not kind and the churn shows it.<</if>></em></p> <</if>> </div> /* ─── Subscriber requests ─── */ <<set _newReq = XCLC.FansOnly.maybeRequest()>> <<if _newReq>> <div class="alert alert--info">💌 New request from <<print _newReq.from>>.</div> <</if>> <<if ($jobs.fansOnly.requests || []).length > 0>> <div class="card"> <div class="card__title">💌 Requests</div> <p style="opacity:0.7;font-size:0.85em;">Subscribers asking for specific things. You can take any of them or turn them down. Declining costs nothing but the ask.</p> <<for _ri = 0; _ri < $jobs.fansOnly.requests.length; _ri++>> <<set _rq = $jobs.fansOnly.requests[_ri]>> <<set _rqIdx = _ri>> <div style="margin-bottom:0.7em; padding-bottom:0.7em; border-bottom:1px solid rgba(255,255,255,0.1);"> <p style="margin:0;"><strong><<print _rq.from>></strong> wants <<print _rq.label>>. <strong>$<<print _rq.pay>></strong></p> <div class="choice-group"> <<capture _rqIdx, _rq>> <<link '<span class="choice-btn">✅ Take it</span>' "Job_FansOnly_Request">> <<set $temp.foRequest = XCLC.FansOnly.takeRequest(_rqIdx)>> <</link>> <<link '<span class="choice-btn">🚫 Turn it down</span>' "Job_FansOnly_Hub">> <<run XCLC.FansOnly.declineRequest(_rqIdx)>> <</link>> <</capture>> </div> </div> <</for>> </div> <</if>> <<divider "Create Content">> <div class="choice-group"> <<link '<span class="choice-btn">🤳 Post a selfie (DC 2, low risk)</span>' "Job_FansOnly_Post">> <<set $temp.foContentType = "selfie">> <<set $temp.foDC = 2>> <<set $temp.foSubGain = random(1, 3)>> <<set $temp.foRepHit = 1>> <</link>> <<link '<span class="choice-btn">👙 Post lingerie photos (DC 3)</span>' "Job_FansOnly_Post">> <<set $temp.foContentType = "lingerie">> <<set $temp.foDC = 3>> <<set $temp.foSubGain = random(2, 6)>> <<set $temp.foRepHit = 2>> <</link>> <<link '<span class="choice-btn">🔥 Post nudes (DC 4)</span>' "Job_FansOnly_Post">> <<set $temp.foContentType = "nude">> <<set $temp.foDC = 4>> <<set $temp.foSubGain = random(5, 12)>> <<set $temp.foRepHit = 3>> <</link>> <<link '<span class="choice-btn">💋 Post explicit content (DC 5)</span>' "Job_FansOnly_Post">> <<set $temp.foContentType = "explicit">> <<set $temp.foDC = 5>> <<set $temp.foSubGain = random(8, 20)>> <<set $temp.foRepHit = 5>> <</link>> <<if $scholarship.totalServiced > 0>> <<link '<span class="choice-btn">🎬 Upload recorded encounter (DC 4)</span>' "Job_FansOnly_RecordedPost">> <</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div>
<h2>💰 Creating Content: <<print $temp.foContentType>></h2> <<advanceTime 60>> <<set $jobs.fansOnly.posts++>> <<set $jobs.fansOnly.lastPostDay = $world.day>> <<set _result = XCLC.Roll.doCheck("camSkill", $temp.foDC)>> <<run XCLC.DicePopup.show()>> <<set _score = XCLC.FansOnly.rate(_result, $temp.foContentType)>> <<set _mult = XCLC.FansOnly.growthMult()>> <<if _result === "crit_success" || _result === "success">> <p>Great content. The lighting is good, the angles are flattering, and the caption is perfect. Subscribers love it.</p> <<set _gained = Math.max(1, Math.round($temp.foSubGain * _mult))>> <<set $jobs.fansOnly.subs += _gained>> <<run XCLC.Toast.show("📈 +" + _gained + " new subscribers!", "info")>> /* Viral chance on crit */ <<if _result === "crit_success">> <p><em>🔥 The post goes viral! Subscriber surge!</em></p> <<set _viralGain = Math.round(random(10, 25) * _mult)>> <<set $jobs.fansOnly.subs += _viralGain>> <<run XCLC.Toast.show("🚀 VIRAL! +" + _viralGain + " more subs!", "info")>> <</if>> <<else>> <p>The content is mediocre. Bad lighting, awkward pose. A few new subs, but nothing exciting.</p> <<set $jobs.fansOnly.subs += Math.max(1, Math.round($temp.foSubGain * 0.3 * _mult))>> <</if>> /* What the subscribers made of it */ <div class="card"> <div class="card__title">⭐ Rated <<print _score>>/5.0</div> <p style="opacity:0.85;">"<<print XCLC.FansOnly.comment(_score)>>"</p> <p style="opacity:0.6;font-size:0.85em;">Account average: <<print $jobs.fansOnly.rating>>/5.0 over <<print $jobs.fansOnly.ratingCount>> posts.</p> <<if _score < 2.8>> <p style="opacity:0.7;font-size:0.85em;"><em>Better kit and more variety would both help. Posting the same thing repeatedly is scored down.</em></p> <</if>> </div> <<addXP "camSkill" 15>> <<modRep "camGirl" $temp.foRepHit>> /* Cap at 500 */ <<set $jobs.fansOnly.subs = Math.min(500, $jobs.fansOnly.subs)>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to dashboard</span>' "Job_FansOnly_Hub">><</link>> </div>
<<set _rq = $temp.foRequest>> <h2>💌 Commission</h2> <<if !_rq>> <p>That request is no longer in the queue.</p> <div class="choice-group"><<link '<span class="choice-btn">🔙 Back</span>' "Job_FansOnly_Hub">><</link>></div> <<else>> <<advanceTime 90>> <<set $jobs.fansOnly.posts++>> <<set $jobs.fansOnly.lastPostDay = $world.day>> <<set _res = XCLC.Roll.doCheck(_rq.skill, _rq.dc)>> <<run XCLC.DicePopup.show()>> <<set _score = XCLC.FansOnly.rate(_res, "request_" + _rq.id)>> <p>You take <<print _rq.from>>'s money up front, which is the rule you set for yourself after the first time somebody did not pay, and then you spend most of an evening on <<print _rq.label>>.</p> <<if _res === "crit_success">> <p>It comes out better than anything you have posted. <<print _rq.from>> tips on top of the fee and then posts about it publicly, which brings other people in behind them.</p> <<set _bonus = Math.round(_rq.pay * 0.5)>> <<set _gain = random(6, 14)>> <<set $jobs.fansOnly.subs = Math.min(500, $jobs.fansOnly.subs + _gain)>> <<payPlayer `_rq.pay + _bonus` "FansOnly commission">> <div class="alert alert--success">💰 $<<print _rq.pay>> + $<<print _bonus>> tip · +<<print _gain>> subscribers · rated <<print _score>>/5.0</div> <<elseif _res === "success">> <p>You deliver what was asked for and it is well received. <<print _rq.from>> says thank you, properly, in a way that suggests they were not certain you would actually do it.</p> <<set _gain = random(2, 6)>> <<set $jobs.fansOnly.subs = Math.min(500, $jobs.fansOnly.subs + _gain)>> <<payPlayer _rq.pay "FansOnly commission">> <div class="alert alert--success">💰 $<<print _rq.pay>> · +<<print _gain>> subscribers · rated <<print _score>>/5.0</div> <<elseif _res === "partial_fail">> <p>It is not quite what they had in mind. They are decent about it, "no worries, appreciate you trying", but they do not ask again for a while.</p> <<payPlayer `Math.round(_rq.pay * 0.5)` "FansOnly commission (partial)">> <div class="alert alert--warning">💰 $<<print Math.round(_rq.pay * 0.5)>>, half by mutual agreement · rated <<print _score>>/5.0</div> <<else>> <p>You misjudge the brief badly enough that refunding is the only reasonable thing to do, so you refund it. The evening is simply gone.</p> <<modStat "mood" -8 "Wasted an evening">> <div class="alert alert--danger">↩️ Refunded. Rated <<print _score>>/5.0.</div> <</if>> <<set $jobs.fansOnly.requestsFilled = ($jobs.fansOnly.requestsFilled || 0) + 1>> <<addXP "camSkill" 20>> <<modRep "camGirl" 2>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to dashboard</span>' "Job_FansOnly_Hub">><</link>> </div> <</if>>
<h2>🎬 Upload Recorded Encounter</h2> <<advanceTime 30>> <p>You edit together footage from a recent hookup. It's raw, authentic content, and your subscribers will love it.</p> <p><em>Note: The person in the video may or may not know they're being filmed...</em></p> <<set $jobs.fansOnly.posts++>> <<set $jobs.fansOnly.lastPostDay = $world.day>> <<set _gained = random(10, 25)>> <<set $jobs.fansOnly.subs = Math.min(500, $jobs.fansOnly.subs + _gained)>> <<modRep "camGirl" 5>> <<modRep "slut" 3>> <<run XCLC.Toast.show("📈 +" + _gained + " subs! They loved it.", "info")>> <<addXP "camSkill" 15>> /* Risk of content leak */ <<set _leak = random(1, 10) <= 2>> <<if _leak>> <p><em>⚠️ Someone shared a clip on campus forums. Your face is recognizable...</em></p> <<modRep "camGirl" 10>> <<modStat "stress" 10 "Content leaked">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to dashboard</span>' "Job_FansOnly_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 💃 STRIPPER: Candy Bar ═══════════════════════════════════════════════════ */
<h2>💃 Candy Bar: Dancer Application</h2> <p>The manager, a stocky man named Vince, looks you over with professional detachment. "Show me your moves."</p> <<canHireCheck>> <<if _canHire>> <<set _danceCheck = XCLC.Roll.doCheck("dance", 3)>> <<run XCLC.DicePopup.show()>> <<if _danceCheck === "crit_success" || _danceCheck === "success">> <p>"You'll do. Shifts are 7 to 2, four hours. Sixty base plus whatever you earn on stage and in privates. Back room access comes after you prove yourself."</p> <<hireJob "stripper">> <<else>> <p>"Not bad, but not Candy Bar material. Practice and come back." He turns away.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>💃 Stripper Shift</h2> <<advanceTime 240>> <<set $jobs.stripper.shifts++>> <<set _basePay = 60 + ($jobs.stripper.tier * 40)>> <p>You head backstage at the Candy Bar. The dressing room smells like hairspray and ambition. Time to work.</p> /* Phase 1: Stage performance */ <h3>🎭 Stage Set</h3> <<set _danceResult = XCLC.Roll.doCheck("dance", 4)>> <<run XCLC.DicePopup.show()>> <<if _danceResult === "crit_success">> <p>You own that stage. The pole work is flawless: inversions, spins, body rolls that make the crowd lose their minds. Dollar bills rain down.</p> <<set _stageTips = random(50, 80)>> <<modStat "confidence" 8 "Killed it on stage">> <<elseif _danceResult === "success">> <p>Solid set. Good moves, good energy. The crowd is into it. Decent tips.</p> <<set _stageTips = random(30, 50)>> <<else>> <p>You slip on the pole. The recovery is awkward. A few polite claps. The next girl takes the stage quickly.</p> <<set _stageTips = random(10, 20)>> <<modStat "confidence" -3 "Rough set">> <</if>> /* Phase 1b: Wearing something under the costume */ <<set _jewelPlug = XCLC.Toys.worn()>> <<set _jewelBonus = 0>> <<if _jewelPlug && _jewelPlug.tags.includes("jewelled")>> <h3>💎 The Detail</h3> <<set _plugRoll = XCLC.Roll.doCheck("dance", 4)>> <<if _plugRoll === "crit_success">> <p>You go into the floor work with your back to the room and take your time about it, and the moment the light catches the gem the noise from the rail changes register entirely. Somebody actually stands up. You do not rush the recovery. You hold the position, look back over your shoulder at the room with an expression of total innocence, and let them work it out for themselves.</p> <p>The bouncer tells you afterwards, with genuine professional respect, that he has not seen the front row spend like that since the Christmas party.</p> <<set _jewelBonus = random(90, 150)>> <<modStat "confidence" 10 "Stopped the room">> <<modRep "slut" 3>> <<addXP "dance" 15>> <<elseif _plugRoll === "success">> <p>You work the reveal in gradually, an angle here and a slow turn there, and let the gem do about a third of the work for you. By the third song there is a small cluster of regulars who have very obviously worked out what they are looking at and are competing to be the one who gets your attention about it.</p> <<set _jewelBonus = random(40, 80)>> <<modRep "slut" 2>> <<addXP "dance" 8>> <<else>> <p>Halfway through a floor spin you feel it shift, and then keep shifting, and there is a horrible four-second window in which you have to decide between the routine and the situation. You choose the situation, exit the stage early with what you hope reads as an artistic decision, and fix it in a toilet cubicle with your heart going like a bird.</p> <p>One of the other dancers is waiting by the mirrors when you come out. "Silicone base," she says, without looking up from her phone. "Not the cheap ones. They walk." It is the single most useful piece of professional advice you have received all semester.</p> <<set _jewelBonus = -20>> <<modStat "stress" 10 "Wardrobe malfunction">> <<modStat "confidence" -4 "Cut a set short">> <</if>> <</if>> /* Phase 2: Floor work: private dances */ <h3>💋 Floor Work</h3> <<set _privateDances = random(1, 3)>> <<set _privateTips = 0>> <<for _d = 0; _d < _privateDances; _d++>> <<set _clientNPC = XCLC.NPC.generate({gender: "male", type: "premium"})>> <<set _lapResult = XCLC.Roll.doCheck("dance", 4)>> <<if _lapResult === "crit_success" || _lapResult === "success">> <<set _privateTips += random(50, 80)>> <<else>> <<set _privateTips += 30>> <</if>> <</for>> <p>You gave <<print _privateDances>> private dance<<if _privateDances > 1>>s<</if>>.</p> /* Phase 3: Back room (if unlocked) */ <<set _backRoomEarnings = 0>> <<if $jobs.stripper.canBackRoom>> <<set _backRoom = random(1, 10) <= 4>> <<if _backRoom>> <p>A regular asks for the back room. "Whatever you're comfortable with, sweetheart."</p> <<set _backRoomEarnings = random(100, 200)>> <<modStat "arousal" 15 "Back room">> <<modRep "slut" 2>> <</if>> <</if>> /* Results */ <<set _totalTips = _stageTips + _privateTips + _backRoomEarnings + _jewelBonus>> <<set _total = _basePay + _totalTips>> <<set $jobs.stripper.tips += _totalTips>> <div class="card"> <div class="card__title">💰 Shift Results</div> <p><strong>Base pay:</strong> $<<print _basePay>></p> <p><strong>Stage tips:</strong> $<<print _stageTips>></p> <p><strong>Private dance tips:</strong> $<<print _privateTips>></p> <<if _backRoomEarnings > 0>><p><strong>Back room:</strong> $<<print _backRoomEarnings>></p><</if>> <<if _jewelBonus > 0>><p><strong>The gem:</strong> $<<print _jewelBonus>></p><<elseif _jewelBonus < 0>><p><strong>Cut a set short:</strong> −$<<print Math.abs(_jewelBonus)>></p><</if>> <p><strong>Total:</strong> $<<print _total>></p> </div> <<payPlayer _total "Stripper shift">> <<addXP "dance" 20>> <<addXP "charm" 10>> <<modRep "slut" 3>> <<modRep "camGirl" 1>> /* Progression */ <<if $jobs.stripper.shifts >= 25 && $jobs.stripper.tier < 2>> <<set $jobs.stripper.tier = 2>> <<run XCLC.Toast.show("👑 Headliner! Name on the marquee. $100 base pay.", "info")>> <<elseif $jobs.stripper.shifts >= 10 && $jobs.stripper.tier < 1>> <<set $jobs.stripper.tier = 1>> <<set $jobs.stripper.canBackRoom = true>> <<run XCLC.Toast.show("⭐ Featured Dancer! Back room access unlocked.", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "BarDistrict">><</link>> </div> /* ═══════════════════════════════════════════════════ 💋 HOOKER: Street Walking & Phone Clients With kink content: bondage, threesomes, gangbangs ═══════════════════════════════════════════════════ */
<h2>💋 The Street</h2> <p>Downtown. Past the restaurants, past the offices, to where the streetlights are dimmer and the cars slow down. You've seen the other girls here, leaning against lamp posts, tottering on heels.</p> <p>You could do this. It's just... standing on a corner. And then whatever comes next.</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">💋 Start walking</span>' "Job_Hooker_Street">> <<hireJob "hooker">> <</link>> <<link '<span class="choice-btn">🚫 Turn around</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>💋 Walking the Street</h2> <<set _period = XCLC.Time.getPeriod($world.time)>> <<if _period !== "night" && _period !== "late_night">> <p>The street is quiet. Nobody's looking for company at this hour.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "CampusMap">><</link>> </div> <<else>> <p>You stand under a flickering streetlight. Cars pass. Most don't stop. Then one does.</p> <<set _clientNPC = XCLC.NPC.generate({gender: "male", type: "premium"})>> <<set $temp.hookerClient = _clientNPC>> /* Determine client type */ <<set _clientType = random(1, 10)>> <<if _clientType <= 4>> <<set $temp.hookerService = "standard">> <<set $temp.hookerBasePay = random(50, 100)>> <p>A <<print _clientNPC.bodyType>> man in a sedan rolls down his window. "How much?"</p> <<elseif _clientType <= 6>> <<set $temp.hookerService = "kinky">> <<set $temp.hookerBasePay = random(100, 150)>> <p>A <<print _clientNPC.bodyType>> man in a nice car. Tinted windows. "I have... specific tastes. You open-minded?"</p> <<elseif _clientType <= 8>> <<set $temp.hookerService = "threesome">> <<set $temp.hookerBasePay = random(150, 250)>> <p>A car pulls up. Two people inside: <<set _threeType = random(1,10) <= 5 ? "MMF" : "FFM">><<set $temp.hookerThreeType = _threeType>><<if _threeType === "MMF">>two guys<<else>>a guy and a girl<</if>>. "We're looking for a third. <<print $temp.hookerBasePay>> bucks."</p> <<elseif _clientType === 9>> <<set $temp.hookerService = "bondage">> <<set $temp.hookerBasePay = random(120, 200)>> <p>A well-dressed man with leather gloves. "I want to tie you up. Nothing dangerous. <<print $temp.hookerBasePay>> dollars."</p> <<else>> <<set $temp.hookerService = "gangbang">> <<set $temp.hookerBasePay = random(200, 400)>> <<set $temp.hookerGangNum = random(3, 5)>> <p>A van pulls up. The side door slides open. <<print $temp.hookerGangNum>> guys inside. "$<<print $temp.hookerBasePay>> for all of us."</p> <</if>> /* Negotiate */ <<set _negResult = XCLC.Roll.doCheck("persuasion", 4)>> <<run XCLC.DicePopup.show()>> <<if _negResult === "crit_success" || _negResult === "success">> <<set $temp.hookerBasePay = Math.round($temp.hookerBasePay * 1.5)>> <p>You negotiate hard. "$<<print $temp.hookerBasePay>>, take it or leave it." He takes it.</p> <<else>> <p>He won't budge on price. $<<print $temp.hookerBasePay>>. Take it or leave it.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💋 Take the job</span>' "Job_Hooker_Service">><</link>> <<link '<span class="choice-btn">🚫 Pass</span>' "Job_Hooker_Street">> <<advanceTime 20>> <</link>> </div> <</if>>
<<advanceTime 45>> <<set $jobs.hooker.clients++>> <<set _service = $temp.hookerService>> <<set _pay = $temp.hookerBasePay>> <<if _service === "standard">> <h2>💋 Standard Client</h2> <<set _skill = ["oral", "vaginal"][random(0, 1)]>> <<set _result = XCLC.Roll.doCheck(_skill, 4)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>Quick, efficient, professional. He finishes, pays, and drives off. You're back on the corner in twenty minutes.</p> <<addXP _skill 15>> <<else>> <p>Awkward. He complains. Tips less than agreed. You pocket what you can.</p> <<set _pay = Math.round(_pay * 0.7)>> <<addXP _skill 8>> <</if>> <<elseif _service === "kinky">> <h2>💋 Kinky Client</h2> <p>He takes you to a hotel room. The bed has restraints. A collar. A blindfold.</p> <p>"Rules: safe word is 'red'. I tie you up. I use you. You let me."</p> <<set _result = XCLC.Roll.doCheck("composure", 5)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>You submit to the restraints. The collar clicks around your neck. He's rough but controlled. The blindfold heightens everything. When it's over, he unties you carefully. "$<<print _pay>>, as agreed." He leaves a tip on the nightstand.</p> <<set _pay += random(20, 50)>> <<modStat "arousal" 25 "Bondage session">> <<addXP "composure" 15>> <<addXP "stamina" 10>> <<else>> <p>You panic when the restraints tighten. "Red! RED!" He stops immediately, unties you. Professional, at least. But the mood is killed. He pays half.</p> <<set _pay = Math.round(_pay * 0.5)>> <<modStat "stress" 10 "Bondage panic">> <</if>> <<elseif _service === "threesome">> <h2>💋 Threesome: <<print $temp.hookerThreeType>></h2> <<if $temp.hookerThreeType === "MMF">> <p>A hotel room. Two men. One takes front, one takes back. It's intense, overwhelming, athletic.</p> <<set _result = XCLC.Roll.doCheck("stamina", 5)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>You handle both like a professional. They're impressed. Tips flow. "Anytime you want to work together again..."</p> <<addXP "stamina" 15>> <<addXP "oral" 10>> <<set _pay += random(50, 100)>> <<else>> <p>It's too much to manage. Coordination fails. One of them finishes too fast, the other gets bored. You get paid, at least.</p> <<addXP "stamina" 8>> <</if>> <<else>> <p>A couple. He watches while his girlfriend takes the lead. She's experienced, assertive. You follow her instructions.</p> <<set _result = XCLC.Roll.doCheck("oral", 4)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>The girlfriend guides your mouth between her thighs while he watches. Then you switch. It's surprisingly intimate. They tip generously.</p> <<addXP "oral" 15>> <<set _pay += random(30, 80)>> <<else>> <p>The chemistry isn't there. The girlfriend gets impatient. It ends quickly.</p> <<addXP "oral" 8>> <</if>> <</if>> <<modStat "arousal" 20 "Threesome">> <<elseif _service === "bondage">> <h2>💋 Bondage Session</h2> <p>Hotel room. Professional setup: silk ropes, a spreader bar, blindfold. He knows what he's doing.</p> <<set _result = XCLC.Roll.doCheck("composure", 5)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>You're tied spread-eagle on the bed. Blindfolded. He edges you for what feels like hours before finishing. It's terrifying and thrilling.</p> <<modStat "arousal" 30 "Bondage">> <<addXP "composure" 15>> <<set _pay += random(30, 60)>> <<else>> <p>You can't relax into the restraints. He cuts the session short. Still pays, but you can tell he's disappointed.</p> <<modStat "stress" 10 "Couldn't submit">> <<addXP "composure" 8>> <</if>> <<elseif _service === "gangbang">> <h2>💋 Gangbang: <<print $temp.hookerGangNum>> Guys</h2> <<set _numGuys = $temp.hookerGangNum>> <<set $temp.gangbangGuys = _numGuys>> <<set $temp.gangbangRound = 0>> <<set $temp.gangbangCompleted = 0>> <p>A dingy apartment. Mattress on the floor. <<print _numGuys>> men. This is the real deal.</p> /* Re-use the frat party gangbang flow but with hooker context */ <<set _result = XCLC.Roll.doCheck("stamina", 5 + Math.floor(_numGuys / 2))>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>You take every single one. It's brutal, exhausting, but you're still standing when it's done. They pay in full, plus extra. "She's a keeper."</p> <<addXP "stamina" 25>> <<addXP "oral" 10>> <<modStat "arousal" 40 "Gangbang">> <<set _pay += random(50, 100)>> <<else>> <p>You tap out after <<set _completed = random(1, _numGuys - 1)>><<print _completed>>. They grumble but pay a reduced rate.</p> <<set _pay = Math.round(_pay * (_completed / _numGuys))>> <<addXP "stamina" 15>> <<modStat "energy" -20 "Overwhelmed">> <</if>> <<modHygiene -40 "Gangbang">> <<modRep "slut" 8>> <</if>> /* === STD risk: street clients, no protection === */ <<if _service === "gangbang">> <<stdRisk "vaginal" `Math.max(2, $temp.hookerGangNum || 2)`>> <<elseif _service === "threesome">> <<stdRisk `($temp.hookerThreeType === "MMF" ? "anal" : "oral")` 2.5>> <<else>> <<stdRisk "vaginal" 2>> <</if>> /* === Arrest check === */ <<set _arrestChance = 10>> <<if _period === "late_night">><<set _arrestChance -= 3>><</if>> <<if $skills.charm.level >= 5>><<set _arrestChance -= 2>><</if>> <<set _arrested = random(1, 100) <= _arrestChance>> <<if _arrested>> <div class="alert alert--warning">🚔 <strong>BUSTED!</strong> An undercover cop. You're arrested.</div> <p>Handcuffs. Back of a squad car. A night in a holding cell. $200 fine.</p> <<set $jobs.hooker.arrested++>> <<set $finance.money = Math.max(0, $finance.money - 200)>> <<modRep "troublemaker" 10>> <<modStat "stress" 20 "Arrested">> <<set _pay = 0>> <<if $jobs.hooker.arrested >= 3>> <p><em>⚠️ Three arrests. A court date is coming...</em></p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">😞 Morning comes...</span>' "DormRoom">> <<set $world.time = 480>> <<advanceDay>> <</link>> </div> <<else>> <<if _pay > 0>><<payPlayer _pay "Escort work">><</if>> <<modRep "slut" 5>> <<addXP "charm" 5>> <<modHygiene -15 "Street work">> /* Phone unlock check */ <<if $jobs.hooker.clients >= 10 && !$jobs.hooker.phoneUnlocked>> <<set $jobs.hooker.phoneUnlocked = true>> <<run XCLC.Toast.show("📱 Word has spread. Phone clients now available!", "info")>> <</if>> <<if $jobs.hooker.clients >= 25 && $jobs.hooker.tier < 1>> <<set $jobs.hooker.tier = 1>> <<run XCLC.Toast.show("⭐ Known girl. Better pay, less danger.", "info")>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💋 Look for another client</span>' "Job_Hooker_Street">> <<advanceTime 15>> <</link>> <<link '<span class="choice-btn">🚪 Call it a night</span>' "CampusMap">><</link>> </div> <</if>>
<h2>📱 Phone Client</h2> <<set _clientNPC = XCLC.NPC.generate({gender: "male", type: "premium"})>> <<set _pay = random(100, 200) + ($jobs.hooker.tier * 50)>> <p>Your phone buzzes. A text from a private number: "Hotel Grand, Room 412. <<print _pay>> for the hour. Dress nice."</p> <p>Phone clients are classier: hotel rooms, better pay, lower risk.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏨 Go to the hotel</span>' "Job_Hooker_PhoneService">> <<set $temp.hookerBasePay = _pay>> <<advanceTime 30>> <</link>> <<link '<span class="choice-btn">🚫 Decline</span>' "JobBoard">><</link>> </div>
<h2>🏨 Hotel Room</h2> <<advanceTime 60>> <<set $jobs.hooker.clients++>> <<set _pay = $temp.hookerBasePay>> <p>The hotel room is nice: king bed, minibar, city views. The client is already there, drink in hand.</p> <<set _skill = ["oral", "vaginal"][random(0, 1)]>> <<set _result = XCLC.Roll.doCheck(_skill, 4)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>Professional. He's satisfied. Tips extra. "I'll call you again."</p> <<set _pay += random(30, 80)>> <<addXP _skill 15>> <<else>> <p>Functional. He pays, dresses, leaves. No tip.</p> <<addXP _skill 8>> <</if>> /* STD risk: vetted clients, slightly safer than the street */ <<stdRisk _skill 1.5>> /* Much lower arrest chance for phone clients */ <<set _arrested = random(1, 100) <= 3>> <<if _arrested>> <div class="alert alert--warning">🚔 <strong>Sting operation!</strong> Arrested at the hotel.</div> <<set $jobs.hooker.arrested++>> <<set $finance.money = Math.max(0, $finance.money - 200)>> <<modRep "troublemaker" 10>> <<set _pay = 0>> <div class="choice-group"> <<link '<span class="choice-btn">😞 Morning...</span>' "DormRoom">> <<set $world.time = 480>> <<advanceDay>> <</link>> </div> <<else>> <<payPlayer _pay "Phone escort">> <<modRep "slut" 3>> <<modHygiene -10 "Hotel encounter">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "CampusMap">><</link>> </div> <</if>> /* ═══════════════════════════════════════════════════ 🧪 DEALER: Campus Drug Trade ═══════════════════════════════════════════════════ */
<h2>🧪 Drug Dealing</h2> <p>You've been thinking about it. The margins are good. Buy wholesale, sell retail. Simple economics.</p> <p>But you'll need a supplier. Downtown, behind the abandoned laundromat, there's a guy named Marco. Everyone knows about Marco.</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">🧪 Meet Marco</span>' "Job_Dealer_Marco">> <<hireJob "dealer">> <<set $jobs.dealer.supplierUnlocked = true>> <</link>> <<link '<span class="choice-btn">🚫 Too risky</span>' "JobBoard">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div> <</if>>
<h2>🧪 Meeting the Supplier</h2> <<advanceTime 60>> <p>Behind the laundromat. Marco is a wiry man with gold teeth and dead eyes. He looks you up and down.</p> <p>"College girl wants to deal? Fine. I'll front you your first batch. After that, you pay upfront. Don't fuck me over."</p> <p>He hands you a bag. Your first stock.</p> <<set $jobs.dealer.stock.weed += 5>> <<set $jobs.dealer.stock.ecstasy += 3>> <<run XCLC.Toast.show("🧪 Got starting stock from Marco.", "info")>> <<modRep "troublemaker" 5>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Done</span>' "Job_Dealer_Hub">><</link>> </div>
<h2>🧪 Drug Dealing</h2> <p><strong>Heat Level:</strong> <<print $jobs.dealer.heatLevel>>/10 <<if $jobs.dealer.heatLevel >= 7>>⚠️ DANGER<<elseif $jobs.dealer.heatLevel >= 5>>⚠️ Warning<</if>></p> <div class="card"> <div class="card__title">📦 Current Stock</div> <p>🌿 Weed: <<print $jobs.dealer.stock.weed>> doses (sell @ $15)</p> <p>💊 Ecstasy: <<print $jobs.dealer.stock.ecstasy>> doses (sell @ $30)</p> <p>❄️ Cocaine: <<print $jobs.dealer.stock.cocaine>> doses (sell @ $50)</p> </div> <<divider "Actions">> <div class="choice-group"> <<if $jobs.dealer.stock.weed > 0 || $jobs.dealer.stock.ecstasy > 0 || $jobs.dealer.stock.cocaine > 0>> <<link '<span class="choice-btn">💰 Sell on campus</span>' "Job_Dealer_Sell">> <<set $temp.dealerLocation = "campus">> <<set $temp.dealerHeatMod = 1>> <</link>> <<link '<span class="choice-btn">🍸 Sell at bars/parties</span>' "Job_Dealer_Sell">> <<set $temp.dealerLocation = "bar">> <<set $temp.dealerHeatMod = 0.5>> <</link>> <</if>> <<link '<span class="choice-btn">📦 Restock from Marco</span>' "Job_Dealer_Restock">><</link>> <<divider "">> <<link '<span class="choice-btn">🔙 Back</span>' "JobBoard">><</link>> </div>
<h2>💰 Making a Sale</h2> <<advanceTime 20>> /* Find a buyer */ <<set _buyerChance = 50>> <<if $temp.dealerLocation === "bar">><<set _buyerChance = 70>><</if>> <<set _period = XCLC.Time.getPeriod($world.time)>> <<if _period === "night" || _period === "late_night">><<set _buyerChance += 20>><</if>> <<set _hasBuyer = random(1, 100) <= _buyerChance>> <<if !_hasBuyer>> <p>You hang around but nobody's buying. Waste of time.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Job_Dealer_Hub">><</link>> </div> <<else>> <p>Someone approaches. "You holding?"</p> /* What do they want? */ <<set _wants = random(1, 10)>> <<if _wants <= 5 && $jobs.dealer.stock.weed > 0>> <<set $temp.dealerDrug = "weed">> <<set $temp.dealerPrice = 15>> <p>"Got any weed?"</p> <<elseif _wants <= 8 && $jobs.dealer.stock.ecstasy > 0>> <<set $temp.dealerDrug = "ecstasy">> <<set $temp.dealerPrice = 30>> <p>"Got any pills?"</p> <<elseif $jobs.dealer.stock.cocaine > 0>> <<set $temp.dealerDrug = "cocaine">> <<set $temp.dealerPrice = 50>> <p>"Got any snow?"</p> <<else>> <p>They want something you don't have.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Job_Dealer_Hub">><</link>> </div> <<if true>><</if>> <</if>> <<if $temp.dealerDrug>> /* Negotiate */ <<set _negResult = XCLC.Roll.doCheck("persuasion", 3)>> <<run XCLC.DicePopup.show()>> <<if _negResult === "crit_success" || _negResult === "success">> <p>"$<<print $temp.dealerPrice>>, no haggling." They pay full price.</p> <<else>> <p>"Come on, cut me a deal." You sell at a discount.</p> <<set $temp.dealerPrice = Math.round($temp.dealerPrice * 0.7)>> <</if>> <<set $jobs.dealer.stock[$temp.dealerDrug]-->> <<set $jobs.dealer.earnings += $temp.dealerPrice>> <<payPlayer $temp.dealerPrice "Drug sale">> <<addXP "persuasion" 10>> /* Heat */ <<set $jobs.dealer.heatLevel = Math.min(10, $jobs.dealer.heatLevel + $temp.dealerHeatMod)>> <<modRep "troublemaker" 2>> /* Heat consequences */ <<if $jobs.dealer.heatLevel >= 7>> <<set _searched = random(1, 10) <= 4>> <<if _searched>> <div class="alert alert--warning">🚔 Campus security stops you. They search your bag!</div> <<if $jobs.dealer.stock.weed + $jobs.dealer.stock.ecstasy + $jobs.dealer.stock.cocaine > 0>> <p>They find your stash. All stock confiscated.</p> <<set $jobs.dealer.stock = {weed: 0, ecstasy: 0, cocaine: 0}>> <<modRep "troublemaker" 10>> <<modStat "stress" 20 "Caught dealing">> <<else>> <p>Nothing on you. They let you go with a warning.</p> <</if>> <</if>> <</if>> <<if $jobs.dealer.heatLevel >= 10>> <div class="alert alert--warning">🚨 <strong>ARRESTED!</strong> Your dealing days are over.</div> <<quitJob "dealer">> <<set $finance.money = Math.max(0, $finance.money - 500)>> <<modRep "troublemaker" 20>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💰 Sell more</span>' "Job_Dealer_Sell">><</link>> <<link '<span class="choice-btn">🔙 Done</span>' "Job_Dealer_Hub">><</link>> </div> <</if>> <</if>>
<h2>📦 Restocking from Marco</h2> <<advanceTime 40>> <p>You meet Marco in the usual spot. "What you need?"</p> <div class="choice-group"> <<if $finance.money >= 50>> <<link '<span class="choice-btn">🌿 5x Weed ($50)</span>' "Job_Dealer_Hub">> <<set $finance.money -= 50>> <<set $jobs.dealer.stock.weed += 5>> <<run XCLC.Toast.show("🌿 +5 weed", "info")>> <</link>> <</if>> <<if $finance.money >= 100>> <<link '<span class="choice-btn">💊 5x Ecstasy ($100)</span>' "Job_Dealer_Hub">> <<set $finance.money -= 100>> <<set $jobs.dealer.stock.ecstasy += 5>> <<run XCLC.Toast.show("💊 +5 ecstasy", "info")>> <</link>> <</if>> <<if $finance.money >= 150>> <<link '<span class="choice-btn">❄️ 5x Cocaine ($150)</span>' "Job_Dealer_Hub">> <<set $finance.money -= 150>> <<set $jobs.dealer.stock.cocaine += 5>> <<run XCLC.Toast.show("❄️ +5 cocaine", "info")>> <</link>> <</if>> <<if $finance.money < 50>> <p><em>You can't afford anything. Marco shakes his head.</em></p> <</if>> <<divider "">> <<link '<span class="choice-btn">🔙 Back</span>' "Job_Dealer_Hub">><</link>> </div>
<h2>💼 Aurelia Companions</h2> <<advanceTime 45>> <p>The agency operates out of a serviced office above a florist, which is either very good cover or no cover at all. The woman who interviews you is fiftyish, immaculate, and introduces herself only as Marguerite.</p> <p>"We are not the street," she says, in the tone of someone who has said it many times. "Clients are vetted. Names, cards, references. If one of them frightens you, you leave and we blacklist him. That is not a favour, it is the product. We take twenty percent and we earn it."</p> <p>She looks at you levelly. "You can refuse any booking, at any point, including in the room. If that is a problem for you, this is the wrong agency."</p> <<if $skills.charm.level < 2 && $jobs.hooker.clients < 5>> <p>She reviews your file and shakes her head, not unkindly. "Come back when you have a little more polish, or a little more experience. Either will do."</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "Downtown">><</link>> </div> <<else>> <p>She slides a phone across the desk. "The app. Bookings appear when they appear."</p> <div class="choice-group"> <<link '<span class="choice-btn">✍️ Sign with the agency</span>' "Downtown">> <<set $jobs.escort.active = true>> <<run XCLC.Toast.show("💼 Signed with Aurelia. Bookings appear in the Escort app on your phone.", "success", 6000)>> <</link>> <<link '<span class="choice-btn">🚫 Not for me</span>' "Downtown">><</link>> </div> <</if>>
<h2>💼 Aurelia: Bookings</h2> <<if !$jobs.escort.active>> <p>You are not with an agency.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> <<else>> <<set _period = XCLC.Time.getPeriod($world.time)>> <<if _period !== "evening" && _period !== "night" && _period !== "late_night">> <p>Nothing this early. Bookings come through from the evening onward.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> <<else>> <<if !$temp.escortOffers || $temp.escortOfferDay !== $world.day>> <<set $temp.escortOfferDay = $world.day>> <<set _pool = [ {name:"Mr. Halloway", tag:"Regular. Dinner first, always.", kind:"dinner", pay:180, vibe:"easy"}, {name:"Mr. Vance", tag:"Businessman, in town two nights.", kind:"standard", pay:220, vibe:"brisk"}, {name:"Mr. Ito", tag:"Wants company at an event, then back to his suite.", kind:"event", pay:300, vibe:"polished"}, {name:"Mr.ブラウン".replace("ブラウン","Brown"), tag:"New client. References check out.", kind:"standard", pay:200, vibe:"unknown"}, {name:"Mrs. Calloway", tag:"Discreet. Her husband travels.", kind:"standard", pay:260, vibe:"warm"}, {name:"Mr. Reyes", tag:"Asked for you by name.", kind:"standard", pay:240, vibe:"familiar"} ]>> <<set _n = random(2, 3)>> <<set _picked = []>> <<for _i = 0; _i < _n; _i++>> <<set _pick = _pool[random(0, _pool.length - 1)]>> <<if _picked.filter(function(p){ return p.name === _pick.name; }).length === 0>> <<run _picked.push(_pick)>> <</if>> <</for>> <<set $temp.escortOffers = _picked>> <</if>> <p style="opacity:0.75; font-size:0.9em;"><em>Agency takes 20%. You can decline anything, including once you are in the room.</em></p> <<for _o = 0; _o < $temp.escortOffers.length; _o++>> <<set _off = $temp.escortOffers[_o]>> <<capture _off>> <div class="card"> <div class="card__title"><<print _off.name>>: $<<print Math.round(_off.pay * 0.8)>> to you</div> <p style="opacity:0.8;"><<print _off.tag>></p> <<link '<span class="choice-btn">🏨 Accept the booking</span>' "Job_Escort_Service">> <<set $temp.escortClient = _off>> <</link>> </div> <</capture>> <</for>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> <</if>> <</if>>
<<set _c = $temp.escortClient || {name: "your booking", kind: "dinner", pay: 200}>> <h2>🏨 <<print _c.name>></h2> <<advanceTime 120>> <<set $jobs.escort.clients++>> <p>A hotel with a doorman who does not look at you twice. Room number by text, no lobby loitering. This is what the twenty percent buys.</p> <<if _c.kind === "dinner">> <p>Dinner first, as always with him. He talks about his daughter at another university, and then catches himself, and you both let it pass. The rest is unhurried and almost tender, and he pays in cash in an envelope like a man from another decade.</p> <<elseif _c.kind === "event">> <p>You are, for three hours, somebody's plus one at a fundraiser: a hand on an elbow, a laugh in the right place, a name you invent on the stairs and then stick to all evening. Then the lift, and his suite, and the part you are actually being paid for.</p> <<modRep "popular" 2>> <<addXP "charm" 15>> <<else>> <p>Efficient and civil. He offers you a drink, you decline, he does not push. Nobody pretends this is anything other than what it is, which is oddly restful.</p> <</if>> <<set _skill = ["oral", "vaginal"][random(0, 1)]>> <<set _result = XCLC.Roll.doCheck(_skill, 3)>> <<run XCLC.DicePopup.show()>> <<set _pay = Math.round(_c.pay * 0.8)>> <<if _result === "crit_success" || _result === "success">> <p>He is unmistakably pleased, and says so in the way clients do, by asking whether you take repeat bookings.</p> <<set _pay += random(20, 60)>> <<addXP _skill 18>> <<set $jobs.escort.agencyRep = Math.min(100, $jobs.escort.agencyRep + 4)>> <<else>> <p>Perfectly fine. Not memorable. He tips nothing and books nothing.</p> <<addXP _skill 9>> <</if>> <<stdRisk _skill `($temp.condomUsed ? 0.25 : 1)`>> <<if _skill === "vaginal">><<pregnancyRisk "unknown">><</if>> <<modHygiene -15 "Hotel booking">> <<modStat "energy" -20 "Booking">> <<modRep "slut" 3>> <<set $jobs.escort.earnings += _pay>> <<payPlayer `_pay` "Escort booking">> <<if $jobs.escort.agencyRep >= 40 && $jobs.escort.tier < 1>> <<set $jobs.escort.tier = 1>> <<run XCLC.Toast.show("⭐ Marguerite moves you up a tier. Better clients, better rates.", "success", 6000)>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">📱 Check for another booking</span>' "Phone_Escort">><</link>> <<link '<span class="choice-btn">🔙 Call it a night</span>' "CampusMap">><</link>> </div> /* ─── THE LANTERN (BROTHEL) ─────────────────────── */
<h2>🏮 The Lantern</h2> <<advanceTime 40>> <p>Two streets back from the main drag, behind a door with a red paper lantern and a camera above it. Inside it is warm, shabby-genteel and startlingly ordinary: a bar, a rota on the wall, somebody doing a crossword.</p> <p>The house manager is a broad woman called Dita who runs the place like a shift supervisor, which is essentially what she is.</p> <p>"Rules. You work the rota, you do not freelance out of my rooms. House takes forty. In exchange: Yuri is on the door all night, there is a panic button in every room, and if a client is a problem he is barred that same evening and does not come back." She shrugs. "Girls on the street get forty percent more per client and a beating twice a year. Your arithmetic."</p> <<canHireCheck>> <<if _canHire>> <div class="choice-group"> <<link '<span class="choice-btn">🏮 Take a spot on the rota</span>' "Downtown">> <<hireJob "brothel">> <<run XCLC.Toast.show("🏮 On the rota at The Lantern. Evening shifts.", "success", 6000)>> <</link>> <<link '<span class="choice-btn">🚫 Not for me</span>' "Downtown">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "Downtown">><</link>> </div> <</if>>
<h2>🏮 Shift at The Lantern</h2> <<advanceTime 240>> <<set $jobs.brothel.shifts++>> <<set _clients = random(2, 4)>> <<set _gross = 0>> <p>You take a room upstairs. Dita marks you on the board. Yuri nods at you from the door and goes back to his phone.</p> <p>It is, unexpectedly, a job. There is a rota and a kettle and someone complaining about their landlord in the next room over. Between clients you sit on the stairs and eat crisps.</p> <<for _cl = 0; _cl < _clients; _cl++>> <<set _skill = ["oral", "vaginal", "anal"][random(0, 2)]>> <<if _skill === "anal" && $skills.anal.level < 1>><<set _skill = "oral">><</if>> <<set _r = XCLC.Roll.doCheck(_skill, 3)>> <<set _base = 90 + ($jobs.brothel.tier * 25)>> <<if _r === "crit_success" || _r === "success">> <<set _gross += _base + random(10, 40)>> <<addXP _skill 12>> <<else>> <<set _gross += Math.round(_base * 0.7)>> <<addXP _skill 6>> <</if>> <<stdRisk _skill 1.2>> <<if _skill === "vaginal">><<pregnancyRisk "unknown">><</if>> <</for>> <<set _take = Math.round(_gross * 0.6)>> <<set _house = _gross - _take>> <p><<print _clients>> clients across the evening. One of them wanted to talk more than anything else, which happens more than you would think.</p> <<set _trouble = random(1, 100) <= 18>> <<if _trouble>> <div class="alert alert--info">🚪 One client got pushy about something you had already said no to. You pressed the button by the bed. Yuri had him on the pavement inside a minute, and Dita took his name off the book.</div> <<modStat "stress" 6 "Handled, but unpleasant">> <<set $jobs.brothel.houseRep = Math.min(100, $jobs.brothel.houseRep + 3)>> <</if>> <div class="card"> <div class="card__title">💰 Shift Complete</div> <p><strong>Clients:</strong> <<print _clients>></p> <p><strong>Gross:</strong> $<<print _gross>></p> <p><strong>House cut (40%):</strong> −$<<print _house>></p> <p><strong>Yours:</strong> $<<print _take>></p> </div> <<set $jobs.brothel.earnings += _take>> <<payPlayer `_take` "Lantern shift">> <<modHygiene -30 "Full shift">> <<modStat "energy" -35 "Full shift">> <<modRep "slut" 5>> <<set $jobs.brothel.houseRep = Math.min(100, $jobs.brothel.houseRep + 2)>> <<if $jobs.brothel.houseRep >= 30 && $jobs.brothel.tier < 1>> <<set $jobs.brothel.tier = 1>> <<run XCLC.Toast.show("⭐ Dita moves you to the better rooms. Higher rates.", "success", 6000)>> <<elseif $jobs.brothel.houseRep >= 70 && $jobs.brothel.tier < 2>> <<set $jobs.brothel.tier = 2>> <<run XCLC.Toast.show("⭐ You are one of the girls Dita phones first.", "success", 6000)>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Head home</span>' "CampusMap">><</link>> </div>
/* ═══════════════════════════════════════════════════ PREGNANCY SYSTEM Risk → Discovery → Choices → Progression Baby genetics based on player + father race ═══════════════════════════════════════════════════ */ /* ─── Pregnancy Risk Check ─── */ /* Called after unprotected internal encounters */ /* Usage: <<pregnancyRisk _npcRace>> */ <<widget "pregnancyRisk">> <<if !$pregnancy.isPregnant>> <<set _fatherRace = _args[0] || "white">> /* Track the risk event: shows the clinic warning, enables morning-after pill */ <<set $pregnancy.riskFlag = true>> <<set $pregnancy.riskDay = $world.day>> /* Base chance by Fertility side effect (level 0 still carries a small risk) */ <<set _fertLevel = $transformation.sideEffects.fertility || 0>> <<set _chances = [5, 15, 30, 55, 85]>> <<set _chance = _chances[_fertLevel] || 5>> /* Birth control blocks (unless Fertility lv4) */ <<if $transformation.addons.birthControl && _fertLevel < 4>> <<set _chance = 0>> <</if>> <<if ($health.birthControlActive || $inventory.onPill) && _fertLevel < 4>> <<set _chance = 0>> <</if>> <<if $inventory.hasIUD && _fertLevel < 4>> <<set _chance = 0>> <</if>> /* Roll: conception happens now; the player finds out via a test */ <<if _chance > 0 && random(1, 100) <= _chance>> <<set $pregnancy.isPregnant = true>> <<set $pregnancy.weeksPregnant = 0>> <<set $pregnancy.discovered = false>> <<set $pregnancy.confirmed = false>> <<set $pregnancy.fatherRace = _fatherRace>> <<set $pregnancy.fatherId = "">> <<set $pregnancy.roommateNoticed = false>> <<set $pregnancy.profNoticed = false>> /* Determined now, revealed later via ultrasound. Fertility widens BOTH the odds and the ceiling: lv0 twins only (3%) ... lv4 up to quintuplets. */ <<set _fMax = [2, 2, 3, 4, 5][_fertLevel] || 2>> <<set _fOdds = [3, 12, 22, 35, 50][_fertLevel] || 3>> <<set $pregnancy.babyCount = 1>> <<if random(1, 100) <= _fOdds>> <<set $pregnancy.babyCount = 2>> /* each further baby is progressively less likely */ <<for _extra = 3; _extra <= _fMax; _extra++>> <<if random(1, 100) <= Math.round(_fOdds / (_extra - 1))>> <<set $pregnancy.babyCount = _extra>> <</if>> <</for>> <</if>> <<set $pregnancy.babyGenders = []>> <<for _bi = 0; _bi < $pregnancy.babyCount; _bi++>> <<run $pregnancy.babyGenders.push(random(1, 2) === 1 ? "boy" : "girl")>> <</for>> <<set $pregnancy.totalPregnancies++>> <</if>> <</if>> <</widget>> /* ─── Pregnancy Weekly Progression ─── */ /* Called during weekly rollover */ <<widget "pregnancyProgress">> <<if $pregnancy.isPregnant>> <<set $pregnancy.weeksPregnant++>> /* Record the starting shape the first week we run */ <<if !$pregnancy.bodyChanges.breastStart>> <<set $pregnancy.bodyChanges.breastStart = $pc.breastSize>> <<set $pregnancy.bodyChanges.buttStart = $pc.buttSize>> <<set $pregnancy.bodyChanges.resolved = false>> <<set $pregnancy.bodyChanges.kept = false>> <</if>> <<pregnancyBody>> <<if $pregnancy.weeksPregnant === 2 && !$pregnancy.discovered>> /* Missed period hint */ <<run XCLC.Toast.show("🩸 You missed your period...", "warning")>> <<elseif $pregnancy.weeksPregnant === 4>> <<modStat "energy" -10 "Morning sickness">> <<if !$pregnancy.discovered>> <<run XCLC.Toast.show("🤢 You've been feeling nauseous every morning...", "warning")>> <</if>> <<elseif $pregnancy.weeksPregnant === 8>> <<modStat "energy" -5 "Pregnancy fatigue">> <<if $pregnancy.discovered>> <<run XCLC.Toast.show("🤰 You're starting to show.", "info")>> <</if>> <<elseif $pregnancy.weeksPregnant === 12>> <<modStat "energy" -10 "Pregnancy">> <<run XCLC.Toast.show("🤰 Your belly is clearly visible now. People notice.", "info")>> <<elseif $pregnancy.weeksPregnant === 30 && !$pregnancy.birthPlan>> <<run XCLC.Toast.show("🏥 Thirty weeks. The clinic wants to know where you plan to deliver.", "warning", 6000)>> <<elseif $pregnancy.weeksPregnant >= 36>> /* Birth event */ <<set $pregnancy.isPregnant = false>> <<goto "PregnancyBirth">> <</if>> <</if>> <</widget>> /* ─── Pregnancy Body Changes ─────────────────────────── Breasts fill out and hips widen as the pregnancy runs. Tracked as steps up their own ladders so the change can be reversed afterwards: the player decides which parts of it they keep. Separate from the weight system. ───────────────────────────────────────────────────── */ <<widget "pregnancyBody">> <<set _bc = $pregnancy.bodyChanges>> <<set _w = $pregnancy.weeksPregnant>> <<set _multi = ($pregnancy.babyCount || 1) > 1>> /* Breasts step up at 10 and 22 weeks; carrying more than one adds a third */ <<set _breastTarget = 0>> <<if _w >= 10>><<set _breastTarget = 1>><</if>> <<if _w >= 22>><<set _breastTarget = 2>><</if>> <<if _multi && _w >= 30>><<set _breastTarget = 3>><</if>> /* Hips widen later and less far */ <<set _buttTarget = 0>> <<if _w >= 16>><<set _buttTarget = 1>><</if>> <<if _w >= 28>><<set _buttTarget = 2>><</if>> <<if _breastTarget > _bc.breastSteps>> <<set _grown = XCLC.Body.step("breastSize", _breastTarget - _bc.breastSteps)>> <<set _bc.breastSteps = _breastTarget>> <<if _grown>> <<run XCLC.Toast.show("🤱 Nothing fits across the chest any more. You are a " + State.variables.pc.breastSize + " cup now.", "info", 6000)>> <</if>> <</if>> <<if _buttTarget > _bc.buttSteps>> <<set _widened = XCLC.Body.step("buttSize", _buttTarget - _bc.buttSteps)>> <<set _bc.buttSteps = _buttTarget>> <<if _widened>> <<run XCLC.Toast.show("🍑 Your hips have opened out. Two pairs of jeans have stopped being an option.", "info", 6000)>> <</if>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ PREGNANCY DISCOVERY ═══════════════════════════════════════════════════ */
<h2>🤰 Pregnancy Test</h2> <<if !$pregnancy.isPregnant>> <p>You stare at the stick. One line. <strong>Negative.</strong></p> <p><<toneThink "Thank god." "Relief washes over you." "Phew! Not this time.">></p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "DormRoom">><</link>> </div> <<else>> <<set $pregnancy.discovered = true>> <<set $pregnancy.confirmed = true>> <<set $pregnancy.confirmedDay = $world.day>> <<set $pregnancy.riskFlag = false>> <p>You stare at the stick. Two lines. <strong>Positive.</strong></p> /* History-aware reaction */ <<if $pregnancy.totalPregnancies === 1>> /* First pregnancy */ <p>Your hands are shaking. This cannot be happening. You're a <<if $pc.femininity < 34>>guy. Were a guy. Whatever this body is now, you are still a <</if>>college student. On a scholarship. And now this.</p> <p><<toneThink "No. No no no. This isn't real." "Oh god. This is actually happening." "Oh my god... I'm going to be a mom?">></p> <<elseif $pregnancy.totalPregnancies === 2>> /* Second pregnancy: the shock is gone; what replaces it depends on what you did last time */ <<if $pregnancy.children.length > 0>> <p>Again. You sit on the edge of the bath with the stick in your hand and listen to the sounds of the child you already have in the next room, and the arithmetic does itself without being asked. Nappies. Sleep. Two of them. Every hour of every day that you do not currently have.</p> <p><<toneThink "I cannot do this twice." "One was already more than I had. Now two." "Oh. A little brother or sister. 🩷">></p> <<elseif ($pregnancy.decisions || []).indexOf("abort") !== -1>> <p>Again. And this time there is no confusion about what the next few weeks look like. You know the waiting room, you know the form, you know exactly how the ceiling tiles are arranged. Familiarity turns out not to be the same thing as ease.</p> <p><<toneThink "I said never again and here I am." "At least I know the route this time." "Maybe this one is meant to happen.">></p> <<elseif ($pregnancy.decisions || []).indexOf("adopt") !== -1>> <p>Again. Somewhere out there is a child with your face who is somebody else's now, and here is another one starting up, and the two facts sit in your chest refusing to be looked at together.</p> <p><<toneThink "I gave one away. I am not doing that twice." "I do not know if I can hand another one over." "Maybe I keep this one.">></p> <<else>> <p>Pregnant again. You stare at the test with a numb familiarity that is somehow worse than the panic was.</p> <p><<toneThink "I need to be more careful." "This is becoming a pattern." "Well... life finds a way.">></p> <</if>> <<elseif $pregnancy.totalPregnancies === 3>> <p>Three. You do not sit down for this one. You check it standing at the sink on your way out, because there is a lecture at ten. Positive. You put it in the bin under a tissue and go to the lecture.</p> <p>Somewhere between the second one and this one, the test stopped being an event and became an errand. You notice that about yourself, briefly, on the stairs, and then you are late.</p> <p><<toneThink "Something has gone badly wrong with my life." "This is just the shape of things now." "Third time lucky, apparently. 🤷">></p> <<else>> /* Fourth and beyond */ <p>Positive. Number <<print $pregnancy.totalPregnancies>>. You look at it for about as long as it takes to read a bus timetable.</p> <p>The clinic has a file on you now, thick enough to have its own elastic band. The nurse who takes your details does not ask how you are feeling about it, which you appreciate, because you do not have an answer that would fit in the box.</p> <p><<toneThink "I do not recognise the person this is happening to." "I have stopped counting the way you stop counting drinks." "Honestly? I have made my peace with it.">></p> <</if>> /* A ledger of what came before: from the second pregnancy on */ <<if $pregnancy.totalPregnancies >= 2 && ($pregnancy.decisions || []).length + $pregnancy.children.length > 0>> <<set _abortCount = ($pregnancy.decisions || []).filter(function(d) { return d === "abort"; }).length>> <<set _adoptCount = ($pregnancy.decisions || []).filter(function(d) { return d === "adopt"; }).length>> <<set _keepCount = $pregnancy.children.length>> <div class="card"> <div class="card__title">📋 Before this one</div> <<if _abortCount > 0>><p><<print _abortCount>> termination<<if _abortCount > 1>>s<</if>>.</p><</if>> <<if _adoptCount > 0>><p><<print _adoptCount>> given up for adoption.</p><</if>> <<if _keepCount > 0>><p><<print _keepCount>> child<<if _keepCount > 1>>ren<</if>> you are raising.</p><</if>> </div> <</if>> <<divider "What do you do?">> <div class="choice-group"> <<link '<span class="choice-btn">🏥 Go to the health centre (abortion: $200)</span>' "PregnancyAbort">><</link>> <<link '<span class="choice-btn">🤰 Carry to term, then adopt</span>' "PregnancyCarry">> <<set $temp.pregnancyPlan = "adopt">> <</link>> <<link '<span class="choice-btn">👶 Carry to term, keep the baby</span>' "PregnancyCarry">> <<set $temp.pregnancyPlan = "keep">> <</link>> </div> <</if>>
<h2>🏥 Health Centre: Termination</h2> <<if $finance.money < 200>> <p>The receptionist checks the price. "$200." You check your wallet. You can't afford it.</p> <div class="choice-group"> <<link '<span class="choice-btn">😞 Leave</span>' "PregnancyTest">><</link>> </div> <<else>> <<set $finance.money -= 200>> <<set $pregnancy.isPregnant = false>> <<set $pregnancy.weeksPregnant = 0>> <<run ($pregnancy.decisions = $pregnancy.decisions || []).push("abort")>> <p>The procedure is quick and clinical. The nurse is kind. You lie on the bed staring at the ceiling tiles.</p> <<if $pregnancy.totalPregnancies === 1>> <p><<toneThink "It's done. I can move on." "That was... harder than I expected." "I feel empty. But also... relieved?">></p> <<else>> <p><<toneThink "Again. Done. Moving on." "Getting too familiar with this place." "I need to start being more careful.">></p> <</if>> <<modStat "stress" 15 "Abortion">> <<modStat "mood" -20 "Abortion">> <<advanceTime 120>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "CampusMap">><</link>> </div> <</if>>
<h2>🤰 Carrying to Term</h2> <<set _plan = $temp.pregnancyPlan || "adopt">> <<if _plan === "keep">> <p>You've decided to keep the baby. It won't be easy, between classes and the scholarship and the service obligations, but you will make it work somehow.</p> <<else>> <p>You'll carry to term and find a family for the baby. It's the hardest option emotionally, but maybe the most responsible.</p> <</if>> <p>For now, life continues. The programme doesn't stop for pregnancy.</p> <<modStat "stress" 10 "Pregnancy decision">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to campus</span>' "CampusMap">><</link>> </div>
/* Router: the delivery itself lives in 16a_birth_children.twee. Default to hospital if the player never chose a plan. */ <<if $pregnancy.birthPlan === "home">> <<goto "Birth_Home">> <<else>> <<goto "Birth_Hospital">> <</if>>
/* ─── Baby genetics: shared by both deliveries ─── */ <<widget "babyGenetics">> <<set _pRace = $pc.race || "white">> <<set _fRace = $pregnancy.fatherRace || "white">> <<set _looks = { "white_white": {skin: "fair", hair: "light brown", eyes: "blue"}, "white_black": {skin: "light brown", hair: "dark curly", eyes: "brown"}, "white_asian": {skin: "light olive", hair: "dark straight", eyes: "brown"}, "white_latina": {skin: "olive", hair: "dark brown", eyes: "hazel"}, "black_white": {skin: "light brown", hair: "dark curly", eyes: "brown"}, "black_black": {skin: "dark brown", hair: "black curly", eyes: "dark brown"}, "black_asian": {skin: "brown", hair: "dark wavy", eyes: "dark brown"}, "black_latina": {skin: "brown", hair: "dark curly", eyes: "brown"}, "asian_white": {skin: "light olive", hair: "dark straight", eyes: "brown"}, "asian_black": {skin: "brown", hair: "dark wavy", eyes: "dark brown"}, "asian_asian": {skin: "light", hair: "black straight", eyes: "dark brown"}, "asian_latina": {skin: "olive", hair: "dark straight", eyes: "brown"}, "latina_white": {skin: "olive", hair: "dark brown", eyes: "hazel"}, "latina_black": {skin: "brown", hair: "dark curly", eyes: "brown"}, "latina_asian": {skin: "olive", hair: "dark straight", eyes: "brown"}, "latina_latina": {skin: "olive", hair: "dark brown", eyes: "brown"} }>> <<set $temp.babyLook = _looks[_pRace + "_" + _fRace] || {skin: "fair", hair: "brown", eyes: "blue"}>> <<set $temp.babyCount = $pregnancy.babyCount || 1>> <<if !Array.isArray($pregnancy.babyGenders) || $pregnancy.babyGenders.length < $temp.babyCount>> <<set $pregnancy.babyGenders = []>> <<for _bg = 0; _bg < $temp.babyCount; _bg++>> <<run $pregnancy.babyGenders.push(random(1, 2) === 1 ? "boy" : "girl")>> <</for>> <</if>> <</widget>> /* ─── The card that describes them ─── */ <<widget "babyCard">> <<set _look = $temp.babyLook>> <<set _count = $temp.babyCount>> <div class="card"> <div class="card__title">👶 Your Bab<<if _count > 1>>ies<<else>>y<</if>></div> <<for _b = 0; _b < _count; _b++>> <p><<if _count > 1>><strong>Baby <<print _b + 1>>:</strong> <</if>>A healthy baby <strong><<print $pregnancy.babyGenders[_b]>></strong>.</p> <</for>> <p><strong>Skin:</strong> <<print _look.skin>></p> <p><strong>Hair:</strong> <<print _look.hair>></p> <p><strong>Eyes:</strong> <<print _look.eyes>></p> </div> <</widget>> /* ═══════════════════════════════════════════════════ 🗓️ BIRTH PLAN: chosen from week 30 ═══════════════════════════════════════════════════ */
<h2>🗓️ Where Are You Having This?</h2> <<if !$pregnancy.isPregnant>> <p>Not a decision you currently need to make.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "DormRoom">><</link>> </div> <<else>> <p>The midwife has a laminated sheet and a biro and the manner of someone who has had this conversation four thousand times. "Two options," she says. "Neither is wrong. I just need to know which, so we can plan for it."</p> <div class="card"> <div class="card__title">🏥 St Aldate's: the hospital</div> <p>Twenty minutes away by taxi. Obstetrician on site, theatre down the corridor, an epidural available the moment you ask for one. If anything goes sideways, it goes sideways in the safest building in the county.</p> <p><strong>Costs $400.</strong> The programme's insurance does not cover maternity, which the handbook mentions on page 61.</p> </div> <div class="card"> <div class="card__title">🏠 Hamilton Hall: your room</div> <p>A community midwife comes to you. Your own bed, your own things, nobody waking you at four in the morning to check a chart. No bill.</p> <p>Also: no theatre, no anaesthetist, and a twenty-minute transfer if you need one. <<if $roommate.name && $roommate.opinion >= 55>> <<print $roommate.name>> has already said she would be there, in a tone that did not leave much room for discussion. <<elseif $roommate.name>> You would be relying on <<print $roommate.name>>, and you are not certain how that would go. <<else>> You would be relying on yourself, largely. <</if>></p> </div> <div class="choice-group"> <<link '<span class="choice-btn">🏥 Hospital: book it</span>' "PregnancyBirthPlan_Set">> <<set $pregnancy.birthPlan = "hospital">> <</link>> <<link '<span class="choice-btn">🏠 Home birth: in the dorm</span>' "PregnancyBirthPlan_Set">> <<set $pregnancy.birthPlan = "home">> <</link>> <<link '<span class="choice-btn">🤷 Decide later</span>' "DormRoom">><</link>> </div> <</if>>
<h2>🗓️ Noted</h2> <<if $pregnancy.birthPlan === "hospital">> <p>She ticks the box and writes a number on the sheet. "Bag packed by thirty-four weeks. Taxi money somewhere you can find it at three in the morning, not in a bank app you have to log into."</p> <<run XCLC.Toast.show("🏥 Birth plan: hospital.", "info", 4000)>> <<else>> <p>She ticks the other box, and does not editorialise about it, which you had half expected. "Then we do it properly. Towels, plastic sheeting, a phone that is charged, and my number where somebody else can reach it as well as you."</p> <p>She looks around the room once, professionally. "It is a small room. That is fine. Most of them are."</p> <<run XCLC.Toast.show("🏠 Birth plan: home.", "info", 4000)>> <</if>> <p style="opacity:0.7;font-size:0.85em;"><em>You can change this at the clinic any time before you go into labour.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ 🏥 HOSPITAL DELIVERY ═══════════════════════════════════════════════════ */
<h2>🏥 St Aldate's</h2> <<advanceTime 480>> <<babyGenetics>> <<set _count = $temp.babyCount>> <p>Thirty-six weeks. It starts during <<showPeriod>>, and not dramatically: just a tightening that comes back, and comes back again, and the third time you look at the clock instead of ignoring it.</p> <<if $finance.money >= 400>> <<set $finance.money -= 400>> <p>The taxi costs eleven dollars and the hospital costs the rest. You hand over the card in a corridor while your body is doing something enormous and involuntary, which is a detail nobody warns you about.</p> <<else>> <p>You cannot pay for it up front, so they take your details and send the bill on, which is its own small dread filed for later.</p> <<set $finance.debt += 400>> <</if>> <p>The room is bright and warm and full of equipment, and the midwife who takes over from the last one calls you by your name every single time she speaks, which turns out to matter more than you would have guessed.</p> <p>It takes hours. It is the hardest physical thing you have ever done in either body. And then, quite suddenly, it is finished, and there is a sound in the room that was not there before.</p> <<if _count === 2>> <p><em>Twins. Even after the scan told you, some part of you did not believe it until right now. Two cries, one after the other.</em></p> <<elseif _count > 2>> <p><em><<print _count>> of them. The room fills with staff you did not know were waiting outside.</em></p> <</if>> <<babyCard>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "Birth_Aftermath">><</link>> </div> /* ═══════════════════════════════════════════════════ 🏠 HOME BIRTH ═══════════════════════════════════════════════════ */
<h2>🏠 Room 207</h2> <<advanceTime 480>> <<babyGenetics>> <<set _count = $temp.babyCount>> <<set _rmHelp = ($roommate.name && $roommate.opinion >= 55)>> /* Multiples at home are genuinely harder; so is doing it with nobody there */ <<set _dc = 3>> <<if _count > 1>><<set _dc = 5>><</if>> <<if !_rmHelp>><<set _dc = _dc + 1>><</if>> <<set _res = XCLC.Roll.doCheck("composure", _dc)>> <<run XCLC.DicePopup.show()>> <p>Thirty-six weeks. It starts in the evening, and because you knew this was the plan you do not panic. You text the number on the fridge and put the kettle on, which is an absurd thing to do and exactly what she told you to do.</p> <<if _rmHelp>> <p><<print $roommate.name>> is back within ten minutes of the message, still in her coat, holding a bag of things nobody asked her to buy. She does not make it about herself for one second of the next six hours. She holds your hand when it is useful and gets out of the way when it is not, and at some point around three in the morning she says "you are doing it, you are actually doing it" in a voice that cracks, and that is the bit you will remember.</p> <<else>> <p>The midwife arrives at half past nine with a canvas bag and an unhurried manner. It is the two of you and a desk lamp and a corridor that has gone quiet, and the strangeness of doing something this enormous in a room with a kettle in it does not wear off at any point.</p> <</if>> <<if _res === "crit_success">> <p>It goes beautifully. Not painlessly, because nothing about it is painless, but your body seems to know the sequence, and you stay ahead of it the whole way, breathing where you are told to breathe, pushing when it is time. The midwife says "textbook" twice and means it both times.</p> <p>And then there is a weight on your chest, in your own bed, in your own room, and no one comes to take it away to be weighed. You get to just lie there.</p> <<modStat "confidence" 12 "Did it yourself">> <<addXP "composure" 40>> <<elseif _res === "success">> <p>It is long and it is loud and at one point you swear at a poster on your own wall, but it works. She keeps a hand on you and a watch in her eye line and never once looks worried, and afterwards she says that first ones are usually harder than that.</p> <p>Nobody moves you anywhere. That is the whole point of it, and it turns out to be worth what it cost.</p> <<modStat "confidence" 7 "Did it yourself">> <<addXP "composure" 25>> <<elseif _res === "partial_fail">> <p>Halfway through, the midwife's manner changes. Still calm, but faster, and she starts explaining what she is doing before she does it, which she was not doing an hour ago. There is a stretch of about twenty minutes that you will not be able to describe afterwards.</p> <p>It resolves. It resolves in the room, without the ambulance she had already put on standby. But you both know it went closer to the line than either of you wanted, and she says so plainly afterwards rather than pretending otherwise.</p> <<modStat "stress" 15 "Frightening delivery">> <<modStat "health" -8 "Difficult birth">> <<else>> <p>It goes wrong quickly. She calls it early, and you will find out later exactly how early and be grateful for it, and the ambulance is at the back entrance of Hamilton Hall within nine minutes with its lights off, because she asked them for that.</p> <p>The rest of it happens at St Aldate's under a very bright light with a lot of people in the room, and it ends well, and it ends with a bill.</p> <<set $finance.debt += 600>> <<modStat "stress" 25 "Emergency transfer">> <<modStat "health" -18 "Complicated birth">> <div class="alert alert--danger">🚑 Emergency transfer. A $600 bill you did not plan for.</div> <</if>> <<if _count === 2>> <p><em>Twins, in a dorm room. The midwife has done it before. She tells you that afterwards, not during.</em></p> <<elseif _count > 2>> <p><em><<print _count>> of them, in a room that has one window and a kettle. There is not really a way to describe the last hour of that.</em></p> <</if>> <<babyCard>> <<if _rmHelp>> <p><<print $roommate.name>> falls asleep in the desk chair at some point after five, still upright, and you look at her for a while before you look at anything else.</p> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 12)>> <<set $roommate.trust = Math.min(100, $roommate.trust + 15)>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "Birth_Aftermath">><</link>> </div> /* ═══════════════════════════════════════════════════ AFTERMATH: keep or place, and what your body keeps ═══════════════════════════════════════════════════ */
<<set _count = $temp.babyCount>> <<set _look = $temp.babyLook>> <<set _plan = $temp.pregnancyPlan || "adopt">> <h2>👶 After</h2> <<if _plan === "keep">> <p>You hold <<if _count > 1>>them<<else>>your <<print $pregnancy.babyGenders[0]>><</if>> close. <<toneThink "What am I doing? I cannot raise a kid." "This is terrifying. And also, somehow, not only terrifying." "I love them so much already. 💕">></p> <<for _b = 0; _b < _count; _b++>> <<run $pregnancy.children.push({gender: $pregnancy.babyGenders[_b], skin: _look.skin, hair: _look.hair, eyes: _look.eyes, born: $world.day, semester: $world.semester})>> <<run $children.list.push({gender: $pregnancy.babyGenders[_b], skin: _look.skin, hair: _look.hair, eyes: _look.eyes, born: $world.day, semester: $world.semester, name: ""})>> <</for>> <<set $children.lastCareDay = $world.day>> <div class="alert alert--info">👶 You now have <<print $children.list.length>> child<<if $children.list.length > 1>>ren<</if>> to look after. They need care every day: see <strong>Look after the baby</strong> in your room, or enrol at the campus nursery.</div> <<else>> <p>The adoption counsellor arrives in the morning, and is kind in the particular flat way of someone who is kind at this for a living. You hold <<if _count > 1>>each of them<<else>>the baby<</if>> one last time. <<toneThink "It is better this way. I cannot be a parent." "Goodbye, little one." "I hope you have a good life. I am sorry.">></p> <<run ($pregnancy.decisions = $pregnancy.decisions || []).push("adopt")>> <<modStat "mood" -25 "Giving up baby">> <</if>> <<set $pregnancy.isPregnant = false>> <<set $pregnancy.weeksPregnant = 0>> <<set $pregnancy.birthPlan = "">> <<modStat "stress" 20 "Childbirth">> <<modStat "energy" -40 "Childbirth">> /* What the pregnancy left behind */ <<set _bc = $pregnancy.bodyChanges>> <<if (_bc.breastSteps > 0 || _bc.buttSteps > 0) && !_bc.resolved>> <div class="card"> <div class="card__title">🪞 Six Weeks Later</div> <p>The bump goes. Most of the rest of it does not, at least not on its own. You are carrying a <<print $pc.breastSize>> cup now where you started this at <<print _bc.breastStart>>, and your hips have gone from <<print _bc.buttStart>> to <<print $pc.buttSize>>.</p> <p>The clinic mentions, without pushing it either way, that there is a programme that will take you back toward where you started if that is what you want. Or you can leave it. Plenty of people leave it.</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">💗 Keep it: this is what you look like now</span>' "Birth_Body_Keep">><</link>> <<link '<span class="choice-btn">↩️ Take the programme: go back to how you were</span>' "Birth_Body_Revert">><</link>> </div> <<else>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Recovery</span>' "DormRoom">><</link>> </div> <</if>>
<<set _bc = $pregnancy.bodyChanges>> <<set _bc.resolved = true>> <<set _bc.kept = true>> <h2>💗 Kept</h2> <p>You do not take the leaflet. It is not a decision you agonise over in the end. The body did a large piece of work and this is what it looks like afterwards, and there is something faintly insulting about being offered the chance to undo the evidence.</p> <p>Half your wardrobe no longer fits. You will deal with that.</p> <<modStat "confidence" 8 "Comfortable in it">> <<modStat "femininity" 5 "This is your body now">> <div class="alert alert--success">💗 <<print $pc.breastSize>> cup · <<print $pc.buttSize>> hips. Permanent.</div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Recovery</span>' "DormRoom">><</link>> </div>
<<set _bc = $pregnancy.bodyChanges>> <<run XCLC.Body.step("breastSize", -_bc.breastSteps)>> <<run XCLC.Body.step("buttSize", -_bc.buttSteps)>> <<set _bc.resolved = true>> <<set _bc.kept = false>> <<set _bc.breastSteps = 0>> <<set _bc.buttSteps = 0>> <h2>↩️ Back</h2> <p>It takes eight weeks and a course of something the clinic hands over with a printed sheet of side effects, and at the end of it you are more or less the shape you were in September.</p> <p>You look at yourself in the mirror for a while afterwards trying to decide whether that is a relief, and settle on: mostly.</p> <div class="alert alert--info">↩️ Back to <<print $pc.breastSize>> cup · <<print $pc.buttSize>> hips.</div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Recovery</span>' "DormRoom">><</link>> </div>
<<widget "childrenDaily">> <<if $children.list.length > 0>> <<set _n = $children.list.length>> /* Nursery bills first: it covers the day automatically */ <<if $children.dayCare>> <<set _fee = 25 * _n>> <<if $finance.money >= _fee>> <<set $finance.money -= _fee>> <<set $children.lastCareDay = $world.day>> <<else>> <<set $children.dayCareOwed += _fee>> <<set $children.lastCareDay = $world.day>> <<if $children.dayCareOwed >= 150>> <<set $children.dayCare = false>> <<set $finance.debt += $children.dayCareOwed>> <<set $children.dayCareOwed = 0>> <<run XCLC.Toast.show("🚸 The nursery has suspended your place over unpaid fees.", "danger", 7000)>> <</if>> <</if>> <<elseif $world.day - $children.lastCareDay >= 2>> /* Two full days with nobody looking after them */ <<set $children.neglect++>> <<set $children.bond = Math.max(0, $children.bond - 4)>> <<modStat "stress" 8 "Guilt">> <<run XCLC.Toast.show("👶 Nobody has looked after them in days.", "danger", 6000)>> <<if $children.neglect === 3 || $children.neglect === 6>> <<goto "Children_Welfare">> <<elseif $children.neglect >= 9>> <<goto "Children_Removed">> <</if>> <</if>> <</if>> <</widget>> /* Small banner for the dorm room */ <<widget "childrenStatus">> <<if $children.list.length > 0>> <<set _n = $children.list.length>> <<set _since = $world.day - $children.lastCareDay>> <<if $children.dayCare>> <div class="alert alert--info">🚸 <<print _n>> child<<if _n > 1>>ren<</if>> at the campus nursery, $<<print 25 * _n>>/day.<<if $children.dayCareOwed > 0>> <strong>$<<print $children.dayCareOwed>> owed.</strong><</if>></div> <<elseif _since >= 1>> <div class="alert alert--warning">👶 <<print _n>> child<<if _n > 1>>ren<</if>>, not looked after <<if _since === 1>>today<<else>>for <<print _since>> days<</if>>.</div> <<else>> <div class="alert alert--success">👶 <<print _n>> child<<if _n > 1>>ren<</if>>, settled for today.</div> <</if>> <</if>> <</widget>>
<<set _n = $children.list.length>> <<if _n === 0>> <p>Nobody here to look after.</p> <div class="choice-group"><<link '<span class="choice-btn">🔙 Back</span>' "DormRoom">><</link>></div> <<else>> <<set _kid = $children.list[0]>> <<set _they = _n > 1 ? "they" : (_kid.gender === "boy" ? "he" : "she")>> <<set _theyC = _they.charAt(0).toUpperCase() + _they.slice(1)>> <<set _months = Math.floor(($world.day - _kid.born) / 30)>> <<advanceTime 180>> <<modStat "energy" `-(12 + _n * 6)` "Looking after a child">> <<set $children.lastCareDay = $world.day>> <<set $children.bond = Math.min(100, $children.bond + 6)>> <<set $children.neglect = Math.max(0, $children.neglect - 1)>> <h2>👶 Three Hours</h2> <<if _months < 1>> <p>Feeding, winding, changing, and then feeding again, because the interval between those two things is considerably shorter than anyone told you it would be. You get very good at doing everything one-handed. You develop strong opinions about brands of wipes.</p> <<elseif _months < 6>> <p><<print _theyC>> <<if _n > 1>>have<<else>>has<</if>> started grabbing at things and putting them in <<if _n > 1>>their<<else>>the<</if>> mouth with real commitment, so most of the afternoon goes on relocating objects to higher surfaces. Nothing you own is where it used to be. You have stopped minding.</p> <<else>> <p>An afternoon of the specific, unglamorous, entirely absorbing work of it. Food that mostly ends up somewhere other than the child, a nap that takes forty minutes to negotiate, and twenty minutes on the floor doing something that is not quite a game and not quite anything else.</p> <</if>> <<if $children.bond >= 60>> <p>Somewhere in the middle of it <<print _they>> <<if _n > 1>>settle<<else>>settles<</if>> against you and go<<if _n === 1>>es<</if>> heavy, and you sit very still for a good deal longer than you need to.</p> <<modStat "mood" 12 "Worth it">> <<modStat "stress" -10 "Worth it">> <<elseif $children.bond >= 25>> <p>It is exhausting and repetitive and you would not describe it as fun, and you would also not hand it to anyone else right now.</p> <<modStat "mood" 6 "Worth it">> <<modStat "stress" -4 "Time together">> <<else>> <p>You get through it. Three hours of your day gone, and a to-do list that has not moved. Whatever people mean when they call this rewarding has not turned up yet.</p> <<modStat "stress" 4 "Hard work">> <</if>> <<if $transformation.sideEffects.lactation >= 1>> <p>🍼 At least the feeding solves itself. That is one thing the X-Change did that has turned out to be straightforwardly useful.</p> <</if>> <div class="alert alert--info">💗 Bond: <<print $children.bond>>/100</div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to your room</span>' "DormRoom">><</link>> </div> <</if>>
<<set _n = $children.list.length>> <h2>🚸 Thornfield Campus Nursery</h2> <<if _n === 0>> <p>A bright room full of low furniture and other people's children. Not something you need.</p> <div class="choice-group"><<link '<span class="choice-btn">🔙 Back</span>' "CampusMap">><</link>></div> <<elseif $children.dayCare>> <p>You are enrolled. Eight until five, which is the only reason your timetable works at all.</p> <div class="alert alert--info">🚸 $<<print 25 * _n>> per day.<<if $children.dayCareOwed > 0>> <strong>$<<print $children.dayCareOwed>> currently owed.</strong><</if>></div> <div class="choice-group"> <<if $children.dayCareOwed > 0 && $finance.money >= $children.dayCareOwed>> <<link '<span class="choice-btn">💵 Settle what you owe</span>' "Children_Nursery">> <<set $finance.money -= $children.dayCareOwed>> <<set $children.dayCareOwed = 0>> <<run XCLC.Toast.show("🚸 Account cleared.", "success")>> <</link>> <</if>> <<link '<span class="choice-btn">🚫 Withdraw from the nursery</span>' "Children_Nursery">> <<set $children.dayCare = false>> <<run XCLC.Toast.show("🚸 Withdrawn. Care is on you now.", "warning", 5000)>> <</link>> <<link '<span class="choice-btn">🔙 Back</span>' "CampusMap">><</link>> </div> <<else>> <p>It is behind the sports centre, in a building that was something else first. The woman who runs it has the unbothered competence of someone who has seen every variety of student parent and formed no opinion about any of them.</p> <p>"Eight till five, term time. Twenty-five a day per child. And before you ask: no, we do not care how you got here."</p> <div class="alert alert--info">🚸 $<<print 25 * _n>> per day for <<print _n>> child<<if _n > 1>>ren<</if>>. Charged automatically. Fall far enough behind and the place is suspended.</div> <p>It is expensive. It is also the difference between attending your classes and not.</p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Enrol</span>' "Children_Nursery">> <<set $children.dayCare = true>> <<set $children.lastCareDay = $world.day>> <<run XCLC.Toast.show("🚸 Enrolled. Your days are yours again.", "success", 5000)>> <</link>> <<link '<span class="choice-btn">🔙 Not right now</span>' "CampusMap">><</link>> </div> <</if>>
<<set _n = $children.list.length>> <<set $children.welfareVisits++>> <h2>📋 A Visit</h2> <p>She is from the university's family support office and she has an appointment card you do not remember agreeing to. She is not unkind. She is, very obviously, taking notes.</p> <<if $children.welfareVisits === 1>> <p>"This is not a disciplinary thing," she says, twice, which is how you know it is at least adjacent to one. "Somebody flagged that <<if _n > 1>>children<<else>>a child<</if>> registered at this address <<if _n > 1>>have<<else>>has<</if>> not been seen at the nursery or the health centre for a while. I am here to establish that everything is fine."</p> <p>She looks around the room once. The room does not help your case.</p> <div class="alert alert--warning">⚠️ First visit logged. Look after them, or enrol at the nursery, before this happens again.</div> <<modStat "stress" 18 "Welfare visit">> <<else>> <p>The same woman. A different tone, still professional but noticeably cooler, and this time she reads the dates from the previous visit back to you before she says anything else.</p> <p>"I want to be direct, because I do not think vagueness helps anyone here. If there is a third of these, it stops being my department and becomes somebody else's. You do not want that and neither do I."</p> <div class="alert alert--danger">🚨 Second visit. One more and they are removed.</div> <<modStat "stress" 30 "Formal warning">> <<modStat "mood" -20 "Ashamed">> <</if>> <p>She leaves a leaflet about the nursery, a phone number, and the specific silence of someone who has decided not to say the other thing.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Close the door</span>' "DormRoom">><</link>> </div>
<<set _n = $children.list.length>> <<set $children.removed = $children.removed + _n>> <<set $children.list = []>> <<set $children.dayCare = false>> <<set $children.neglect = 0>> <<set $children.bond = 0>> <<run ($pregnancy.decisions = $pregnancy.decisions || []).push("removed")>> <h2>🚨 Taken Into Care</h2> <p>It happens on a Tuesday morning, which is somehow the detail that stays with you: that it was an ordinary morning, that there was a bus going past, that you had been about to make toast.</p> <p>There are three of them and a folder and a set of dates read out loud, and none of the dates are wrong. That is the part you cannot get past afterwards: there is nothing in the folder you can argue with.</p> <p>It is not framed as a punishment. It is framed, repeatedly and gently, as a temporary arrangement pending assessment. You are given a card with a name on it and told you can call any time.</p> <p>The room is very quiet by ten o'clock.</p> <div class="alert alert--danger">🚨 <<print _n>> child<<if _n > 1>>ren<</if>> removed into care.</div> <<modStat "mood" -45 "Children taken">> <<modStat "stress" 40 "Children taken">> <<modStat "willpower" -10 "Hollowed out">> <<modRep "troublemaker" 5>> <<if $roommate.name>> <p><<print $roommate.name>> comes back at four, stops in the doorway, and does not ask, because she has clearly worked it out from the missing cot. She sits down on the end of your bed and stays there for a long time without saying anything useful, which is the correct thing to do.</p> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 5)>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Sit down</span>' "DormRoom">><</link>> </div>
/* ═══════════════════════════════════════════════════ SEASONAL EVENTS: calendar-based campus events Triggered during weekly rollover by week number ═══════════════════════════════════════════════════ */ /* ─── Check for seasonal event ─── */ <<widget "checkSeasonalEvent">> <<set _sem = $world.semester>> <<set _week = $world.week>> <<set _isOddSem = (_sem % 2 === 1)>> <<if _isOddSem>> /* Fall semester */ <<if _week === 1>> <<set $temp.seasonalEvent = "freshmanWeek">> <<elseif _week === 5>> <<set $temp.seasonalEvent = "homecoming">> <<elseif _week === 8>> <<set $temp.seasonalEvent = "halloween">> <<elseif _week === 12>> <<set $temp.seasonalEvent = "thanksgiving">> <<elseif _week === 15>> <<set $temp.seasonalEvent = "winterFormal">> <</if>> <<else>> /* Spring semester */ <<if _week === 1>> <<set $temp.seasonalEvent = "newYears">> <<elseif _week === 6>> <<set $temp.seasonalEvent = "valentines">> <<elseif _week === 12>> <<set $temp.seasonalEvent = "springBreak">> <<elseif _week === 16>> <<set $temp.seasonalEvent = "endOfYear">> <</if>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ 🎉 FRESHMAN WEEK: Sem 1, Week 1 ═══════════════════════════════════════════════════ */
<h2><<yearVariant "🎉 Welcome Week!" "🎉 Welcome Back Week" "🎉 Welcome Back Week">></h2> <<yearVariant "<p>Welcome Week has taken the whole campus over: free t-shirts nobody will wear twice, pizza in flat cardboard stacks, and several thousand freshmen doing their best impression of people who know where they are going. There's an orientation mixer at the Student Center tonight.</p>" "<p>Welcome Week again, and this time you are on the other side of it. The same t-shirts, the same flat pizza, the same several thousand freshmen not knowing where anything is. You know exactly where everything is, which is its own quiet horror. There's a mixer at the Student Center tonight.</p>" "<p>Your third Welcome Week. You could run it at this point. The freshmen look impossibly young and one of them asks you for directions to a building you can see from where you are standing. There's a mixer at the Student Center tonight, and you have no illusions about what it is.</p>">> <<toneThink "Great. A party full of strangers while I'm stuck in this body." "I should try to meet some people." "Omg, my first college party! Well... my first as a girl.">> <div class="choice-group"> <<link '<span class="choice-btn">🎉 Go to the mixer</span>' "FreshmanWeek_Mixer">><</link>> <<link '<span class="choice-btn">🏠 Skip it, stay in the dorm</span>' "DormRoom">> <<modStat "mood" -5 "Skipped mixer">> <</link>> </div>
<h2>🎉 Freshman Mixer</h2> <<advanceTime 120>> <p>The Student Center is packed. Music, free drinks (non-alcoholic... officially), and a sea of nervous faces. You grab a cup of punch and survey the room.</p> <<set _event = random(1, 4)>> <<if _event === 1>> <p>A group of girls waves you over. "Come sit with us! Are you in Hamilton Hall too?" They're friendly, chatty, and completely oblivious to your situation.</p> <<modStat "mood" 10 "Made friends">> <<modRep "popular" 3>> <<elseif _event === 2>> <p>A cute upperclassman corners you near the snack table. "You're new, right? Let me give you the tour." His hand lingers on your lower back.</p> <<modStat "arousal" 10 "Flirting">> <<modRep "popular" 2>> <<elseif _event === 3>> <p>Someone spikes the punch. By the time you notice, you're already tipsy and dancing in a circle of laughing strangers.</p> <<modStat "mood" 15 "Surprise party">> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<else>> <p>You win a free campus hoodie in a raffle. It's way too big, but it's cozy. A small win.</p> <<modStat "mood" 5 "Free stuff">> <</if>> <<addXP "charm" 10>> <<modRep "popular" 3>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Head back</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ 🏟️ HOMECOMING: Sem 1, Week 5 ═══════════════════════════════════════════════════ */
<h2>🏟️ Homecoming Week!</h2> <<yearNote "Your <<yearOrdinal>> Homecoming. The bunting goes up in the same places every year.">> <p>Thornfield is decked out in school colours. Homecoming week means a parade, a football game, and the big dance on Saturday night.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏟️ Go to the football game</span>' "Homecoming_Game">><</link>> <<link '<span class="choice-btn">💃 Get ready for the dance</span>' "Homecoming_Dance">><</link>> <<link '<span class="choice-btn">🏠 Skip homecoming</span>' "CampusMap">> <<modStat "mood" -5 "Skipped homecoming">> <</link>> </div>
<h2>🏟️ Football Game</h2> <<advanceTime 180>> <p>The stadium is packed. Cheerleaders, marching band, face paint everywhere. The Wildcats score in the fourth quarter and the crowd goes insane.</p> <<modStat "mood" 15 "Homecoming game">> <<modRep "popular" 3>> <<if $jobs.cheerleader.active>> <p>You're front and center in your uniform. The crowd roars for you. This is YOUR moment.</p> <<modStat "confidence" 10 "Cheering at homecoming">> <<modRep "popular" 5>> <</if>> <<toneThink "Just a game. Whatever." "That was actually fun." "WILDCATS FOREVER! 🐾">> <div class="choice-group"> <<link '<span class="choice-btn">🎉 Go to the after-party</span>' "Homecoming_AfterParty">><</link>> <<link '<span class="choice-btn">🏠 Head home</span>' "DormRoom">><</link>> </div>
<h2>💃 Homecoming Dance</h2> <<advanceTime 180>> <p>The gymnasium has been transformed to within an inch of its life: fairy lights strung across the rafters, a DJ booth where the free throw line ought to be, and a sea of dresses and borrowed suits. You're in <<if $pc.makeupApplied>>full makeup and<</if>> the best thing you own.</p> <<set _beautyCheck = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _beautyCheck === "crit_success" || _beautyCheck === "success">> <p>You turn heads the moment you walk in. People stare. Someone whispers "who IS that?" You feel like a queen.</p> <<modStat "confidence" 15 "Belle of the ball">> <<modRep "popular" 5>> <<else>> <p>The dance is nice. Nothing spectacular. You hover near the punch bowl and sway to the music.</p> <<modStat "mood" 5 "Homecoming dance">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🎉 After-party!</span>' "Homecoming_AfterParty">><</link>> <<link '<span class="choice-btn">🏠 Go home</span>' "DormRoom">><</link>> </div>
<h2>🎉 Homecoming After-Party</h2> <<advanceTime 120>> <p>Sigma Phi's house is shaking with bass. Everyone from the game is here. Kegs, shots, and chaos.</p> <<set _drinkCheck = random(1, 10)>> <<if _drinkCheck <= 6>> <p>Someone hands you a drink. And then another. The night gets blurry.</p> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 2)>> <<set $substances.drinksToday += 3>> <</if>> <<modStat "mood" 10 "After-party">> <<modRep "partyGirl" 5>> <<modRep "popular" 3>> <<addXP "charm" 10>> <<toneThink "I'm too drunk for this." "This is actually a great night." "BEST. NIGHT. EVER! 🎉">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Stumble home</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ 🎃 HALLOWEEN: Sem 1, Week 8 ═══════════════════════════════════════════════════ */
<h2>🎃 Halloween!</h2> <<yearNote "You have a much clearer idea of what these parties are than you did last year.">> <p>Halloween at Thornfield. Every sorority and frat is throwing a costume party. The question is: what do you wear?</p> <div class="choice-group"> <<link '<span class="choice-btn">😇 Cute costume (angel/cat ears)</span>' "Halloween_Party">> <<set $temp.halloweenCostume = "cute">> <</link>> <<link '<span class="choice-btn">🔥 Slutty costume (nurse/devil/schoolgirl)</span>' "Halloween_Party">> <<set $temp.halloweenCostume = "slutty">> <</link>> <<link '<span class="choice-btn">🧟 Scary costume (zombie/witch)</span>' "Halloween_Party">> <<set $temp.halloweenCostume = "scary">> <</link>> <<link '<span class="choice-btn">🏠 Stay in</span>' "DormRoom">> <<modStat "mood" -5 "Skipped Halloween">> <</link>> </div>
<h2>🎃 Halloween Party: Greek Row</h2> <<advanceTime 180>> <p>Greek Row is a wall of noise and costumes. <<if $temp.halloweenCostume === "slutty">>Your costume leaves very little to the imagination. You feel exposed but powerful.<<elseif $temp.halloweenCostume === "cute">>Your costume is cute and knows it: ears, whiskers, a little tail that moves when you do.<<else>>Your zombie makeup is genuinely unsettling. People keep doing double takes.<</if>></p> /* Costume contest */ <<if $temp.halloweenCostume === "slutty">> <p>The sorority hosts a "Best Costume" contest. Given the... interpretation of "costume" tonight, it's really a hotness contest.</p> <<set _contestResult = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _contestResult === "crit_success" || _contestResult === "success">> <p>🏆 <strong>You WIN!</strong> The crowd cheers. First prize: $50 bar tab and a plastic crown. Photos are taken. You're the Halloween Queen.</p> <<payPlayer 50 "Costume contest">> <<modRep "popular" 8>> <<modRep "slut" 5>> <<modStat "confidence" 15 "Won costume contest">> <<else>> <p>You don't win, but you get plenty of attention. A few too many "accidental" touches in the crowd.</p> <<modRep "slut" 3>> <<modStat "arousal" 10 "Slutty costume attention">> <</if>> <<elseif $temp.halloweenCostume === "cute">> <p>Your costume gets a lot of "awww!" reactions. Guys offer to buy you drinks. You feel popular.</p> <<modRep "popular" 5>> <<modRep "sweetheart" 3>> <<else>> <p>Your costume scares a few people. One girl actually screams. You're equal parts proud and unsettling.</p> <<modRep "popular" 2>> <</if>> /* Haunted house hookup */ <<set _hauntEvent = random(1, 10)>> <<if _hauntEvent <= 3>> <p>Someone pulls you into the "haunted house" (really just a dark room with strobe lights). In the darkness, hands find you...</p> <<modStat "arousal" 20 "Dark room groping">> <<modRep "slut" 3>> <</if>> <<modStat "mood" 10 "Halloween party">> <<modRep "partyGirl" 5>> <<addXP "charm" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Head home</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ 🦃 THANKSGIVING: Sem 1, Week 12 ═══════════════════════════════════════════════════ */
<h2>🦃 Thanksgiving Break</h2> <p>Most students have gone home for the long weekend. The campus is eerily quiet. Dorms are half-empty. The cafeteria is serving sad turkey sandwiches.</p> <p><<toneThink "Can't exactly go home looking like this." "I don't have anywhere to go." "A quiet weekend might be nice, actually.">></p> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Stay on campus</span>' "Thanksgiving_StayOnCampus">><</link>> </div>
<h2>🦃 Thanksgiving on Campus</h2> <<advanceTime 240>> <p>You, your roommate (who also stayed), and a handful of other stragglers gather in the common room. Someone ordered pizza. It's quiet but oddly warm.</p> <<set _event = random(1, 4)>> <<if _event === 1>> <p>Your roommate opens up about her own family drama. You bond over shared loneliness. It's genuine.</p> <<modStat "mood" 15 "Bonding">> <<if $roommate>><<set $roommate.opinion = Math.min(100, $roommate.opinion + 10)>><</if>> <<elseif _event === 2>> <p>A campus-wide "friendsgiving" potluck materializes. Someone brought actual homemade pie. You feel weirdly grateful.</p> <<modStat "mood" 15 "Friendsgiving">> <<modRep "sweetheart" 3>> <<elseif _event === 3>> <p>The quiet campus is actually peaceful. You take a long walk. No catcalls, no obligations, just autumn leaves and silence.</p> <<modStat "stress" -15 "Peaceful break">> <<modStat "mood" 10 "Quiet time">> <<else>> <p>You binge-watch an entire season of trash TV with your roommate. Judgment-free zone.</p> <<modStat "mood" 10 "TV binge">> <<modStat "stress" -10 "Relaxing">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to routine</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ ❄️ WINTER FORMAL: Sem 1, Week 15 ═══════════════════════════════════════════════════ */
<h2>❄️ Winter Formal</h2> <<yearNote "You have done this before. The dress is different; the room is not.">> <p>The grand hall is draped in silver and white. Black tie, ballgowns, a live string quartet working through something tasteful in the corner. This is comfortably the fanciest night of the semester and everybody is slightly too aware of it.</p> <div class="choice-group"> <<link '<span class="choice-btn">👗 Go solo: dress to kill</span>' "WinterFormal_Dance">> <<set $temp.formalDate = "solo">> <</link>> <<link '<span class="choice-btn">🤵 Find a date</span>' "WinterFormal_Date">><</link>> <<link '<span class="choice-btn">🏠 Skip it</span>' "DormRoom">> <<modStat "mood" -5 "Skipped formal">> <</link>> </div>
<h2>🤵 Finding a Date</h2> <<set _charmCheck = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _charmCheck === "crit_success" || _charmCheck === "success">> <<set _dateNPC = XCLC.NPC.generate({gender: "male", type: "premium"})>> <p>You ask around and land a date: a <<print _dateNPC.bodyType>> <<print _dateNPC.race>> guy from your econ class who turns out to clean up considerably better than econ suggested.</p> <<set $temp.formalDate = "date">> <<else>> <p>Everyone's already paired up. Looks like you're going solo.</p> <<set $temp.formalDate = "solo">> <</if>> <<goto "WinterFormal_Dance">>
<h2>❄️ The Dance</h2> <<advanceTime 240>> <p>The hall is beautiful. Crystal chandeliers, candlelight, slow music. Everyone looks stunning. <<if $temp.formalDate === "date">>Your date offers his arm. You look good together.<<else>>You walk in alone. Heads turn anyway.<</if>></p> <<set _danceCheck = XCLC.Roll.doCheck("charm", 3)>> <<run XCLC.DicePopup.show()>> <<if _danceCheck === "crit_success" || _danceCheck === "success">> <p>The evening is magical. Slow dances, champagne, and <<if $temp.formalDate === "date">>his hand on your waist.<<else>>the attention of everyone in the room.<</if>> <<toneThink "This is... nice. Too nice. Don't get comfortable." "I feel beautiful tonight." "I'm like a princess! ✨">></p> <<modStat "mood" 20 "Magical evening">> <<modStat "confidence" 10 "Winter formal">> <<modRep "popular" 5>> <<modStat "femininity" 3 "Formal dress">> <<else>> <p>You step on your dance partner's feet twice. The champagne is good though.</p> <<modStat "mood" 5 "Decent evening">> <</if>> /* After-party */ <div class="choice-group"> <<if $temp.formalDate === "date">> <<link '<span class="choice-btn">🏨 Go back to his place</span>' "WinterFormal_HotelRoom">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Head home</span>' "DormRoom">><</link>> </div>
<h2>🏨 Hotel Room</h2> <<advanceTime 120>> <p>He booked a room at the Grand. Champagne on ice. City lights through the window. <<toneThink "Don't do this. You're not actually a girl." "One night won't change who I am." "This is SO romantic. I want this.">></p> <<set _result = XCLC.Roll.doCheck("charm", 3)>> <<run XCLC.DicePopup.show()>> <<if _result === "crit_success" || _result === "success">> <p>The night is intense, passionate. He's attentive, gentle. You lose yourself completely.</p> <<modStat "arousal" 30 "Romantic night">> <<modStat "femininity" 5 "Romantic surrender">> <<modStat "mood" 15 "Amazing night">> <<else>> <p>It's awkward. He's clumsy. You fake it. At least the bed is comfortable.</p> <<modStat "mood" 3 "Decent night">> <</if>> <<modHygiene -20 "Hotel room">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Morning...</span>' "DormRoom">> <<advanceDay>> <</link>> </div> /* ═══════════════════════════════════════════════════ 💘 VALENTINE'S DAY: Sem 2, Week 6 ═══════════════════════════════════════════════════ */
<h2>🎆 New Year's Eve</h2> <<yearNote "Another one. The years have started arriving faster than they used to.">> <p>Winter break is ending and campus is filling up again. Tonight the Student Center hosts the annual New Year's Eve countdown: string lights, a DJ, and enough contraband champagne to float a small boat.</p> <<toneThink "New year. Same body. Same contract." "A fresh start. Maybe this year I figure out who I actually am." "NEW YEAR'S PARTY!! New year, hotter me!! 🎉">> <div class="choice-group"> <<link '<span class="choice-btn">🎆 Go to the countdown party</span>' "NewYears_Party">><</link>> <<link '<span class="choice-btn">🏠 See the year out alone</span>' "DormRoom">> <<modStat "mood" -5 "Alone at midnight">> <<modStat "stress" -5 "Quiet night">> <</link>> </div>
<h2>🎆 The Countdown</h2> <<advanceTime 180>> <p>The Student Center is packed. Someone presses a plastic flute of champagne into your hand before you've even taken your coat off. Then another. It's that kind of night.</p> <<set $substances.drunkLevel = Math.max($substances.drunkLevel, 1)>> <<set $substances.drinksToday += 2>> <p><em>🍾 The champagne goes straight to your head. You're tipsy before eleven.</em></p> <<modStat "mood" 10 "Party atmosphere">> <<modRep "partyGirl" 3>> <p>The DJ cuts the music. "TEN! NINE! EIGHT!" The whole room counts it down. Someone catches your waist as the crowd compresses toward the middle of the floor. "THREE! TWO! ONE!"</p> <<divider "Midnight">> <p>🎆 The room erupts. Confetti. Noise. And suddenly everyone is kissing someone.</p> <<set _kissRoll = random(1, 3)>> <<if $roommate.name && XCLC.Roommate.isHome() === false && _kissRoll === 1>> <p><<print $roommate.name>> appears out of the crowd, cheeks flushed, and plants a champagne-sticky kiss right on your mouth. "HAPPY NEW YEAR, ROOMIE!" She's gone again before you can react.</p> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 5)>> <<modStat "femininity" 2 "Midnight kiss">> <<elseif _kissRoll <= 2>> <<set _kissNpc = XCLC.NPC.generate('student')>> <p>A <<print _kissNpc.bodyType>> <<if _kissNpc.gender === "male">>guy<<else>>girl<</if>> with <<print _kissNpc.hairColour>> hair turns to you, shrugs at you with a grin, says "tradition," and kisses you as the confetti comes down. It's brief and warm and tastes like cheap champagne.</p> <<modStat "arousal" 10 "Midnight kiss">> <<modStat "femininity" 2 "Midnight kiss">> <<modRep "popular" 2>> <<else>> <p>Nobody kisses you. You stand in the middle of a hundred kissing couples, holding your plastic flute. <<toneThink "Fine by me." "Well. That stings a little." "Umm?? RUDE. I'm adorable??">></p> <<modStat "mood" -3 "Unkissed at midnight">> <</if>> <<divider "New Year, New Me">> <p>Walking home through the cold, a little drunk, you make yourself a resolution. This year, you're going to work on...</p> <div class="choice-group"> <<link '<span class="choice-btn">💪 Confidence: own who you are (+8 Confidence)</span>' "DormRoom">> <<modStat "confidence" 8 "New Year resolution">> <<run XCLC.Toast.show("🎆 Resolution set: Confidence +8", "success")>> <</link>> <<link '<span class="choice-btn">🧠 Discipline: grades come first (+8 Willpower)</span>' "DormRoom">> <<modStat "willpower" 8 "New Year resolution">> <<run XCLC.Toast.show("🎆 Resolution set: Willpower +8", "success")>> <</link>> <<link '<span class="choice-btn">🧘 Balance: stress less, live more (-15 Stress)</span>' "DormRoom">> <<modStat "stress" -15 "New Year resolution">> <<run XCLC.Toast.show("🎆 Resolution set: Stress -15", "success")>> <</link>> </div>
<h2>💘 Valentine's Day</h2> <p>The campus is sickeningly pink. Heart-shaped everything. Couples everywhere. Someone left a rose on your door.</p> <<set _admirerEvent = random(1, 4)>> <<if _admirerEvent === 1>> <p>There's a card attached. "<em>I watch you in class. You're beautiful.<br>Your secret admirer.</em>"</p> <<toneThink "Creepy." "Flattering, I guess." "OMG A SECRET ADMIRER! 😍">> <<modStat "mood" 5 "Secret admirer">> <<elseif _admirerEvent === 2>> <p>A box of chocolates is on your desk with a note: "<em>To the hottest girl in Thornfield.</em>" No name.</p> <<modStat "mood" 8 "Chocolates">> <<elseif _admirerEvent === 3>> <p>Your phone buzzes. Three different guys sent you "Happy Valentine's" texts. <<toneThink "Kill me." "Popular, I guess." "So many valentines! 💕">></p> <<modStat "mood" 5 "Attention">> <<else>> <p>Nothing. No roses. No cards. No admirers. Just pink hearts mocking you from every surface.</p> <<modStat "mood" -10 "Lonely Valentine's">> <</if>> /* ─── The CCUMDUP Valentine's assignment ─── */ <<divider "📱 CampusHub">> <p>Your phone buzzes. A CampusHub notification, except this one is formatted differently. Gold border. Official seal.</p> <div class="alert alert--warning">💘 <strong>VALENTINE'S COUPLES PROGRAMME</strong><br>Per Section 12(c) of your agreement, you have been paired with a Premium Student for the full day. Companionship, affection, and services as requested. Compensation: <strong>3 service credits + $100 stipend</strong>. Declining incurs a rating penalty.</div> <div class="choice-group"> <<link '<span class="choice-btn">💘 Accept the assignment (full day)</span>' "Valentines_CouplesDay">><</link>> <<link '<span class="choice-btn">🚫 Decline (-0.3 rating)</span>' "Valentines_Declined">><</link>> </div>
<h2>💘 The Valentine's Assignment</h2> <<set _vnpc = XCLC.NPC.generate('daddy')>> <<set $temp.valentineNpc = _vnpc>> <<advanceTime 120>> <p>He's waiting outside your dorm at ten sharp, holding a single rose like he read a manual on it. <<print _vnpc.firstName>> <<print _vnpc.lastName>>. <<print XCLC.Service.describeNPC(_vnpc)>></p> <<if _vnpc.personality === "romantic">> <p>"I know what today is and I know what this is," he says, handing you the rose. "But I'd like to pretend otherwise, if that's alright with you."</p> <<elseif _vnpc.personality === "aggressive" || _vnpc.personality === "demanding">> <p>"Rules are: you smile, you hold my hand, you laugh at my jokes." He hands you the rose like a receipt. "The rest we'll get to tonight."</p> <<else>> <p>"This is a little weird for me too," he admits, offering the rose. "Brunch first? I figured we'd start easy."</p> <</if>> <p>Brunch. A walk across the frosted quad with his coat around your shoulders. A film where his hand finds yours somewhere in the second act and stays there. It is a strange kind of theatre, and by the middle of the afternoon you have caught yourself forgetting that it is theatre at all.</p> <<modStat "mood" 10 "Being courted">> <<modStat "femininity" 3 "A whole day as his girl">> <<divider "Evening">> <p>Dinner is somewhere with cloth napkins. Then his apartment. The rose goes in a glass of water, and his hands go everywhere else.</p> <<set _vOutcome = XCLC.Roll.doCheck("vaginal", 3)>> <<run XCLC.DicePopup.show()>> <<if _vOutcome === "crit_success" || _vOutcome === "success">> <p>It's unhurried and warm, and nothing whatsoever like a CampusHub booking in a bathroom stall with one eye on the clock. Afterwards he traces the length of your spine with one fingertip, slowly, and does not check his phone once.</p> <<modStat "mood" 10 "A genuinely good night">> <<addXP "vaginal" 20>> <<else>> <p>The spell of the day doesn't quite survive contact with the bedroom. It's awkward and slightly rushed and you are both plainly performing. Still. Not the worst Valentine's you have had.</p> <<addXP "vaginal" 10>> <</if>> <<pregnancyRisk `_vnpc.race`>> <<stdRisk "vaginal" 1>> <<run (function(){ var sv = State.variables; sv.scholarship.currentWeekServiced += 1; sv.scholarship.currentWeekCredits += 3; sv.scholarship.totalServiced += 1; sv.scholarship.totalCredits += 3; }())>> <<payPlayer 100 "Valentine's Couples Programme">> <<modHygiene -15 "Long day">> <<modStat "energy" -25 "Full-day assignment">> <<run XCLC.NPC.remember(State.temporary.vnpc)>> <<run XCLC.Toast.show("💘 Assignment complete: +3 credits, +$100 stipend", "success", 6000)>> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Home to bed</span>' "DormRoom">><</link>> </div>
<h2>💘 Declined</h2> <p>You dismiss the notification. Thirty seconds later, the confirmation arrives: <em>"Your withdrawal from the Couples Programme has been recorded and reflected in your rating."</em></p> <<applyServiceRating 3.0>> <<modStat "stress" 5 "Rating hit">> <p>The rest of Valentine's Day is yours. For whatever that's worth.</p> <div class="choice-group"> <<link '<span class="choice-btn">💘 Go to the Valentine\'s mixer</span>' "Valentines_Mixer">><</link>> <<link '<span class="choice-btn">🏠 Wallow alone</span>' "DormRoom">> <<modStat "mood" -5 "Alone on V-Day">> <</link>> </div>
<h2>💘 Valentine's Mixer</h2> <<advanceTime 120>> <p>The Student Center is hosting a "singles mixer." Speed dating, karaoke, and too much pink champagne.</p> <<set _charmCheck = XCLC.Roll.doCheck("charm", 3)>> <<run XCLC.DicePopup.show()>> <<if _charmCheck === "crit_success" || _charmCheck === "success">> <p>You charm your way through speed dating. Three numbers, two compliments, and one guy who won't stop staring. Good Valentine's Day.</p> <<modStat "mood" 15 "Valentine's mixer">> <<modStat "confidence" 8 "Desired">> <<modRep "popular" 3>> <<else>> <p>Speed dating is awkward. You run out of things to say. The champagne helps but not enough.</p> <<modStat "mood" 3 "Awkward mixer">> <</if>> <<modRep "popular" 2>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Head home</span>' "DormRoom">><</link>> </div> /* ═══════════════════════════════════════════════════ 🏖️ SPRING BREAK: Sem 2, Week 12 Redirects to full Playa Caliente in 17b_spring_break.twee ═══════════════════════════════════════════════════ */
<h2>🏖️ Spring Break!</h2> <<yearNote "You know what the bus is like now, and you have packed accordingly.">> <p>One week of freedom. No classes, no obligations, and CCUMDUP quota is paused for the duration once you're at the resort. The bus to Playa Caliente leaves in an hour.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏖️ Go to Playa Caliente!</span>' "PlayaCaliente_Hub">><</link>> <<link '<span class="choice-btn">🏠 Stay on campus and catch up</span>' "SpringBreak_Campus">><</link>> </div>
<h2>🏠 Spring Break on Campus</h2> <<advanceTime 480>> <p>The campus is a ghost town. But the quiet is nice. You catch up on sleep, studying, and self-care.</p> <<modStat "stress" -25 "Break rest">> <<modStat "mood" 10 "Quiet break">> <<modStat "energy" 30 "Rest">> <<addXP "studying" 20>> <<addXP "intelligence" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to routine</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 🎓 END OF YEAR PARTY: Sem 2, Week 16 ═══════════════════════════════════════════════════ */
<h2>🎓 End of Year Blowout!</h2> <<yearVariant "" "<p style=\"opacity:0.7;font-size:0.9em;\"><em>One year left after this one.</em></p>" "<p style=\"opacity:0.7;font-size:0.9em;\"><em>This is the last one. Whatever happens next, it does not happen here.</em></p>">> <p>The last day of the academic year. Every dorm, frat, and sorority is throwing something. The campus is a festival of chaos, nostalgia, and reckless abandon.</p> <div class="choice-group"> <<link '<span class="choice-btn">🎉 Hit ALL the parties</span>' "EndOfYear_PartyHop">><</link>> <<link '<span class="choice-btn">📸 Yearbook photos and chill</span>' "EndOfYear_Chill">><</link>> </div>
<h2>🎉 Party Hopping</h2> <<advanceTime 300>> <p>You hit five parties in one night. Each one wilder than the last. By party three, you've lost your shoes. By party five, you've lost your dignity.</p> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 3)>> <<set $substances.drinksToday += 5>> <<modStat "mood" 25 "Epic night">> <<modRep "partyGirl" 10>> <<modRep "popular" 5>> <<modStat "stress" -15 "Year end release">> <<toneThink "I survived. Barely." "What a year. What a night." "BEST YEAR EVER! I can't wait for next year! 🎉">> <p>You collapse into bed at dawn with a phone full of photos you don't remember taking.</p> <div class="choice-group"> <<link '<span class="choice-btn">😴 Pass out</span>' "DormRoom">> <<advanceDay>> <</link>> </div>
<h2>📸 Last Day Reflections</h2> <<advanceTime 180>> <p>Yearbook photos on the quad. You pose with classmates, your roommate, sorority sisters. Everyone's sentimental.</p> <p><<toneThink "One year down. Two to go. I can do this." "It hasn't been all bad. Some of it was... good?" "I'm going to miss everyone SO much! 😭 But we'll be back!">></p> <<modStat "mood" 15 "Nostalgia">> <<modRep "sweetheart" 3>> <<modRep "popular" 3>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 🔄 YEAR TRANSITION Fires between academic years. Before this the year rolled over with no acknowledgement at all. ═══════════════════════════════════════════════════ */
<h2>🔄 <<if $world.year === 2>>Summer, and then Year Two<<else>>Summer, and then Year Three<</if>></h2> <<if $world.year === 2>> <p>The dorms empty out over four days. You watch most of your floor leave with their parents carrying boxes, and then the building goes quiet in a way it has not been since you arrived.</p> <p>Summer is administratively simple and personally strange. The programme does not pause, exactly, but it thins out: fewer requests, longer gaps, whole afternoons with nothing scheduled and nobody expecting you anywhere. You get used to your own company again. You are not certain you like what you find there.</p> <p>In September the freshmen arrive and you recognise the look on all of them, because you wore it a year ago.</p> <<else>> <p>Your last summer before the last year. The maths of it keeps ambushing you in ordinary moments: two down, one to go, and then whatever comes after.</p> <p>You have stopped counting the encounters. That happened somewhere in the spring and you only noticed afterwards, which tells you more than the number would have.</p> <p>The campus in August is a different place, half-shuttered and enormous. You walk through it and it belongs to you in a way it never does in term time.</p> <</if>> <div class="card"> <div class="card__title">📈 Year <<print $world.year>> begins</div> <p><strong>Weekly quota:</strong> <<print $scholarship.weeklyQuota>> (was <<print Math.max(1, $scholarship.weeklyQuota - 1)>>). The programme expects more of you each year.</p> <p><strong>Rating:</strong> <<print $scholarship.rating.toFixed(1)>> · <strong>Total serviced:</strong> <<print $scholarship.totalServiced>></p> <<if $roommate.name && !$roommate.movedOut>> <p><strong><<print $roommate.name>></strong> is rooming with you again. <<if $world.year === 2>>Year two together.<<else>>Third year running.<</if>></p> <</if>> </div> <<if $roommate.name && !$roommate.movedOut>> <<if $roommate.isConfidant>> <p><<print $roommate.name>> is back before you are, and has already claimed the same bed. "I checked the housing form about four times," she says. "I was not rooming with a stranger this year."</p> <<elseif $roommate.opinion >= 60>> <p><<print $roommate.name>> texts you in August to ask whether you are rooming together again. You say yes faster than you meant to.</p> <<else>> <p>You and <<print $roommate.name>> end up in the same room again, less by choice than by neither of you filling in the form to change it. It works well enough.</p> <</if>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">📅 Start the year</span>' "DormRoom">><</link>> </div>
/* ═══════════════════════════════════════════════════ PLAYA CALIENTE: SPRING BREAK RESORT Self-contained sandbox hub. 10 locations. Triggers Sem 2, Weeks 12-13. CCUMDUP quota paused, voluntary service = 2× credits. ═══════════════════════════════════════════════════ */ /* ─── Init spring break state ─── */ <<widget "initSpringBreak">> <<if !$springBreak || !$springBreak.active>> <<set $springBreak = { active: true, day: 1, maxDays: 7, queenPoints: 0, contestsEntered: 0, contestsWon: 0, hookups: 0, drugsUsed: 0, photosPosted: 0, vipAccess: false, themedNight: "", massageSpecial: false, skinnyDipped: false, lastNightEvent: "" }>> <</if>> <</widget>> /* ─── Advance resort day ─── */ <<widget "advanceResortDay">> <<set $springBreak.day++>> <<advanceDay>> <<if $springBreak.day > $springBreak.maxDays>> <<goto "PlayaCaliente_Return">> <</if>> <</widget>> /* ─── Generate resort NPC ─── */ <<widget "genResortNPC">> <<set _rnpc = XCLC.NPC.generate({gender: _args[0] || "male", type: "resort"})>> <</widget>> /* ═══════════════════════════════════════════════════ 🏖️ RESORT HUB ═══════════════════════════════════════════════════ */
<<initSpringBreak>> <h2>🏖️ Playa Caliente: Day <<print $springBreak.day>> of <<print $springBreak.maxDays>></h2> <p><<if $springBreak.day === 1>>You step off the bus into a wall of heat, tequila fumes, and reggaeton. Playa Caliente Resort stretches out in front of you: turquoise pools, white sand, and several hundred barely dressed college students. This is spring break.<<else>>Another day in paradise. The sun is blazing, the bass is thumping, and the resort is alive with chaos.<</if>></p> <<set _timeOfDay = "morning">> <<if $world.time >= 720>><<set _timeOfDay = "afternoon">><</if>> <<if $world.time >= 1020>><<set _timeOfDay = "evening">><</if>> <<if $world.time >= 1260>><<set _timeOfDay = "night">><</if>> /* Themed night announcement */ <<if _timeOfDay === "evening" || _timeOfDay === "night">> <<set _nights = ["Foam Party 🫧", "Neon Party 🌈", "Lingerie Party 🩱", "Anything Goes 🔞"]>> <<set $springBreak.themedNight = _nights[($springBreak.day - 1) % _nights.length]>> <div class="alert alert--info">🌙 <strong>Tonight at Fuego:</strong> <<print $springBreak.themedNight>></div> <</if>> <<divider "Where to?">> <div class="choice-group"> <<link '<span class="choice-btn">🏨 Hotel Room</span>' "PlayaCaliente_Hotel">><</link>> <<if _timeOfDay === "morning" || _timeOfDay === "afternoon">> <<link '<span class="choice-btn">🏊 Pool Party</span>' "PlayaCaliente_Pool">><</link>> <<link '<span class="choice-btn">🏖️ Beach</span>' "PlayaCaliente_Beach">><</link>> <<link '<span class="choice-btn">🎤 Contest Stage</span>' "PlayaCaliente_Contest">><</link>> <<link '<span class="choice-btn">💆 Spa</span>' "PlayaCaliente_Spa">><</link>> <<link '<span class="choice-btn">🌮 Resort Town</span>' "PlayaCaliente_Town">><</link>> <</if>> <<link '<span class="choice-btn">🍹 Swim-Up Bar</span>' "PlayaCaliente_Bar">><</link>> <<if _timeOfDay === "evening" || _timeOfDay === "night">> <<link '<span class="choice-btn">🎶 Club Fuego</span>' "PlayaCaliente_Club">><</link>> <<link '<span class="choice-btn">🌊 Secluded Cove</span>' "PlayaCaliente_Cove">><</link>> <</if>> <<if $springBreak.vipAccess>> <<link '<span class="choice-btn">🥂 VIP Lounge</span>' "PlayaCaliente_VIP">><</link>> <</if>> </div> <<divider "">> <p class="stat-value" style="font-size:0.8em">👑 Queen Points: <<print $springBreak.queenPoints>> | 💋 Hookups: <<print $springBreak.hookups>> | 📸 Posts: <<print $springBreak.photosPosted>></p> /* ═══════════════════════════════════════════════════ 🏨 HOTEL ROOM ═══════════════════════════════════════════════════ */
<h2>🏨 Hotel Room</h2> <p>Your room on the 4th floor. Two queen beds (you're sharing with a girl from your dorm), a balcony overlooking the pool, and a minibar you've already raided.</p> <div class="choice-group"> <<link '<span class="choice-btn">😴 Sleep (next day)</span>' "PlayaCaliente_Hub">> <<advanceResortDay>> <<modStat "energy" 40 "Resort sleep">> <<modStat "stress" -10 "Vacation rest">> <</link>> <<link '<span class="choice-btn">🚿 Shower</span>' "PlayaCaliente_Hotel">> <<shower>> <</link>> <<link '<span class="choice-btn">📸 Post selfie to InstaGlam</span>' "PlayaCaliente_Hotel">> <<set $springBreak.photosPosted++>> <<set $springBreak.queenPoints += 2>> <<modRep "popular" 3>> <<run XCLC.Toast.show("📸 Spring break selfie posted! +3× followers!", "success")>> <</link>> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🏊 POOL PARTY ═══════════════════════════════════════════════════ */
<h2>🏊 Pool Party Area</h2> <<advanceTime 60>> <p>The pool is enormous, an infinity edge running out over the ocean. A DJ blasts music from a floating platform. Bikini-clad bodies everywhere. Someone's already doing body shots off the diving board.</p> <<genResortNPC "male">> <<set _poolEvent = random(1, 5)>> <<if _poolEvent === 1>> <p>A group of guys from State U challenge you to a chicken fight. <<toneThink "Hard pass." "Sure, why not." "Omg YES!">></p> <div class="choice-group"> <<link '<span class="choice-btn">🐔 Chicken fight!</span>' "PlayaCaliente_Pool_ChickenFight">><</link>> <<link '<span class="choice-btn">🏊 Just swim</span>' "PlayaCaliente_Pool_Chill">><</link>> </div> <<elseif _poolEvent === 2>> <p>"BODY SHOTS!" someone screams. A crowd forms around the pool bar. Tequila, salt, and bare stomachs.</p> <div class="choice-group"> <<link '<span class="choice-btn">🧂 Do body shots</span>' "PlayaCaliente_Pool_BodyShots">><</link>> <<link '<span class="choice-btn">🍹 Just watch</span>' "PlayaCaliente_Pool_Chill">><</link>> </div> <<elseif _poolEvent === 3>> <p>The pool DJ is running a dance competition on the pool deck. Winner gets a $100 bar tab.</p> <div class="choice-group"> <<link '<span class="choice-btn">💃 Enter the dance-off</span>' "PlayaCaliente_Pool_Dance">><</link>> <<link '<span class="choice-btn">🏊 Nah, just chill</span>' "PlayaCaliente_Pool_Chill">><</link>> </div> <<else>> <p>You find a lounger and settle in. Sun, music, and people-watching. This is what spring break is about.</p> <<goto "PlayaCaliente_Pool_Chill">> <</if>>
<h2>🐔 Chicken Fight!</h2> <<advanceTime 30>> <p>You climb onto a guy's shoulders. His hands grip your thighs. The other team charges.</p> <<set _fightResult = XCLC.Roll.doCheck("stamina", 4)>> <<run XCLC.DicePopup.show()>> <<if _fightResult === "crit_success" || _fightResult === "success">> <p>You DOMINATE. The other girl topples into the water. The crowd cheers. Your partner high-fives you, and his hand definitely lingers.</p> <<modStat "mood" 15 "Won chicken fight">> <<modStat "confidence" 5 "Pool victory">> <<set $springBreak.queenPoints += 3>> <<else>> <p>You go down hard, hitting the water with a graceless splash. Your bikini top... shifts. You surface to wolf-whistles and scramble to fix it.</p> <<modStat "arousal" 10 "Wardrobe malfunction">> <<modRep "slut" 2>> <<set $springBreak.queenPoints += 1>> <</if>> <<addXP "stamina" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to pool</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>🧂 Body Shots</h2> <<advanceTime 30>> <p>You lie back on the pool bar. Salt on your stomach, lime between your lips. A stranger's tongue trails up your abs, licks the salt, takes the shot, and bites the lime from your mouth. The crowd roars.</p> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<set $substances.drinksToday++>> <<modStat "arousal" 15 "Body shots">> <<modStat "mood" 10 "Party">> <<modRep "partyGirl" 3>> <<modRep "slut" 2>> <<set $springBreak.queenPoints += 2>> <<toneThink "I can't believe I just did that." "That was... intense." "That was SO hot. Next round!">>; <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>💃 Pool Deck Dance-Off</h2> <<advanceTime 30>> <<set _danceResult = XCLC.Roll.doCheck("dance", 4)>> <<run XCLC.DicePopup.show()>> <<if _danceResult === "crit_success" || _danceResult === "success">> <p>You OWN the dance floor. Hips, shoulders, drops. The crowd is chanting your name. First place! $100 bar tab is yours.</p> <<payPlayer 100 "Dance-off winner">> <<set $springBreak.queenPoints += 5>> <<modStat "confidence" 10 "Won dance-off">> <<modRep "popular" 5>> <<else>> <p>Your moves are... okay. You don't win but you don't embarrass yourself. Third place gets you a free drink.</p> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<set $springBreak.queenPoints += 1>> <</if>> <<addXP "dance" 15>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>🏊 Pool Chill</h2> <<advanceTime 60>> <p>You float in the pool, drink in hand, sun on your face. This is the life. <<toneThink "At least the resort is nice." "This is actually relaxing." "This is HEAVEN! ☀️">></p> <<modStat "stress" -10 "Pool relaxation">> <<modStat "mood" 5 "Chilling">> <<modHygiene -10 "Pool">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🏖️ BEACH ═══════════════════════════════════════════════════ */
<h2>🏖️ Beach</h2> <<advanceTime 60>> <p>White sand stretches forever. Volleyball nets, surfboards, and a suspicious number of guys with camera phones.</p> <<set _beachEvent = random(1, 4)>> <<if _beachEvent === 1>> <p>A volleyball game is forming up. They need one more player.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏐 Play volleyball</span>' "PlayaCaliente_Beach_Volleyball">><</link>> <<link '<span class="choice-btn">🏖️ Just tan</span>' "PlayaCaliente_Beach_Tan">><</link>> </div> <<elseif _beachEvent === 2>> <p>A group is playing a drinking game. Loser strips.</p> <div class="choice-group"> <<link '<span class="choice-btn">🍺 Join the game</span>' "PlayaCaliente_Beach_DrinkGame">><</link>> <<link '<span class="choice-btn">🏖️ Just tan</span>' "PlayaCaliente_Beach_Tan">><</link>> </div> <<else>> <p>It's a gorgeous day. Perfect for tanning.</p> <<goto "PlayaCaliente_Beach_Tan">> <</if>>
<h2>🏐 Beach Volleyball</h2> <<advanceTime 60>> <<set _vbResult = XCLC.Roll.doCheck("stamina", 3)>> <<run XCLC.DicePopup.show()>> <<if _vbResult === "crit_success" || _vbResult === "success">> <p>Your team wins! High fives, victory screams, and someone pours a beer over your head in celebration. You're drenched but grinning.</p> <<modStat "mood" 15 "Volleyball win">> <<set $springBreak.queenPoints += 3>> <<addXP "stamina" 15>> <<else>> <p>Your team loses. But you played hard and looked good doing it. A cute guy from the other team asks for your number.</p> <<modStat "mood" 5 "Good game">> <<set $springBreak.queenPoints += 1>> <<addXP "stamina" 10>> <</if>> <<modHygiene -15 "Beach sports">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>🍺 Strip Drinking Game</h2> <<advanceTime 60>> <p>It's Kings with a twist: every time you lose a round, something comes off. You start with 4 items.</p> <<set _rounds = 0>> <<set _stripped = 0>> <<for _r = 0; _r < 4; _r++>> <<if random(1, 6) <= 3>> <<set _stripped++>> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<set $substances.drinksToday++>> <</if>> <</for>> <<if _stripped >= 3>> <p>Three rounds in and you're down to your underwear. Everyone's cheering. The fourth round... you lose your top. The beach erupts.</p> <<modStat "arousal" 20 "Stripped on beach">> <<modRep "slut" 5>> <<modRep "partyGirl" 5>> <<set $springBreak.queenPoints += 5>> <<elseif _stripped >= 1>> <p>You lose a couple rounds but manage to keep the essentials on. Still, everyone saw more of you than you intended.</p> <<modStat "arousal" 10 "Partially stripped">> <<modRep "partyGirl" 3>> <<set $springBreak.queenPoints += 2>> <<else>> <p>Lady luck is on your side. You win every round. Everyone else is stripping while you sip your drink smugly.</p> <<modStat "confidence" 10 "Won strip game">> <<set $springBreak.queenPoints += 2>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>☀️ Tanning</h2> <<advanceTime 60>> <p>You lay out a towel and soak in the sun. The waves crash. The world is warm and lazy.</p> <<modStat "stress" -10 "Beach relaxation">> <<modStat "mood" 8 "Tanning">> <<set $pc.beautyBase = Math.min(60, $pc.beautyBase + 1)>> <<run XCLC.Beauty.recalculate()>> <<run XCLC.Toast.show("☀️ Got a nice tan! Beauty +1", "success")>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🍹 SWIM-UP BAR ═══════════════════════════════════════════════════ */
<h2>🍹 Swim-Up Bar</h2> <<advanceTime 30>> <p>The bar is literally in the pool. You wade up on a submerged stool, water lapping at your waist, and the bartender slides over a menu of catastrophically strong cocktails.</p> <div class="choice-group"> <<link '<span class="choice-btn">🍹 Order a cocktail (+1 drunk)</span>' "PlayaCaliente_Bar">> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<set $substances.drinksToday++>> <<modStat "mood" 5 "Resort drink">> <<payPlayer -15 "Cocktail">> <<run XCLC.Toast.show("🍹 Mmm, tropical!", "info")>> <</link>> <<link '<span class="choice-btn">🌿 Score some weed ($30)</span>' "PlayaCaliente_Bar">> <<if $finance.money >= 30>> <<payPlayer -30 "Resort weed">> <<set $substances.weed.high = true>> <<set $springBreak.drugsUsed++>> <<modStat "stress" -15 "Weed">> <<modStat "mood" 10 "High">> <<run XCLC.Toast.show("🌿 The resort stuff hits different.", "success")>> <<else>> <<run XCLC.Toast.show("💸 Can't afford it.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">💊 Score ecstasy ($50)</span>' "PlayaCaliente_Bar">> <<if $finance.money >= 50>> <<payPlayer -50 "Ecstasy">> <<set $substances.ecstasy.rolling = true>> <<set $springBreak.drugsUsed++>> <<modStat "mood" 30 "Rolling">> <<modStat "arousal" 25 "Ecstasy">> <<modStat "willpower" -20 "Ecstasy">> <<run XCLC.Toast.show("💊 Everything is beautiful.", "info")>> <<else>> <<run XCLC.Toast.show("💸 Can't afford it.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">💬 Flirt with someone</span>' "PlayaCaliente_Bar_Flirt">><</link>> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>💬 Bar Flirting</h2> <<advanceTime 30>> <<genResortNPC "male">> <p>A <<print _rnpc.bodyType>> <<print _rnpc.race>> guy with a tan and a confident grin leans against the bar next to you. "You here with anyone?"</p> <<set _flirtResult = XCLC.Roll.doCheck("charm", 3)>> <<run XCLC.DicePopup.show()>> <<if _flirtResult === "crit_success" || _flirtResult === "success">> <p>The chemistry is instant. Drinks, laughter, his hand on your knee under the water. <<toneThink "Don't let this get to me." "He's actually charming." "He's SO hot. Where has he been all week?">></p> <<modStat "arousal" 15 "Flirting">> <<modStat "mood" 10 "Chemistry">> <<set $springBreak.hookups++>> <<set $springBreak.queenPoints += 2>> <div class="choice-group"> <<link '<span class="choice-btn">🏨 Take him back to the hotel</span>' "PlayaCaliente_Hookup">><</link>> <<link '<span class="choice-btn">😘 Just flirt, nothing more</span>' "PlayaCaliente_Hub">><</link>> </div> <<else>> <p>He's nice but there's no spark. You chat politely and move on.</p> <<modStat "mood" 3 "Nice chat">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> <</if>>
<h2>🏨 Resort Hookup</h2> <<advanceTime 90>> <p>You stumble back to the hotel room together, barely making it through the door before his hands are everywhere. The balcony door is open, ocean breeze mixing with heavy breathing.</p> <<set _hookupResult = XCLC.Roll.doCheck("vaginal", 3)>> <<run XCLC.DicePopup.show()>> <<if _hookupResult === "crit_success" || _hookupResult === "success">> <p>It's passionate, intense, and over too quickly. He collapses next to you. "That was incredible." <<toneReact "Whatever." "It was... good." "AMAZING! 🔥">></p> <<modStat "mood" 15 "Good hookup">> <<modStat "arousal" -30 "Satisfaction">> <<addXP "vaginal" 15>> <<else>> <p>It's clumsy, rushed, and he finishes before you even get started. He passes out immediately. You stare at the ceiling.</p> <<modStat "mood" -5 "Disappointing">> <<modStat "arousal" 10 "Unfinished">> <<addXP "vaginal" 5>> <</if>> <<modHygiene -20 "Hookup">> <<modRep "slut" 3>> <<set $springBreak.hookups++>> /* Pregnancy risk: resort hookups are unprotected */ <<pregnancyRisk _rnpc.race>> <<stdRisk "vaginal" 1.5>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🎤 CONTEST STAGE ═══════════════════════════════════════════════════ */
<h2>🎤 Contest Stage</h2> <<advanceTime 30>> <p>The beachside stage is set up for today's competition. A crowd is already gathering. The MC grabs his mic.</p> <div class="choice-group"> <<link '<span class="choice-btn">💦 Wet T-Shirt Contest</span>' "PlayaCaliente_WetTshirt">><</link>> <<link '<span class="choice-btn">👙 Bikini Contest</span>' "PlayaCaliente_BikiniContest">><</link>> <<if $springBreak.day >= 5>> <<link '<span class="choice-btn">👑 Spring Break Queen Finals</span>' "PlayaCaliente_QueenFinals">><</link>> <</if>> <<link '<span class="choice-btn">👀 Just watch</span>' "PlayaCaliente_Hub">> <<modStat "mood" 3 "People watching">> <</link>> </div>
<h2>💦 Wet T-Shirt Contest</h2> <<advanceTime 60>> <<set $springBreak.contestsEntered++>> <p>You stand on stage in a white t-shirt. The MC counts down. "THREE... TWO... ONE..." Cold water hits you like a truck. The shirt turns transparent instantly. Hundreds of phones come out.</p> <<set _wtResult = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _wtResult === "crit_success" || _wtResult === "success">> <p>🏆 <strong>WINNER!</strong> The crowd is insane. You're drenched, exposed, and somehow triumphant. Prize: $200 and a bottle of champagne.</p> <<payPlayer 200 "Wet t-shirt winner">> <<set $springBreak.contestsWon++>> <<set $springBreak.queenPoints += 10>> <<modRep "slut" 5>> <<modRep "popular" 8>> <<modStat "confidence" 10 "Contest winner">> <<else>> <p>You don't win, but you put on a show. The crowd appreciated the effort. Participation prize: a free shot of tequila.</p> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<set $springBreak.queenPoints += 3>> <<modRep "slut" 3>> <<modRep "partyGirl" 2>> <</if>> <<modHygiene -10 "Soaked">> <<set $springBreak.photosPosted++>> <<addXP "charm" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>👙 Bikini Contest</h2> <<advanceTime 60>> <<set $springBreak.contestsEntered++>> <p>You strut across the stage in your swimwear. The MC narrates your "talents." The crowd cheers based on volume.</p> <<set _bikiniResult = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _bikiniResult === "crit_success" || _bikiniResult === "success">> <p>🏆 The crowd ROARS for you! You win by a landslide. $150 prize and a tiara.</p> <<payPlayer 150 "Bikini contest">> <<set $springBreak.contestsWon++>> <<set $springBreak.queenPoints += 8>> <<modRep "popular" 5>> <<modStat "confidence" 10 "Bikini queen">> <<else>> <p>You place in the middle. Not bad, not great. The winner had implants, which feels like cheating.</p> <<set $springBreak.queenPoints += 2>> <<modStat "mood" 3 "Decent showing">> <</if>> <<addXP "charm" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>👑 Spring Break Queen: FINALS</h2> <<advanceTime 120>> <p>The grand finale. All week's accumulated Queen Points determine who gets crowned Spring Break Queen of Playa Caliente.</p> <<if $springBreak.queenPoints >= 30>> <p>🏆👑 <strong>YOU WIN! YOU ARE THE SPRING BREAK QUEEN!</strong></p> <p>The tiara goes on your head. Champagne is sprayed. You're lifted onto shoulders. Photos everywhere. Your InstaGlam explodes with notifications.</p> <<modStat "confidence" 20 "Spring Break Queen">> <<modRep "popular" 15>> <<modStat "mood" 30 "Crowned queen">> <<modStat "femininity" 5 "Embraced fame">> <<awardAchievement "springBreakQueen">> <<elseif $springBreak.queenPoints >= 15>> <p>Runner-up. Close but not close enough. The winner is a blonde from USC who seemed to live at the contest stage. Still, second place gets you a sash and photos.</p> <<modStat "mood" 10 "Runner up">> <<modRep "popular" 5>> <<else>> <p>You didn't even make the top 5. Maybe next year. The crowd barely notices.</p> <<modStat "mood" -5 "Didn't place">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🎶 CLUB FUEGO + VIP ═══════════════════════════════════════════════════ */
<h2>🎶 Club Fuego: <<print $springBreak.themedNight>></h2> <<advanceTime 120>> <p>The club is massive. Three floors of pounding bass, laser lights, and writhing bodies. Tonight's theme: <<print $springBreak.themedNight>>.</p> <<if $springBreak.themedNight.indexOf("Foam") !== -1>> <p>Foam cannons blast from the ceiling. Within minutes you're covered in suds, sliding against strangers, unable to tell where one body ends and another begins.</p> <<modStat "arousal" 15 "Foam party">> <<modHygiene -15 "Foam">> <<elseif $springBreak.themedNight.indexOf("Neon") !== -1>> <p>UV paint stations at the entrance. You're covered in glowing patterns. Under the blacklights, the whole club is a psychedelic fever dream.</p> <<modStat "mood" 10 "Neon party">> <<elseif $springBreak.themedNight.indexOf("Lingerie") !== -1>> <p>Everyone's in their underwear. Or less. The dress code is "bedroom." You feel simultaneously exposed and powerful.</p> <<modStat "arousal" 20 "Lingerie party">> <<modRep "slut" 3>> <<else>> <p>"Anything Goes" means exactly what it sounds like. The back rooms are open. The VIP section is a free-for-all. Things are getting wild.</p> <<modStat "arousal" 25 "Anything goes">> <<modRep "slut" 5>> <</if>> <<modRep "partyGirl" 5>> <<set $springBreak.queenPoints += 3>> <<addXP "dance" 10>> <<addXP "charm" 5>> <div class="choice-group"> <<link '<span class="choice-btn">💃 Dance (build Queen points)</span>' "PlayaCaliente_Club">> <<set $springBreak.queenPoints += 2>> <<modStat "mood" 5 "Dancing">> <<advanceTime 60>> <</link>> <<if !$springBreak.vipAccess>> <<link '<span class="choice-btn">🥂 Try to get into VIP</span>' "PlayaCaliente_VIP_Check">><</link>> <<else>> <<link '<span class="choice-btn">🥂 VIP Lounge</span>' "PlayaCaliente_VIP">><</link>> <</if>> <<link '<span class="choice-btn">🌊 Sneak to the cove</span>' "PlayaCaliente_Cove">><</link>> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>🥂 VIP Bouncer</h2> <p>A massive bouncer blocks the velvet rope. "VIP only. You on the list?"</p> <<set _vipCheck = XCLC.Roll.doCheck("charm", 5)>> <<run XCLC.DicePopup.show()>> <<if _vipCheck === "crit_success" || _vipCheck === "success">> <p>You flash your best smile, lean in, and whisper something in his ear. He grins and unhooks the rope. "Go ahead, beautiful."</p> <<set $springBreak.vipAccess = true>> <<run XCLC.Toast.show("🥂 VIP access unlocked for the week!", "success")>> <<goto "PlayaCaliente_VIP">> <<else>> <p>"Sorry, sweetheart. List only." He doesn't budge. Maybe try again tomorrow, or find another way in.</p> <<modStat "mood" -5 "Rejected">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to the club</span>' "PlayaCaliente_Club">><</link>> </div> <</if>>
<h2>🥂 VIP Lounge</h2> <<advanceTime 60>> <p>Crystal chandeliers, champagne towers, and people who look like they own things. The VIP lounge is another world. Wealthy older men, trophy wives, and a few celebrities you half-recognise.</p> <<genResortNPC "male">> <p>A man in a tailored linen shirt watches you from across the lounge. Silver hair, expensive watch. He sends over a bottle of champagne with his card. <em>"Join me?"</em>, and underneath it a single initial: <em>R</em>.</p> <div class="choice-group"> <<link '<span class="choice-btn">🥂 Join him</span>' "PlayaCaliente_VIP_SugarDaddy">><</link>> <<link '<span class="choice-btn">🍾 Enjoy the champagne alone</span>' "PlayaCaliente_Hub">> <<set $substances.drunkLevel = Math.min(4, $substances.drunkLevel + 1)>> <<modStat "mood" 10 "Free champagne">> <</link>> </div>
<h2>🥂 The Wealthy Stranger</h2> <<advanceTime 60>> <p>"R" turns out to be a businessman from Miami. Charming, confident, and very generous. He orders another bottle. His hand finds your knee.</p> <p>"I have a suite upstairs. Penthouse. Want to see the view?"</p> <<toneThink "This is dangerous." "He's rich. And attractive. Why not?" "Omg he's like a real sugar daddy! 💎">> <div class="choice-group"> <<link '<span class="choice-btn">🏨 Go to his penthouse</span>' "PlayaCaliente_Hookup">> <<payPlayer 300 "Sugar daddy gift">> <<set $springBreak.queenPoints += 5>> <</link>> <<link '<span class="choice-btn">😘 Politely decline</span>' "PlayaCaliente_Hub">> <<modStat "confidence" 5 "Turned down sugar daddy">> <</link>> </div> /* ═══════════════════════════════════════════════════ 🌊 SECLUDED COVE ═══════════════════════════════════════════════════ */
<h2>🌊 Secluded Cove</h2> <<advanceTime 60>> <p>A hidden beach around the headland. Moonlight on dark water. The sounds of the resort fade to distant bass. It's private, romantic, and slightly dangerous.</p> <<set _coveEvent = random(1, 3)>> <<if _coveEvent === 1 && !$springBreak.skinnyDipped>> <p>A group of students is skinny dipping in the cove. They wave you over. "Come on! The water's perfect!"</p> <div class="choice-group"> <<link '<span class="choice-btn">🩱 Strip and swim!</span>' "PlayaCaliente_Cove_Skinny">><</link>> <<link '<span class="choice-btn">🔙 Not tonight</span>' "PlayaCaliente_Hub">><</link>> </div> <<elseif _coveEvent === 2>> <<genResortNPC "male">> <p>You find a couple making out in the shallows. They spot you and grin. "Want to join?" <<toneThink "No. Absolutely not." "...maybe?" "YES. 😏">></p> <div class="choice-group"> <<link '<span class="choice-btn">😏 Join them</span>' "PlayaCaliente_Cove_Threesome">><</link>> <<link '<span class="choice-btn">🔙 Leave them to it</span>' "PlayaCaliente_Hub">><</link>> </div> <<else>> <p>The cove is empty. Just you, the ocean, and the stars. Peaceful.</p> <<modStat "stress" -15 "Cove serenity">> <<modStat "mood" 10 "Stargazing">> <<toneThink "Quiet is good." "This is beautiful." "So romantic... wish someone was here with me. 💫">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> <</if>>
<h2>🌊 Skinny Dipping</h2> <<advanceTime 30>> <<set $springBreak.skinnyDipped = true>> <p>You strip down on the rocks. The moonlight catches your skin. You dive in. The water is warm silk. You're naked in the ocean with strangers and it feels... free.</p> <<modStat "arousal" 15 "Skinny dipping">> <<modStat "mood" 15 "Freedom">> <<modStat "femininity" 2 "Embracing body">> <<modRep "slut" 2>> <<set $springBreak.queenPoints += 3>> <<toneThink "This is insane. What am I doing?" "This is... actually amazing." "BEST. FEELING. EVER! 🌊">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Get dressed, head back</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>🌊 Cove Encounter</h2> <<advanceTime 60>> <p>The water is warm. Hands find you in the dark. What happens in the cove stays in the cove.</p> <<set _threesomeResult = XCLC.Roll.doCheck("vaginal", 3)>> <<run XCLC.DicePopup.show()>> <<if _threesomeResult === "crit_success" || _threesomeResult === "success">> <p>The three of you move together in the shallow waves. It's primal, beautiful, and absolutely unforgettable.</p> <<modStat "mood" 15 "Amazing encounter">> <<addXP "vaginal" 20>> <<else>> <p>It's awkward. Someone swallows seawater. You bang your knee on a rock. But it's still an experience.</p> <<addXP "vaginal" 10>> <</if>> <<modHygiene -25 "Beach sex">> <<modRep "slut" 5>> <<set $springBreak.hookups += 2>> <<set $springBreak.queenPoints += 5>> <<pregnancyRisk "unknown">> <<stdRisk "vaginal" 2>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 💆 SPA + 🌮 TOWN ═══════════════════════════════════════════════════ */
<h2>💆 Resort Spa</h2> <<advanceTime 60>> <p>Cool marble, eucalyptus steam, and the sound of whale music. The spa is an oasis of calm amid the chaos.</p> <div class="choice-group"> <<link '<span class="choice-btn">💆 Standard massage ($30)</span>' "PlayaCaliente_Spa">> <<if $finance.money >= 30>> <<payPlayer -30 "Spa massage">> <<modStat "stress" -25 "Massage">> <<modStat "mood" 10 "Relaxed">> <<set $pc.beautyBase = Math.min(60, $pc.beautyBase + 1)>> <<run XCLC.Beauty.recalculate()>> <<run XCLC.Toast.show("💆 So relaxing... Beauty +1", "success")>> <<advanceTime 60>> <<else>> <<run XCLC.Toast.show("💸 Can't afford it.", "warning")>> <</if>> <</link>> <<if !$springBreak.massageSpecial>> <<link '<span class="choice-btn">😏 "Special" massage ($80)</span>' "PlayaCaliente_Spa_Special">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>😏 The "Special" Massage</h2> <<advanceTime 90>> <<if $finance.money < 80>> <p>You can't afford the special treatment.</p> <<else>> <<payPlayer -80 "Special massage">> <<set $springBreak.massageSpecial = true>> <p>The masseuse closes the door and dims the lights further. "This is our... premium service." Warm oil, skilled hands, and the massage goes places a normal massage doesn't.</p> <<modStat "stress" -30 "Deep relaxation">> <<modStat "arousal" 25 "Special massage">> <<modStat "mood" 15 "Spa bliss">> <<toneThink "What is happening." "Okay, that's... good." "Oh my GOD this is incredible. 😳">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div>
<h2>🌮 Resort Town</h2> <<advanceTime 60>> <p>A dusty strip of colourful buildings outside the resort gates. Market stalls, a taco stand, a pharmacist, and a souvenir shop.</p> <div class="choice-group"> <<link '<span class="choice-btn">🌮 Eat tacos ($10, +energy)</span>' "PlayaCaliente_Town">> <<if $finance.money >= 10>> <<payPlayer -10 "Street tacos">> <<modStat "energy" 15 "Fed">> <<modStat "mood" 5 "Good food">> <<run XCLC.Toast.show("🌮 Amazing street tacos!", "success")>> <<else>> <<run XCLC.Toast.show("💸 Too broke for tacos.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">👙 Buy swimwear ($40)</span>' "PlayaCaliente_Town">> <<if $finance.money >= 40>> <<payPlayer -40 "New swimwear">> <<set $pc.beautyClothing = Math.min(20, $pc.beautyClothing + 5)>> <<run XCLC.Beauty.recalculate()>> <<run XCLC.Toast.show("👙 New bikini! Beauty +5", "success")>> <<else>> <<run XCLC.Toast.show("💸 Can't afford it.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">💊 Farmacia: morning-after pill ($25)</span>' "PlayaCaliente_Town">> <<if $finance.money >= 25>> <<payPlayer -25 "Morning after pill">> <<if $pregnancy.isPregnant && $pregnancy.weeksPregnant === 0>> <<set $pregnancy.isPregnant = false>> <<run XCLC.Toast.show("💊 Taken. Crisis averted.", "success")>> <<else>> <<run XCLC.Toast.show("💊 Taken, just in case.", "info")>> <</if>> <<else>> <<run XCLC.Toast.show("💸 Can't afford it.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">🛍️ Buy souvenirs ($20)</span>' "PlayaCaliente_Town">> <<if $finance.money >= 20>> <<payPlayer -20 "Souvenirs">> <<modStat "mood" 5 "Souvenirs">> <<run XCLC.Toast.show("🛍️ Tacky fridge magnets acquired!", "success")>> <<else>> <<run XCLC.Toast.show("💸 Can't afford it.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">🔙 Back to resort</span>' "PlayaCaliente_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🔙 RETURN TO CAMPUS ═══════════════════════════════════════════════════ */
<h2>🔙 Back to Campus</h2> <<set $springBreak.active = false>> <p>The bus back to Thornfield is quiet. Everyone's sunburnt, hungover, and carrying way too many souvenirs. You stare out the window, replaying the week in your head.</p> <div class="card"> <div class="card__title">🏖️ Spring Break Recap</div> <p><strong>Days at resort:</strong> <<print $springBreak.maxDays>></p> <p><strong>👑 Queen Points:</strong> <<print $springBreak.queenPoints>></p> <p><strong>💋 Hookups:</strong> <<print $springBreak.hookups>></p> <p><strong>🏆 Contests entered:</strong> <<print $springBreak.contestsEntered>> (won <<print $springBreak.contestsWon>>)</p> <p><strong>📸 Photos posted:</strong> <<print $springBreak.photosPosted>></p> <<if $springBreak.drugsUsed > 0>><p><strong>💊 Substances used:</strong> <<print $springBreak.drugsUsed>> times</p><</if>> <<if $springBreak.skinnyDipped>><p>🌊 <em>Went skinny dipping!</em></p><</if>> <<if $springBreak.vipAccess>><p>🥂 <em>Got VIP access!</em></p><</if>> <<if $springBreak.massageSpecial>><p>💆 <em>Had the "special" massage...</em></p><</if>> </div> <<toneThink "Survived. Back to the grind." "That was actually... fun. Back to reality." "Best week EVER. I'm already planning next year! 🏖️">> <<modRep "partyGirl" 5>> <div class="choice-group"> <<link '<span class="choice-btn">🗺️ Back to Campus</span>' "CampusMap">><</link>> </div>
<h2>🎓 Graduation Day</h2> <p>Three years. Six semesters. Countless encounters, classes, parties, and transformations. You stand in the back row of the graduation ceremony in a cap and gown, heart pounding.</p> <p>Dean Harrison calls your name. "<<print $pc.firstName>> <<print $pc.lastName>>." You walk across the stage. The crowd applauds. Your roommate whistles from the front row.</p> <p>It's over. The CCUMDUP programme is complete. You have your degree. And you have... a very different life than you started with.</p> /* Calculate dominant path */ <<set _path = "ordinary">> <<set _maxRep = 0>> /* Scholar */ <<if $reputation.goodStudent >= 60 && $pc.intelligence >= 60>> <<set _path = "scholar">> <</if>> /* Embraced */ <<if $pc.femininity >= 80 && $pc.mood >= 50>> <<set _path = "embraced">> <</if>> /* Celebrity */ <<if $reputation.popular >= 60 || $reputation.camGirl >= 60>> <<if _path !== "embraced" || $reputation.popular > 70>> <<set _path = "celebrity">> <</if>> <</if>> /* Professional */ <<if $jobs.current.length >= 2 && $pc.intelligence >= 50 && $reputation.goodStudent >= 40>> <<if _path === "ordinary">> <<set _path = "professional">> <</if>> <</if>> /* Corruption */ <<if $reputation.slut >= 80 && $reputation.troublemaker >= 40>> <<set _path = "corruption">> <</if>> <<divider "Your Future">> <<include `"Ending_" + _path`>> <<divider "">> <<include "EndingStats">> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🏙️ Stay in town: keep playing <em>(endless mode)</em></span>' "PostGrad_Start">><</link>> <<link '<span class="choice-btn">🔄 New Game</span>'>><<run Engine.restart()>><</link>> </div> /* ═══════════════════════════════════════════════════ EPILOGUE PASSAGES ═══════════════════════════════════════════════════ */
<h2>📚 The Scholar</h2> <p>Your grades were exceptional. Despite all of it, the services and the side effects and the general ongoing chaos of the last three years, you graduated with honours. The Dean recommends you for graduate school personally.</p> <p>You apply to a masters programme. Accepted. A quiet apartment, a teaching assistantship, and a life that looks almost... normal. You keep your head down. Study hard. Try not to think about those three years.</p> <p><<if $pc.femininity >= 50>>Sometimes, late at night, you catch yourself in the mirror and wonder if you miss it. The attention. The power. The feeling of being... wanted. You push the thought away and open your textbook.<<else>>You're back in your male body within weeks of graduation. The memories fade, mostly. But sometimes in a crowded lecture hall, you'll catch the scent of someone's perfume and your heart will race for reasons you can't explain.<</if>></p> <<reasonCoda "stayed">> <p class="thought"><em>THE END · The Scholar 📚</em></p>
<h2>💃 Embraced</h2> <p>Somewhere during those three years, something shifted. You stopped fighting. Stopped pretending this was temporary. The X-Change transformation was supposed to end at graduation. But you don't want it to.</p> <p>You contact CCUMDUP administration. "I'd like to extend my transformation. Permanently." The paperwork takes a week. The decision takes a lifetime.</p> <p><<if $roommate && $roommate.opinion >= 70>>Your roommate cries. "I knew it," she says, hugging you tight. "Welcome to the sisterhood. For real this time."<<else>>Your friends aren't surprised. "We could tell," they say. "You've been happier this way for a while now."<</if>></p> <p>You get a job. An apartment. A life. As a woman. As yourself. It's not the life you planned. But it's yours.</p> <<reasonCoda "stayed">> <p class="thought"><em>THE END · Embraced 💃</em></p>
<h2>⭐ The Celebrity</h2> <p>Your InstaGlam has 200K followers. Your FansOnly clears five figures a month. You were recognised at three different airports on the way home from spring break. You're famous. Internet famous, at least, which counts for more every year.</p> <p>A talent agency reaches out before you even graduate. "We'd love to represent you." Sponsorships, appearances, brand deals. The CCUMDUP programme gave you a platform, and you built an empire on it.</p> <p><<if $reputation.camGirl >= 80>>Your cam career transitions into mainstream content creation. Well, "mainstream." You're the poster girl for a new generation of performers who refuse to be ashamed.<<else>>You leverage your campus celebrity into an influencer career. Fashion, lifestyle, "wellness." Nobody needs to know how it all started.<</if>></p> <<reasonCoda "stayed">> <p class="thought"><em>THE END · The Celebrity ⭐</em></p>
<h2>💼 The Professional</h2> <p>You put it all on your resume. Well, not ALL of it. "Programme Participant, CCUMDUP Scholarship, Thornfield University." It's a talking point in every interview. The networking, the social skills, the ability to perform under pressure.</p> <p>You land a corporate job. Good salary. Benefits. A corner office by year two. Your colleagues have no idea what you went through. You keep it that way.</p> <p>The transformation fades after graduation. You're male again. But the confidence, the social instincts, the ability to read a room. Those stay. CCUMDUP taught you more than any business class ever could.</p> <<reasonCoda "stayed">> <p class="thought"><em>THE END · The Professional 💼</em></p>
<h2>😈 The Underground</h2> <p>You didn't graduate so much as escape. Three years of pushing boundaries, breaking rules, and building connections that don't appear in any alumni directory.</p> <<if $jobs.dealer.active || ($jobs.dealer && $jobs.dealer.earnings >= 500)>> <p>Marco has a proposition. "You've got talent, kid. The campus thing was small time. I've got connections in the city. Real money." You know you should say no. You say yes.</p> <<elseif $jobs.hooker.active || ($jobs.hooker && $jobs.hooker.sessions >= 20)>> <p>You start your own service. Premium clientele only. Discreet. Expensive. Within a year, you're running a small empire of your own. CCUMDUP taught you the business. You just took it freelance.</p> <<else>> <p>The connections you made, the dangerous ones and the exciting ones equally, lead you down paths that never once show up on LinkedIn. They pay extremely well.</p> <</if>> <<reasonCoda "stayed">> <p class="thought"><em>THE END · The Underground 😈</em></p>
<h2>🏠 Moving On</h2> <p>You graduate. The transformation ends. You go home. You get a job. A normal one. You try to pick up where you left off three years ago, before CCUMDUP, before the pills, before everything.</p> <p>It's harder than you expected. The world feels flat. Colours less vivid. Conversations less electric. You catch yourself reaching for a phone that doesn't buzz with service requests anymore.</p> <p><<if $pc.femininity >= 50>>Sometimes you think about going back. About taking another pill. Not for the programme. Just for yourself. The thought scares you more than anything that happened at Thornfield.<<else>>You tell yourself you're glad it's over. Most days, you mean it. But some nights, in that half-space between sleep and waking, you remember how it felt to be someone else entirely. And you're not sure "glad" is the right word.<</if>></p> <<reasonCoda "stayed">> <p class="thought"><em>THE END · Moving On 🏠</em></p> /* ═══════════════════════════════════════════════════ STAT SUMMARY SCREEN ═══════════════════════════════════════════════════ */
<<if $pc.maleFirstName>> <p style="opacity:0.7;font-size:0.9em;"><em>The degree certificate has to carry your legal name. Somebody in an office had to decide which one that was, and you were not consulted.</em></p> <<oldNameNote>> <</if>> <div class="card"> <div class="card__title">📊 Final Statistics</div> <p><strong>Total Days:</strong> <<print $world.day>></p> <p><strong>Semesters Completed:</strong> <<print Math.min(6, $world.semester)>></p> <p><strong>Final Femininity:</strong> <<print $pc.femininity>>/100</p> <p><strong>Final Rating:</strong> <<print Math.round($scholarship.rating * 10) / 10>> ⭐</p> </div> <div class="card"> <div class="card__title">🎀 CCUMDUP Service</div> <p><strong>Total serviced:</strong> <<print $scholarship.totalServiced>></p> <p><strong>Total credits:</strong> <<print $scholarship.totalCredits>></p> <p><strong>Total ratings received:</strong> <<print $scholarship.totalRatings>></p> </div> <div class="card"> <div class="card__title">💰 Finances</div> <p><strong>Total earned:</strong> $<<print $finance.totalEarned>></p> <p><strong>Total spent:</strong> $<<print $finance.totalSpent>></p> <p><strong>Cash at graduation:</strong> $<<print $finance.money>></p> </div> <div class="card"> <div class="card__title">📊 Reputation</div> <<set _repNames = {slut: "🔥 Slut", partyGirl: "🎉 Party Girl", goodStudent: "📚 Good Student", camGirl: "📷 Cam Girl", sweetheart: "💕 Sweetheart", troublemaker: "💀 Troublemaker", popular: "⭐ Popular"}>> <<set _repKeys = Object.keys(_repNames)>> <<for _rk = 0; _rk < _repKeys.length; _rk++>> <<set _key = _repKeys[_rk]>> <<if $reputation[_key] >= 10>> <p><<print _repNames[_key]>>: <<print $reputation[_key]>>/100</p> <</if>> <</for>> </div> <<if $pregnancy.totalPregnancies > 0>> <div class="card"> <div class="card__title">🤰 Pregnancy History</div> <p><strong>Total pregnancies:</strong> <<print $pregnancy.totalPregnancies>></p> <<if $pregnancy.children && $pregnancy.children.length > 0>> <p><strong>Children:</strong> <<print $pregnancy.children.length>></p> <</if>> <<if $pregnancy.decisions && $pregnancy.decisions.length > 0>> <<set _aborts = $pregnancy.decisions.filter(function(d) { return d === "abort"; }).length>> <<set _adopts = $pregnancy.decisions.filter(function(d) { return d === "adopt"; }).length>> <<if _aborts > 0>><p>Abortions: <<print _aborts>></p><</if>> <<if _adopts > 0>><p>Adoptions: <<print _adopts>></p><</if>> <</if>> </div> <</if>> <<if $achievements && $achievements.unlocked>> <div class="card"> <div class="card__title">🏆 Achievements</div> <p><strong>Unlocked:</strong> <<print $achievements.unlocked.length>> / <<print $achievements.definitions.length>></p> </div> <</if>> /* ═══════════════════════════════════════════════════ EXPULSION ═══════════════════════════════════════════════════ */
<h2>🚫 Expelled</h2> <p>The letter is short. Official university letterhead, the Dean's signature at the bottom.</p> <p><em>"Dear <<print $pc.firstName>>,</em></p> <p><em>Following multiple violations of university policy and the CCUMDUP Programme guidelines, we regret to inform you that your enrollment at Thornfield University is hereby <strong>terminated effective immediately</strong>.</em></p> <p><em>You are required to vacate campus housing within 48 hours."</em></p> <<if $reputation.troublemaker >= 60>> <p><<toneThink "They can't do this!" "I suppose I brought this on myself." "No... this can't be happening...">></p> <<else>> <p><<toneThink "Finally. Maybe I'm free." "This was always going to happen." "But... my friends... my life here...">></p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🗣️ Appeal the decision</span>' "Expulsion_Appeal">><</link>> <<link '<span class="choice-btn">📦 Pack up and leave</span>' "Expulsion_Leave">><</link>> </div>
<h2>🗣️ Appeal</h2> <p>You sit across from the Dean in her oak-paneled office. She looks tired.</p> <p>"<<print $pc.firstName>>, this isn't personal. But the university has standards. The programme has rules."</p> <<set _appealResult = XCLC.Roll.doCheck("charm", 7)>> <<run XCLC.DicePopup.show()>> <<if _appealResult === "crit_success">> <p>You make your case. Passionately, eloquently, desperately. The Dean pauses. Sighs. "One more chance. <strong>One.</strong> You step out of line again and there's nothing I can do."</p> <<modStat "stress" 20 "Narrow escape">> <<set $scholarship.onProbation = true>> <<set $scholarship.probationWeeks = 0>> <<run XCLC.Toast.show("🎓 Expulsion reversed! On strict probation.", "success")>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to campus (on thin ice)</span>' "CampusMap">><</link>> </div> <<else>> <p>"I've made my decision, <<print $pc.firstName>>. I'm sorry." She slides the paperwork across the desk. There's nothing left to say.</p> <<goto "Expulsion_Leave">> <</if>>
<h2>📦 Leaving Thornfield</h2> <p>You pack your things. Your roommate watches from her bed, silent. The dorm room that was your world for <<if $world.year >= 2>>two years<<else>>a year<</if>> looks smaller now.</p> <<if $roommate && $roommate.opinion >= 60>> <p>She hugs you at the door. "I'll miss you," she says. You believe her.</p> <<else>> <p>She waves awkwardly. "Good luck out there."</p> <</if>> <p>The campus gates close behind you. The X-Change transformation has <<if $world.semester >= 4>>months<<else>>weeks<</if>> left. After that, you'll be yourself again. Or whoever you are now.</p> <<toneThink "Good riddance." "I'll figure something out." "I... I don't want to go... 😢">> <<divider "Final Stats">> <<include "EndingStats">> <<divider "">> <<reasonCoda "left">> <p class="thought"><em>THE END · Expelled 🚫</em></p> <div class="choice-group"> <<link '<span class="choice-btn">🔄 New Game</span>'>><<run Engine.restart()>><</link>> </div> /* ═══════════════════════════════════════════════════ DROPOUT (voluntary) ═══════════════════════════════════════════════════ */
<h2>🏃 Dropping Out</h2> <p>You walk into the Dean's office on your own terms. "I want to leave the programme."</p> <p>She looks surprised. "You understand this means forfeiting your scholarship? The transformation will reverse within weeks of discontinuing the programme."</p> <p>"I know."</p> <<toneThink "I can't do this anymore." "It's time to go." "I need to find my own path.">> <p>The paperwork takes an hour. By afternoon, you're packing.</p> <<divider "Final Stats">> <<include "EndingStats">> <<divider "">> <<reasonCoda "left">> <p class="thought"><em>THE END · Dropout 🏃</em></p> <div class="choice-group"> <<link '<span class="choice-btn">🔄 New Game</span>'>><<run Engine.restart()>><</link>> </div>
<<set $world.postGrad = true>> <<set $world.postGradDay = $world.day>> <<set $scholarship.active = false>> <<set $scholarship.activeRequest = null>> <<set $scholarship.inService = false>> <<set $scholarship.onProbation = false>> <<set $scholarship.weeklyQuota = 0>> <<set $world.rentDue = $world.day + 7>> <<set $world.isFinalsWeek = false>> <h2>🏙️ After</h2> <p>You do not leave. That is the whole of the decision, and you make it in about four seconds standing in a car park in a gown you have to return by Tuesday.</p> <p>The lease on a one-bed above the launderette on Fenwick Street is four hundred a month and the landlord does not ask what you do. The programme's people process your exit paperwork with the brisk indifference of an organisation that has got what it wanted from you, and hand back a set of documents in a name you had to think about for a second before recognising.</p> <div class="card"> <div class="card__title">📋 What changes</div> <p><strong>The scholarship is over.</strong> No quota, no rating, no CampusHub requests, no probation. Nobody is counting any more.</p> <p><strong>Classes are over.</strong> No lectures, no exams, no GPA.</p> <p><strong>Rent is $400 a week.</strong> Charged every seven days. Miss enough of it and you will be dealing with a landlord instead of a Dean.</p> <p><strong>Everything else continues.</strong> Your jobs, the people you know, the city, <<if $children.list.length > 0>>your <<if $children.list.length > 1>>children<<else>>child<</if>>, <</if>>your body, whatever you have built.</p> </div> <<if $children.list.length > 0>> <p>The nursery does not care that you have graduated. It cares that the standing order clears.</p> <</if>> <<if $roommate.name>> <<if $roommate.opinion >= 60>> <p><<print $roommate.name>> helps you move the boxes up the stairs on the Saturday and stays for a takeaway on the floor of a flat with no furniture in it. She is going home to her parents for the summer and then somewhere else after that, and neither of you says the thing about how this is probably the last easy version of knowing each other.</p> <<else>> <p><<print $roommate.name>> is gone by the time you come back for your things. Moved out early, room stripped, a note left on the desk that says <em>good luck with everything</em> in handwriting you would not have recognised.</p> <</if>> <</if>> <p>The first night in the flat is very quiet. There is no timetable in the morning. There has not been a morning without a timetable in three years.</p> <div class="choice-group"> <<link '<span class="choice-btn">🏙️ Get on with it</span>' "CampusMap">> <<run XCLC.Toast.show("🏙️ Endless mode. Rent is due in 7 days.", "info", 7000)>> <</link>> </div>
/* Rent, charged weekly once the programme is behind you */ <<widget "rentCheck">> <<if $world.postGrad && $world.day >= $world.rentDue>> <<set $world.rentDue = $world.day + 7>> <<set _rent = 400>> <<if $finance.money >= _rent>> <<set $finance.money -= _rent>> <<run XCLC.Toast.show("🏠 Rent paid: $" + _rent + ".", "info", 5000)>> <<else>> <<set $world.rentOwed += _rent>> <<run XCLC.Toast.show("🏠 You could not cover the rent. $" + State.variables.world.rentOwed + " owed.", "danger", 7000)>> <<if $world.rentOwed >= 1200>> <<goto "PostGrad_Eviction">> <</if>> <</if>> <</if>> <</widget>>
<<set _owed = $world.rentOwed>> <h2>🏠 Three Months Behind</h2> <p>He is not a cartoon about it. That is somehow worse. He sits on the arm of your own sofa with a folder and goes through the dates, and every date is correct, and at the end of it he says "so you can see the position I'm in" and you genuinely can.</p> <p>You have two weeks. The two weeks are a courtesy and he makes sure you understand that they are a courtesy.</p> <div class="alert alert--danger">🏠 $<<print _owed>> owed. Two weeks to clear it or you are out.</div> <<set $finance.debt += _owed>> <<set $world.rentOwed = 0>> <<set $world.rentDue = $world.day + 14>> <<modStat "stress" 30 "Eviction notice">> <<modStat "mood" -20 "Eviction notice">> <div class="choice-group"> <<link '<span class="choice-btn">🏙️ Work something out</span>' "CampusMap">><</link>> </div>
/* ═══════════════════════════════════════════════════ THORNFIELD: SUBSTANCE SYSTEM WIDGETS Alcohol states, drug effects, hangovers ═══════════════════════════════════════════════════ */ /* ─── Drink a beverage ─── */ <<widget "drink">> /* Usage: <<drink "beer">> / <<drink "cocktail">> / <<drink "shot">> / <<drink "wine">> */ <<set _type = _args[0] || "beer">> <<set _units = {beer: 1, cocktail: 1.5, shot: 2, wine: 1}>> <<set _costs = {beer: 4, cocktail: 10, shot: 6, wine: 8}>> <<set _drinkUnits = _units[_type] || 1>> <<set _drinkCost = _costs[_type] || 5>> <<if $finance.money < _drinkCost>> <<run XCLC.Toast.show("❌ Can't afford that ($" + _drinkCost + ")", "error")>> <<else>> <<set $finance.money -= _drinkCost>> <<set $substances.drinksToday += _drinkUnits>> <<set $substances.lastDrinkTime = $world.time>> <<checkDrunkState>> <<if !$flags.firstDrunk && $substances.drunkLevel >= 2>> <<set $flags.firstDrunk = true>> <<run XCLC.Toast.show("🍺 First time getting drunk...", "warning")>> <</if>> <<run XCLC.Toast.show("🍺 " + _type.charAt(0).toUpperCase() + _type.slice(1) + " (-$" + _drinkCost + ")", "info")>> <<checkIntoxCombo>> <</if>> <</widget>> /* ─── Substances interact ─────────────────────────── Called after any drink or dose. One combination is dangerous specifically because it hides how bad it is. ─────────────────────────────────────────────────── */ <<widget "checkIntoxCombo">> <<set _combo = XCLC.Intox.check()>> <<if _combo>> <div class="alert alert--warning"><strong><<print $temp.comboLabel>></strong><br><<print $temp.comboText>></div> <</if>> <</widget>> /* ─── Evaluate drunk level from drinks + tolerance ─── */ <<widget "checkDrunkState">> <<set _drinks = $substances.drinksToday>> <<set _tol = $substances.alcoholTolerance>> /* Tolerance shifts thresholds up */ <<set _tipsy = 2 + Math.floor(_tol / 2)>> <<set _drunk = 5 + Math.floor(_tol / 2)>> <<set _wasted = 8 + _tol>> <<set _blackout = 10 + _tol>> <<if _drinks >= _blackout>> <<set $substances.drunkLevel = 4>> <<elseif _drinks >= _wasted>> <<set $substances.drunkLevel = 3>> <<elseif _drinks >= _drunk>> <<set $substances.drunkLevel = 2>> <<elseif _drinks >= _tipsy>> <<set $substances.drunkLevel = 1>> <<else>> <<set $substances.drunkLevel = 0>> <</if>> /* Apply stat modifiers based on drunk level */ <<if $substances.drunkLevel === 1>> /* Tipsy: mild effects applied contextually via getModifiers */ <<elseif $substances.drunkLevel === 2>> /* Drunk */ <<elseif $substances.drunkLevel === 3>> /* Wasted */ <<if !$flags.firstBlackout>> /* First time wasted */ <</if>> <<elseif $substances.drunkLevel === 4>> /* Blackout: handled in passage logic */ <<set $flags.firstBlackout = true>> <</if>> /* Build tolerance with regular drinking */ <<if $substances.drinksToday >= 3 && $substances.alcoholTolerance < 10>> <<set $substances.alcoholTolerance = Math.min(10, $substances.alcoholTolerance + 0.1)>> <</if>> <</widget>> /* ─── Sober up over time ─── */ <<widget "soberUp">> /* Usage: <<soberUp _hoursElapsed>>: called by time advancement */ <<set _hours = _args[0] || 1>> <<set _soberUnits = Math.floor(_hours / 2)>> <<if _soberUnits > 0 && $substances.drinksToday > 0>> <<set $substances.drinksToday = Math.max(0, $substances.drinksToday - _soberUnits)>> <<checkDrunkState>> <<if $substances.drunkLevel === 0 && $substances.drinksToday === 0>> <<run XCLC.Toast.show("☕ You've sobered up.", "info")>> <</if>> <</if>> <</widget>> /* ─── Apply hangover on morning wake-up ─── */ <<widget "applyHangover">> <<if $substances.hangover>> <<set _sev = $substances.hangoverSeverity>> <<set _energyPen = [0, -20, -40, -60][_sev] || -20>> <<set _moodPen = [0, -10, -20, -30][_sev] || -10>> <<set _intPen = [0, -5, -10, -15][_sev] || -5>> <<modStat "energy" _energyPen "Hangover">> <<modStat "mood" _moodPen "Hangover">> /* Intelligence penalty applied contextually */ <<run XCLC.Toast.show("🤢 Hangover... (" + ["mild", "moderate", "severe"][_sev - 1] + ")", "warning")>> /* Hangover clears at noon */ <</if>> <</widget>> /* ─── Trigger hangover for next morning ─── */ <<widget "triggerHangover">> <<if $substances.drunkLevel >= 2>> <<set $substances.hangover = true>> <<set $substances.hangoverSeverity = Math.min(3, $substances.drunkLevel - 1)>> <</if>> <</widget>> /* ─── Clear hangover (called at noon) ─── */ <<widget "clearHangover">> <<set $substances.hangover = false>> <<set $substances.hangoverSeverity = 0>> <</widget>> /* ─── Reset daily drinking (called at sleep) ─── */ <<widget "resetDrinking">> <<triggerHangover>> <<set $substances.drinksToday = 0>> <<set $substances.drunkLevel = 0>> <<set $substances.lastDrinkTime = 0>> <</widget>> /* ─── Use a drug ─── */ <<widget "useDrug">> /* Usage: <<useDrug "weed">> / <<useDrug "ecstasy">> / <<useDrug "cocaine">> */ <<set _drug = _args[0] || "weed">> <<if _drug === "weed">> <<if $substances.weed.doses <= 0>> <<run XCLC.Toast.show("❌ No weed to smoke.", "error")>> <<else>> <<set $substances.weed.doses-->> <<set $substances.weed.high = true>> <<modStat "stress" -30 "Getting high">> <<modStat "mood" 20 "Weed">> <<modStat "arousal" 10 "Weed">> <<run XCLC.Toast.show("🌿 You smoke a joint. Everything slows down...", "info")>> <<checkIntoxCombo>> <</if>> <<elseif _drug === "ecstasy">> <<if $substances.ecstasy.doses <= 0>> <<run XCLC.Toast.show("❌ No pills to drop.", "error")>> <<else>> <<set $substances.ecstasy.doses-->> <<set $substances.ecstasy.high = true>> <<set $substances.ecstasy.rolling = true>> <<modStat "mood" 50 "Rolling">> <<modStat "arousal" 40 "Ecstasy">> <<run XCLC.Toast.show("💊 You drop a pill. The music starts to feel AMAZING.", "info")>> <<checkIntoxCombo>> <</if>> <<elseif _drug === "cocaine">> <<if $substances.cocaine.doses <= 0>> <<run XCLC.Toast.show("❌ Nothing to snort.", "error")>> <<else>> <<set $substances.cocaine.doses-->> <<set $substances.cocaine.high = true>> <<set $substances.cocaine.addiction = Math.min(10, $substances.cocaine.addiction + 0.5)>> <<modStat "energy" 40 "Cocaine rush">> <<modStat "confidence" 50 "Cocaine">> <<modStat "arousal" 20 "Cocaine">> <<run XCLC.Toast.show("❄️ You're fucking INVINCIBLE.", "info")>> <<checkIntoxCombo>> <</if>> <</if>> <</widget>> /* ─── Process drug effects (called each time period) ─── */ <<widget "processDrugEffects">> /* Weed wears off after 3 hours */ <<if $substances.weed.high>> <<set $substances.weed.high = false>> <<run XCLC.Toast.show("🌿 The high fades. You feel a bit groggy.", "info")>> <</if>> /* Ecstasy comedown */ <<if $substances.ecstasy.rolling>> <<set $substances.ecstasy.rolling = false>> <<set $substances.ecstasy.high = false>> <<set $substances.ecstasy.comedown = true>> <<run XCLC.Toast.show("💊 The roll is fading... everything feels hollow.", "warning")>> <</if>> <<if $substances.ecstasy.comedown>> <<modStat "mood" -40 "Comedown">> <<modStat "energy" -30 "Post-roll crash">> <<set $substances.ecstasy.comedown = false>> <</if>> /* Cocaine crash */ <<if $substances.cocaine.high>> <<set $substances.cocaine.high = false>> <<modStat "energy" -50 "Cocaine crash">> <<modStat "mood" -30 "Cocaine crash">> <<run XCLC.Toast.show("❄️ The rush is gone. You feel empty.", "warning")>> <</if>> <</widget>> /* ─── Show drunk status ─── */ <<widget "showDrunkStatus">> <<if $substances.drunkLevel === 1>> <div class="alert alert--info">🥂 You're feeling tipsy. Everything's a bit fuzzy and fun.</div> <<elseif $substances.drunkLevel === 2>> <div class="alert alert--warning">🍺 You're drunk. The room sways. Judgement: impaired.</div> <<elseif $substances.drunkLevel === 3>> <div class="alert alert--warning">🤮 You're wasted. Standing is a challenge. You might not remember this.</div> <<elseif $substances.drunkLevel === 4>> <div class="alert alert--warning">💀 You're blacked out. The world goes dark...</div> <</if>> <<if $substances.weed.high>> <div class="alert alert--info">🌿 You're stoned. Everything is slow and mellow.</div> <</if>> <<if $substances.ecstasy.rolling>> <div class="alert alert--info">💊 You're rolling. Colors are vivid, music is transcendent, everyone is beautiful.</div> <</if>> <<if $substances.cocaine.high>> <div class="alert alert--info">❄️ You're wired. Heart pounding, jaw clenching, feeling invincible.</div> <</if>> <</widget>>
<<set $substances.dealerOffered = true>> <h2>🤫 Another Arrangement</h2> <p>You are counting what you have and it is visibly not enough, and he watches you do it with the patience of a man who has watched a lot of people do it.</p> <p>"Look," he says. "No pressure either way. But I do trade. Some people pay cash, some people pay other ways, and I genuinely do not care which. It all spends the same to me." He shrugs, and it is a real shrug, not a loaded one. "Say no and I will still sell to you next week at the normal price. I am not doing the thing where I make it weird."</p> <<if $reputation.slut >= 50>> <p>"I have heard your name, for what it is worth," he adds. "Not in a bad way. In a 'she knows what she is doing' way."</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💬 Ask what the rate is</span>' "Dealer_Offer_Rates">><</link>> <<link '<span class="choice-btn">🚫 "No. Cash or nothing."</span>' "Dealer_Offer_Decline">><</link>> <<link '<span class="choice-btn">↩️ Walk away entirely</span>' "BarDistrict">><</link>> </div>
<h2>🚫 No</h2> <p>"Cash or nothing," you say.</p> <p>"Cash or nothing," he agrees, and goes straight back to watching the door. That is the whole of it. No sulk, no second try, no comment when you are still standing there ten seconds later working out whether something else is coming. Nothing else is coming.</p> <<modStat "confidence" 3 "Held your line">> <<addXP "composure" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to the board</span>' "Bar_DrugDeal">><</link>> <<link '<span class="choice-btn">🚪 Leave</span>' "BarDistrict">><</link>> </div>
<h2>💱 The Rate</h2> <p>"Simple," he says. "Bag of weed, that is nothing, that is a favour between friends. Pills, bit more. The white stuff." He tips his head. "The white stuff is expensive and I am not going to pretend otherwise."</p> <p>He lists it out flatly, like a man reading a menu he did not write. There is nothing leering about it, which somehow makes it easier and harder at once.</p> <p style="opacity:0.7;font-size:0.85em;"><em>You can still buy any of this with money. This is an alternative, not a replacement, and you can stop at any point, including after you have agreed.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">🌿 Weed: <em>oral, and he is not going to be difficult about it</em></span>' "Dealer_Trade_Setup">> <<set $temp.tradeDrug = "weed">> <<set $temp.tradeType = "oral">> <</link>> <<link '<span class="choice-btn">💊 Ecstasy (×2): <em>he wants more than your mouth</em></span>' "Dealer_Trade_Setup">> <<set $temp.tradeDrug = "ecstasy">> <<set $temp.tradeType = "vaginal">> <</link>> <<if $skills.anal.level >= 1>> <<link '<span class="choice-btn">❄️ Cocaine (×2): <em>the expensive one, and he says so</em></span>' "Dealer_Trade_Setup">> <<set $temp.tradeDrug = "cocaine">> <<set $temp.tradeType = "anal">> <</link>> <<else>> <p style="opacity:0.6;font-size:0.85em;"><em>He names a price for the cocaine that you are not remotely prepared for. You let it go.</em></p> <</if>> <<divider "">> <<link '<span class="choice-btn">🚫 Actually: no. Cash or nothing.</span>' "Dealer_Offer_Decline">><</link>> </div>
<<set _drug = $temp.tradeDrug>> <<set _type = $temp.tradeType>> <<set _label = _drug === "weed" ? "a bag" : _drug === "ecstasy" ? "two pills" : "two grams">> <h2>🚪 The Back Hallway</h2> <p>He does not take you anywhere dramatic. Behind the bar, past the cellar door, into a storeroom stacked with crates of mixers and a strip light that buzzes. He puts <<print _label>> on a crate where you can see it and leaves it there, which is either a courtesy or a sales technique.</p> <p>"Whenever you want," he says. "And if you change your mind halfway through, you change your mind. I will still be here Thursday."</p> <<if $substances.dealerTrades === 0>> <p>You stand in a storeroom that smells of stale lager and cardboard, doing arithmetic you would not have recognised as arithmetic six months ago, and you notice that the part of you that should be objecting is quiet.</p> <<elseif $substances.dealerTrades >= 3>> <p>You know where the light switch is now. That is the detail that lands. Not the storeroom, not the crate, but the fact that you reach for the switch without looking.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔥 Do it properly: make it worth more than he offered <em>(Performance System)</em></span>' "Dealer_Trade_Go">> <<set $temp.tradeQuick = false>> <</link>> <<link '<span class="choice-btn">⚡ Get it over with <em>(single check)</em></span>' "Dealer_Trade_Quick">> <<set $temp.tradeQuick = true>> <</link>> <<link '<span class="choice-btn">✋ Changed your mind: walk out</span>' "Dealer_Trade_Backout">><</link>> </div>
<h2>✋ Out</h2> <p>"Changed my mind," you say, already moving.</p> <p>"Sure," he says, and picks the stuff back up off the crate, and that is genuinely the end of it. You are back out in the noise of the bar four seconds later with your heart going and nothing to show for it, which is, on balance, fine.</p> <<modStat "confidence" 4 "Left when you wanted to">> <<addXP "composure" 12>> <div class="choice-group"> <<link '<span class="choice-btn">🚪 Back to the bar</span>' "BarDistrict">><</link>> </div>
<<set _npc = XCLC.NPC.generate({gender: "male", type: "student"})>> <<set _npc.firstName = "Marco">> <<run XCLC.Encounter.setup({ npc: _npc, serviceType: $temp.tradeType, locationName: "the storeroom behind the bar", locationPrivacy: "medium", returnPassage: "Dealer_Trade_Result" })>> <<advanceTime 40>> <<goto "ServiceSex_Start">>
<<set _skill = $temp.tradeType === "anal" ? "anal" : $temp.tradeType === "vaginal" ? "vaginal" : "oral">> <<set _res = XCLC.Roll.doCheck(_skill, 3)>> <<run XCLC.DicePopup.show()>> <<set $temp.sexMinigameOutcome = _res>> <<advanceTime 25>> <h2>⚡ Transaction</h2> <<if _res === "crit_success" || _res === "success">> <p>You keep it brisk and competent and entirely on your own terms. You set the pace, you decide when it is finished, and you are pulling your clothes straight again before the strip light has finished its next flicker. He looks slightly winded and slightly reassessed.</p> <<else>> <p>It is functional and it is quick and neither of you is going to describe it as a highlight. You get through it by thinking about the crate, and then about Thursday, and then about nothing much at all.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">Continue →</span>' "Dealer_Trade_Result">><</link>> </div>
<<set _drug = $temp.tradeDrug>> <<set _out = $temp.sexMinigameOutcome>> <<set _good = (_out === "crit_success" || _out === "success")>> <<set _base = _drug === "weed" ? 1 : 2>> <<set _bonus = (_out === "crit_success") ? 1 : 0>> <<set _doses = _base + _bonus>> <<run XCLC.Encounter.clear()>> <<set $substances.dealerTrades++>> <<set $substances[_drug].doses += _doses>> <h2>💱 Paid</h2> <<if _out === "crit_success">> <p>He hands you the crate stock and then, after a pause, adds to it. He starts to say something, thinks better of it, and settles on: "Take the extra. Seriously."</p> <<elseif _good>> <p>He passes you what was on the crate without comment, which is its own kind of respect. Transaction closed, both parties satisfied with the terms.</p> <<else>> <p>He hands it over anyway, because a deal is a deal, but there is a flatness to it, and you both know the difference between paying a price and paying it well.</p> <</if>> <div class="alert alert--info">🧪 +<<print _doses>> <<print _drug>><<if _doses > 1>> doses<</if>>. No money changed hands.</div> <<modRep "troublemaker" `_drug === "weed" ? 1 : 3`>> <<modRep "slut" 3>> <<modCorruption 4 "Paid in kind">> <<if !_good>><<modStat "mood" -6 "Grim little transaction">><</if>> /* Health consequences apply exactly as they would anywhere else */ <<if $temp.tradeType !== "oral">> <<stdRisk `$temp.tradeType`>> <</if>> <<if $substances.dealerTrades === 3>> <div class="alert alert--warning">⚠️ Three times now. He has stopped quoting you cash prices first.</div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚪 Back out into the noise</span>' "BarDistrict">><</link>> </div>
<<widget "checkMorningAfter">> <<set _rev = XCLC.Goggles.pendingReveal()>> <<if _rev && !$temp.morningAfterShown>> <<set $temp.morningAfterShown = true>> <<set $temp.revealName = _rev.name>> <<set $temp.revealShift = _rev.shift>> <<set $temp.revealGender = _rev.gender>> <<set $temp.revealBody = _rev.bodyType>> <<set $temp.revealHair = _rev.hairColour>> <<goto "MorningAfter_Reveal">> <</if>> <</widget>>
<<set _name = $temp.revealName>> <<set _shift = $temp.revealShift>> <<set _they = $temp.revealGender === "male" ? "he" : "she">> <<set _them = $temp.revealGender === "male" ? "him" : "her">> <<set _their = $temp.revealGender === "male" ? "his" : "her">> <<run XCLC.Goggles.clearLog()>> <h2>☀️ In Daylight</h2> <<if _shift >= 3>> <p>You wake up with a headache behind one eye and a very clear memory of thinking, at some point last night, that <<print _name>> was the most beautiful person you had ever seen.</p> <p>You have <<print _their>> number. There is a photo. In the photo <<print _they>> is a perfectly ordinary <<print $temp.revealBody>> person with <<print $temp.revealHair>> hair, standing in bad lighting outside a kebab shop, and you cannot locate a single one of the qualities you were so certain about six hours ago.</p> <p>It is not that <<print _they>> looks bad. It is that the gap between what you saw and what is actually there is enormous, and it was entirely manufactured inside your own head by four hours of drinking.</p> <<modStat "mood" -6 "Recalibrating">> <<modStat "confidence" -3 "Questioning your own judgement">> <<elseif _shift === 2>> <p>Somewhere around eleven you find yourself thinking about <<print _name>> in daylight, and the picture that comes back is noticeably less impressive than the one you went to sleep with.</p> <p>Not a disaster. Just ordinary, the way almost everybody is ordinary. Pleasant, even. Nothing like the thing your brain was insisting on at one in the morning with a drink in your hand.</p> <<modStat "mood" -3 "Recalibrating">> <</if>> <<if $substances.maskedDrunk > 0>> <p>There is also the small matter of last night's arithmetic. You felt entirely sober by midnight. You were not sober by midnight. You were <<print ["", "tipsy", "drunk", "wasted", "blackout"][$substances.maskedDrunk] || "drunk">>, and the only reason you could not tell is that you had put something on top of it that lies about exactly this.</p> <div class="alert alert--warning">❄️ Your body kept the score even when you could not feel it.</div> <<modStat "health" -5 "Last night caught up">> <<set $substances.maskedDrunk = 0>> <</if>> <p style="opacity:0.7;font-size:0.85em;"><em>Beer goggles: what you thought you saw, corrected. Your judgement, nobody else's.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">☕ Get some coffee</span>' "DormRoom">><</link>> </div>
/* Generate the roommate: call once during orientation */ <<widget "generateRoommate">> <<run XCLC.Roommate.generate()>> <</widget>>
/* Called during orientation when player first enters dorm */ <<set _rmHome = XCLC.Roommate.isHome()>> <<set _rmDesc = XCLC.Roommate.describe()>> <p>You push open the door to Room 207. It's small. Two beds, two desks, a bathroom you could shave in without moving your elbows, and just enough floor between everything to unroll a yoga mat if nobody else needs to stand up.</p> <p>One side is already claimed. Posters on the wall, bedspread in place, a laptop charger snaking across the desk.</p> <<if $roommate.personality === "shy">> <p>A girl sits on the far bed with her knees drawn up and a paperback tented on them. She looks up when the door goes, loses her place, and pushes her glasses back with one knuckle.</p> <p>"Oh. Hi." The wave barely clears the mattress. "I'm <<print $roommate.name>>. I think we're roommates."</p> <<elseif $roommate.personality === "party">> <p>Something with a lot of bass is coming out of a speaker the size of a soup can. A girl lies across her bed scrolling, one leg swinging off the side in time. She sits up the second she clocks you.</p> <p>"Hey. Hey. You're my roomie." She's off the bed and hugging you before you've put the bag down. She smells like coconut and hairspray. "I'm <<print $roommate.name>>, and we are going to have such a good year."</p> <<elseif $roommate.personality === "mean">> <p>A girl sits at her desk doing her nails. She glances up, prices you from shoes to hairline in about a second and a half, and goes back to the nails.</p> <p>"<<print $roommate.name>>." She turns back to her nails. "Your side is... that one. Don't touch my stuff."</p> <<elseif $roommate.personality === "supportive">> <p>A round-faced girl is unpacking a box of books, sorting them into piles that clearly mean something to her. She stops when she sees you and her whole face opens up.</p> <p>"Hi. I'm <<print $roommate.name>>. There's tea, if you want it." She nods at a travel kettle balanced on a stack of paperbacks. "I put fresh sheets on your bed as well. The ones they issue you feel like envelopes."</p> <<elseif $roommate.personality === "horny">> <p>The door is already open. Inside, a girl is halfway through changing, down to a thong and nothing else, and she takes her time about noticing you.</p> <p>"Oh, hey." She turns to face you rather than away, which answers a question you hadn't asked yet. "I'm <<print $roommate.name>>. Fair warning, I mostly live like this. Say now if that's a problem."</p> <p>She says it the way other people mention they snore.</p> <<elseif $roommate.personality === "athletic">> <p>There's a girl in a sports bra and compression leggings doing push-ups in the gap between the beds. She finishes the set before she gets up, which tells you most of what you need to know.</p> <p>"<<print $roommate.name>>." She wipes her palm on her hip and offers it. The grip is serious. "I run at five. I'll try to be quiet. I won't be."</p> <</if>> <div class="card"> <div class="card__title">👤 <<print $roommate.name>>: Your Roommate</div> <p><<print _rmDesc>></p> <p><em><<print $roommate.personalityLabel>></em>. <<print $roommate.personalityDesc>></p> </div> <<set $flags.metRoommate = true>>
<h2>💬 Talk to <<print $roommate.name>></h2> <<if !XCLC.Roommate.isHome()>> <p><<print $roommate.name>> isn't here right now.</p> <<link '<span class="choice-btn">← Back</span>' "DormRoom">><</link>> <<elseif $roommate.talkedToday>> <p><<print $roommate.name>> looks up. "We already chatted today, <<print $pc.femaleFirstName>>. I've got stuff to do."</p> <<link '<span class="choice-btn">← Back</span>' "DormRoom">><</link>> <<else>> <p><<print $roommate.name>> is <<print XCLC.Roommate.getActivity()>>.</p> <div class="choice-group"> /* Always available */ <<link '<span class="choice-btn">💬 Small talk (How\'s your day?)</span>' "Roommate_SmallTalk">> <<set $roommate.talkedToday = true>> <<advanceTime 15>> <</link>> /* Classes topic */ <<if $roommate.topics.includes("classes")>> <<link '<span class="choice-btn">📚 Talk about classes</span>' "Roommate_Classes">> <<set $roommate.talkedToday = true>> <<advanceTime 15>> <</link>> <</if>> /* Weekend plans: unlocked at opinion 40+ */ <<if $roommate.opinion >= 40 && $roommate.topics.includes("weekend")>> <<link '<span class="choice-btn">🎉 Weekend plans?</span>' "Roommate_Weekend">> <<set $roommate.talkedToday = true>> <<advanceTime 15>> <</link>> <</if>> /* Confide: unlocked at trust 60+ */ <<if $roommate.trust >= 60 && !$roommate.isConfidant>> <<link '<span class="choice-btn">🤫 Confide about the programme...</span>' "Roommate_Confide">> <<set $roommate.talkedToday = true>> <<advanceTime 30>> <</link>> <</if>> /* Vent: the recurring payoff for having told her. Being a confidant was a one-shot; this is the reason it was worth doing. */ <<if $roommate.isConfidant>> <<link '<span class="choice-btn">😮💨 Just... talk to her about it</span>' "Roommate_Vent">> <<set $roommate.talkedToday = true>> <<advanceTime 45>> <</link>> <</if>> /* Borrow clothes: unlocked at trust 50+ */ <<if $roommate.trust >= 50>> <<link '<span class="choice-btn">👗 Borrow something to wear?</span>' "Roommate_BorrowClothes">> <<set $roommate.talkedToday = true>> <<advanceTime 10>> <</link>> <</if>> <<link '<span class="choice-btn">← Back</span>' "DormRoom">><</link>> </div> <</if>>
<<set _mood = random(1,4)>> <<if $roommate.personality === "shy">> <<if _mood === 1>> <p><<print $roommate.name>> peeks over her book. "Oh, um. My day was okay. Just studying." She pauses. "The cafeteria mac and cheese is actually good. If... if you haven't tried it."</p> <<elseif _mood === 2>> <p>"There was a cat on the library steps today," she says, and then holds her phone out at arm's length so you can see it without having to sit next to her. The cat is enormous and deeply unimpressed. You both laugh at it, and she takes the phone back looking pleased with herself.</p> <<else>> <p>She turns her glasses over in her hands. "Do you like it here? So far, I mean." A beat. "I keep waiting to stop feeling like a visitor." She watches you properly while you answer, which not many people do.</p> <</if>> <<elseif $roommate.personality === "party">> <<if _mood === 1>> <p>"Oh my GOD, <<print $pc.femaleFirstName>>, you have to hear what happened at Sigma Phi last night." She launches into an elaborate story involving a keg stand and someone's pants.</p> <<elseif _mood === 2>> <p>"We should go OUT tonight. Like, OUT out. I know a guy who can get us into The Basement. Drink specials on Wednesdays!" She's already planning your outfit.</p> <<else>> <p>"Your hair looks unreal today. I'm not being nice, I'm being accurate." She's already scrolling. "Okay, you have to see this."</p> <</if>> <<elseif $roommate.personality === "mean">> <<if _mood === 1>> <p><<print $roommate.name>> doesn't look up from her phone. "Ugh, Carla from floor 3 is wearing the same top as me. I'm going to kill her."</p> <<elseif _mood === 2>> <p>"You know what would really help this room? If you kept your stuff on YOUR side." She smiles sweetly. It doesn't reach her eyes.</p> <<else>> <p>She's in something close to a good mood. "There's a sale on at Nordstrom. You should go." She gestures at your outfit, taking her time. "You could use the intervention."</p> <</if>> <<elseif $roommate.personality === "supportive">> <<if _mood === 1>> <p>"Hey, how are you REALLY doing?" <<print $roommate.name>> puts down her tea and gives you her full attention. "Adjusting to college is hard. I'm here if you need to talk."</p> <<elseif _mood === 2>> <p>"I made brownies." She pushes the tub across the gap between the beds. They're still slightly warm in the middle. "My mom's recipe. I bake when I'm stressed, so there'll be more by Thursday."</p> <<else>> <p>"You look wrecked, <<print $pc.femaleFirstName>>." She says it gently, and she doesn't dress it up as a joke afterwards. "Are you sleeping? Actually sleeping."</p> <</if>> <<elseif $roommate.personality === "horny">> <<if _mood === 1>> <p>"So there's this guy in my Econ class..." <<print $roommate.name>> grins. "Absolute UNIT. I'm talking like..." She holds her hands apart at an alarming distance.</p> <<elseif _mood === 2>> <p>She's lying on her bed in a crop top and underwear. "Have you hooked up with anyone yet? No judgement either way but also give me ALL the details."</p> <<else>> <p>"Ugh, I'm so pent up." She stretches dramatically. "Wanna go see who's at the bar tonight? Mama needs to hunt."</p> <</if>> <<elseif $roommate.personality === "athletic">> <<if _mood === 1>> <p>"Did my 5K this morning in under 22 minutes!" <<print $roommate.name>> looks absurdly proud. "You should come running with me sometime. It'll change your life."</p> <<elseif _mood === 2>> <p>She's mixing a protein shake the colour and consistency of engine oil. "Want some?" She reads your face. "Your loss. It's incredible for recovery and it tastes like a punishment."</p> <<else>> <p>"Intramural volleyball sign-ups are this week. We should start a team! I'll play setter."</p> <</if>> <</if>> <<modStat "mood" 5 "Socialising">> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 3)>> <<run XCLC.Toast.show('💬 +3 Opinion with ' + State.variables.roommate.name, 'success')>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
<p>You ask <<print $roommate.name>> about her classes.</p> <<if $roommate.personality === "shy">> <p>"I'm doing English Lit and Philosophy. The reading list is... massive." She shows you a stack of books. "But I love it. Professor Hartley is brilliant."</p> <<elseif $roommate.personality === "party">> <p>"Ugh, don't remind me. I have a paper due Friday and I haven't started." She shrugs. "But honestly? College isn't about grades, it's about experiences."</p> <<elseif $roommate.personality === "mean">> <p>"Business Admin. I'm going to run a company one day." She says it like it's already decided. "What are YOU studying?"</p> <<elseif $roommate.personality === "supportive">> <p>"Psychology. I want to be a counsellor." She says it without a shred of embarrassment. "People are the interesting bit. Like right now. You're stressed, and you're doing the thing where you pretend you're not."</p> <<elseif $roommate.personality === "horny">> <p>"Gender Studies." She grins. "Ironically. Or maybe appropriately. The professor is hot, too."</p> <<elseif $roommate.personality === "athletic">> <p>"Sports Science, obviously. I want to go into physical therapy after I graduate." She flexes. "Gotta know the body, you know?"</p> <</if>> <<modStat "mood" 3 "Chatting">> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 2)>> <<set $roommate.trust = Math.min(100, $roommate.trust + 1)>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
<p>You ask <<print $roommate.name>> about her weekend plans.</p> <<if $roommate.personality === "shy">> <p>"I was going to binge-watch this new show and maybe go to the bookstore..." She pauses. "You could come? If you want?"</p> <<elseif $roommate.personality === "party">> <p>"Okay SO. Delta Chi is having a foam party Saturday. I already have our outfits planned. You're coming. Non-negotiable."</p> <<elseif $roommate.personality === "mean">> <p>"Spa day. You need one too, honestly." A backhanded invitation, but an invitation nonetheless.</p> <<elseif $roommate.personality === "supportive">> <p>"Farmers market Sunday morning! Then maybe brunch? I found this cute café downtown."</p> <<elseif $roommate.personality === "horny">> <p>"I've got a date Saturday. And a different date Sunday." She winks. "What? Don't look at me like that."</p> <<elseif $roommate.personality === "athletic">> <p>"5K Saturday morning, then the volleyball tournament in the afternoon. Sunday's a rest day." She says rest day the way other people say <em>light run</em>, because that is exactly what she means by it.</p> <</if>> <<modStat "mood" 5 "Making plans">> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 3)>> <<set $roommate.trust = Math.min(100, $roommate.trust + 2)>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
<p>You take a deep breath. "<<print $roommate.name>>... there's something I need to tell you. About why I'm here."</p> <p>She looks at you, waiting.</p> <<set _memLoss = $transformation.sideEffects.memoryLoss || 0>> <<if _memLoss >= 4>> <p>"I'm on the X-Change programme. The scholarship. And apparently I was..." You stop. The sentence has a hole in it. "The paperwork says I was a guy before. A whole other person, with a name I have to look up on my student file." You laugh, and it comes out strange. "I don't remember him. At all. I know it the way you know a fact from a textbook. Isn't that insane?"</p> <<elseif _memLoss >= 3>> <p>"I'm on the X-Change programme. The scholarship. I was a guy before. I think." You press a palm to your forehead. "No. I <em>was</em>. I know I was. It's just that when I reach for it there's fog. Flashes. A voice lower than this one. Things I can't swear actually happened." Saying it out loud makes the fog feel thicker, not thinner.</p> <<elseif _memLoss >= 1>> <p>"I'm on the X-Change programme. The scholarship. I was..." You swallow. "I was a guy, before." The memories are still there, mostly. Some of the edges have gone soft in the last few weeks, and that frightens you considerably more than the confession does.</p> <<else>> <p>"I'm on the X-Change programme. The scholarship. I was..." You swallow. "I was a guy, before."</p> <</if>> <<if $roommate.personality === "shy">> <p>Her eyes go wide. Her mouth opens, closes. Opens again. "I... oh. OH." She's processing. "That's... wow. Okay." She fidgets with her glasses. "I don't... I mean, you're still you, right? You're still <<print $pc.femaleFirstName>>?"</p> <p>She reaches over and awkwardly pats your hand. "Your secret is safe with me."</p> <<elseif $roommate.personality === "party">> <p>"Shut up. Shut <em>up</em>." She has you by both shoulders. "That is the single best thing anyone has ever told me. Wait. So you had a." She gestures, vaguely, downward. "And now you've got." She gestures at your chest with considerably more confidence. "I need to sit down. I am sitting down."</p> <p>"I won't tell anyone. But oh my God, we need drinks and you need to tell me EVERYTHING."</p> <<elseif $roommate.personality === "mean">> <p>She stares at you for a long moment. "Huh." She goes back to her phone. Then: "That actually explains a lot." She looks up. "Relax. I don't care. Just don't make it weird."</p> <p>It's the closest to acceptance she's capable of.</p> <<elseif $roommate.personality === "supportive">> <p>She immediately comes over and hugs you. "Oh honey. That must be so much to deal with." She holds you at arm's length. "Thank you for trusting me. I mean that."</p> <p>"Whatever you need. Someone to talk to, someone to lie to your professors for you, someone to sit here and not talk at all. I'm here."</p> <<elseif $roommate.personality === "horny">> <p>"Wait, seriously?" She looks fascinated rather than shocked. "So you know what it's like on both sides?" She grins. "That's actually kind of hot."</p> <p>"Don't worry, I won't out you. But I have SO many questions."</p> <<elseif $roommate.personality === "athletic">> <p>She nods slowly. "The transformation programme. I've heard of it." She looks you over the way she'd look over a new bike. "They did good work, for what it's worth. You're well put together."</p> <p>"I respect the guts it takes. Your secret's safe with me."</p> <</if>> <<set $roommate.isConfidant = true>> <<set $roommate.trust = Math.min(100, $roommate.trust + 20)>> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 10)>> <<set $roommate.awareness = 100>> <<set $roommate.awarenessMilestone = 100>> <<run XCLC.Toast.show('🤝 ' + State.variables.roommate.name + ' is now your confidant.', 'success')>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
<<if $roommate.trust >= 50>> <p>You ask <<print $roommate.name>> if you can borrow something to wear.</p> <<if $roommate.personality === "mean">> <p>She sighs dramatically. "Fine. But if you stretch out my good top, I WILL end you." She opens her closet.</p> <<elseif $roommate.personality === "horny">> <p>"Ooh, what are we dressing up for?" She opens her closet with enthusiasm. Most of the options are extremely revealing.</p> <<else>> <p>"Sure!" <<print $roommate.name>> opens her closet. "Take whatever you need."</p> <</if>> <<set $roommate.sharedClothes = true>> <<set $roommate.trust = Math.min(100, $roommate.trust + 3)>> <<else>> <p><<print $roommate.name>> looks uncomfortable. "Uh... maybe not yet? We're not really at that level."</p> <</if>> <<link '<span class="choice-btn">← Back to room</span>' "DormRoom">><</link>>
/* ═══════════════════════════════════════════════════ ROOMMATE AWARENESS MILESTONES 0-20 normal | 21-50 suspects | 51-80 knows | 81-100 fully aware Fires a conversation when a threshold is crossed and she's home. ═══════════════════════════════════════════════════ */ <<widget "checkRoommateAwareness">> /* Pregnancy notice takes priority: she lives with you, she can see */ <<if $roommate.name && XCLC.Roommate.isHome() && $pregnancy.isPregnant && $pregnancy.weeksPregnant >= 12 && !$pregnancy.roommateNoticed>> <<set $pregnancy.roommateNoticed = true>> <<goto "Roommate_PregnancyNotice">> <</if>> <<if $roommate.name && XCLC.Roommate.isHome() && !$roommate.isConfidant>> <<if $roommate.awareness >= 85 && $roommate.awarenessMilestone < 85>> <<set $roommate.awarenessMilestone = 85>> <<goto "Roommate_Aware_Full">> <<elseif $roommate.awareness >= 55 && $roommate.awarenessMilestone < 55>> <<set $roommate.awarenessMilestone = 55>> <<goto "Roommate_Aware_Knows">> <<elseif $roommate.awareness >= 25 && $roommate.awarenessMilestone < 25>> <<set $roommate.awarenessMilestone = 25>> <<goto "Roommate_Aware_Suspects">> <</if>> <</if>> <</widget>>
<h2>🤰 She Noticed</h2> <p><<print $roommate.name>> is watching you from her bed. Not subtly. Her eyes are on your midsection.</p> <<if $roommate.personality === "mean">> <p>"So are we going to talk about it, or are we pretending that's the cafeteria food?" She points at your belly with her pen. "Because I've watched you turn green every morning for weeks, and now there's... that."</p> <<elseif $roommate.personality === "shy">> <p>"Um." She's gone red before she's got the sentence out. "I don't want to be weird. But you're. I mean. Are you?" Her eyes drop to your bump and come straight back up, and she looks like she'd like the floor to open.</p> <<elseif $roommate.personality === "party">> <p>"Okay, I've been DYING to ask for like two weeks." She sits up cross-legged. "You're pregnant, right? Like, actually? Babe. BABE. This is enormous. Who is it? Do you know? Is it a secret? Can I plan the shower?"</p> <<elseif $roommate.personality === "horny">> <p>"You know," she says, looking you up and down with open appreciation, "pregnancy suits you. You've got the glow. And the..." she gestures at your chest, "...upgrades. So who's the lucky donor?"</p> <<elseif $roommate.personality === "supportive">> <p>"Hey." She says it softly and pats the bed beside her. "I've noticed. You don't owe me a word of it. But whatever you need, I'm here. Appointments. Cover stories. Someone to hold your hair at six in the morning. Any of it."</p> <<set $roommate.trust = Math.min(100, $roommate.trust + 10)>> <<else>> <p>"Not to be blunt, but you're pregnant, right?" She says it like she's confirming a training schedule. "Thought so. Okay. If you need someone to walk you to the clinic or run interference, say the word."</p> <</if>> <<set $roommate.awareness = Math.min(100, $roommate.awareness + 15)>> <div class="choice-group"> <<link '<span class="choice-btn">🤰 "Yeah. I am."</span>' "DormRoom">> <<set $roommate.trust = Math.min(100, $roommate.trust + 10)>> <<modStat "stress" -5 "Said it out loud">> <<run XCLC.Toast.show("🤝 It's out there now. Trust +10.", "info")>> <</link>> <<link '<span class="choice-btn">🙅 "I don\'t want to talk about it."</span>' "DormRoom">> <<modStat "stress" 5 "Bottling it up">> <</link>> </div>
<h2>🤔 Something's Off</h2> <p><<print $roommate.name>> is sitting on her bed when you come in. She puts her phone face down on the duvet, deliberately, so that you see her do it.</p> <<if $roommate.personality === "shy">> <p>"Hey, um..." She fidgets with her sleeve. "Can I ask you something weird? You get a lot of... calls. And you're out at strange hours. Is everything okay? You'd tell me if you were in trouble, right?"</p> <<elseif $roommate.personality === "party">> <p>"Okay, real talk." She grins. "You disappear at the WEIRDEST times, you came back at 2am on a Tuesday, and someone said they saw you leaving the frat house. Who ARE you? I need the lore."</p> <<elseif $roommate.personality === "mean">> <p>"So." She examines her nails. "Three guys this week asked me if I'm 'the CCUMDUP girl's roommate.' Care to explain why strangers know our room number?"</p> <<elseif $roommate.personality === "horny">> <p>"Babe." She props her chin on her hands. "You keep sneaking off and coming back looking absolutely wrecked. Either you have the world's most demanding study group or you're having way more fun than me. Spill."</p> <<elseif $roommate.personality === "athletic">> <p>"Hey. Not my business, but you keep odd hours and you came back limping on Thursday. If someone's messing with you, say the word."</p> <<else>> <p>"Can we talk for a second?" She keeps her voice level and kind. "You're out a lot, at strange hours, and you come back wound up like a spring. I'm not judging you. I just want to know you're safe."</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🙅 Deflect: "It\'s just a campus job."</span>' "DormRoom">> <<set $roommate.awareness = Math.max(0, $roommate.awareness - 10)>> <<run XCLC.Toast.show("She doesn't look convinced.", "info")>> <</link>> <<link '<span class="choice-btn">🫤 Hint at the truth: "It\'s... complicated. Scholarship stuff."</span>' "DormRoom">> <<set $roommate.trust = Math.min(100, $roommate.trust + 10)>> <<set $roommate.awareness = Math.min(100, $roommate.awareness + 10)>> <<run XCLC.Toast.show("🤝 Trust +10. She's more curious than ever.", "info")>> <</link>> <<link '<span class="choice-btn">💬 Tell her everything</span>' "Roommate_Confide">><</link>> </div>
<h2>😨 She Knows</h2> <p><<print $roommate.name>> is waiting for you. Arms crossed. On her laptop screen: the CCUMDUP programme's public information page.</p> <<if $roommate.personality === "mean">> <p>"The Cross-Campus Undergraduate... whatever. The scholarship. The <em>service</em> scholarship." She lets the silence sit. "That's you. Don't insult me by denying it."</p> <<elseif $roommate.personality === "shy">> <p>"I wasn't snooping. I promise I wasn't snooping." It comes out in a rush. "Somebody put it in the class group chat and I recognised things in it." She's addressing this mostly to her own knees. "It's you. Isn't it."</p> <<elseif $roommate.personality === "party">> <p>"BABE." She spins the laptop toward you. "This is the actual wildest thing I have ever read, and I once woke up in a different state. This is you, right? It's you."</p> <<elseif $roommate.personality === "horny">> <p>"So I did some reading." She's smiling like the cat that got the cream. "The scholarship. The pills. The <em>quota</em>. You've been living a whole double life across the hall from me."</p> <<else>> <p>"I found the programme page," she says quietly. "And then I put the rest of it together. The schedule, the calls, the way you are on Sunday nights. I'm not going to make this weird. I just couldn't keep sitting here pretending I hadn't worked it out."</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">😔 Come clean</span>' "Roommate_Confide">><</link>> <<link '<span class="choice-btn">🧊 Deny everything</span>' "DormRoom">> <<set $roommate.opinion = Math.max(0, $roommate.opinion - 15)>> <<set $roommate.trust = Math.max(0, $roommate.trust - 10)>> <<run XCLC.Toast.show("💔 She knows you're lying. Opinion -15, Trust -10.", "warning")>> <</link>> </div>
<h2>⚖️ Cards on the Table</h2> <p>There's nothing left to be vague about. <<print $roommate.name>> knows. She's seen too much, overheard more than that, and worked out the remainder on her own.</p> <<if $roommate.personality === "mean" && $roommate.opinion < 50>> <p>"Here's the thing." She smiles, and it isn't friendly. "Housing services would be <em>fascinated</em> by what happens in this room. So would your Dean. But I can be very forgetful..." She holds out her hand. "$150. Call it a roommate tax."</p> <div class="choice-group"> <<if $finance.money >= 150>> <<link '<span class="choice-btn">💸 Pay her off ($150)</span>' "DormRoom">> <<set $finance.money -= 150>> <<set $roommate.awarenessMilestone = 100>> <<modStat "stress" 10 "Extorted by roommate">> <<run XCLC.Toast.show("💸 She pockets the cash. 'Pleasure doing business, roomie.'", "warning")>> <</link>> <</if>> <<link '<span class="choice-btn">😤 Call her bluff: "Report me. The programme is university-sanctioned."</span>' "DormRoom">> <<set $roommate.awarenessMilestone = 100>> <<set _bluff = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _bluff === "crit_success" || _bluff === "success">> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 10)>> <<run XCLC.Toast.show("😎 She backs down. Grudging respect: Opinion +10.", "success")>> <<else>> <<modRep "slut" 8>> <<modStat "stress" 15 "Rumours spreading">> <<run XCLC.Toast.show("🗣️ She doesn't report you. She does something worse. By Friday the whole floor has heard her version.", "error", 6000)>> <</if>> <</link>> </div> <<elseif $roommate.personality === "horny" && $roommate.trust >= 40>> <p>"Okay, I have to know." She leans forward, eyes bright. "What's it LIKE? The requests, the app, all of it. God, I'd sign up tomorrow if I qualified." She pauses. "...If you ever want company on one of your appointments, I'm just saying. I'm right here."</p> <<set $roommate.awarenessMilestone = 100>> <<set $roommate.trust = Math.min(100, $roommate.trust + 15)>> <<modCorruption 2 "Roommate wants in">> <div class="choice-group"> <<link '<span class="choice-btn">😏 "I\'ll keep it in mind."</span>' "DormRoom">><</link>> <<link '<span class="choice-btn">😅 "You are SO much."</span>' "DormRoom">><</link>> </div> <<else>> <p><<if $roommate.personality === "shy">>"I know everything," she says, barely above a whisper. "And I don't care. You're still just... you. My roommate."<<elseif $roommate.personality === "party">>"Your secret's safe with me, superstar. But I'm living vicariously through you from now on, deal?"<<elseif $roommate.personality === "athletic">>"You're tougher than half my team, and I'd tell them so. Whatever you need. Cover story, alibi, protein bar. I've got you."<<else>>"I've known for a while," she admits. "I kept waiting for you to tell me. You don't have to carry this alone anymore."<</if>></p> <<set $roommate.awarenessMilestone = 100>> <<set $roommate.isConfidant = true>> <<set $roommate.trust = Math.min(100, $roommate.trust + 20)>> <<modStat "stress" -10 "Someone knows: relief">> <<run XCLC.Toast.show('🤝 ' + State.variables.roommate.name + ' is now your confidant.', 'success')>> <div class="choice-group"> <<link '<span class="choice-btn">🥹 "Thank you."</span>' "DormRoom">><</link>> </div> <</if>>
<<set _rm = $roommate>> <<set _trust = _rm.trust || 0>> <<set _relief = Math.round(8 + (_trust / 100) * 22)>> <<set _stressBefore = $pc.stress>> <h2>😮💨 Talking To <<print _rm.name>></h2> /* What is actually weighing on you tonight: picked by state, most pressing first, so the scene is about your real situation */ <<set _topic = "general">> <<if $pregnancy.isPregnant && $pregnancy.discovered>> <<set _topic = "pregnancy">> <<elseif $children.list.length > 0 && $children.neglect >= 1>> <<set _topic = "children">> <<elseif $health.hasSTD && $health.stdSymptomatic>> <<set _topic = "health">> <<elseif $scholarship.onProbation>> <<set _topic = "probation">> <<elseif $finance.money < 30>> <<set _topic = "money">> <<elseif $scholarship.currentWeekServiced < $scholarship.weeklyQuota && $world.dayOfWeek >= 5>> <<set _topic = "quota">> <<elseif $pc.stress >= 60>> <<set _topic = "stress">> <</if>> <<if _rm.personality === "shy">> <p>She puts the book face-down without marking her page, which for her is the equivalent of clearing an entire afternoon.</p> <<elseif _rm.personality === "party">> <p>She mutes whatever she was watching and swings her legs off the bed. "Right. Go."</p> <<elseif _rm.personality === "mean">> <p>"Ugh, fine," she says, in a tone that has stopped being convincing to either of you. She puts her phone down screen-first.</p> <<elseif _rm.personality === "supportive">> <p>She is already moving before you have finished the sentence. Kettle on, second mug out, sitting down on the end of your bed with her feet tucked under her.</p> <<elseif _rm.personality === "horny">> <p>"Okay, but properly," she says, and for once there is nothing arch about it at all. She sits cross-legged and gives you her whole face.</p> <<else>> <p>She takes her headphones out and loops them round her neck, which means she is not putting them back in.</p> <</if>> <<if _topic === "pregnancy">> <p>You talk about being pregnant. Not the logistics of it, which you have been over a hundred times in your own head at four in the morning, but the part underneath, which is that you cannot work out whether you are frightened of the thing happening or of how little you seem to be feeling about it.</p> <p>"I don't think there's a correct amount to be freaking out," she says. "I think you've decided there's a score and you're failing it."</p> <<elseif _topic === "children">> <p>You admit, out loud, that there have been days you have not been able to make yourself do it. Not could not. Did not. That the difference between those two words has been keeping you up.</p> <p>She does not tell you it is fine. That is the thing you will remember about it afterwards. She says: "Then tomorrow you do it. Not to fix this week. Just tomorrow."</p> <<elseif _topic === "health">> <p>You tell her about the health centre, and about the specific quality of the shame, which is not really about being ill and is mostly about what having it says about how you have been living.</p> <p>"Half this building has had something," she says flatly. "The only difference is you're the one who went and got it seen to."</p> <<elseif _topic === "probation">> <p>You talk about the probation letter, which you have read enough times to quote, and about the fact that everything you have given up for this place is now contingent on a number that other people assign to you.</p> <p>"That's an insane way to live," she says. "I'm not saying that to be nice. I mean it's genuinely insane and you've stopped noticing."</p> <<elseif _topic === "money">> <p>You talk about money, badly, the way people talk about money when there is not any: circling it, making jokes that do not land, arriving eventually at the actual number.</p> <p>She does not offer to lend you any, which you are grateful for, because you would have had to say no and then it would have been a whole thing. What she does instead is get out a piece of paper.</p> <<elseif _topic === "quota">> <p>It is Friday and you are behind on the quota, and you say the number out loud to another person for the first time, and it sounds considerably worse in the air than it does in your head.</p> <p>"Do you ever think about just... not?" she asks. She means it as a real question. You are surprised by how long it takes you to answer.</p> <<elseif _topic === "stress">> <p>You do not have a single specific thing. That turns out to be harder to explain than a specific thing would have been: the sense of being permanently three steps behind a life that was assembled for you by other people.</p> <p>She listens to all of it without trying to solve any of it, which is the entire trick and almost nobody manages it.</p> <<else>> <p>Nothing is especially wrong. You talk anyway. About the programme, about the body, about the odd experience of getting used to something you never agreed to in any meaningful sense and then catching yourself enjoying parts of it.</p> <p>"That's the bit that would mess me up," she says. "Not the change. The getting used to it."</p> <</if>> <<if _trust >= 85>> <p>At some point the conversation stops being about your problem and becomes just a conversation, and it goes on for a good while past the point where either of you should have gone to sleep.</p> <<modStat "mood" 12 "Real friendship">> <<elseif _trust >= 60>> <p>You feel about fifteen percent less like a collection of overdue obligations in a wig. It is not nothing.</p> <<modStat "mood" 7 "Being heard">> <<else>> <p>It is awkward in places. She is trying, and you can see her trying, and somehow that helps almost as much as if she had been good at it.</p> <<modStat "mood" 4 "She tried">> <</if>> <<modStat "stress" `-_relief` "Talked it out">> <<set $roommate.trust = Math.min(100, $roommate.trust + 2)>> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 2)>> <<addXP "composure" 12>> <div class="alert alert--success">😮💨 Stress <<print _stressBefore>> → <<print $pc.stress>>.</div> <div class="choice-group"> <<link '<span class="choice-btn">← Back to your room</span>' "DormRoom">><</link>> </div>
<<set _npc = XCLC.Presence.byId($temp.presenceNPCId) || $temp.serviceNPC>> <<if !_npc>> <p>They have gone.</p> <div class="choice-group"><<link '<span class="choice-btn">↩️ Back</span>' "CampusMap">><</link>></div> <<else>> <<set _they = _npc.gender === "male" ? "he" : "she">> <<set _them = _npc.gender === "male" ? "him" : "her">> <h2>💬 Asking</h2> <p>You ask <<print _npc.firstName>> whether <<print _they>> wants to do something that is not this. Not a booking, not the app, not a slot in a schedule. Dinner, or a film, or standing somewhere outdoors for an hour talking about nothing.</p> <p>It takes you two attempts to get the sentence out, because you have not asked anybody anything in this register since before the programme, and the muscle has gone.</p> <<set _res = XCLC.Roll.doCheck("charm", 4)>> <<run XCLC.DicePopup.show()>> <<if _res === "crit_success" || _res === "success">> <p><<print _npc.firstName>> says yes before you have finished, and then looks slightly embarrassed about how fast that was.</p> <<set $relationship.partnerId = _npc.id>> <<set $relationship.partnerName = _npc.firstName>> <<set $relationship.partnerGender = _npc.gender>> <<set $relationship.stage = "seeing">> <<set $relationship.startedDay = $world.day>> <<run XCLC.Toast.show("💞 You are seeing " + State.variables.relationship.partnerName + ".", "success", 6000)>> <<modStat "mood" 15 "Someone said yes">> <div class="choice-group"> <<link '<span class="choice-btn">😊 Good</span>' "CampusMap">><</link>> </div> <<else>> <p>"That's kind," <<print _they>> says, and means it, "but no. I know what the programme is. I do not think I am built for the version of this where I share you with a rota."</p> <p>It is not cruel and it is not wrong, which is the part that stays with you.</p> <<modStat "mood" -10 "Turned down">> <div class="choice-group"> <<link '<span class="choice-btn">↩️ Leave it</span>' "CampusMap">><</link>> </div> <</if>> <</if>>
<<set $relationship.dates = ($relationship.dates || 0) + 1>> <<advanceTime 150>> <<set _n = $relationship.partnerName>> <h2>🍽️ An Evening Off</h2> <<if $relationship.dates === 1>> <p>You are twenty minutes early, which you have not been for anything in a year, and you spend those twenty minutes discovering that you have no idea how to stand while waiting for someone.</p> <p><<print _n>> arrives and the first ten minutes are terrible in the ordinary way first dates are terrible. Then something catches, and by the time the plates are cleared you have talked for two hours about nothing that would survive being written down.</p> <p>Nobody's phone buzzes. You keep noticing that it hasn't.</p> <<elseif $relationship.tension >= 40>> <p>It is a good evening and there is a shape in the middle of it that neither of you goes near. <<print _n>> asks how your week was and you give an answer with the load-bearing parts removed, and <<print _n>> lets you, which is worse than being pushed.</p> <<else>> <p>Easier than last time. You have started to have a way of doing this together: the same place, roughly the same table, an argument about a film that you are both enjoying losing.</p> <</if>> <<modStat "mood" 18 "A real evening">> <<modStat "stress" -15 "Time off the clock">> <<set $relationship.tension = Math.max(0, $relationship.tension - 12)>> <<if $relationship.stage === "seeing" && $relationship.dates >= 3>> <<set $relationship.stage = "dating">> <<run XCLC.Toast.show("💞 This is a thing now, apparently.", "success", 5000)>> <</if>> <div class="choice-group"> <<if !$relationship.knowsAboutProgramme && $relationship.dates >= 2>> <<link '<span class="choice-btn">🗣️ Tell <<print _n>> about the programme</span>' "Relationship_Disclosure">><</link>> <</if>> <<link '<span class="choice-btn">🏠 Head back</span>' "DormRoom">><</link>> </div>
<<set _n = $relationship.partnerName>> <h2>🗣️ Telling <<print _n>></h2> <p>You tell <<print _n>> what the scholarship actually is. Not the euphemism on the website. The quota, the app, the rating, the fact that it does not stop because you met somebody.</p> <p>You get through it without stopping, which you had not expected, and then there is a silence with a great deal in it.</p> <<set _res = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _res === "crit_success" || _res === "success">> <p>"Okay," <<print _n>> says eventually. "Okay. I am not going to pretend I like it. But I would rather know it than find it out, and I would rather have you than not."</p> <p>Something in your chest that has been clenched for weeks lets go slightly.</p> <<set $relationship.knowsAboutProgramme = true>> <<set $relationship.tension = Math.max(0, $relationship.tension - 30)>> <<modStat "stress" -20 "Said it out loud">> <<run XCLC.Toast.show("🤝 " + State.variables.relationship.partnerName + " knows. Strain accumulates far slower now.", "success", 7000)>> <<if $relationship.stage === "dating">> <<set $relationship.stage = "exclusive">> <</if>> <<else>> <p>"Right," <<print _n>> says. "Right." And then, after a while: "I need to go and think about that, and I do not want to say the wrong thing while I am doing it."</p> <p><<print _n>> does not slam anything. That would be easier.</p> <<set $relationship.knowsAboutProgramme = true>> <<set $relationship.tension = Math.min(100, $relationship.tension + 20)>> <<modStat "mood" -15 "Left it hanging">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Go home</span>' "DormRoom">><</link>> </div>
<h2>💞 <<print $relationship.partnerName>></h2> <<if $relationship.stage === "none">> <p>You are not seeing anybody.</p> <<else>> <div class="card"> <div class="card__title">Status</div> <p><strong>Stage:</strong> <<print $relationship.stage>></p> <p><strong>Evenings out:</strong> <<print $relationship.dates>></p> <p><strong>Knows about the programme:</strong> <<if $relationship.knowsAboutProgramme>>yes<<else>>no<</if>></p> <p><strong>Strain:</strong> <<print $relationship.tension>>/100</p> </div> <<if $relationship.tension >= 70>> <p><em>This is not sustainable in its current shape and you both know it.</em></p> <<elseif $relationship.tension >= 40>> <p><em>There is a conversation you keep not having.</em></p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🍽️ Arrange an evening</span>' "Relationship_Date">><</link>> <<if !$relationship.knowsAboutProgramme>> <<link '<span class="choice-btn">🗣️ Tell them about the programme</span>' "Relationship_Disclosure">><</link>> <</if>> <<link '<span class="choice-btn">💔 End it</span>' "Relationship_End">><</link>> </div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">↩️ Back</span>' "DormRoom">><</link>> </div>
<<set _n = $relationship.partnerName>> <h2>💔 Ending It</h2> <p>You end it. <<if $relationship.tension >= 60>>Neither of you is surprised, and the lack of surprise is the saddest part of the conversation.<<else>>It is not that anything went wrong. It is that you cannot hold this and the programme in the same two hands, and you have known which one you are contractually obliged to keep.<</if>></p> <p><<print _n>> takes it better than you deserve.</p> <<set $relationship.endedReason = "ended by player">> <<set $relationship.stage = "none">> <<set $relationship.partnerId = null>> <<set $relationship.partnerName = "">> <<set $relationship.tension = 0>> <<set $relationship.dates = 0>> <<set $relationship.knowsAboutProgramme = false>> <<modStat "mood" -25 "Ended it">> <<modStat "stress" 10 "Ended it">> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Go home</span>' "DormRoom">><</link>> </div>
/* ─── Main event check: called from advanceTime ─── */ <<widget "checkRandomEvent">> /* Only fire once per period, 8% base chance, never during service or spring break */ <<if $temp.lastRandomEventPeriod !== XCLC.Time.getPeriodName($world.time)>> <<set $temp.lastRandomEventPeriod = XCLC.Time.getPeriodName($world.time)>> <<if random(1, 100) <= 8 && !$scholarship.inService && !($springBreak && $springBreak.active)>> /* Toys you own or are wearing get first refusal, because they are the most specific thing that can be happening to you */ <<checkToyEvent>> <<if !$temp.toyEventFired>> /* Pick a category weighted by game state */ <<set _roll = random(1, 100)>> <<if _roll <= 20>> <<include "RE_Campus">> <<elseif _roll <= 35>> <<include "RE_Phone">> <<elseif _roll <= 50>> <<include "RE_Reputation">> <<elseif _roll <= 65>> <<include "RE_Transformation">> <<elseif _roll <= 80 && $reputation.slut >= 30>> <<include "RE_Sexual">> <<else>> <<include "RE_Ambient">> <</if>> <</if>> <</if>> <</if>> <</widget>> /* ─── Corruption widget ─── */ <<widget "modCorruption">> /* $args[0] = amount, $args[1] = reason */ <<set $corruption.score = Math.min(100, Math.max(0, $corruption.score + _args[0]))>> <<set $corruption.lastGain = _args[1] || "">> /* Update tier */ <<if $corruption.score >= 80>> <<set $corruption.tier = "fallen">> <<elseif $corruption.score >= 60>> <<set $corruption.tier = "corrupted">> <<elseif $corruption.score >= 40>> <<set $corruption.tier = "compromised">> <<elseif $corruption.score >= 20>> <<set $corruption.tier = "tempted">> <<else>> <<set $corruption.tier = "innocent">> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ 🚶 CAMPUS ENCOUNTERS ═══════════════════════════════════════════════════ */
<<set _ev = random(1, 8)>> <<if _ev === 1>> <div class="alert alert--warning">🚶 A guy wolf-whistles as you cross the quad. "Hey gorgeous!" <<toneThink "Ignore him." "That's... flattering?" "Omg, he noticed me! 😊">></div> <<modStat "femininity" 1 "Catcalled">> <<elseif _ev === 2>> <div class="alert alert--info">📸 A freshman stops you. "Aren't you <<print $pc.firstName>>? Can I get a selfie?" You're... recognisable now.</div> <<modRep "popular" 2>> <<elseif _ev === 3>> <div class="alert alert--warning">😳 You pass a group of guys and hear one whisper: "That's the girl from the programme. Five stars on CampusHub." Your stomach drops.</div> <<modStat "stress" 5 "Recognised">> <<modStat "femininity" 1 "Treated as girl">> <<elseif _ev === 4>> <div class="alert alert--info">🎒 A girl from your class catches up. "Hey! Want to grab coffee after?" <<toneThink "No." "Sure, why not." "Omg yes, girl time! ☕">></div> <<modStat "mood" 5 "Social invite">> <<elseif _ev === 5>> <div class="alert alert--warning">👀 You catch your reflection in a window and pause. For a split second, you don't recognise yourself. Just a <<print $pc.bodyType>> <<print $pc.race>> girl staring back.</div> <<modStat "femininity" 2 "Reflection">> <<elseif _ev === 6>> <div class="alert alert--info">🎵 Someone's busking on the quad. Acoustic guitar, singing badly, entirely undeterred. A few students throw coins on the way past.</div> <<modStat "mood" 3 "Campus vibes">> <<elseif _ev === 7>> <div class="alert alert--warning">💐 Someone left flowers on your dorm door. No name. Just a note: "<em>Thinking about you.</em>" <<toneThink "Creepy." "Sweet, actually." "A SECRET ADMIRER! 😍">></div> <<modStat "mood" 5 "Secret admirer">> <<else>> <div class="alert alert--info">🐿️ A campus squirrel steals a chip from your hand. You chase it for three steps before giving up. Life at Thornfield.</div> <<modStat "mood" 2 "Squirrel">> <</if>> /* ═══════════════════════════════════════════════════ 📱 PHONE INTERRUPTS ═══════════════════════════════════════════════════ */
<<set _ev = random(1, 7)>> <<if _ev === 1 && $scholarship.currentWeekServiced < $scholarship.weeklyQuota>> <div class="alert alert--danger">📱 <strong>CampusHub Reminder:</strong> You've completed <<print $scholarship.currentWeekServiced>>/<<print $scholarship.weeklyQuota>> services this week. Deadline approaching!</div> <<modStat "stress" 5 "Quota reminder">> <<elseif _ev === 2>> <div class="alert alert--info">📱 <strong>Chirpr Trending:</strong> "#ThornfieldLife" is trending. Someone posted a meme about the cafeteria food. Relatable.</div> <<modStat "mood" 2 "Chirpr">> <<elseif _ev === 3 && $reputation.popular >= 30>> <div class="alert alert--info">📱 <strong>InstaGlam:</strong> Your last post got <<print random(50, 200)>> likes! <<if $phone.instaGlam.followers > 500>>You're gaining followers fast.<</if>></div> <<modStat "mood" 3 "Social media">> <<modRep "popular" 1>> <<elseif _ev === 4>> <div class="alert alert--warning">📱 <strong>Email from Dean Harrison:</strong> "All students are reminded that campus curfew is 2 AM. Violations will be noted."</div> <<elseif _ev === 5 && $roommate>> <div class="alert alert--info">📱 <strong><<print $roommate.name>>:</strong> "where r u?? want to grab food?"</div> <<modStat "mood" 3 "Roommate text">> <<elseif _ev === 6>> <div class="alert alert--info">📱 <strong>Campus Alert:</strong> Library closing early today due to maintenance. Plan accordingly.</div> <<else>> <div class="alert alert--info">📱 A notification from an app you don't remember downloading: "HOT SINGLES IN YOUR AREA." Delete.</div> <<modStat "mood" 1 "Spam">> <</if>> /* ═══════════════════════════════════════════════════ 🎭 REPUTATION EVENTS ═══════════════════════════════════════════════════ */
<<if $reputation.slut >= 60>> <<set _rr = random(1, 3)>> <<if _rr === 1>> <div class="alert alert--warning">👀 You walk into a room and the conversation stops. Someone whispers. You catch fragments: "...heard she does anything..." Your reputation precedes you.</div> <<modStat "stress" 5 "Whispers">> <<modStat "femininity" 1 "Known as a girl">> <<elseif _rr === 2>> <div class="alert alert--danger">📱 Someone AirDropped you an unsolicited dick pic. Charming. <<toneThink "Disgusting." "Happens a lot now." "Ooh, not bad actually...">></div> <<modStat "arousal" 3 "Dick pic">> <<else>> <div class="alert alert--warning">🗣️ A girl from your econ class: "I heard about you. Is it true? Like, all of it?" She looks simultaneously horrified and fascinated.</div> <<modStat "stress" 3 "Confronted">> <</if>> <<elseif $reputation.popular >= 50>> <<set _rr = random(1, 3)>> <<if _rr === 1>> <div class="alert alert--info">⭐ A group of freshmen wave excitedly. "That's <<print $pc.firstName>>! From InstaGlam!" You wave back. This is your life now.</div> <<modRep "popular" 2>> <<modStat "confidence" 3 "Fan recognition">> <<elseif _rr === 2>> <div class="alert alert--info">🎤 The campus newspaper wants an interview. "We're doing a piece on campus influencers." <<toneThink "Hard pass." "Maybe." "OMG YES! 📰">></div> <<modRep "popular" 3>> <<else>> <div class="alert alert--info">💌 A freshman slides a note under your door: "You're my inspiration." Genuinely sweet. Or genuinely stalker-ish. Hard to tell.</div> <<modStat "mood" 3 "Fan note">> <</if>> <<elseif $reputation.goodStudent >= 60>> <<set _rr = random(1, 2)>> <<if _rr === 1>> <div class="alert alert--info">📚 A classmate asks if you want to join a study group. "You always seem to know the material." <<toneThink "Fine." "Sure." "Study group! So academic! 🤓">></div> <<modRep "goodStudent" 2>> <<modStat "mood" 3 "Academic recognition">> <<else>> <div class="alert alert--info">📚 Your professor stops you after class. "Excellent work on the last assignment, <<print $pc.firstName>>. Keep it up."</div> <<modStat "confidence" 5 "Professor praise">> <<modRep "goodStudent" 2>> <</if>> <<else>> <div class="alert alert--info">🚶 Nothing unusual. Just another day blending into the campus crowd.</div> <</if>> /* ═══════════════════════════════════════════════════ 😳 TRANSFORMATION EVENTS ═══════════════════════════════════════════════════ */
<<if $pc.femininity < 25>> <<set _te = random(1, 4)>> <<if _te === 1>> <div class="alert alert--warning">😳 You reach for a door handle and notice your nails. Slender fingers. Smooth skin. These aren't your hands. They'll never be your hands again.</div> <<modStat "stress" 5 "Dysphoria">> <<elseif _te === 2>> <div class="alert alert--warning">🪞 You brush your <<print $pc.hairColour>> hair behind your ear without thinking. You used to have short hair. When did this become automatic?</div> <<modStat "femininity" 2 "Automatic gesture">> <<elseif _te === 3>> <div class="alert alert--warning">😐 Someone calls you "miss" and you respond without correcting them. You don't even notice until five minutes later.</div> <<modStat "femininity" 2 "Gendered language">> <<else>> <div class="alert alert--warning">👕 Your chest bounces when you take stairs too fast. It's disorienting, embarrassing, and a constant reminder of what you've become.</div> <<modStat "stress" 3 "Body awareness">> <</if>> <<elseif $pc.femininity < 50>> <<set _te = random(1, 4)>> <<if _te === 1>> <div class="alert alert--info">💃 You catch yourself walking with a sway. Hips, shoulders, the whole thing. You didn't plan it. Your body just... does it now.</div> <<modStat "femininity" 2 "Natural walk">> <<elseif _te === 2>> <div class="alert alert--warning">🪞 Your old male name sounds foreign when you try to say it in your head. <<print $pc.firstName>> feels more... real.</div> <<modStat "femininity" 3 "Name shift">> <<elseif _te === 3>> <div class="alert alert--info">👗 You browse a clothing store window and catch yourself thinking "that would look cute on me." Then freeze. When did this start?</div> <<modStat "femininity" 2 "Shopping instinct">> <<else>> <div class="alert alert--warning">💭 A cute guy smiles at you and your heart does something you have no filing system for. Not attraction. Obviously not attraction. Just a reaction, arriving in a body that has started having opinions without consulting you.</div> <<modStat "arousal" 5 "Male attention">> <<modStat "femininity" 2 "Attraction response">> <</if>> <<elseif $pc.femininity < 75>> <<set _te = random(1, 3)>> <<if _te === 1>> <div class="alert alert--info">✨ You spend 20 minutes on your hair this morning without realising. It used to be shampoo and done. Now you have a routine. And you like it.</div> <<modStat "femininity" 2 "Beauty routine">> <<modStat "mood" 3 "Self-care">> <<elseif _te === 2>> <div class="alert alert--info">💅 You check your nails and notice they need redoing. The thought "I should get them done" comes naturally. You don't fight it.</div> <<modStat "femininity" 2 "Grooming instinct">> <<else>> <div class="alert alert--info">👠 You walk past a shoe store and actually stop. Heels. You're thinking about heels. Your old self would be horrified. You're... intrigued.</div> <<modStat "femininity" 2 "Fashion interest">> <</if>> <<else>> <<set _te = random(1, 3)>> <<if _te === 1>> <div class="alert alert--info">🌸 You wake up, stretch, and pad to the mirror. The girl looking back is beautiful. She's you. She's always been you. The thought doesn't scare you anymore.</div> <<modStat "mood" 5 "Self-acceptance">> <<elseif _te === 2>> <div class="alert alert--info">💕 Someone asks your male name on a form. You stare at the blank space. You can't remember how to spell it. You write <<print $pc.firstName>> instead.</div> <<modStat "femininity" 2 "Identity shift">> <<else>> <div class="alert alert--info">👗 You help another girl pick out an outfit. "You've got such good taste!" she says. You beam. This is who you are now.</div> <<modStat "mood" 5 "Belonging">> <<modStat "confidence" 3 "Compliment">> <</if>> <</if>> /* ═══════════════════════════════════════════════════ 🔞 SEXUAL / PUBLIC USE EVENTS (Scaled by slut reputation) ═══════════════════════════════════════════════════ */
<<if $reputation.slut >= 80>> /* Tier 4: Free Use territory */ <<set _se = random(1, 4)>> <<if _se === 1>> <div class="alert alert--danger">🚪 A guy pulls you into an empty classroom as you walk past. "Hey, you're that girl right? The one who's always... available?" He locks the door.</div> <<modStat "arousal" 15 "Classroom ambush">> <<modCorruption 3 "Public use">> <<elseif _se === 2>> <div class="alert alert--danger">🚻 You're cornered in the bathroom by two guys. "We heard you don't say no." One blocks the door. The other unzips.</div> <<modStat "arousal" 10 "Bathroom corner">> <<modStat "stress" 10 "Cornered">> <<modCorruption 5 "Cornered">> <<elseif _se === 3>> <div class="alert alert--danger">📱 An anonymous text: "I know what you are. Meet me behind the gym in 10 minutes. Or I post everything." <<toneThink "Ignore it." "Should I go?" "...maybe I want to go.">></div> <<modStat "stress" 10 "Threat">> <<else>> <div class="alert alert--danger">👥 A group of guys you've never met wave you over in the cafeteria. "We're having a party tonight. Heard you're the entertainment." They're not asking.</div> <<modStat "stress" 8 "Group demand">> <<modCorruption 3 "Known reputation">> <</if>> <<elseif $reputation.slut >= 60>> /* Tier 3: Open propositions */ <<set _se = random(1, 3)>> <<if _se === 1>> <div class="alert alert--warning">🗣️ A guy you barely know propositions you in the hallway. Openly. "Everyone says you're great. How about tonight?" He's not even embarrassed.</div> <<modStat "arousal" 8 "Propositioned">> <<modCorruption 2 "Open proposition">> <<elseif _se === 2>> <div class="alert alert--warning">📱 Your phone buzzes with a message from an unknown number: "heard you give great head. prove it? dorm 314."</div> <<modStat "arousal" 5 "Sext">> <<else>> <div class="alert alert--warning">🚻 Someone slips a note under the bathroom stall: "Stick it through. I know who you are." <<toneThink "Hell no." "...maybe?" "Omg how exciting!">></div> <<modStat "arousal" 10 "Bathroom note">> <</if>> <<elseif $reputation.slut >= 40>> /* Tier 2: Catcalls, groping */ <<set _se = random(1, 3)>> <<if _se === 1>> <div class="alert alert--warning">👋 Someone grabs your ass in a crowded hallway. You spin around but can't tell who. <<toneThink "Disgusting." "Whatever." "Kinda exciting honestly...">></div> <<modStat "arousal" 5 "Groped">> <<modStat "stress" 3 "Violated">> <<elseif _se === 2>> <div class="alert alert--warning">🗣️ "Hey <<print $pc.firstName>>! Still available on CampusHub?" yelled across the quad. Loudly. Everyone heard.</div> <<modStat "stress" 5 "Public callout">> <<else>> <div class="alert alert--warning">👀 You notice a guy from your class staring at your chest. Not even trying to hide it. <<toneThink "Creep." "At least he's cute." "God I love attention!">></div> <<modStat "arousal" 3 "Stared at">> <</if>> <<else>> /* Tier 1: Mild */ <div class="alert alert--info">👀 A guy holds the door open for you and gives you a lingering once-over. "After you, beautiful." It's routine now.</div> <<modStat "femininity" 1 "Treated as a girl">> <</if>> /* ═══════════════════════════════════════════════════ 🌧️ AMBIENT EVENTS ═══════════════════════════════════════════════════ */
<<set _ev = random(1, 8)>> <<if _ev === 1>> <div class="alert alert--info">🌧️ It starts raining. You forgot your umbrella. Your white top is getting transparent. <<toneThink "Run for cover." "It's just rain." "OMG my shirt! 😱... actually, kind of sexy?">></div> <<modHygiene -5 "Rain">> <<if $transformation.sideEffects.exhibitionist >= 2>> <<modStat "arousal" 5 "Wet clothes exhibitionism">> <</if>> <<elseif _ev === 2>> <div class="alert alert--info">🔔 Fire alarm. Everyone pours out of the buildings. You're standing in the cold in whatever you were wearing. Which is... not much.</div> <<modStat "stress" 3 "Fire alarm">> <<elseif _ev === 3>> <div class="alert alert--info">🐈 There's a cat on campus. A fluffy orange one. It rubs against your legs and purrs. You feel inexplicably happy.</div> <<modStat "mood" 5 "Campus cat">> <<modStat "stress" -3 "Cat therapy">> <<elseif _ev === 4>> <div class="alert alert--info">☕ The campus coffee cart is giving away free samples. You grab one. It's terrible. But free is free.</div> <<modStat "energy" 5 "Free coffee">> <<elseif _ev === 5>> <div class="alert alert--info">🏗️ Construction noise all morning. They're building a new wing on the science building. Impossible to concentrate.</div> <<modStat "stress" 3 "Construction noise">> <<elseif _ev === 6>> <div class="alert alert--info">⚡ Power outage in the dorms. Just for an hour, but your phone's at 3%. Everyone's panicking like it's the apocalypse.</div> <<modStat "stress" 3 "Power outage">> <<elseif _ev === 7>> <div class="alert alert--info">🌅 The sunset over campus is genuinely stunning tonight. Orange and pink and gold. You stop and stare for a full minute.</div> <<modStat "mood" 5 "Beautiful sunset">> <<modStat "stress" -5 "Moment of peace">> <<else>> <div class="alert alert--info">🎶 Someone's blasting music from their dorm window. It's your guilty pleasure song. You catch yourself humming along.</div> <<modStat "mood" 3 "Music">> <</if>>
/* ─── Check for dream at sleep ─── */ <<widget "checkDream">> /* Don't dream twice in same day; base 30% chance + erotic dreams SE bonus */ <<set _dreamChance = 30 + ($transformation.sideEffects.eroticDreams * 15)>> <<if $dreams.lastDreamDay !== $world.day && random(1, 100) <= _dreamChance>> <<set $dreams.lastDreamDay = $world.day>> <<set $dreams.totalDreams++>> /* Select dream tier based on femininity */ <<if $pc.femininity < 25>> <<include "Dream_Resistance">> <<elseif $pc.femininity < 50>> <<include "Dream_Confusion">> <<elseif $pc.femininity < 75>> <<include "Dream_Acceptance">> <<else>> <<include "Dream_Embrace">> <</if>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ 💀 RESISTANCE TIER: Femininity 0-25 Nightmares, dysphoria, male memories fading ═══════════════════════════════════════════════════ */
<<set _d = random(1, 5)>> <<set _se = $transformation.sideEffects>> <div class="card" style="border-left: 3px solid #666;"> <div class="card__title">💤 Dream...</div> <<if _d === 1>> <p><em>You're in your old bedroom. Your old body. Flat chest, deep voice, stubble. You look in the mirror and it's... wrong. The face doesn't fit. You try to speak your name but only <<print $pc.firstName>> comes out. You wake gasping.</em></p> <<modStat "stress" 5 "Nightmare">> <<set $dreams.lastDreamType = "dysphoria">> <<elseif _d === 2>> <p><em>You're running through campus corridors but your body keeps changing. Taller, shorter, curves appearing and vanishing. Someone calls your male name but you can't remember how to respond to it. You turn a corner and fall.</em></p> <<modStat "stress" 5 "Body horror">> <<modStat "femininity" 1 "Dream shift">> <<elseif _d === 3>> <p><em>Your old friends. A bar. Guy talk. Sports. Beer. One of them looks at you and says "dude, your tits are showing." You look down. You're wearing a dress. Everyone laughs. You can't take it off.</em></p> <<modStat "stress" 8 "Humiliation dream">> <<elseif _d === 4>> <<if _se.memoryLoss >= 2>> <p><em>You're trying to remember your old life but the details blur. Your childhood home. Was it blue? Green? You can't remember your mother's face. Just <<print $pc.firstName>>. Just this body. The gaps terrify you.</em></p> <<modStat "stress" 10 "Memory loss dream">> <<else>> <p><em>You dream of the clinic. The pill. The transformation. Playing it backwards: the breasts shrinking, the curves flattening, your voice dropping. When you wake up, nothing has changed. You're still her.</em></p> <<modStat "stress" 5 "Transformation replay">> <</if>> <<else>> <p><em>A dark room. A voice whispers: "This is what you are now." You look at your hands. Small, manicured. You try to clench them into fists but they stay open, fingers spread, feminine, passive. You wake with your heart racing.</em></p> <<modStat "stress" 5 "Identity dream">> <<modStat "femininity" 1 "Dream conditioning">> <</if>> </div> /* ═══════════════════════════════════════════════════ 😕 CONFUSION TIER: Femininity 26-50 Mixed dreams, guilt, enjoying the female body ═══════════════════════════════════════════════════ */
<<set _d = random(1, 5)>> <<set _se = $transformation.sideEffects>> <div class="card" style="border-left: 3px solid #b89330;"> <div class="card__title">💤 Dream...</div> <<if _d === 1>> <p><em>You're at a party. A guy asks you to dance. In the dream, you say yes without hesitation. His hands on your waist feel natural. Good, even. You wake up confused and a little aroused.</em></p> <<modStat "arousal" 15 "Dance dream">> <<modStat "femininity" 2 "Enjoyed male attention">> <<set $dreams.lastDreamType = "mixed_romantic">> <<elseif _d === 2>> <p><em>You're shopping. Trying on dresses. In the dream you're laughing, spinning, asking the mirror "does this make my butt look good?" You wake up and the guilt hits like a truck.</em></p> <<modStat "femininity" 2 "Shopping dream">> <<modStat "mood" -3 "Dream guilt">> <<elseif _d === 3>> <p><em>You dream you're back as a guy. But it feels... wrong. Claustrophobic. Your chest is flat and it feels like something's missing. You reach for your breasts and they're not there and you feel a stab of loss. Wait. Loss?</em></p> <<modStat "femininity" 3 "Missing femininity">> <<modStat "stress" 3 "Confused">> <<elseif _d === 4>> <<if _se.bimbofication >= 2>> <p><em>Everything is pink. Soft. Giggly. You're doing your makeup in the dream and everything is just like, SO pretty? Someone tells you you're a good girl and you feel warm all over. You wake up smiling. Then stop.</em></p> <<modStat "femininity" 3 "Bimbo dream">> <<modStat "mood" 5 "Pink happiness">> <<else>> <p><em>You're in class. The professor calls on you and you answer in a voice that's pure soprano. Sweet, feminine, confident. Everyone nods along. You don't know the answer but it doesn't matter. You're charming.</em></p> <<modStat "femininity" 2 "Voice dream">> <<modStat "confidence" 3 "Dream confidence">> <</if>> <<else>> <p><em>A dream about your roommate. Nothing sexual, just the two of you talking, painting each other's nails, laughing at something on TV. It feels domestic. It feels like belonging.</em></p> <<modStat "mood" 5 "Friendship dream">> <<modStat "femininity" 2 "Sisterhood">> <</if>> </div> /* ═══════════════════════════════════════════════════ 💕 ACCEPTANCE TIER: Femininity 51-75 Erotic dreams, fantasising, waking aroused ═══════════════════════════════════════════════════ */
<<set _d = random(1, 5)>> <<set _se = $transformation.sideEffects>> <div class="card" style="border-left: 3px solid #e040a0;"> <div class="card__title">💤 Dream...</div> <<if _d === 1>> <p><em>His hands. Everywhere. You can't see his face but his body is warm against yours and you're arching into him, gasping his name. Your body is electric. The orgasm wakes you, and it was real.</em></p> <<modStat "arousal" 30 "Erotic dream">> <<modStat "femininity" 2 "Sexual fantasy">> <<set $dreams.lastDreamType = "erotic">> <<elseif _d === 2>> <p><em>You're in lingerie. Lace, silk, everything. You're posing for a camera. Not for anyone else. For you. You look in the mirror and you're stunning. You feel powerful. Desired. Complete.</em></p> <<modStat "confidence" 5 "Power dream">> <<modStat "femininity" 2 "Self-admiration">> <<modStat "arousal" 15 "Lingerie dream">> <<elseif _d === 3>> <<if _se.submissive >= 2>> <p><em>You're on your knees. Looking up. A voice says "good girl" and pleasure floods through you like a drug. You don't want to stand up. You never want to stand up. Being on your knees feels right.</em></p> <<modStat "arousal" 25 "Submissive dream">> <<modStat "femininity" 3 "Submission acceptance">> <<modCorruption 2 "Submissive dream">> <<else>> <p><em>A beach. Sunset. A stranger kisses you and you melt into it. You feel his hand slide down your back and you press closer. When you wake up, your pillow is between your thighs and you're drenched in sweat.</em></p> <<modStat "arousal" 25 "Beach dream">> <<modStat "femininity" 2 "Romance fantasy">> <</if>> <<elseif _d === 4>> <p><em>You dream you're at your own wedding. In a white dress. Walking down the aisle. You're crying happy tears. The groom is blurry but it doesn't matter. What matters is the dress, the flowers, the feeling of being cherished.</em></p> <<modStat "femininity" 3 "Wedding dream">> <<modStat "mood" 5 "Happy dream">> <<else>> <<if _se.oralLover >= 2>> <p><em>You're on your knees again. But this time you're eager. Hungry. The taste, the rhythm, the sounds he makes. All of it is intoxicating. You wake up with your mouth watering. Literally.</em></p> <<modStat "arousal" 30 "Oral dream">> <<modCorruption 2 "Oral craving dream">> <<else>> <p><em>Dancing. A club. Bodies pressed together. Hands on your hips. Someone whispers in your ear: "You're the most beautiful girl here." And for one perfect moment, you believe it completely.</em></p> <<modStat "arousal" 20 "Club dream">> <<modStat "femininity" 2 "Beauty dream">> <</if>> <</if>> </div> /* ═══════════════════════════════════════════════════ 🌸 EMBRACE TIER: Femininity 76-100 Vivid romantic/sexual dreams, can't remember being male ═══════════════════════════════════════════════════ */
<<set _d = random(1, 5)>> <<set _se = $transformation.sideEffects>> <div class="card" style="border-left: 3px solid #e040e0;"> <div class="card__title">💤 Dream...</div> <<if _d === 1>> <p><em>You dream of a life. Not your old one. Your real one. An apartment. A boyfriend. Sunday mornings in his t-shirt. Coffee and newspapers and his arm around you. Normal. Perfect. When you wake up, you reach for him and the bed is empty.</em></p> <<modStat "mood" -3 "Lonely waking">> <<modStat "femininity" 2 "Future fantasy">> <<set $dreams.lastDreamType = "domestic">> <<elseif _d === 2>> <p><em>The dream is so vivid you can feel it: his mouth on your neck, your legs wrapped around him, the bed creaking, your voice breaking as you cry out his name. You wake mid-orgasm, trembling, gasping, clutching the sheets.</em></p> <<modStat "arousal" 40 "Vivid erotic dream">> <<modStat "femininity" 2 "Complete surrender">> <<elseif _d === 3>> <p><em>Someone asks "were you always a girl?" and in the dream you laugh. "Of course. What a weird question." You genuinely can't remember being anything else. The male past is a stranger's biography.</em></p> <<modStat "femininity" 3 "Complete identity shift">> <<modStat "mood" 5 "Peace">> <<elseif _d === 4>> <<if _se.bimbofication >= 3>> <p><em>Like, everything is SO good? You're at a party and everyone loves you and your hair is perfect and boys keep buying you drinks and you're just SO happy? You wake up and your first thought is "I need to do my nails." You don't even question it.</em></p> <<modStat "femininity" 3 "Bimbo dream">> <<modStat "mood" 8 "Bliss">> <<set $pc.intelligence = Math.max(0, $pc.intelligence - 1)>> <<else>> <p><em>You're pregnant. The belly, the glow, someone rubbing your back. You look down and feel... complete. Terrifying and beautiful. You wake up with your hand on your flat stomach, searching.</em></p> <<modStat "femininity" 3 "Pregnancy dream">> <<modStat "mood" 3 "Maternal instinct">> <</if>> <<else>> <p><em>No narrative. Just sensation. Warmth. Touch. Pleasure. Being held. Being full. Being loved. Being a woman. It doesn't need a story anymore. It just IS.</em></p> <<modStat "mood" 8 "Pure acceptance">> <<modStat "femininity" 2 "Being">> <<modStat "arousal" 20 "Warm dream">> <</if>> </div>
<h2>🖤 An Unmarked Door</h2> <<advanceTime 15>> <p>Down a side street behind The Rusty Nail, you notice a door you've never seen before. Black, no sign, just a small brass placard: <em>"V.R."</em></p> <p>A woman in a leather corset opens the peephole. "First time?" She looks you over. "You have the look. Come in. First visit is free."</p> <<set $velvetRoom.discovered = true>> <div class="choice-group"> <<link '<span class="choice-btn">🖤 Enter</span>' "VelvetRoom_Hub">> <<set $velvetRoom.visited = true>> <<set $velvetRoom.membership = "visitor">> <</link>> <<link '<span class="choice-btn">🔙 Not today</span>' "BarDistrict">><</link>> </div>
<h2>🖤 The Velvet Room</h2> <<advanceTime 30>> <p>Red light. Black walls. The thud of bass from unseen speakers. The Velvet Room is a study in controlled darkness: velvet booths, iron fixtures, and alcoves curtained off for purposes nobody here feels any need to spell out.</p> <<if $velvetRoom.membership === "visitor">> <p>The hostess gestures to the bar. "As a visitor, you can watch. To participate, you'll need a membership. $100 for a month. Or..." she smiles, "you can earn one."</p> <<elseif $velvetRoom.membership === "regular">> <p>The hostess nods. "Welcome back. The rooms are open. Choose your experience."</p> <<elseif $velvetRoom.membership === "vip">> <p>"VIP! The private suite is available. And we have some... new equipment you might enjoy." She winks.</p> <</if>> <div class="choice-group"> <<if $velvetRoom.membership === "visitor">> <<link '<span class="choice-btn">💰 Buy membership ($100)</span>' "VelvetRoom_Hub">> <<if $finance.money >= 100>> <<payPlayer -100 "Velvet Room membership">> <<set $velvetRoom.membership = "regular">> <<run XCLC.Toast.show("🖤 Regular membership activated!", "success")>> <<else>> <<run XCLC.Toast.show("💸 Not enough money.", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">😏 Earn a membership</span>' "VelvetRoom_Earn">> <<modCorruption 3 "Velvet Room submission">> <</link>> <<link '<span class="choice-btn">👀 Just watch</span>' "VelvetRoom_Watch">><</link>> <<else>> <<link '<span class="choice-btn">🧎 Submissive Training</span>' "VelvetRoom_SubTraining">><</link>> <<link '<span class="choice-btn">🪢 Bondage Session</span>' "VelvetRoom_Bondage">><</link>> <<if $velvetRoom.sessionsAttended >= 3>> <<link '<span class="choice-btn">🐾 Pet Play</span>' "VelvetRoom_PetPlay">> <<set $velvetRoom.petPlayUnlocked = true>> <</link>> <</if>> <<if $velvetRoom.sessionsAttended >= 5>> <<link '<span class="choice-btn">👋 Impact Play</span>' "VelvetRoom_Impact">> <<set $velvetRoom.impactUnlocked = true>> <</link>> <</if>> <<if $velvetRoom.sessionsAttended >= 7>> <<link '<span class="choice-btn">🕯️ Sensation Play</span>' "VelvetRoom_Sensation">><</link>> <</if>> <<if $velvetRoom.membership === "regular" && $velvetRoom.sessionsAttended >= 10>> <<link '<span class="choice-btn">⭐ Apply for VIP</span>' "VelvetRoom_VIPUpgrade">><</link>> <</if>> <</if>> <<link '<span class="choice-btn">🔙 Leave</span>' "BarDistrict">><</link>> </div> <p class="stat-value" style="font-size:0.8em">Sessions: <<print $velvetRoom.sessionsAttended>> | Membership: <<print $velvetRoom.membership>> | Sub Training: <<print $velvetRoom.subTraining>></p>
<h2>👀 Watching</h2> <<advanceTime 30>> <p>You settle into a velvet booth with a drink and watch. A woman in a leather harness leads another woman on a leash across the room. In an alcove, someone is bent over a bench, the sound of impact rhythmic and precise. At the bar, a man feeds a kneeling girl sips of wine from his glass.</p> <p>It's simultaneously shocking and... magnetic. <<toneThink "This is messed up." "I can't look away." "This is the hottest thing I've ever seen. 😳">></p> <<modStat "arousal" 15 "Watching BDSM">> <<modCorruption 1 "Voyeurism">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to main room</span>' "VelvetRoom_Hub">><</link>> </div>
<h2>😏 Earning Your Membership</h2> <<advanceTime 60>> <p>The hostess leads you to a back room. "Simple. One session as a demonstration sub. The dom's experienced, safe, and will respect your limits. After that, you're a Regular."</p> <p>A tall man in a black shirt enters. "On your knees." His voice is calm, absolute.</p> <<set _earnResult = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _earnResult === "crit_success" || _earnResult === "success">> <p>You kneel. He walks around you slowly. "Good posture. You listen. That's rare." The session is intense. He works your limits with restraints, verbal commands and light impact, checking your colour between each without once breaking the frame of the thing. You take all of it.</p> <p>"Impressive. Welcome to the Velvet Room."</p> <<set $velvetRoom.membership = "regular">> <<set $velvetRoom.sessionsAttended++>> <<set $velvetRoom.subTraining += 2>> <<modStat "arousal" 25 "Sub initiation">> <<modStat "confidence" -5 "Submission">> <<modStat "femininity" 3 "Submissive role">> <<modCorruption 5 "BDSM initiation">> <<else>> <p>You try, but you flinch. You pull away. The dom stops immediately. "Not ready. Come back when you are."</p> <<modStat "stress" 5 "Failed initiation">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🧎 SUBMISSIVE TRAINING ═══════════════════════════════════════════════════ */
<h2>🧎 Submissive Training</h2> <<advanceTime 90>> <<set $velvetRoom.sessionsAttended++>> <<set $velvetRoom.lastVisitDay = $world.day>> <p>Your trainer is a woman called Mistress K, tall and striking and entirely untroubled by what you might make of her. She circles you slowly.</p> <<set _subLevel = $velvetRoom.subTraining>> <<if _subLevel < 3>> <p>"The first lesson is stillness. Kneel. Don't move. Don't speak unless spoken to." Time passes. Your knees ache. Your mind screams. But you stay.</p> <<modStat "willpower" -3 "Obedience training">> <<modStat "arousal" 10 "Kneeling">> <<elseif _subLevel < 6>> <p>"Good. You've learned stillness. Now: service positions." She puts you through a series of poses: presenting, waiting, offering. Each one strips away another layer of resistance.</p> <<modStat "willpower" -5 "Position training">> <<modStat "arousal" 15 "Posing">> <<modStat "femininity" 2 "Submission deepening">> <<elseif _subLevel < 10>> <p>"You respond to commands now without thinking. That's progress." She attaches a collar. The leather is warm. "This stays on for the session. You're property right now. Mine."</p> <<modStat "willpower" -8 "Collared">> <<modStat "arousal" 25 "Collar">> <<modStat "femininity" 3 "Deep submission">> <<else>> <p>"You've become... exceptional." Mistress K strokes your hair as you kneel. "The collar isn't a restraint anymore, is it? It's a relief." She's right. It is.</p> <<modStat "willpower" -10 "Total submission">> <<modStat "arousal" 30 "Deep sub space">> <<modStat "mood" 10 "Sub space bliss">> <<modStat "femininity" 3 "Surrender">> <</if>> <<set $velvetRoom.subTraining++>> <<modCorruption 3 "Sub training">> <<addXP "composure" 15>> <<payPlayer 50 "Sub session pay">> <<run XCLC.Toast.show("🖤 Sub Training Level: " + $velvetRoom.subTraining, "info")>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🪢 BONDAGE SESSION ═══════════════════════════════════════════════════ */
<h2>🪢 Bondage Session</h2> <<advanceTime 60>> <<set $velvetRoom.sessionsAttended++>> <<set $velvetRoom.bondageUnlocked = true>> <p>The rope artist is gentle but precise. Japanese rope bondage, intricate patterns that bind and support in the same motion, tension and structure doing one job between them.</p> <<set _bondResult = XCLC.Roll.doCheck("flexibility", 3)>> <<run XCLC.DicePopup.show()>> <<if _bondResult === "crit_success" || _bondResult === "success">> <p>Your flexibility makes the poses effortless. The ropes frame your body like art. You catch sight of yourself in the mirror. Bound, beautiful, and unexpectedly at peace with both.</p> <<modStat "arousal" 25 "Beautiful bondage">> <<modStat "mood" 10 "Rope art">> <<modStat "confidence" 3 "Body appreciation">> <<else>> <p>The ropes bite. Some positions are uncomfortable. But there is something in the vulnerability of it, in handing control over completely and entirely on purpose, that loosens something a long way down.</p> <<modStat "arousal" 15 "Bondage discomfort">> <<modStat "stress" -5 "Letting go">> <</if>> <<addXP "flexibility" 15>> <<modCorruption 2 "Bondage">> <<modStat "femininity" 2 "Vulnerability">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🐾 PET PLAY ═══════════════════════════════════════════════════ */
<h2>🐾 Pet Play</h2> <<advanceTime 60>> <<set $velvetRoom.sessionsAttended++>> <p>A collar with a little bell. Ears on a headband. A leash. You're led to a cushioned area with the other pets: two girls crawling, being hand-fed treats, curling into their owners' laps.</p> <p>"You don't have to think. You don't have to be human. Just be a good kitty." <<toneThink "This is insane." "It's... strangely calming?" "Purrrr! 🐱">></p> <<modStat "stress" -15 "Pet space">> <<modStat "willpower" -5 "Giving up autonomy">> <<modStat "arousal" 10 "Pet play">> <<modStat "femininity" 3 "Cute and passive">> <<modCorruption 3 "Pet play">> <p>Your "owner" for the session scratches behind your ears. You lean into it. They feed you strawberries from their hand. You eat without thinking.</p> <<modStat "mood" 10 "Being cared for">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 👋 IMPACT PLAY ═══════════════════════════════════════════════════ */
<h2>👋 Impact Play</h2> <<advanceTime 60>> <<set $velvetRoom.sessionsAttended++>> <p>You're bent over a padded bench. The dom shows you the implements: paddle, crop, flogger, hand.</p> <p>"Colour system. Green is go, yellow is slow, red is stop. What's your colour?"</p> <<set _impactResult = XCLC.Roll.doCheck("stamina", 4)>> <<run XCLC.DicePopup.show()>> <<if _impactResult === "crit_success" || _impactResult === "success">> <p>You take it well. The pain blooms into warmth. Each strike pushes you deeper into a floating, disconnected space where nothing matters but the rhythm. Your voice breaks into whimpers that border on moans.</p> <p>"Good girl. You took that beautifully."</p> <<modStat "arousal" 30 "Impact high">> <<modStat "mood" 10 "Endorphins">> <<modCorruption 4 "Impact play">> <<else>> <p>You call yellow after the third strike. It's too much. But the dom is entirely professional about it. Ice, aftercare, reassurance. "That's okay. You found a limit. That's what this is about."</p> <<modStat "arousal" 10 "Mild impact">> <<modStat "stress" 5 "Pain">> <</if>> <<addXP "stamina" 10>> <<modStat "femininity" 2 "Submissive role">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div> /* ═══════════════════════════════════════════════════ 🕯️ SENSATION PLAY ═══════════════════════════════════════════════════ */
<h2>🕯️ Sensation Play</h2> <<advanceTime 60>> <<set $velvetRoom.sessionsAttended++>> <p>Blindfolded. The world shrinks to touch. Ice traces down your spine. Warm wax drips on your collarbone. Silk, then rough leather. Feather-light fingertips, then sharp pinching.</p> <<if $transformation.sideEffects.increasedSensitivity >= 2>> <p>With your heightened sensitivity, every touch is amplified tenfold. The ice makes you gasp. The wax makes you cry out. A single fingertip between your shoulder blades makes your whole body arch.</p> <<modStat "arousal" 40 "Hypersensitive sensation">> <<modStat "mood" 15 "Overwhelming pleasure">> <<else>> <p>The alternation between hot and cold, rough and smooth, keeps your nerves singing. You can't predict what comes next. Your body responds to every stimulus with increasing urgency.</p> <<modStat "arousal" 25 "Sensation play">> <<modStat "mood" 10 "Sensory exploration">> <</if>> <<modCorruption 3 "Sensation play">> <<modStat "femininity" 2 "Sensory surrender">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div>
<h2>⭐ VIP Application</h2> <p>The hostess reviews your file. "<<print $velvetRoom.sessionsAttended>> sessions. Sub training level <<print $velvetRoom.subTraining>>. You've earned it."</p> <p>She clips a black card from her desk. "Welcome to VIP. Private suite access, priority scheduling, and... special events." She slides the card across the bar.</p> <<set $velvetRoom.membership = "vip">> <<run XCLC.Toast.show("⭐ VIP membership unlocked!", "success")>> <<modRep "slut" 3>> <<modCorruption 3 "VIP membership">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "VelvetRoom_Hub">><</link>> </div>
/* ─── Check if blackmail should trigger ─── */ <<widget "checkBlackmail">> <<if !$blackmail.active && !$blackmail.resolved>> /* Trigger conditions */ <<set _triggered = false>> <<set _type = "">> <<set _mailer = "">> /* FansOnly + popular = classmate recognises */ <<if $jobs.fansOnly.active && $reputation.popular >= 40 && random(1, 100) <= 10>> <<set _triggered = true>> <<set _type = "fansonly">> <<set _mailer = "classmate">> <</if>> /* Cam girl + high exposure */ <<if !_triggered && $jobs.camGirl.active && $jobs.camGirl.viewers >= 200 && random(1, 100) <= 8>> <<set _triggered = true>> <<set _type = "cam">> <<set _mailer = "viewer">> <</if>> /* Spring break photos surface */ <<if !_triggered && $springBreak && $springBreak.photosPosted >= 3 && random(1, 100) <= 5>> <<set _triggered = true>> <<set _type = "springbreak">> <<set _mailer = "anonymous">> <</if>> <<if _triggered>> <<set $blackmail.active = true>> <<set $blackmail.evidenceType = _type>> <<set $blackmail.blackmailer = _mailer>> <<set $blackmail.stage = 1>> <<sendMessage "Unknown Number" "I know what you do, " + $pc.firstName + ". I have proof. Check your phone when you're alone. 📸">> <<run XCLC.Toast.show("📱 New message from Unknown Number...", "warning")>> <</if>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ 📱 BLACKMAIL ARC — Stage-based progression ═══════════════════════════════════════════════════ */
<h2>📱 Unknown Number</h2> <<if $blackmail.stage === 1>> <p>The message comes with a photo. It's you. Unmistakably you.</p> <<if $blackmail.evidenceType === "fansonly">> <p>A screenshot of your FansOnly page, your face clearly visible, your bio, your most explicit post. The message reads:</p> <div class="alert alert--danger"><em>"<<print $pc.firstName>>, or should I say @<<print $pc.firstName.toLowerCase()>>_secret? $500 and this stays between us. Or the whole campus finds out by Monday. Your choice."</em></div> <<elseif $blackmail.evidenceType === "cam">> <p>A recording. A screenshot from one of your cam sessions, mid-performance, face in frame. The message reads:</p> <div class="alert alert--danger"><em>"Nice show last Tuesday. I recorded the whole thing. $500 and nobody sees this. Or I send it to your professors."</em></div> <<else>> <p>Photos from spring break. You, barely clothed, in compromising positions. The message reads:</p> <div class="alert alert--danger"><em>"Remember Playa Caliente? These photos are everywhere on my phone. $500 keeps them off the internet."</em></div> <</if>> <<modStat "stress" 20 "Blackmailed">> <<modStat "mood" -15 "Blackmail threat">> <div class="choice-group"> <<link '<span class="choice-btn">💰 Pay them ($500)</span>' "Blackmail_Pay">> <<if $finance.money >= 500>> <<payPlayer -500 "Blackmail payment">> <<set $blackmail.totalPaid += 500>> <<set $blackmail.stage = 2>> <<modCorruption 5 "Blackmail compliance">> <<else>> <<run XCLC.Toast.show("💸 You don't have $500!", "warning")>> <</if>> <</link>> <<link '<span class="choice-btn">🔍 Try to figure out who they are</span>' "Blackmail_Investigate">><</link>> <<link '<span class="choice-btn">🏛️ Report to Dean Harrison</span>' "Blackmail_Report">><</link>> <<link '<span class="choice-btn">🤷 Ignore it</span>' "Blackmail_Ignore">><</link>> </div> <<elseif $blackmail.stage === 2>> /* Escalation: demands get worse */ <p>They're back. Another message. This time the demands have escalated.</p> <div class="alert alert--danger"><em>"The money was nice. But I want more now. Meet me behind the gym storage room tonight at 10pm. Alone. Or the photos go live. You know what I want."</em></div> <<modStat "stress" 15 "Escalation">> <div class="choice-group"> <<link '<span class="choice-btn">😰 Go to the meeting</span>' "Blackmail_Meeting">><</link>> <<link '<span class="choice-btn">🔍 Investigate (find clues)</span>' "Blackmail_Investigate">><</link>> <<link '<span class="choice-btn">🤷 Ignore (risk exposure)</span>' "Blackmail_Ignore">><</link>> </div> <<elseif $blackmail.stage === 3>> /* Final escalation */ <p>The messages have become daily. Demanding. Controlling. They want to dictate what you wear, where you go, who you see.</p> <div class="alert alert--danger"><em>"You belong to me now. Tomorrow, wear a skirt. No underwear. I'll be watching. And smile, <<print $pc.firstName>>. You should be grateful someone still wants you."</em></div> <<modStat "stress" 25 "Total control">> <<modStat "willpower" -10 "Dominated">> <div class="choice-group"> <<link '<span class="choice-btn">😰 Comply</span>' "Blackmail_Comply">><</link>> <<if $blackmail.cluesFound >= 3>> <<link '<span class="choice-btn">🔍 Confront them (you know who it is)</span>' "Blackmail_Confront">><</link>> <</if>> <<link '<span class="choice-btn">💪 Refuse: leak it all</span>' "Blackmail_Refuse">><</link>> </div> <</if>>
<h2>💰 Paid Off</h2> <p>You transfer the money. For a week, silence. Then another message arrives.</p> <div class="alert alert--warning"><em>"Good girl. That wasn't so hard, was it? I'll be in touch."</em></div> <<modStat "stress" 10 "Waiting">> <<sendMessage "Unknown Number" "Good girl. That wasn't so hard, was it? I'll be in touch.">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Continue</span>' "CampusMap">><</link>> </div>
<h2>😰 The Meeting</h2> <<advanceTime 60>> <<set $blackmail.stage = 3>> <<set $blackmail.totalComplied++>> <p>You go. Behind the gym. 10pm. It's dark and your heart is hammering.</p> <p>A figure steps out of the shadows. <<if $blackmail.blackmailer === "classmate">>You recognise him Tyler, from your econ class. The quiet one who always sat in the back. He's not quiet now.<<elseif $blackmail.blackmailer === "viewer">>You don't recognise them. A man, mid-twenties, ordinary-looking. The kind of face you'd walk past without noticing.<<else>>They're wearing a hoodie, face obscured. You can't tell who they are.<<set $blackmail.cluesFound++>><</if>></p> <p>"On your knees." The command is flat. Emotionless. He shows you his phone, his thumb hovering over a "Share All" button.</p> <<modStat "stress" 15 "Forced encounter">> <<modStat "arousal" 10 "Power dynamic">> <<modCorruption 8 "Blackmail submission">> <div class="choice-group"> <<link '<span class="choice-btn">🧎 Comply</span>' "Blackmail_Comply">><</link>> <<link '<span class="choice-btn">💪 Refuse and walk away</span>' "Blackmail_Refuse">><</link>> </div>
<h2>😰 Compliance</h2> <<advanceTime 30>> <<set $blackmail.totalComplied++>> <p>You do what they say. It's degrading, mechanical, and they record everything, adding to their leverage. When it's over, they walk away without a word.</p> <<modStat "stress" 20 "Degraded">> <<modStat "willpower" -10 "Broken">> <<modStat "mood" -15 "Used">> <<modCorruption 10 "Blackmail service">> <<modRep "slut" 3>> <<sendMessage "Unknown Number" "Same time next week. Unless you find another way to make me happy. 📸">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Continue</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ 🔍 INVESTIGATION ARC ═══════════════════════════════════════════════════ */
<h2>🔍 Investigation</h2> <<advanceTime 60>> <<set $blackmail.investigating = true>> <p>You start digging. Who could it be?</p> <<set _investigateResult = XCLC.Roll.doCheck("intelligence", 4)>> <<run XCLC.DicePopup.show()>> <<if _investigateResult === "crit_success" || _investigateResult === "success">> <<set $blackmail.cluesFound++>> <<if $blackmail.cluesFound === 1>> <p>The phone number traces back to a burner but the area code is local. Campus.</p> <<elseif $blackmail.cluesFound === 2>> <p>You check the photo metadata. It was taken at a specific angle that narrows the location. And the timestamp matches a time when only a few people had access.</p> <<elseif $blackmail.cluesFound >= 3>> <p>You've got enough. The IP from a message, the angle of the photos, the timing it's <<if $blackmail.blackmailer === "classmate">>Tyler Morris. From your econ class.<<elseif $blackmail.blackmailer === "viewer">>someone who followed your cam sessions closely. You track the username to a campus network.<<else>>an anonymous account, but the digital trail leads back to campus IT, someone with server access.<</if>></p> <div class="alert alert--info">🔍 <strong>You know who the blackmailer is.</strong> You can confront them.</div> <</if>> <<else>> <p>Dead end. The messages are routed through anonymous services. You need to try again.</p> <<modStat "stress" 5 "Investigation frustration">> <</if>> <div class="choice-group"> <<if $blackmail.cluesFound >= 3>> <<link '<span class="choice-btn">⚡ Confront them NOW</span>' "Blackmail_Confront">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Continue for now</span>' "CampusMap">><</link>> </div>
<h2>⚡ Confrontation</h2> <<advanceTime 30>> <p>You find them. Face to face. Your evidence on your phone, their evidence on theirs.</p> <p>"It's over. I know who you are. <<if $blackmail.blackmailer === "classmate">>Tyler.<<else>>I traced your IP.<</if>> Delete everything. Now. Or I go to campus police with this." You show your evidence trail.</p> <<set _confrontResult = XCLC.Roll.doCheck("persuasion", 5)>> <<run XCLC.DicePopup.show()>> <<if _confrontResult === "crit_success" || _confrontResult === "success">> <p>Their face drains of colour. "Fine. Fine! It's deleted. Just... don't report me." They fumble with their phone, deleting files.</p> <<set $blackmail.active = false>> <<set $blackmail.resolved = true>> <<set $blackmail.resolutionType = "confronted">> <<modStat "confidence" 15 "Took back control">> <<modStat "mood" 10 "Justice">> <<awardAchievement "blackmailSurvivor">> <<run XCLC.Toast.show("✊ Blackmail arc RESOLVED. You won.", "success")>> <<else>> <p>They laugh. "You think that's enough? I have copies everywhere. Cloud, USB, email. Try again, sweetheart." They walk away. But they're nervous now. You can tell.</p> <<modStat "stress" 10 "Failed confrontation">> <<set $blackmail.cluesFound++>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Continue</span>' "CampusMap">><</link>> </div>
<h2>🏛️ Report to the Dean</h2> <<advanceTime 30>> <p>You go to Dean Harrison's office. You show him the messages. His expression darkens.</p> <p>"This is serious. Campus security will investigate. But <<print $pc.firstName>>... you should know. The investigation may expose the content itself. Are you prepared for that?"</p> <<set $blackmail.active = false>> <<set $blackmail.resolved = true>> <<set $blackmail.resolutionType = "reported">> <<modRep "slut" 5>> <<modRep "popular" -5>> <<modStat "stress" 10 "Investigation stress">> <<modStat "confidence" 5 "Stood up for self">> <<sendMessage "Dean Harrison" "The investigation is underway. We'll handle this, " + $pc.firstName + ". You did the right thing.">> <<run XCLC.Toast.show("🏛️ Blackmail reported. Investigation underway.", "info")>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Continue</span>' "CampusMap">><</link>> </div>
<h2>💪 Refuse</h2> <p>You take a breath. "Do it. Post everything. I don't care anymore."</p> <p><<toneThink "I'll deal with the fallout." "It can't be worse than this." "Let them see. I'm DONE hiding.">></p> <<set $blackmail.active = false>> <<set $blackmail.resolved = true>> <<set $blackmail.resolutionType = "refused">> /* Content gets leaked */ <<modRep "slut" 10>> <<modRep "popular" 5>> <<modStat "confidence" 10 "Refused to be controlled">> <<modStat "stress" 15 "Content leaked">> <<modStat "femininity" 3 "Embraced identity">> <<run XCLC.Toast.show("💪 Blackmail arc RESOLVED. You called their bluff.", "success")>> <p>They leak everything. For a week, campus buzzes. But then... people move on. Some people admire your courage. Others just shrug. "Everyone's got a FansOnly these days."</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Continue</span>' "CampusMap">><</link>> </div>
<h2>🤷 Ignoring It</h2> <p>You don't respond. Days pass. Then:</p> <<if $blackmail.stage < 3>> <<set $blackmail.stage++>> <div class="alert alert--danger">📱 <em>"I see you're ignoring me. Bad choice, <<print $pc.firstName>>. Tick tock."</em></div> <<modStat "stress" 10 "Threat escalation">> <<sendMessage "Unknown Number" "I see you're ignoring me. Bad choice, " + $pc.firstName + ". Tick tock.">> <<else>> /* They leak some content */ <<modRep "slut" 5>> <<modStat "stress" 15 "Content leaked">> <<sendMessage "Unknown Number" "You had your chance.">> <p>Some photos appear on campus social media. It's bad. But survivable. Barely.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Continue</span>' "CampusMap">><</link>> </div>
<h2>📱 Phone</h2> <<set _unread = $phone.messages.filter(function(m) { return !m.read; }).length>> <div class="phone-grid"> <<link '<div class="phone-app"><div class="phone-app-icon">🟣</div><div class="phone-app-name">CampusHub</div></div>' "Phone_CampusHub">><</link>> <<link '<div class="phone-app"><div class="phone-app-icon">📸</div><div class="phone-app-name">InstaGlam</div></div>' "Phone_InstaGlam">><</link>> <<link '<div class="phone-app"><div class="phone-app-icon">🐦</div><div class="phone-app-name">Chirpr</div></div>' "Phone_Chirpr">><</link>> <<link '<div class="phone-app"><div class="phone-app-icon">📅</div><div class="phone-app-name">Calendar</div></div>' "Phone_Calendar">><</link>> <<link '<div class="phone-app"><div class="phone-app-icon">👥</div><div class="phone-app-name">Contacts</div></div>' "Phone_Contacts">><</link>> <<if _unread gt 0>><<link '<div class="phone-app has-badge"><div class="phone-app-icon">💬</div><div class="phone-app-name">Messages</div></div>' "Phone_Messages">><</link>><<else>><<link '<div class="phone-app"><div class="phone-app-icon">💬</div><div class="phone-app-name">Messages</div></div>' "Phone_Messages">><</link>><</if>> <<if $notifications.unread > 0>><<link '<div class="phone-app has-badge"><div class="phone-app-icon">🔔</div><div class="phone-app-name">Alerts</div></div>' "Phone_Notifications">><</link>><<else>><<link '<div class="phone-app"><div class="phone-app-icon">🔔</div><div class="phone-app-name">Alerts</div></div>' "Phone_Notifications">><</link>><</if>> <<if $jobs.escort.active>><<link '<div class="phone-app"><div class="phone-app-icon">💼</div><div class="phone-app-name">Aurelia</div></div>' "Phone_Escort">><</link>><</if>> <<link '<div class="phone-app"><div class="phone-app-icon">🏦</div><div class="phone-app-name">Bank</div></div>' "Phone_Bank">><</link>> <<link '<div class="phone-app"><div class="phone-app-icon">🗺️</div><div class="phone-app-name">Maps</div></div>' "Phone_Maps">><</link>> <<if $cheats.enabled>><<link '<div class="phone-app"><div class="phone-app-icon">🧪</div><div class="phone-app-name">Cheats</div></div>' "Phone_Cheats">><</link>><</if>> <<link '<div class="phone-app"><div class="phone-app-icon">⚙️</div><div class="phone-app-name">Settings</div></div>' "Phone_Settings">><</link>> </div> <div class="choice-group"> <<link '<span class="choice-btn">📴 Put phone away</span>' `($ui.returnPassage || "CampusMap")`>><</link>> </div> /* ═══════════════════════════════════════════════════ 🟣 CAMPUSHUB: Service tracking ═══════════════════════════════════════════════════ */
<h2>🟣 CampusHub</h2> <div class="card"> <div class="card__title">📊 Weekly Quota</div> <p><strong>Serviced:</strong> <<print $scholarship.currentWeekServiced>> / <<print $scholarship.weeklyQuota>></p> <p><strong>Rating:</strong> <<print Math.round($scholarship.rating * 10) / 10>> ⭐</p> <p><strong>Total lifetime:</strong> <<print $scholarship.totalServiced>> encounters</p> <<if $scholarship.onProbation>> <p class="alert alert--danger">⚠️ ON PROBATION: rating below 4.0</p> <</if>> </div> <div class="card"> <div class="card__title">ℹ️ Matching policy</div> <p style="opacity:0.75;font-size:0.9em;">Requests are allocated by availability and proximity. Scholar preference is recorded at intake for statistical purposes and is not a factor in assignment.</p> <<if $pc.orientation && $pc.orientation !== "heterosexual">> <p style="opacity:0.6;font-size:0.85em;"><em>You read that line properly on about your fourth week. It is doing a great deal of work for one sentence.</em></p> <</if>> </div> <<if $scholarship.activeRequest>> <div class="card"> <div class="card__title">📍 Active Request</div> <<set _req = $scholarship.activeRequest>> <p><strong>Type:</strong> <<print _req.serviceType>></p> <p><strong>Location:</strong> <<print _req.locationName>></p> <p><strong>NPC:</strong> <<print _req.npc.firstName>></p> </div> <<else>> <div class="card"> <div class="card__title">📍 No Active Request</div> <p>Check back later or visit a campus location to receive requests.</p> </div> <</if>> <<if $scholarship.weeklyHistory && $scholarship.weeklyHistory.length > 0>> <div class="card"> <div class="card__title">📈 History</div> <<set _hist = $scholarship.weeklyHistory>> <<for _h = Math.max(0, _hist.length - 4); _h < _hist.length; _h++>> <p>Week <<print _hist[_h].week>>: <<print _hist[_h].serviced>> serviced, <<print _hist[_h].credits>> credits</p> <</for>> </div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ 📸 INSTAGLAM: Social media ═══════════════════════════════════════════════════ */
<h2>📸 InstaGlam</h2> <div class="card"> <div class="card__title">Your Profile: @<<print $pc.firstName.toLowerCase()>>_xo</div> <p>👤 <strong>Followers:</strong> <<print $phone.instaGlam.followers>></p> <p>📸 <strong>Posts:</strong> <<print $phone.instaGlam.posts>></p> <p>💕 <strong>Engagement:</strong> <<print Math.round($phone.instaGlam.engagement * 10) / 10>>%</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">📸 Post a selfie</span>' "Phone_InstaGlam"> <<advanceTime 10>> <<set $phone.instaGlam.posts++>> /* Follower gain based on beauty + outfit */ <<set _followGain = Math.floor(($pc.beautyTotal / 10) + random(5, 20))>> <<if $reputation.popular >= 50>><<set _followGain = Math.floor(_followGain * 1.5)>><</if>> <<set $phone.instaGlam.followers += _followGain>> <<set $phone.instaGlam.engagement = Math.min(10, $phone.instaGlam.engagement + 0.3)>> <<modRep "popular" 2>> <<run XCLC.Toast.show("📸 Posted! +" + _followGain + " followers!", "success")>> <</link>> <<if $jobs.camGirl.active || $jobs.fansOnly.active>> <<link '<span class="choice-btn">🔥 Post a thirst trap</span>' "Phone_InstaGlam"> <<advanceTime 15>> <<set $phone.instaGlam.posts++>> <<set _followGain = Math.floor(($pc.beautyTotal / 5) + random(20, 50))>> <<set $phone.instaGlam.followers += _followGain>> <<set $phone.instaGlam.engagement = Math.min(15, $phone.instaGlam.engagement + 0.8)>> <<modRep "popular" 3>> <<modRep "slut" 2>> <<modCorruption 1 "Thirst trap">> <<run XCLC.Toast.show("🔥 Thirst trap posted! +" + _followGain + " followers!", "success")>> <</link>> <</if>> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ 🐦 CHIRPR: Campus gossip feed ═══════════════════════════════════════════════════ */
<h2>🐦 Chirpr</h2> /* ─── Your profile & posting ─── */ <div class="card"> <div class="card__title">@<<print $pc.firstName.toLowerCase()>>_xo <span style="float:right; font-weight:400; font-size:0.85em; opacity:0.7;">👤 <<print $phone.chirpr.followers>> followers</span></div> <<set _period = XCLC.Time.getPeriodName($world.time)>> <<set _canPost = ($phone.chirpr.lastTweetDay !== $world.day || $phone.chirpr.lastTweetPeriod !== _period)>> <<if _canPost>> <p style="opacity:0.7; font-size:0.85em;">What's happening?</p> <div class="choice-group"> <<link '<span class="choice-btn">☕ Post about your day</span>' "Phone_Chirpr">> <<chirprPost "day">> <</link>> <<if $reputation.partyGirl >= 20>> <<link '<span class="choice-btn">🎉 Post party content</span>' "Phone_Chirpr">> <<chirprPost "party">> <</link>> <</if>> <<if $reputation.goodStudent >= 30>> <<link '<span class="choice-btn">📚 Post study grind content</span>' "Phone_Chirpr">> <<chirprPost "study">> <</link>> <</if>> <<if $pc.beautyTotal >= 50 || $reputation.slut >= 30>> <<link '<span class="choice-btn">🔥 Post something spicy</span>' "Phone_Chirpr">> <<chirprPost "spicy">> <</link>> <</if>> <<if $pregnancy.isPregnant && $pregnancy.discovered && !$phone.chirpr.announcedPregnancy>> <<link '<span class="choice-btn">🤰 Announce the pregnancy</span>' "Phone_Chirpr">> <<chirprPost "pregnancy">> <<set $phone.chirpr.announcedPregnancy = true>> <</link>> <</if>> </div> <<else>> <p style="opacity:0.6;"><em>You already chirped this <<print _period.toLowerCase()>>. Give the timeline a break.</em></p> <</if>> </div> /* ─── Your recent chirps ─── */ <<if $phone.chirpr.tweets.length > 0>> <div class="card"> <div class="card__title">📝 Your Chirps</div> <<for _t = $phone.chirpr.tweets.length - 1; _t >= Math.max(0, $phone.chirpr.tweets.length - 3); _t-->> <<set _tw = $phone.chirpr.tweets[_t]>> <div style="margin-bottom: 0.5em; padding: 0.5em; border-bottom: 1px solid rgba(255,255,255,0.1);"> <p style="margin: 0;"><<print _tw.text>></p> <p style="margin: 0.25em 0 0 0; font-size: 0.8em; opacity: 0.6;">❤️ <<print _tw.likes>> 🔁 <<print _tw.retweets>> <em>Day <<print _tw.day>></em></p> </div> <</for>> </div> <</if>> /* ─── Trending ─── */ <<set _trend = XCLC.Trending.build()>> <<if _trend.length > 0>> <div class="card"> <div class="card__title">📈 Trending at Thornfield</div> <<for _tr = 0; _tr < _trend.length; _tr++>> <<set _tt = _trend[_tr]>> <div style="margin-bottom: 0.4em;"> <p style="margin: 0;"><strong><<print _tt.tag>></strong><<if _tt.note>> <span style="opacity:0.65; font-size:0.85em;">· <<print _tt.note>></span><</if>></p> </div> <</for>> </div> <</if>> <div class="card"> <div class="card__title">📢 Campus Feed</div> /* Generate procedural chirps based on game state */ <<set _chirps = []>> /* General campus chirps */ <<run _chirps.push({user: "campuslife420", text: "the caf mac and cheese hits different at 2am ngl 🧀"})>> <<run _chirps.push({user: "thornfield_memes", text: "Professor Wilson's lectures could put caffeine to sleep ☕😴"})>> <<run _chirps.push({user: "dorm_drama", text: "someone set off the fire alarm AGAIN at 3am. i will find you. 🔥"})>> /* Rep-reactive chirps */ <<if $reputation.popular >= 50>> <<run _chirps.push({user: "gossip_queen", text: "ok but has anyone seen @" + $pc.firstName.toLowerCase() + "_xo lately?? goals 😍", aboutYou: true})>> <</if>> <<if $reputation.slut >= 50>> <<run _chirps.push({user: "anonymous_tbh", text: "that CCUMDUP girl is wild lmao. no judgment tho 👀", aboutYou: true})>> <</if>> <<if $reputation.goodStudent >= 60>> <<run _chirps.push({user: "studybuddy", text: $pc.firstName + " from the programme got the highest mark in econ. HOW?? 📚", aboutYou: true})>> <</if>> <<if $reputation.partyGirl >= 50>> <<run _chirps.push({user: "greeklife_tf", text: "Party at Sigma tonight. " + $pc.firstName + " better show up, she's the LIFE of every party 🎉", aboutYou: true})>> <</if>> <<if $jobs.camGirl.active>> <<run _chirps.push({user: "latenight_tbh", text: "ok who else found that cam girl and she looks JUST like someone on campus... 👀📷", aboutYou: true})>> <</if>> /* Seasonal chirps */ <<if $world.month === 10>> <<run _chirps.push({user: "halloween_szn", text: "slutty costume ideas thread go GO 🎃👻"})>> <</if>> <<if $springBreak && $springBreak.active>> <<run _chirps.push({user: "breakszn", text: "PLAYA CALIENTE BABY!! Who's here?? 🏖️🍹"})>> <</if>> /* Show latest 5 chirps: ones about you can be replied to */ <<set _repliedToday = ($phone.chirpr.lastReplyDay === $world.day)>> <<for _c = Math.max(0, _chirps.length - 5); _c < _chirps.length; _c++>> <<capture _c>> <div style="margin-bottom: 0.5em; padding: 0.5em; border-bottom: 1px solid rgba(255,255,255,0.1);"> <strong style="color: var(--accent);">@<<print _chirps[_c].user>></strong> <p style="margin: 0.25em 0 0 0;"><<print _chirps[_c].text>></p> <<if _chirps[_c].aboutYou>> <<if _repliedToday>> <p style="margin:0.3em 0 0 0; font-size:0.75em; opacity:0.5;"><em>You've already been in the replies today.</em></p> <<else>> <div class="choice-group" style="margin-top:0.35em;"> <<link '<span class="choice-btn" style="font-size:0.8em;">😏 Own it 👀</span>' "Phone_Chirpr">> <<chirprReply "own">> <</link>> <<link '<span class="choice-btn" style="font-size:0.8em;">🫣 Act embarrassed</span>' "Phone_Chirpr">> <<chirprReply "caught">> <</link>> <<link '<span class="choice-btn" style="font-size:0.8em;">💅 Reply with just an emoji</span>' "Phone_Chirpr">> <<chirprReply "emoji">> <</link>> <<if $pc.beautyTotal >= 50 || $reputation.slut >= 30>> <<link '<span class="choice-btn" style="font-size:0.8em;">🔥 Reply with a spicy pic</span>' "Phone_Chirpr">> <<chirprReply "spicy">> <</link>> <</if>> </div> <</if>> <</if>> </div> <</capture>> <</for>> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ 📅 CALENDAR: Academic calendar ═══════════════════════════════════════════════════ */
<h2>📅 Calendar</h2> <div class="card"> <div class="card__title">📆 <<print XCLC.Time.monthName($world.month)>>: Year <<print $world.year>>, Semester <<print $world.semester>></div> <p><strong>Today:</strong> <<showDate>>, Week <<print $world.week>></p> </div> /* Determine which events are coming up */ <<set _sem = $world.semester>> <<set _week = $world.week>> <<set _isOddSem = (_sem % 2 === 1)>> <<set _events = []>> <<if _isOddSem>> /* Fall semester events */ <<if _week <= 1>><<run _events.push({week: 1, name: "🎉 Freshman/Welcome Week", type: "social"})>><</if>> <<if _week <= 5>><<run _events.push({week: 5, name: "🏟️ Homecoming", type: "social"})>><</if>> <<if _week <= 8>><<run _events.push({week: 8, name: "🎃 Halloween", type: "social"})>><</if>> <<if _week <= 12>><<run _events.push({week: 12, name: "🦃 Thanksgiving Break", type: "break"})>><</if>> <<if _week <= 14>><<run _events.push({week: 14, name: "📝 Finals Week Begins", type: "academic"})>><</if>> <<if _week <= 15>><<run _events.push({week: 15, name: "❄️ Winter Formal", type: "social"})>><</if>> <<else>> /* Spring semester events */ <<if _week <= 6>><<run _events.push({week: 6, name: "💘 Valentine's Day", type: "social"})>><</if>> <<if _week <= 8>><<run _events.push({week: 8, name: "📝 Midterm Exams", type: "academic"})>><</if>> <<if _week <= 12>><<run _events.push({week: 12, name: "🏖️ Spring Break!", type: "break"})>><</if>> <<if _week <= 14>><<run _events.push({week: 14, name: "📝 Finals Week Begins", type: "academic"})>><</if>> <<if _week <= 16>><<run _events.push({week: 16, name: "🎓 End of Year", type: "social"})>><</if>> <</if>> /* Recurring events */ <<run _events.push({week: _week, name: "📋 CCUMDUP Quota Deadline", type: "service", recurring: "Every Sunday"})>> /* Dynamic events */ <<if $hypnosis.discovered && $hypnosis.sessionsAttended > 0>> <<run _events.push({week: _week, name: "🌀 Dr. Crane: Session", type: "appointment"})>> <</if>> <<if $jobs.cheerleader.active>> <<run _events.push({week: _week, name: "📣 Cheer Practice", type: "job", recurring: "Tuesdays & Thursdays"})>> <</if>> <<if $pregnancy.isPregnant && $pregnancy.discovered>> <<run _events.push({week: _week, name: "🤰 Pregnancy: Week " + $pregnancy.weeksPregnant, type: "health"})>> <</if>> /* Sort by week */ <<run _events.sort(function(a, b) { return a.week - b.week; })>> <div class="card"> <div class="card__title">📋 Upcoming Events</div> <<if _events.length === 0>> <p>Nothing upcoming.</p> <<else>> <<for _e = 0; _e < _events.length; _e++>> <<set _ev = _events[_e]>> <<set _weeksAway = _ev.week - _week>> <<set _style = "">> <<if _weeksAway <= 0>><<set _style = "color: var(--accent); font-weight: bold;">><</if>> <<if _weeksAway <= 1 && _weeksAway > 0>><<set _style = "color: var(--warning);">><</if>> <p @style="_style"> <<if _weeksAway <= 0>>📌 <strong>THIS WEEK:</strong> <<elseif _weeksAway === 1>>⏰ <strong>Next week:</strong> <<else>>📅 <strong>Week <<print _ev.week>>:</strong> <</if>> <<print _ev.name>> <<if _ev.recurring>> <em style="opacity:0.6;">(<<print _ev.recurring>>)</em><</if>> </p> <</for>> <</if>> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ 👥 CONTACTS ═══════════════════════════════════════════════════ */
<h2>👥 Contacts</h2> <div class="card"> <div class="card__title">📇 Your Contacts</div> <<if $roommate && $roommate.name>> <p>🏠 <strong><<print $roommate.name>></strong> · Roommate (Opinion: <<print $roommate.opinion>>/100)</p> <</if>> <<if $greekLife.member && $greekLife.sorority>> <p>💜 <strong><<print $greekLife.sorority>></strong> · Sisters</p> <</if>> <<if $jobs.barista.active>> <p>☕ <strong>Bean Scene</strong> · Work</p> <</if>> <<if $jobs.bartender.active>> <p>🍸 <strong>The Rusty Nail</strong> · Work</p> <</if>> <<if $jobs.stripper.active>> <p>💃 <strong>Club Velour</strong> · Work</p> <</if>> <<if $hypnosis.discovered>> <p>🌀 <strong>Dr. Crane</strong> · Therapist</p> <</if>> <<if $velvetRoom.discovered>> <p>🖤 <strong>The Velvet Room</strong> · ???</p> <</if>> <p>🏫 <strong>Dean Harrison</strong> · University Admin</p> <p>🔬 <strong>CCUMDUP Clinic</strong> · Programme Support</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ 💬 MESSAGES ═══════════════════════════════════════════════════ */
<h2>💬 Messages</h2> <<if $phone.messages.length === 0>> <div class="card"> <div class="card__title">No messages</div> <p>Your inbox is empty.</p> </div> <<else>> /* Conversation list: one entry per sender, tap to open the thread */ <<set _senders = {}>> <<for _m = 0; _m < $phone.messages.length; _m++>> <<set _msg = $phone.messages[_m]>> <<if !_senders[_msg.from]>><<set _senders[_msg.from] = {latest: _msg, unread: 0, count: 0}>><</if>> <<set _senders[_msg.from].latest = _msg>> <<set _senders[_msg.from].count++>> <<if !_msg.read>><<set _senders[_msg.from].unread++>><</if>> <</for>> <<set _senderKeys = Object.keys(_senders)>> <<for _s = 0; _s < _senderKeys.length; _s++>> <<capture _s>> <<set _entry = _senders[_senderKeys[_s]]>> <div class="card" @style="'margin-bottom: 0.5em;' + (_entry.unread > 0 ? ' border-left: 3px solid var(--accent-primary);' : '')"> <div class="card__title"><<if _entry.unread > 0>>🔵 <</if>><<print _senderKeys[_s]>> <<if _entry.count > 1>><em style="opacity:0.6; font-weight:normal;">(<<print _entry.count>> messages<<if _entry.unread > 0>>, <<print _entry.unread>> new<</if>>)</em><</if>></div> <p style="opacity: 0.8; font-size: 0.9em;"><<print _entry.latest.text.substring(0, 80)>><<if _entry.latest.text.length > 80>>...<</if>></p> <<link '<span class="choice-btn" style="font-size:0.85em;">📖 Open conversation</span>' "Phone_Thread">> <<set $temp.threadSender = _senderKeys[_s]>> <</link>> </div> <</capture>> <</for>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div>
<<set _sender = $temp.threadSender || "">> <h2>💬 <<print _sender>></h2> <<set _thread = $phone.messages.filter(function(m) { return m.from === _sender; })>> <<if _thread.length === 0>> <p>No messages here.</p> <<else>> <<for _t = 0; _t < _thread.length; _t++>> <<set _msg = _thread[_t]>> <div class="card" style="margin-bottom: 0.5em;"> <div class="card__title" style="font-size:0.8em; opacity:0.6;">Day <<print _msg.day>><<if typeof _msg.time === 'number'>>: <<print XCLC.Time.format(_msg.time)>><</if>></div> <p><<print _msg.text>></p> </div> <<run _msg.read = true>> <</for>> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to Messages</span>' "Phone_Messages">><</link>> </div> /* ═══════════════════════════════════════════════════ 🔔 NOTIFICATIONS: everything you scrolled past ═══════════════════════════════════════════════════ */
<h2>🔔 Alerts</h2> <<set _items = $notifications.items>> <<if _items.length === 0>> <div class="card"><div class="card__title">Nothing yet</div><p>Follower counts, XP, stat changes and events will collect here.</p></div> <<else>> <p style="opacity:0.7; font-size:0.85em;"><<print _items.length>> recent, newest first<<if $notifications.unread > 0>>, <<print $notifications.unread>> new<</if>>.</p> <div class="card"> <<for _n = _items.length - 1; _n >= Math.max(0, _items.length - 30); _n-->> <<set _it = _items[_n]>> <<set _isNew = (_items.length - 1 - _n) < $notifications.unread>> <div class="stat-bar-row" style="grid-template-columns: 8px 1fr 90px; padding: 3px 0;"> <span><<if _isNew>>🔵<</if>></span> <span style="font-size:0.9em;"><<print _it.text>></span> <span style="font-size:0.75em; opacity:0.5; text-align:right;">Day <<print _it.day>> <<print _it.time>></span> </div> <</for>> </div> <</if>> <div class="choice-group"> <<if _items.length > 0>> <<link '<span class="choice-btn">🧹 Clear all</span>' "Phone_Notifications">> <<set $notifications.items = []>> <<set $notifications.unread = 0>> <</link>> <</if>> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">> <<set $notifications.unread = 0>> <</link>> </div> /* ═══════════════════════════════════════════════════ 🏦 BANK: Finances & transaction history ═══════════════════════════════════════════════════ */
<h2>🏦 Thornfield Credit Union</h2> <div class="card"> <div class="card__title">💰 Account</div> <p style="font-size: 1.4em; margin: 0.2em 0;"><strong>$<<print $finance.money>></strong></p> <<if $finance.debt > 0>> <div class="alert alert--warning">💳 <strong>Outstanding debt: $<<print $finance.debt>></strong>, from your X-Change financing.</div> <<set _installment = Math.min(50, $finance.debt)>> <<if $finance.money >= _installment && $finance.debt > _installment>> <<capture _installment>> <<link '<span class="choice-btn" style="font-size:0.85em;">💳 Pay $<<print _installment>> toward debt</span>' "Phone_Bank">> <<set $finance.money -= _installment>> <<set $finance.debt = Math.max(0, $finance.debt - _installment)>> <<logExpense `_installment` "Debt payment">> <<run XCLC.Toast.show("💳 Debt payment made. $" + State.variables.finance.debt + " remaining.", "success")>> <</link>> <</capture>> <</if>> <<if $finance.money >= $finance.debt>> <<link '<span class="choice-btn" style="font-size:0.85em;">💳 Pay off entire debt ($<<print $finance.debt>>)</span>' "Phone_Bank">> <<set _payoff = $finance.debt>> <<set $finance.money -= _payoff>> <<set $finance.debt = 0>> <<logExpense `_payoff` "Debt cleared">> <<run XCLC.Toast.show("🎉 Debt fully paid off!", "success")>> <</link>> <<elseif $finance.money < _installment>> <p style="opacity:0.6; font-size:0.85em;"><em>You need at least $<<print _installment>> to make a payment.</em></p> <</if>> <</if>> </div> <div class="card"> <div class="card__title">📊 Lifetime</div> <p><strong>Total earned:</strong> $<<print $finance.totalEarned>></p> <p><strong>Total spent (tracked):</strong> $<<print $finance.totalSpent>></p> </div> <div class="card"> <div class="card__title">🧾 Recent Transactions</div> <<if !$finance.transactions || $finance.transactions.length === 0>> <p style="opacity:0.6;"><em>No transactions on record yet.</em></p> <<else>> <<for _tx = $finance.transactions.length - 1; _tx >= Math.max(0, $finance.transactions.length - 10); _tx-->> <<set _t = $finance.transactions[_tx]>> <p style="margin: 0.2em 0; font-family: var(--font-mono); font-size: 0.85em;"> <span @style="'color: ' + (_t.amount >= 0 ? 'var(--success)' : 'var(--danger)')"><<if _t.amount >= 0>>+<<else>>−<</if>>$<<print Math.abs(_t.amount)>></span> <<print _t.reason>> <em style="opacity:0.5;">(Day <<print _t.day>>)</em> </p> <</for>> <</if>> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ 🗺️ MAPS: Quick travel ═══════════════════════════════════════════════════ */
<h2>🗺️ Campus Maps</h2> <div class="card"> <div class="card__title">📍 Quick Travel</div> <p>Tap a destination:</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">🏠 Dorm Room</span>' "DormRoom">><</link>> <<link '<span class="choice-btn">🗺️ Campus Map</span>' "CampusMap">><</link>> <<link '<span class="choice-btn">🎭 Student Center</span>' "StudentCenter">><</link>> <<link '<span class="choice-btn">📚 Library</span>' "Library">><</link>> <<link '<span class="choice-btn">🍽️ Cafeteria</span>' "Cafeteria">><</link>> <<link '<span class="choice-btn">💪 Gym</span>' "Gym">><</link>> <<link '<span class="choice-btn">🏥 Health Centre</span>' "HealthCentre">><</link>> <<link '<span class="choice-btn">🏛️ Lecture Halls</span>' "LectureHalls">><</link>> <<link '<span class="choice-btn">🛍️ Mall</span>' "Mall">><</link>> <<link '<span class="choice-btn">🍸 Bar District</span>' "BarDistrict">><</link>> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> /* ═══════════════════════════════════════════════════ ⚙️ SETTINGS: Save/Load ═══════════════════════════════════════════════════ */
<h2>⚙️ Settings</h2> <div class="card"> <div class="card__title">💾 Save & Load</div> <div class="choice-group"> <<link '<span class="choice-btn">💾 Save Game</span>' "Phone_SaveGame">><</link>> <<link '<span class="choice-btn">📂 Load Game</span>' "Phone_LoadGame">><</link>> <<link '<span class="choice-btn">📤 Export Save (JSON)</span>' "Phone_Settings">> <<run XCLC.SaveSystem.exportSave()>> <</link>> <<link '<span class="choice-btn">📥 Import Save (JSON)</span>'>> <<run XCLC.SaveSystem.importSave()>> <</link>> </div> </div> <div class="card"> <div class="card__title">🧪 Developer Options</div> <p style="opacity:0.75;">Cheats are currently <strong><<if $cheats.enabled>>on<<else>>off<</if>></strong>.</p> <div class="choice-group"> <<link '<span class="choice-btn">🧪 Developer Options</span>' "Phone_Cheats_Toggle">><</link>> </div> </div> <div class="card"> <div class="card__title">🎮 Game Info</div> <p><strong>Day:</strong> <<print $world.day>> | <strong>Week:</strong> <<print $world.week>> | <strong>Semester:</strong> <<print $world.semester>></p> <p><strong>Corruption:</strong> <<print $corruption.score>>/100 (<<print $corruption.tier>>)</p> <p><strong>Femininity:</strong> <<print $pc.femininity>>/100</p> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div>
<h2>💾 Save Game</h2> <div class="card"> <div class="card__title">Choose a slot</div> <<for _slot = 1; _slot <= 5; _slot++>> <<capture _slot>> <<set _saveData = XCLC.SaveSystem.getSlotInfo(_slot)>> <<if _saveData>> <div style="margin-bottom: 0.5em;"> <p><strong>Slot <<print _slot>>:</strong> Day <<print _saveData.day>>, Sem <<print _saveData.semester>>, Fem <<print _saveData.femininity>></p> <<link '<span class="choice-btn" style="font-size:0.8em;">💾 Overwrite</span>' "Phone_SaveGame">> <<run XCLC.SaveSystem.saveToSlot(_slot)>> <<run XCLC.Toast.show("💾 Saved to Slot " + _slot + "!", "success")>> <</link>> </div> <<else>> <<link '<span class="choice-btn">💾 Save to Slot <<print _slot>> (empty)</span>' "Phone_SaveGame">> <<run XCLC.SaveSystem.saveToSlot(_slot)>> <<run XCLC.Toast.show("💾 Saved to Slot " + _slot + "!", "success")>> <</link>> <</if>> <</capture>> <</for>> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Settings">><</link>> </div>
<h2>📂 Load Game</h2> <div class="card"> <div class="card__title">Choose a slot</div> <<for _slot = 1; _slot <= 5; _slot++>> <<capture _slot>> <<set _saveData = XCLC.SaveSystem.getSlotInfo(_slot)>> <<if _saveData>> <<link '<span class="choice-btn">📂 Slot <<print _slot>>: Day <<print _saveData.day>>, Sem <<print _saveData.semester>></span>' "Phone_LoadGame">> <<run XCLC.SaveSystem.loadFromSlot(_slot)>> <</link>> <<else>> <p style="opacity:0.5;">Slot <<print _slot>>: Empty</p> <</if>> <</capture>> <</for>> </div> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Settings">><</link>> </div> /* ═══════════════════════════════════════════════════ 📱 MESSAGE SENDING WIDGET Used by other systems to send phone messages ═══════════════════════════════════════════════════ */
/* ─── Post a chirp ─── */ /* Usage: <<chirprPost "day"|"party"|"study"|"spicy">> */ <<widget "chirprPost">> <<set _kind = _args[0] || "day">> <<set _texts = { day: [ "survived another day at thornfield. barely. ☕", "the campus coffee cart said 'the usual?' and i have never felt more seen 🥹", "me vs my 9am: the 9am is winning", "today was actually kind of a good day?? suspicious 🤨" ], party: [ "last night was a MOVIE 🎬🍺 no further comments", "greek row is undefeated. my liver is not 🎉", "if you weren't there, you missed it. that's all. 💅", "pregaming the pregame. it's called efficiency 🥂" ], study: [ "library grind szn 📚 gpa we rise", "4 hours in the stacks. i AM the curve now 🧠", "professor said my essay was 'insightful' so i am framing this chirp", "study group carried? no. i carried the study group 📈" ], pregnancy: [ "so. small announcement. there's going to be one more of me around here soon 🤰", "turns out the programme has side effects they don't put on the flyer 🤰💕", "me + 1. figuring it out as I go, like everything else this year 🤰", "guess who's got a doctor's appointment and a whole new set of problems 🤰" ], spicy: [ "gym fit check... you're welcome 🍑", "felt cute. dangerous, even. 😏📸", "my DMs are a warzone rn and honestly? deserved 🔥", "some of you know exactly what you did to my notifications 👀" ] }>> <<set _pool = _texts[_kind]>> <<set _tweetText = _pool[random(0, _pool.length - 1)]>> /* Engagement scales with popularity + beauty; spicy scales harder */ <<set _base = 3 + Math.floor($reputation.popular / 5) + Math.floor($pc.beautyTotal / 15)>> <<if _kind === "spicy">><<set _base = Math.round(_base * 2) + Math.floor($reputation.slut / 10)>><</if>> <<set _likes = _base + random(0, _base)>> <<set _rts = Math.floor(_likes / 4) + random(0, 2)>> <<set _newFollowers = Math.max(1, Math.floor(_likes / 3) + random(0, 5))>> <<set $phone.chirpr.followers += _newFollowers>> <<run $phone.chirpr.tweets.push({text: _tweetText, likes: _likes, retweets: _rts, day: $world.day, kind: _kind})>> <<if $phone.chirpr.tweets.length > 10>><<run $phone.chirpr.tweets.shift()>><</if>> <<set $phone.chirpr.lastTweetDay = $world.day>> <<set $phone.chirpr.lastTweetPeriod = XCLC.Time.getPeriodName($world.time)>> /* Reputation effects */ <<modRep "popular" 1>> <<if _kind === "party">><<modRep "partyGirl" 2>><</if>> <<if _kind === "study">><<modRep "goodStudent" 1>><</if>> <<if _kind === "spicy">><<modRep "slut" 2>><<modCorruption 1 "Spicy chirp">><</if>> <<run XCLC.Toast.show("🐦 Chirped! +" + _newFollowers + " followers, " + _likes + " likes", "success")>> <</widget>> /* ─── Reply to a chirp that's about you ─── */ <<widget "chirprReply">> <<set _kind = _args[0] || "own">> <<set _base = 2 + Math.floor($reputation.popular / 8) + Math.floor($pc.beautyTotal / 20)>> <<if _kind === "spicy">><<set _base = _base * 2 + Math.floor($reputation.slut / 12)>><</if>> <<set _gain = Math.max(1, _base + random(0, _base))>> <<set $phone.chirpr.followers += _gain>> <<set $phone.chirpr.lastReplyDay = $world.day>> <<if _kind === "own">> <<modRep "popular" 1>> <<run XCLC.Toast.show("🐦 You owned it in the replies. +" + _gain + " followers", "success")>> <<elseif _kind === "caught">> <<modRep "popular" 1>> <<modStat "femininity" 1 "Playing along">> <<run XCLC.Toast.show("🐦 Played it perfectly. +" + _gain + " followers", "success")>> <<elseif _kind === "emoji">> <<run XCLC.Toast.show("🐦 One emoji. Devastating. +" + _gain + " followers", "info")>> <<else>> <<modRep "popular" 2>> <<modRep "slut" 2>> <<modCorruption 1 "Spicy reply">> <<run XCLC.Toast.show("🔥 The quote-chirps are feral. +" + _gain + " followers", "success")>> <</if>> <</widget>> <<widget "sendMessage">> /* $args[0] = from, $args[1] = text */ <<set _newMsg = { id: $phone.nextMessageId++, from: _args[0], text: _args[1], read: false, day: $world.day, time: $world.time }>> <<run $phone.messages.push(_newMsg)>> <<set $phone.notifications++>> <</widget>>
<h2>🚻 Library Bathroom</h2> <<advanceTime 5>> <p>You duck into the library bathroom. Third stall from the left. Someone's scratched something into the paint:</p> <p style="font-family: monospace; color: var(--accent);"><em>"Tuesdays & Thursdays. 9pm. Knock twice. GH"</em></p> <p>Below it, a rough hole in the wall, about waist height, plugged with toilet paper. <<toneThink "Disgusting." "...interesting." "Oh my GOD. Is that a...?">></p> <<set $gloryHole.libraryDiscovered = true>> <div class="choice-group"> <<link '<span class="choice-btn">🚻 Come back later</span>' "Library">><</link>> </div>
<h2>🚻 Library Glory Hole</h2> <<advanceTime 30>> <<if $world.dayOfWeek !== 2 && $world.dayOfWeek !== 4>> <p>It's not Tuesday or Thursday. The stall is empty, the hole plugged. Come back on the right day.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Library">><</link>> </div> <<elseif $world.time < 1260>> <p>Too early. The note said 9pm. Come back tonight.</p> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "Library">><</link>> </div> <<else>> <p>The third stall. 9pm. You lock the door. Your heart is hammering. The toilet paper has been removed from the hole. On the other side, you can hear breathing.</p> <p>A low voice: "You here for this?"</p> <div class="choice-group"> <<link '<span class="choice-btn">🧎 Participate</span>' "GloryHole_Library_Act">><</link>> <<link '<span class="choice-btn">👀 Watch through the gap</span>' "GloryHole_Library_Watch">><</link>> <<link '<span class="choice-btn">🔙 Leave (this is insane)</span>' "Library">><</link>> </div> <</if>>
<h2>🚻 Anonymous</h2> <<advanceTime 15>> <<set $gloryHole.timesUsed++>> <<set $gloryHole.lastVisitDay = $world.day>> <p>No names. No faces. Just a wall and anonymity. You kneel on the cold tile.</p> <<set _ghResult = XCLC.Roll.doCheck("oral", 3)>> <<run XCLC.DicePopup.show()>> <<if _ghResult === "crit_success" || _ghResult === "success">> <p>Quick, efficient, and strangely empowering. The voice on the other side: "Holy shit. Five stars." You hear them zip up and leave.</p> <<modStat "mood" 5 "Skilled performance">> <<else>> <p>Awkward. Your jaw aches. They finish eventually. No thanks, just the sound of footsteps leaving.</p> <</if>> <<addXP "oral" 15>> <<addXP "deepThroat" 10>> <<modStat "arousal" 20 "Glory hole">> <<modRep "slut" 3>> <<modCorruption 3 "Glory hole">> <<stdRisk "oral" 2>> /* Reduced service credits for anonymous */ <<set $scholarship.currentWeekCredits += 0.5>> <<run XCLC.Toast.show("🚻 +0.5 service credits (anonymous)", "info")>> <<toneThink "I can't believe I did that." "That was... easy. Too easy." "Omg I want to go again. 🤤">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave quickly</span>' "Library">><</link>> </div>
<h2>👀 Watching</h2> <<advanceTime 10>> <p>You peer through the gap in the stall wall. Another girl is in the third stall. She kneels. Through the hole... the scene plays out. Anonymous, efficient, oddly mechanical.</p> <p>Your face burns. You shouldn't be watching. But you can't look away.</p> <<modStat "arousal" 15 "Voyeurism">> <<modCorruption 1 "Watching">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "Library">><</link>> </div>
<h2>🚻 Bar Bathroom Glory Hole</h2> <<advanceTime 20>> <p>The bathroom at The Rusty Nail. Graffiti-covered walls, flickering light, and the unmistakable hole in the stall divider. This one's more... aggressive than the library. No schedule. Just opportunity.</p> <<set $gloryHole.timesUsed++>> <<set $gloryHole.lastVisitDay = $world.day>> <<set _ghResult = XCLC.Roll.doCheck("oral", 4)>> <<run XCLC.DicePopup.show()>> <<if _ghResult === "crit_success" || _ghResult === "success">> <p>You handle it like a professional. Fast, skilled, no hesitation. A crumpled $20 bill slides through the hole after. "You're a natural."</p> <<payPlayer 20 "Glory hole tip">> <<modStat "mood" 3 "Bar glory hole">> <<else>> <p>Rough. He pushes through too eagerly. You gag, eyes watering. When it's over, there's no tip. Just silence.</p> <<modStat "stress" 5 "Rough encounter">> <</if>> <<addXP "oral" 20>> <<addXP "deepThroat" 15>> <<modStat "arousal" 15 "Bar glory hole">> <<modRep "slut" 3>> <<modCorruption 4 "Bar glory hole">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to bar</span>' "BarDistrict">><</link>> </div> /* ═══════════════════════════════════════════════════ 🌀 DR. CRANE: "STRESS MANAGEMENT" A thriller, not a fetish arc. Crane is a predator who conditions patients without their knowledge. The player detects it, investigates, and stops him. Nothing here is eroticised: the violation is written as violation, and the player always has a way out that the game rewards. ═══════════════════════════════════════════════════ */
<h2>🏥 Health Centre: Notice Board</h2> <p>A flyer on the Health Centre notice board, printed on nice paper, slightly nicer than everything around it:</p> <div class="card"> <div class="card__title">🌀 Stress Management Sessions</div> <p><em>Feeling overwhelmed? Dr. Elias Crane offers free weekly relaxation and mindfulness sessions for CCUMDUP programme participants. Reduce stress, improve focus, find your calm.</em></p> <p><strong>Tuesdays, 4pm · Room 3B</strong></p> </div> <p>Free, on campus, and aimed squarely at people in the programme. <<toneThink "Probably useless." "Honestly? I could use it." "Free therapy! My mental health! 🧠">></p> <<set $hypnosis.discovered = true>> <div class="choice-group"> <<link '<span class="choice-btn">📅 Book a session</span>' "HealthCentre">> <<run XCLC.Toast.show("📅 Booked: Tuesdays, 4pm, Room 3B", "success")>> <</link>> <<link '<span class="choice-btn">🔙 Not for me</span>' "HealthCentre">><</link>> </div>
<h2>🌀 Room 3B</h2> <<advanceTime 60>> <<set $hypnosis.sessionsAttended++>> <<set $hypnosis.lastSessionDay = $world.day>> <<set _n = $hypnosis.sessionsAttended>> <p>Room 3B is dim and warm. Dr. Crane is silver-haired, unhurried, with the kind of calm that makes you feel like the only person in the building. "Welcome back, <<print $pc.firstName>>. Sit wherever's comfortable."</p> <<if _n <= 2>> /* ── Genuinely helpful. This is how it works. ── */ <p>He talks you through breathing. Four counts in, six out. It's not mystical and it isn't a trick. It's the standard stuff, done well, and by the end of the hour the knot you've been carrying between your shoulders has loosened for the first time in weeks.</p> <p>"Same time next week, if it helps."</p> <<modStat "stress" -20 "Genuine relaxation">> <<modStat "mood" 8 "An hour of calm">> <<else>> /* ── Something is wrong. ── */ <<set _flagPool = [ "You surface mid-sentence, your own, with no memory of having started it. The clock says forty minutes have gone. It felt like five.", "He's writing while you talk. When you shift to see the page, he closes the notebook without breaking eye contact or his sentence.", "There's a small recorder on the desk that wasn't there last week. He doesn't mention it. Neither do you, and you can't work out why you didn't.", "A word snags on the way past. Ordinary, harmless, and your chest goes tight for no reason you can name. He watches you notice it.", "You come round with your hands folded in your lap. You don't fold your hands. You have never once sat like that." ]>> <<set _flag = _flagPool[random(0, _flagPool.length - 1)]>> <p>He guides you down again, further than last time. His voice does most of the work. Somewhere in the hour, you lose the thread.</p> <p><em><<print _flag>></em></p> <<modStat "stress" -10 "Something like rest">> /* Perception check: do you catch it? */ <<set _catch = XCLC.Roll.doCheck("intelligence", Math.max(2, 6 - $hypnosis.redFlags))>> <<run XCLC.DicePopup.show()>> <<if _catch === "crit_success" || _catch === "success">> <<set $hypnosis.redFlags++>> <div class="alert alert--warning">🧠 You hold onto it this time. That's the <<print $hypnosis.redFlags === 1 ? "first" : "third or fourth">> time something hasn't added up in this room, and you're done writing it off as tiredness.</div> <<modStat "willpower" 3 "Trusting your own judgement">> <<else>> <p>You turn it over on the walk back and it slides out of your hands. By the time you reach Hamilton you couldn't say what was bothering you. Probably nothing. You're tired, that's all.</p> <<set $hypnosis.lingering = true>> <<modStat "willpower" -4 "Something wearing thin">> <<modStat "stress" 5 "Unnamed unease">> <</if>> /* Failsafe: the player is never trapped. */ <<if _n >= 6 && !$hypnosis.suspicious>> <<set $hypnosis.redFlags = Math.max($hypnosis.redFlags, 2)>> <div class="alert alert--danger">🧠 <strong>You wake up in the corridor.</strong> Not the room. The corridor, coat on, bag packed, no memory of having stood up. Whatever is happening in Room 3B, it is happening to you, and you have been letting it.</div> <<modStat "stress" 15 "Real fear">> <</if>> <</if>> <<if $hypnosis.redFlags >= 2 && !$hypnosis.suspicious>> <<set $hypnosis.suspicious = true>> <<run XCLC.Toast.show("🔍 You can start looking into Dr. Crane.", "warning", 6000)>> <</if>> <div class="choice-group"> <<if $hypnosis.suspicious>> <<link '<span class="choice-btn">🔍 Start looking into him</span>' "Crane_Investigate">><</link>> <<link '<span class="choice-btn">🚪 Stop going. Just stop.</span>' "Crane_Walk">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Leave</span>' "HealthCentre">><</link>> </div>
<h2>🚪 Not Going Back</h2> <p>You don't book another session. You don't email to cancel, you just stop appearing, and the relief of that decision tells you everything you needed to know about whether it was the right one.</p> <<if $hypnosis.lingering>> <p>It takes a fortnight to feel like yourself. Certain words still land oddly. You find yourself avoiding the east corridor of the Health Centre without deciding to.</p> <div class="alert alert--info">🏥 The clinic can screen you for lingering suggestion and clear it. Ask at reception.</div> <<else>> <p>Whatever he was building, he didn't finish it.</p> <</if>> <<modStat "confidence" 8 "Trusted your gut">> <<modStat "willpower" 8 "Walked away">> <<set $hypnosis.resolved = true>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "HealthCentre">><</link>> </div>
<h2>🔍 Building a File</h2> <p>If you're going to say this out loud to anyone who matters, "it felt weird" won't survive contact with a disciplinary panel. You need something they can't wave away.</p> <<set _ev = $hypnosis.evidence>> <div class="card"> <div class="card__title">📁 What You Have (<<print _ev.length>>/4)</div> <<if _ev.length === 0>> <p style="opacity:0.6;"><em>Nothing yet.</em></p> <<else>> <<for _e = 0; _e < _ev.length; _e++>> <p>✅ <<print _ev[_e]>></p> <</for>> <</if>> </div> <div class="choice-group"> <<if _ev.indexOf("Zoe's account of your missing evenings") === -1 && $roommate.name>> <<link '<span class="choice-btn">🏠 Ask <<print $roommate.name>> what she has noticed</span>' "Crane_Evidence_Roommate">><</link>> <</if>> <<if _ev.indexOf("His registration, or the absence of one") === -1>> <<link '<span class="choice-btn">🏥 Ask the nurse about his credentials</span>' "Crane_Evidence_Nurse">><</link>> <</if>> <<if _ev.indexOf("Forty minutes of audio you don't remember") === -1>> <<link '<span class="choice-btn">📱 Leave your phone recording in your bag</span>' "Crane_Evidence_Recording">><</link>> <</if>> <<if _ev.indexOf("Two other students with the same gap" ) === -1>> <<link '<span class="choice-btn">💬 Find other students from his sessions</span>' "Crane_Evidence_Students">><</link>> <</if>> <<if _ev.length >= 2>> <<link '<span class="choice-btn">🛑 Confront him with it</span>' "Crane_Confront">><</link>> <<link '<span class="choice-btn">🏛️ Take it to Dean Harrison</span>' "Crane_Report">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Later</span>' "CampusMap">><</link>> </div>
<h2>🏠 Zoe</h2> <<advanceTime 20>> <p>You ask <<print $roommate.name>> if you've been odd on Tuesdays. She puts her phone down, which is how you know the answer before she says it.</p> <p>"You come in and you don't say hi. You sit on your bed with your coat still on. Last week I asked what you wanted for dinner and you said 'that's fine' to a question with no yes in it." She pulls her knees up. "I thought it was the programme. I've been worried for a month and I didn't want to be weird about it."</p> <<run $hypnosis.evidence.push("Zoe's account of your missing evenings")>> <<set $roommate.trust = Math.min(100, $roommate.trust + 10)>> <<modStat "stress" 5 "Hearing it out loud">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Crane_Investigate">><</link>> </div>
<h2>🏥 Reception</h2> <<advanceTime 25>> <p>You ask the nurse, casually, what Dr. Crane's actual speciality is.</p> <p>She checks. Checks again. Her face does something complicated. "He's not on our clinical roster. He's listed as a," she reads it twice, "'visiting wellbeing facilitator.' That's not a licence. That's a room booking." A pause. "Who approved Room 3B?"</p> <p>She writes something down and doesn't tell you what.</p> <<run $hypnosis.evidence.push("His registration, or the absence of one")>> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Crane_Investigate">><</link>> </div>
<h2>📱 Forty Minutes</h2> <<advanceTime 60>> <<set $hypnosis.sessionsAttended++>> <<set $hypnosis.lastSessionDay = $world.day>> <p>You start the recorder, drop the phone in your bag, and let him take you under one more time.</p> <p>You listen to it that night with the lights on. For thirty-one minutes it is a relaxation script. Then his voice changes register, lower and flatter and instructional, and begins repeating phrases about compliance and agreeableness, and your own voice answers them in a slack monotone you have never made in your life.</p> <p>You stop it. Start it again. Stop it. <<toneThink "That is not my voice. That is my voice." "I need to sit down." "Oh god. Oh god, oh god.">></p> <<run $hypnosis.evidence.push("Forty minutes of audio you don't remember")>> <<modStat "stress" 20 "Hearing yourself">> <<modStat "mood" -10 "Violated">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Crane_Investigate">><</link>> </div>
<h2>💬 Not Just You</h2> <<advanceTime 40>> <p>Two names off the sign-up sheet. Both in the programme. Both agree to coffee and both spend the first ten minutes insisting nothing happened.</p> <p>Then one of them says, "Do you lose Tuesdays?", and the other one starts crying, and the three of you sit there in the corner of the campus café realising you are a pattern rather than a coincidence.</p> <p>They'll both put their names to a statement. One of them asks you to go first.</p> <<run $hypnosis.evidence.push("Two other students with the same gap")>> <<modStat "confidence" 5 "Not alone">> <div class="choice-group"> <<link '<span class="choice-btn">🔍 Keep going</span>' "Crane_Investigate">><</link>> </div>
<h2>🛑 Room 3B</h2> <<advanceTime 30>> <p>You go at four on a Tuesday and stay standing. You tell him what you have: the gaps, the roster, the recording, the others.</p> <p>He doesn't deny it. He tilts his head slightly, the way he does when you say something he finds interesting. "You're cleverer than most," he says, warm as ever, and the warmth is the worst part.</p> <<set _stand = XCLC.Roll.doCheck("composure", 4)>> <<run XCLC.DicePopup.show()>> <<if _stand === "crit_success" || _stand === "success">> <p>"Don't." Your voice comes out level. "Whatever you're about to do with your voice. Don't. I'm not sitting down and I'm not closing my eyes, and there are three of us with statements."</p> <p>Something behind his face recalculates. He says nothing at all, and that is the first honest thing he has ever given you.</p> <<modStat "confidence" 12 "Held your ground">> <<modStat "willpower" 10 "Unshakeable">> <<else>> <p>He starts to speak, the register dropping, the cadence changing, and you feel the pull of it like a hand laid on the back of your neck. You leave before he finishes the sentence, heart hammering, furious at how close it was.</p> <<modStat "stress" 15 "Too close">> <</if>> <<set $hypnosis.confronted = true>> <div class="choice-group"> <<link '<span class="choice-btn">🏛️ Take it to the Dean</span>' "Crane_Report">><</link>> <<link '<span class="choice-btn">🔙 Leave</span>' "CampusMap">><</link>> </div>
<h2>🏛️ Dean Harrison's Office</h2> <<advanceTime 60>> <<set _n = $hypnosis.evidence.length>> <p>Dean Harrison listens without interrupting, which you weren't expecting, and takes notes, which you were expecting even less.</p> <<if _n >= 3>> <p>When you finish she is quiet for a long moment. "Room 3B was booked as a wellbeing pilot. Nobody credentialed him because nobody thought they had to." She looks up. "That's my failure, not yours. He will not be on this campus tomorrow, and you will be hearing from an investigator, not from me."</p> <p>He isn't. There's a notice on the board by Thursday, worded so carefully it says nothing and everything.</p> <<modStat "confidence" 15 "Stopped him">> <<modRep "goodStudent" 5>> <<modRep "sweetheart" 8>> <<set $hypnosis.resolved = true>> <<run XCLC.Toast.show("🏛️ Crane has been removed from campus pending investigation.", "success", 7000)>> <<elseif _n >= 2>> <p>"I believe you," she says, and you can hear her meaning it and also meaning the next part. "I also have to hand this to an investigator, and two accounts and no recording is a slower road than three and one. It will move. It will move at the speed institutions move."</p> <p>His sessions are suspended within the week. The investigation outlives your second year.</p> <<modStat "confidence" 8 "Did the right thing">> <<modRep "sweetheart" 5>> <<set $hypnosis.resolved = true>> <<run XCLC.Toast.show("🏛️ Crane's sessions have been suspended pending review.", "info", 7000)>> <<else>> <p>She is kind about it, and kindness is not the same as action. "Bring me something I can put in front of a panel."</p> <</if>> <<if $hypnosis.lingering && $hypnosis.resolved>> <div class="alert alert--info">🏥 The clinic has offered you a screening for lingering suggestion, free of charge. You should take it.</div> <</if>> <div class="choice-group"> <<if $hypnosis.resolved && $hypnosis.lingering>> <<link '<span class="choice-btn">🏥 Get screened</span>' "Crane_Deprogram">><</link>> <</if>> <<link '<span class="choice-btn">🔙 Leave</span>' "CampusMap">><</link>> </div>
<h2>🏥 Screening</h2> <<advanceTime 90>> <p>The replacement clinician is brisk, middle-aged, and visibly angry on your behalf in a way she keeps carefully out of her voice. She walks you through what was done, names it, and undoes what can be undone.</p> <p>"Some of it will fade on its own. Some of it you'll notice for a while: a word landing wrong, a room you would rather not walk past. That's not damage. That's your brain being sensible about something that hurt it."</p> <p>She writes you a note excusing two weeks of missed deadlines and tells you to use it.</p> <<set $hypnosis.lingering = false>> <<set $hypnosis.triggersPlanted = []>> <<modStat "willpower" 15 "Cleared">> <<modStat "stress" -25 "Named and handled">> <<modStat "mood" 10 "Yourself again">> <<run XCLC.Toast.show("🧠 Lingering suggestion cleared.", "success", 6000)>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Leave</span>' "HealthCentre">><</link>> </div> /* ═══════════════════════════════════════════════════ ✍️ BODY WRITING: Degradation marks ═══════════════════════════════════════════════════ */
<<widget "applyBodyWriting">> /* $args[0] = text, $args[1] = location */ <<set $bodyWriting.active = true>> <<run $bodyWriting.texts.push({text: _args[0], location: _args[1] || "body", day: $world.day})>> <<set $bodyWriting.totalWritten++>> <<set $bodyWriting.lastAppliedDay = $world.day>> <<modCorruption 3 "Body writing">> <<modRep "slut" 2>> <</widget>> <<widget "showBodyWriting">> <<if $bodyWriting.active && $bodyWriting.texts.length > 0>> <div class="alert alert--warning"> ✍️ <strong>Body Writing:</strong> <<for _bw = 0; _bw < $bodyWriting.texts.length; _bw++>> <em>"<<print $bodyWriting.texts[_bw].text>>"</em> (<<print $bodyWriting.texts[_bw].location>>)<<if _bw < $bodyWriting.texts.length - 1>>, <</if>> <</for>> <br><span style="opacity:0.6;">Wash off in the shower.</span> </div> <</if>> <</widget>>
/* ─── Called from checkRandomEvent. Returns true if it fired. ─── */ <<widget "checkToyEvent">> <<set $temp.toyEventFired = false>> <<set _plug = XCLC.Toys.worn()>> <<set _hem = XCLC.Toys.hemRisk()>> <<set _bag = $inventory.hasPurse || $inventory.hasTote>> <<set _carryable = XCLC.Toys.discreet()>> <<set _indoors = ["DormRoom", "DormRoom_Shower", "DormRoom_Sleep"].includes(passage())>> /* ── Worn plug + short hem: something shows ── */ <<if !$temp.toyEventFired && _plug && _hem >= 2 && !_indoors && random(1, 100) <= (_hem === 3 ? 45 : 25)>> <<set $temp.toyEventFired = true>> <<include "TE_PlugSeen">> <</if>> /* ── Worn plug, general awareness ── */ <<if !$temp.toyEventFired && _plug && random(1, 100) <= 30>> <<set $temp.toyEventFired = true>> <<include "TE_PlugFelt">> <</if>> /* ── Something falls out of your bag ── */ <<if !$temp.toyEventFired && _bag && _carryable.length > 0 && !_indoors && random(1, 100) <= 22>> <<set $temp.toyEventFired = true>> <<include "TE_BagSpill">> <</if>> <</widget>>
<<set _plug = XCLC.Toys.worn()>> <<if _plug>> <<set _jewel = _plug.tags.includes("jewelled")>> <<set $inventory.plugSpotted = ($inventory.plugSpotted || 0) + 1>> <<set _who = random(1, 4)>> <<if _who === 1>> <div class="alert alert--warning">👀 You bend to pick up a dropped pen and hear, from directly behind you, a sharp intake of breath and then a very deliberate silence. When you straighten up the guy behind you is examining the ceiling with the intensity of a man who has decided to become an architect. <<if _jewel>>The gem caught the light. There is no other explanation.<<else>>He saw something. You are choosing not to establish what.<</if>></div> <<modRep "slut" 2>> <<modStat "arousal" 8 "Nearly caught">> <<modStat "confidence" 2 "Getting away with it">> <<elseif _who === 2>> <div class="alert alert--warning">😳 A girl from your hall falls into step beside you, leans in, and says pleasantly: "Just so you know, when you go up stairs in that skirt, everyone behind you gets the full presentation." She pats your arm and peels off toward the library before you can answer. <<toneThink "Kill me." "Noted, apparently." "Good. That was sort of the plan. 💎">></div> <<modRep "slut" 3>> <<modStat "stress" 5 "Mortification">> <<modStat "arousal" 10 "Everyone behind you">> <<elseif _who === 3>> <div class="alert alert--danger">📱 You catch the reflection too late: someone across the quad, phone up, angled low, taking a photo of you on the steps. By the time you turn around they are walking away fast. Whatever is on that phone, you were not consulted about it.</div> <<modRep "slut" 3>> <<modStat "stress" 10 "Photographed">> <<else>> <div class="alert alert--info">🌬️ The wind on the walk between buildings does exactly what you knew it would do, and for about a second and a half you are considerably more public than you intended. A cyclist nearly leaves the path. You keep walking with the poise of someone who has decided that acknowledging it would be worse. <<if _jewel>>Somewhere behind you a very confused conversation is starting up.<</if>></div> <<modRep "slut" 2>> <<modStat "arousal" 12 "Public exposure">> <<modStat "confidence" 3 "Handled it">> <</if>> <</if>>
<<set _plug = XCLC.Toys.worn()>> <<set _days = $world.day - ($inventory.plugWornSince || $world.day)>> <<set _r = random(1, 4)>> <<if _r === 1>> <div class="alert alert--info">💎 You sit down too fast and the reminder is immediate and total. You spend the next ninety seconds of the lecture very carefully not moving, and absorb none of it.</div> <<modStat "arousal" 10 "Constant reminder">> <<elseif _r === 2>> <div class="alert alert--info">💎 Stairs. You had not thought about stairs. Every single step is a small private event and there are forty-one of them. <<toneThink "This was a mistake." "This was an interesting choice." "This was the best decision I have made all week. 🔥">></div> <<modStat "arousal" 12 "Stairs">> <<elseif _r === 3>> <div class="alert alert--info">💎 Someone asks if you are all right, because you have apparently been shifting in your seat for ten minutes. "Fine," you say brightly. "Just uncomfortable chairs." They accept this. You are becoming an extremely good liar.</div> <<modStat "arousal" 8 "Squirming">> <<addXP "composure" 6>> <<else>> <div class="alert alert--info">💎 It has stopped being a sensation and become a fact: background information your body reports on continuously, like temperature. <<if _days >= 2>>You have been wearing it for <<print _days>> days running now. That is worth thinking about, and you decide not to.<</if>></div> <<modStat "arousal" 6 "Background hum">> <<modRep "slut" 1>> <</if>>
<<set _carry = XCLC.Toys.discreet()>> <<if _carry.length > 0>> <<set _item = _carry[random(0, _carry.length - 1)]>> <<set _bagName = $inventory.hasTote ? "tote" : "clutch">> <<set _r = random(1, 3)>> <<if _r === 1>> <div class="alert alert--danger">🎒 Your <<print _bagName>> tips off the seat and everything in it goes across the floor of the lecture hall. Pens. Lip balm. Your keys. And, rolling with real commitment toward the front row, your <<print XCLC.Toys.plain(_item)>>.<br><br>A boy in the second row picks it up, understands what he is holding, and freezes with it in his outstretched hand like a man defusing something. "Uh," he says. <<toneThink "I want to die." "I want a fire alarm." "I take it back and say thank you. Loudly. 😏">></div> <<modRep "slut" 4>> <<modStat "stress" 12 "Public humiliation">> <<modStat "confidence" -4 "Mortified">> <<elseif _r === 2>> <div class="alert alert--warning">🎒 You are digging in your <<print _bagName>> for your student ID and you pull out your <<print XCLC.Toys.plain(_item)>> instead, in front of the desk attendant, at eye level, for a full second before your brain catches up. She does not react at all, which is somehow worse. "ID?" she says.</div> <<modRep "slut" 2>> <<modStat "stress" 8 "Caught out">> <<addXP "composure" 8>> <<else>> <div class="alert alert--info">🎒 "Excuse me. I think you dropped this." A woman in her fifties, holding your <<print XCLC.Toys.plain(_item)>> out to you between two fingers with an expression of absolutely magnificent neutrality. "Thank you," you say. "Not at all," she says. Neither of you breaks. It is the most professional interaction of your life.</div> <<modStat "stress" 5 "Excruciating">> <<modStat "confidence" 2 "Survived it">> <<addXP "composure" 10>> <</if>> <</if>> /* ═══════════════════════════════════════════════════ 🧺 ROOMMATE FINDS WHAT YOU LEFT OUT Full scene: checked on entering the dorm room. ═══════════════════════════════════════════════════ */
<<widget "checkToysLeftOut">> <<set _out = XCLC.Toys.leftOut()>> <<if _out.length > 0 && $roommate.name && $world.day > ($temp.toysFoundDay || -1)>> <<set _homeNow = XCLC.Roommate.isHome()>> <<if _homeNow && random(1, 100) <= 55>> <<set $temp.toysFoundDay = $world.day>> <<goto "Roommate_FindsToys">> <</if>> <</if>> <</widget>>
<<set _found = XCLC.Toys.leftOut()>> /* Only reachable via checkToysLeftOut, which already requires an item, but a stray link or an old save should not crash the room. */ <<if _found.length === 0>> <p>Whatever you thought you left out, it is not there now.</p> <div class="choice-group"><<link '<span class="choice-btn">← Back</span>' "DormRoom">><</link>></div> <<else>> <<set _item = _found[0]>> <<set _all = _found.length>> <<set _rm = $roommate>> <<set _rel = _rm.opinion || 0>> <<run XCLC.Toys.tidyUp()>> <<set $inventory.toysFoundCount = ($inventory.toysFoundCount || 0) + 1>> <h2>🧺 She Found It</h2> <p><<print _rm.name>> is sitting on her bed with her laptop shut, which is never a good sign, and she looks up the moment you open the door.</p> <p>Your <<print XCLC.Toys.plain(_item)>> is on your desk. In the middle of your desk. Where you left it<<if _all > 1>>, along with <<print _all - 1>> other item<<if _all > 2>>s<</if>> that make the overall picture considerably less ambiguous<</if>>. You had genuinely forgotten it existed until this exact second.</p> <<if _rm.personality === "shy">> <p>"I wasn't. I didn't go through your stuff," she says immediately, to the wall, at speed. "It was just <em>there</em>. When I came in. And I didn't want to touch it because that felt worse than leaving it, so I left it, and then I've been sitting here for an hour thinking about how to not mention it."</p> <p>She finally looks at you, scarlet. "I have failed at not mentioning it."</p> <<elseif _rm.personality === "party" || _rm.personality === "horny">> <p>"So." She sets the laptop aside with the air of a woman convening a meeting. "I have questions. Not judgment. <em>Questions</em>. Because that is a serious piece of equipment and I have been told my whole life that I have bad taste and I am starting to think it might just be a lack of ambition."</p> <p>She props her chin on her hand. "Where did you get it and is it worth the money."</p> <<elseif _rm.personality === "supportive">> <p>"Okay, don't panic," she says, before you have said anything at all. "Nothing happened. I put a towel over it, which in hindsight made it look like a crime scene, so I took the towel off again."</p> <p>She pulls a face at herself. "I'm only saying anything because Housing does spot checks and I'd rather you heard it from me than from a maintenance form. That's genuinely the whole reason."</p> <<elseif _rm.personality === "athletic">> <p>"I'm going to say one thing," she says, not unkindly, "and then we never discuss it again."</p> <p>She holds up a finger. "This is a shared room. I do not care what you own. I care that I sat down at your desk to borrow a pen and had a genuinely alarming moment. That's it. That's the whole speech."</p> <<else>> <p>She holds your eye for a long, level moment, and there is the faintest curl at the corner of her mouth. "Not a word from me," she says. "But you might want to think about the fact that Marcus from down the hall wandered in here at lunchtime looking for a phone charger."</p> <p>A beat. "He definitely saw it. And Marcus talks."</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">😳 Apologise and put it away, mortified</span>' "Roommate_FindsToys_Sorry">><</link>> <<link '<span class="choice-btn">😏 Own it completely: no apology</span>' "Roommate_FindsToys_Own">><</link>> <<if _rel >= 40>> <<link '<span class="choice-btn">💬 Actually: sit down and talk to her about it properly</span>' "Roommate_FindsToys_Talk">><</link>> <</if>> </div> <</if>>
<<set _rm = $roommate>> <p>You cross the room fast, sweep it into a drawer, and apologise about four more times than the situation strictly required.</p> <p>"It's fine," <<print _rm.name>> says. "Honestly." She stops, and starts again. "You know everyone has them, right? Like, statistically, everyone in this building. It's not a scandal. It's just a thing you left on a desk."</p> <p>You feel marginally better and about forty percent more embarrassed at the same time, which you had not known was possible.</p> <<modStat "stress" 5 "Mortification">> <<modStat "confidence" -3 "Caught out">> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 2)>> <div class="choice-group"> <<link '<span class="choice-btn">← Move on with your life</span>' "DormRoom">><</link>> </div>
<<set _rm = $roommate>> <p>You pick it up, look at it, and put it in the drawer with no more ceremony than you would give a hairbrush.</p> <p>"Yeah," you say. "It's mine. It's good. Sorry it was out."</p> <p><<print _rm.name>> blinks. Whatever she was braced for, it was not that. "Okay," she says, and then, after a pause in which something visibly recalibrates behind her eyes, "okay, honestly, good for you. I'd have died."</p> <p>"I'm running low on things left to die about," you tell her, and she laughs, and the whole thing is over.</p> <<modStat "confidence" 6 "Zero shame">> <<modRep "slut" 2>> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 3)>> <<addXP "composure" 15>> <div class="choice-group"> <<link '<span class="choice-btn">← Move on with your life</span>' "DormRoom">><</link>> </div>
<<set _rm = $roommate>> <p>You sit down on the end of your bed facing her, and instead of dealing with the object you deal with the actual thing.</p> <p>"Can I just say something weird," you start, and she says "obviously," and you tell her, carefully, leaving out the parts you are not ready to say out loud, that everything about this body is louder than the old one. That you did not choose the volume. That you have been figuring out what to do with it mostly by trial and error and quite a lot of the error has been embarrassing.</p> <p><<print _rm.name>> listens the whole way through without doing the thing people do where they start assembling their response halfway.</p> <p>"That sounds exhausting," she says finally. "And also, and I do mean this, completely normal? Like, the specifics are yours. The rest of it is just being a woman in a body that has opinions. Welcome. There's no handbook. We all just wing it and lie about how much we're winging it."</p> <p>Something in your chest unknots by a few degrees.</p> <<modStat "stress" -12 "Genuinely talked to someone">> <<modStat "mood" 10 "Understood">> <<modStat "femininity" 3 "Welcomed in">> <<set $roommate.opinion = Math.min(100, $roommate.opinion + 8)>><<set $roommate.trust = Math.min(100, $roommate.trust + 6)>> <div class="choice-group"> <<link '<span class="choice-btn">← Move on with your life</span>' "DormRoom">><</link>> </div>
<<widget "checkStreetProposition">> <<if $reputation.slut >= 35 && $world.day !== $social.lastPropositionDay && !$scholarship.inService>> <<set _period = XCLC.Time.getPeriod($world.time)>> <<set _lateEnough = (_period === "evening" || _period === "night" || _period === "late_night")>> /* Refusing consistently makes it rarer: word gets around both ways */ <<set _base = Math.min(22, 6 + Math.round(($reputation.slut - 35) / 4))>> <<set _chance = Math.max(2, _base - ($social.propositionsRefused * 2))>> <<if _lateEnough && random(1, 100) <= _chance>> <<set $social.lastPropositionDay = $world.day>> <<set $temp.streetOrigin = passage()>> <<goto "Street_Proposition">> <</if>> <</if>> <</widget>>
<<set $social.propositions++>> <<set _kind = random(1, 4)>> <<set $temp.streetKind = _kind>> <<set _npc = XCLC.NPC.generate({gender: (_kind === 3 ? "female" : "male")})>> <<set $temp.streetNPC = _npc>> <<set _offer = 40 + random(0, 4) * 10 + Math.round($pc.beautyTotal / 3)>> <<set $temp.streetOffer = _offer>> <h2>🚶 Somebody Slows Down</h2> <<if _kind === 1>> <p>A car pulls level with you and keeps pace for about ten metres before the window comes down. The driver is fortyish, wedding ring, radio on low. "Evening," he says, in the tone of a man asking about parking.</p> <p>"Sorry?" you say, and he says, "No. I know. I'm being rude." He keeps his eyes on the road. "Someone said you were around here sometimes."</p> <p>A pause, and then, still not looking at you: "Was that a wrong thing to have said?"</p> <<set _priceLine = "He has clearly had the figure ready since before he pulled level.">> <<elseif _kind === 2>> <p>He falls into step beside you outside the chicken shop, close enough to talk over the traffic and not so close that you would call it looming. Student, maybe a year or two above you, hood up.</p> <p>"You're the X-Change girl," he says. Not a question. "Sorry. I know that's a thing people say to you." He is talking too fast. "I wanted to ask before I lost my nerve about it."</p> <<set _priceLine = "He names it like a number he has been rehearsing.">> <<elseif _kind === 3>> <p>She is leaning on the railings outside the launderette with a vape in one hand, and as you pass she says your name. Not the programme name. Your actual name. When you stop she looks pleased with herself.</p> <p>"Thought so. A girl I know says you're..." She does a small gesture, deliberately vague and entirely legible. "Anyway. I'm asking. That's all this is."</p> <<set _priceLine = "She names it without looking away, and waits.">> <<else>> <p>Two of them, on the steps outside the off-licence, and one elbows the other before either speaks, which tells you the conversation happened before you arrived. It is the taller one who straightens up and crosses the pavement; his friend stays on the steps, pretending to look at his phone.</p> <p>"Look, don't take this the wrong way," he says, and then has to start again. "How much?"</p> <p>Behind him his friend has not looked up from the phone once.</p> <<set _priceLine = "The number has obviously been argued about on those steps before you arrived.">> <</if>> <p><strong>$<<print _offer>>.</strong> <<print _priceLine>></p> <p>It does not land on you the way it left <<print _npc.gender === "male" ? "him" : "her">>.</p> <<if $social.propositions === 1>> <p>It is the first time, and it is not the offer that stays with you afterwards. It is the discovery that there is a version of you in other people's mouths: discussed, priced, agreed upon, in conversations you were never in.</p> <<elseif $social.propositions >= 5>> <p>The fifth time, or the sixth. You have stopped keeping count, which is itself information.</p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚫 "No." Keep walking.</span>' "Street_Prop_Refuse">><</link>> <<link '<span class="choice-btn">🗣️ Shut it down hard: loud enough to be repeated</span>' "Street_Prop_Shutdown">><</link>> <<link '<span class="choice-btn">💬 Negotiate: that number is insulting <em>(Persuasion)</em></span>' "Street_Prop_Haggle">><</link>> <<link '<span class="choice-btn">💵 Accept ($<<print _offer>>)</span>' "Street_Prop_Accept">><</link>> </div>
<<set $social.propositionsRefused++>> <<set _npc = $temp.streetNPC>> <<set _they = _npc.gender === "male" ? "He" : "She">> <h2>🚫 No</h2> <p>"No," you say, and keep walking, and do not look back to see how it landed.</p> <p>Nothing happens. <<print _they>> does not follow. There is no scene. You are two streets away before your heart rate comes down, and you spend most of those two streets annoyed that your heart rate went up at all.</p> <<modStat "stress" 5 "Rattled">> <<modStat "confidence" 2 "Said no and meant it">> <<addXP "composure" 10>> <div class="choice-group"> <<link '<span class="choice-btn">🚶 Carry on</span>' `$temp.streetOrigin || "CampusMap"`>><</link>> </div>
<<set _npc = $temp.streetNPC>> <<set _they = _npc.gender === "male" ? "He" : "She">> <<set _res = XCLC.Roll.doCheck("composure", 3)>> <<run XCLC.DicePopup.show()>> <<set $social.propositionsRefused += 2>> <h2>🗣️ Loudly</h2> <<if _res === "crit_success" || _res === "success">> <p>You stop dead, turn round, and say it at a volume calibrated precisely for the bus queue twenty feet away. "<em>No.</em> And you can tell whoever told you I was worth asking that they were wrong, and that I know exactly who it was."</p> <p>You did not know who it was. It does not matter. Somebody in the bus queue actually laughs. <<print _they>> goes an extraordinary colour and leaves at speed, and you are fairly confident this specific version of the conversation is going to be retold by three different people before midnight, which is the entire point.</p> <<modStat "confidence" 8 "Made an example">> <<modRep "slut" -3>> <<addXP "composure" 25>> <<run XCLC.Toast.show("🗣️ Word gets around. Fewer of these for a while.", "success", 4500)>> <<else>> <p>You go loud and it comes out shrill rather than commanding. Too high, too fast. A sentence that starts as a demolition and ends as a question. <<print _they>> does not leave immediately. <<print _they>> does the worse thing, which is to hold up both hands and say "all <em>right</em>, Jesus" in the tone of a man being unreasonably treated, and several people look at <em>you</em>.</p> <p>You walk away with your ears burning.</p> <<modStat "stress" 12 "Public scene">> <<modStat "confidence" -4 "It came out wrong">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚶 Carry on</span>' `$temp.streetOrigin || "CampusMap"`>><</link>> </div>
<<set _npc = $temp.streetNPC>> <<set _they = _npc.gender === "male" ? "he" : "she">> <<set _theyC = _npc.gender === "male" ? "He" : "She">> <<set _them = _npc.gender === "male" ? "him" : "her">> <<set _their = _npc.gender === "male" ? "his" : "her">> <<set _offer = $temp.streetOffer>> <<set _res = XCLC.Roll.doCheck("persuasion", 4)>> <<run XCLC.DicePopup.show()>> <h2>💬 The Number</h2> <<if _res === "crit_success">> <<set $temp.streetOffer = Math.round(_offer * 2)>> <p>You laugh at <<print _them>>. Not cruelly. Worse than that: warmly, the way you would laugh at a child who had made a reasonable attempt. Then you name a figure that is double <<print _their>>, and you say it like it is a discount, and you let the silence afterwards do the arguing.</p> <p>"...Yeah," <<print _they>> says eventually. "Yeah, okay."</p> <div class="alert alert--success">💵 $<<print _offer>> → $<<print $temp.streetOffer>></div> <<elseif _res === "success">> <<set $temp.streetOffer = Math.round(_offer * 1.5)>> <p>"That's not a serious number," you say, and give <<print _them>> one that is. <<print _theyC>> does the arithmetic on <<print _their>> face and arrives at yes.</p> <div class="alert alert--success">💵 $<<print _offer>> → $<<print $temp.streetOffer>></div> <<elseif _res === "partial_fail">> <p>You push and <<print _they>> pushes back, and you meet more or less exactly where you started. <<print _theyC>> counts it out on the wall between you, twice, and the second count comes to the same thing as the first.</p> <p>It is not a negotiating position. It is just what <<print _they>> has.</p> <<else>> <<set $temp.streetOffer = Math.round(_offer * 0.75)>> <p>You overplay it badly. <<print _theyC>> shrugs, says "fair enough," and starts to walk off, and you hear yourself calling after <<print _them>> with a lower number than <<print _they>> opened with, and the worst part is how quickly <<print _they>> turns around.</p> <div class="alert alert--warning">💵 $<<print _offer>> → $<<print $temp.streetOffer>></div> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">💵 Accept ($<<print $temp.streetOffer>>)</span>' "Street_Prop_Accept">><</link>> <<link '<span class="choice-btn">🚫 Walk away anyway</span>' "Street_Prop_Refuse">><</link>> </div>
<<set _npc = $temp.streetNPC>> <<set _offer = $temp.streetOffer>> <h2>🚪 Somewhere Else</h2> <p>You say yes, and then there is the wholly unromantic business of deciding where, which is a conversation held in a doorway, in low voices, about car parks and stairwells and whether the flatmate is in.</p> <p style="opacity:0.7;font-size:0.85em;"><em>Money up front, and you can still walk at any point.</em></p> <div class="choice-group"> <<link '<span class="choice-btn">💋 Mouth only ($<<print Math.round(_offer * 0.7)>>)</span>' "Street_Prop_Go">> <<set $temp.streetType = "oral">> <<set $temp.streetOffer = Math.round(_offer * 0.7)>> <</link>> <<link '<span class="choice-btn">🔥 The full thing ($<<print _offer>>)</span>' "Street_Prop_Go">> <<set $temp.streetType = "vaginal">> <</link>> <<if $skills.anal.level >= 1>> <<link '<span class="choice-btn">🍑 Anything they want ($<<print Math.round(_offer * 1.6)>>)</span>' "Street_Prop_Go">> <<set $temp.streetType = "anal">> <<set $temp.streetOffer = Math.round(_offer * 1.6)>> <</link>> <</if>> <<divider "">> <<link '<span class="choice-btn">✋ Actually, no. Changed your mind.</span>' "Street_Prop_Backout">><</link>> </div>
<<set $social.propositionsRefused++>> <<set _npc = $temp.streetNPC>> <<set _they = _npc.gender === "male" ? "He" : "She">> <<set _them = _npc.gender === "male" ? "him" : "her">> <h2>✋ Not Doing This</h2> <p>"No," you say, in the doorway, halfway through the logistics. "Sorry. No."</p> <p><<print _they>> is annoyed, and lets you see it, and says something about time-wasting that is not quite loud enough to be a problem. And then <<print _they.toLowerCase()>> goes, because the alternative to going is becoming a much bigger deal than fifty dollars is worth to <<print _them>>.</p> <p>You stand in the doorway for a second afterwards, shaking slightly, and take the long way home.</p> <<modStat "stress" 8 "Close call">> <<modStat "confidence" 5 "Stopped it when you wanted to">> <<addXP "composure" 20>> <div class="choice-group"> <<link '<span class="choice-btn">🚶 Go home</span>' `$temp.streetOrigin || "CampusMap"`>><</link>> </div>
<<set _npc = $temp.streetNPC>> <<run XCLC.Encounter.setup({ npc: _npc, serviceType: $temp.streetType, locationName: "a stairwell two streets over", locationPrivacy: "low", returnPassage: "Street_Prop_Result" })>> <<advanceTime 45>> <<goto "ServiceSex_Start">>
<<set _npc = $temp.streetNPC>> <<set _offer = $temp.streetOffer>> <<set _out = $temp.sexMinigameOutcome>> <<set _good = (_out === "crit_success" || _out === "success")>> <<set _tip = (_out === "crit_success") ? Math.round(_offer * 0.4) : 0>> <<set _paid = _offer + _tip>> <<run XCLC.Encounter.clear()>> <<set $social.propositionsAccepted++>> <<set _theyC = _npc.gender === "male" ? "He" : "She">> <h2>💵 Paid</h2> <<if _out === "crit_success">> <p><<print _theyC>> pays what is owed and then, fumbling, adds to it: notes pulled out of a different pocket, the way people do when they have decided something on the spot and want to act before they reconsider. "That was..." <<print _theyC>> stops. "Take it. Please."</p> <<elseif _good>> <p><<print _theyC>> counts it into your hand in the stairwell light and looks at the money the whole time, which saves both of you something.</p> <<else>> <p><<print _theyC>> pays. <<print _theyC>> is not thrilled about it and it shows in the counting, note by note, as if the audit might turn something up.</p> <</if>> <div class="alert alert--info">💵 $<<print _paid>><<if _tip>> (including a $<<print _tip>> tip)<</if>>. Nobody is going to ask where this came from.</div> <<payPlayer _paid "Street work">> <<modRep "slut" 4>> <<modRep "troublemaker" 1>> <<modCorruption 5 "Sold it on the street">> <<stdRisk `$temp.streetType`>> <<if $temp.streetType === "vaginal" && _npc.gender === "male">> <<pregnancyRisk `_npc.race`>> <</if>> <<if $social.propositionsAccepted === 1>> <p>Walking back, you keep taking the money out of your pocket and looking at it. It is just money. It looks exactly like the money you get from the coffee shop. That is somehow the worst thing about it.</p> <p>You do not put it in your purse with the rest. You put it in the inside pocket of your coat, on its own, and you are three streets away before you work out why you did that.</p> <<modStat "mood" -8 "First time">> <<elseif $social.propositionsAccepted >= 5>> <p>You are home in twenty minutes and asleep in forty. It has become a thing you do, filed alongside the shifts and the seminars, and you have stopped waiting for the part where you feel something about it.</p> <<modStat "mood" -3 "Routine">> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🚶 Go home</span>' `$temp.streetOrigin || "CampusMap"`>><</link>> </div>
<<if !$cheats.enabled>> <h2>🧪 Not Installed</h2> <p>Developer Options are switched off. Turn them on in Settings first.</p> <div class="choice-group"> <<link '<span class="choice-btn">⚙️ Settings</span>' "Phone_Settings">><</link>> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Home">><</link>> </div> <<else>> <h2>🧪 Cheats</h2> <<if !$temp.cheatSection>><<set $temp.cheatSection = "money">><</if>> <div class="cheat-tabs"> <<set _tabs = [ {k: "money", label: "💰 Money"}, {k: "stats", label: "📊 Stats"}, {k: "skills", label: "🎯 Skills"}, {k: "rep", label: "🌟 Reputation"}, {k: "body", label: "🧬 Body"}, {k: "health", label: "🩺 Health"}, {k: "items", label: "🎒 Items"}, {k: "progress", label: "🏆 Progress"}, {k: "time", label: "🕐 Time"} ]>> <<for _ti = 0; _ti < _tabs.length; _ti++>> <<set _tab = _tabs[_ti]>> <<set _cls = ($temp.cheatSection === _tab.k) ? "cheat-tab is-active" : "cheat-tab">> <<set _tabText = '<span class="' + _cls + '">' + _tab.label + '</span>'>> <<capture _tab, _tabText>> <<link _tabText "Phone_Cheats">> <<set $temp.cheatSection = _tab.k>> <</link>> <</capture>> <</for>> </div> <div id="cheat-display" class="cheat-panel"><p style="opacity:0.5;">Loading…</p></div> <<run setTimeout(function(){ XCLC.Cheats.mount(State.variables.temp.cheatSection); }, 40)>> <<if $cheats.used>> <p style="opacity:0.5;font-size:0.8em;margin-top:1em;"><em>This save has been modified <<print $cheats.uses>> time<<if $cheats.uses !== 1>>s<</if>>.</em></p> <</if>> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back to phone</span>' "Phone_Home">><</link>> </div> <</if>>
<h2>🧪 Developer Options</h2> <<if $cheats.enabled>> <p>Cheats are <strong>on</strong>. The 🧪 app is on your home screen.</p> <p style="opacity:0.7;">Turning them off hides the app. It does not undo anything you have already changed, and the save stays flagged.</p> <div class="choice-group"> <<link '<span class="choice-btn">🚫 Turn cheats off</span>' "Phone_Settings">> <<set $cheats.enabled = false>> <<run XCLC.Toast.show("🧪 Cheats disabled.", "info")>> <</link>> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Settings">><</link>> </div> <<else>> <p>This adds a 🧪 app to your phone that lets you set money, stats, skills, reputation, body, health, items, progression and the clock directly.</p> <p style="opacity:0.7;">It is a sandbox switch, not a shortcut through a difficulty spike. Most of what it touches is meant to be earned, and the game is more interesting when it is. Your call.</p> <p style="opacity:0.7;">The save records that cheats were used. Nothing else changes.</p> <div class="choice-group"> <<link '<span class="choice-btn">✅ Turn cheats on</span>' "Phone_Cheats">> <<set $cheats.enabled = true>> <<run XCLC.Toast.show("🧪 Cheats enabled. Check your home screen.", "success", 4000)>> <</link>> <<link '<span class="choice-btn">🔙 Back</span>' "Phone_Settings">><</link>> </div> <</if>>
/* ═══════════════════════════════════════════════════ REPUTATION SYSTEM: Threshold Effects 7 tracks, each 0-100. Events fire at 40/60/80. ═══════════════════════════════════════════════════ */ /* ─── Check rep effects (called periodically) ─── */ <<widget "checkRepEffects">> /* Only fire once per day per track */ <<if !$temp.repCheckedToday>> <<set $temp.repCheckedToday = true>> <<set _chance = random(1, 10)>> /* Only fire events ~30% of the time to avoid spam */ <<if _chance <= 3>> <<set _track = "">> <<set _level = 0>> /* Pick highest-threshold track */ <<if $reputation.slut >= 80>><<set _track = "slut">><<set _level = 80>> <<elseif $reputation.partyGirl >= 80>><<set _track = "partyGirl">><<set _level = 80>> <<elseif $reputation.camGirl >= 80>><<set _track = "camGirl">><<set _level = 80>> <<elseif $reputation.troublemaker >= 80>><<set _track = "troublemaker">><<set _level = 80>> <<elseif $reputation.popular >= 80>><<set _track = "popular">><<set _level = 80>> <<elseif $reputation.slut >= 60>><<set _track = "slut">><<set _level = 60>> <<elseif $reputation.partyGirl >= 60>><<set _track = "partyGirl">><<set _level = 60>> <<elseif $reputation.camGirl >= 60>><<set _track = "camGirl">><<set _level = 60>> <<elseif $reputation.slut >= 40>><<set _track = "slut">><<set _level = 40>> <<elseif $reputation.popular >= 40>><<set _track = "popular">><<set _level = 40>> <</if>> <<if _track !== "">> <<include "RepEvent_" + _track + "_" + _level>> <</if>> <</if>> <</if>> <</widget>> /* ─── Display Reputation Panel ─── */ <<widget "showReputation">> <<set _tracks = [ {id: "slut", name: "🔥 Slut", val: $reputation.slut}, {id: "partyGirl", name: "🎉 Party Girl", val: $reputation.partyGirl}, {id: "goodStudent", name: "📚 Good Student", val: $reputation.goodStudent}, {id: "camGirl", name: "📷 Cam Girl", val: $reputation.camGirl}, {id: "sweetheart", name: "💕 Sweetheart", val: $reputation.sweetheart}, {id: "troublemaker", name: "💀 Troublemaker", val: $reputation.troublemaker}, {id: "popular", name: "⭐ Popular", val: $reputation.popular} ]>> <<for _i = 0; _i < _tracks.length; _i++>> <<set _t = _tracks[_i]>> <<set _label = "Unknown">> <<if _t.val >= 80>><<set _label = "Legendary">> <<elseif _t.val >= 60>><<set _label = "Famous">> <<elseif _t.val >= 40>><<set _label = "Known">> <<elseif _t.val >= 20>><<set _label = "Noticed">> <</if>> <div class="stat-row"> <span class="stat-label"><<print _t.name>></span> <div class="stat-bar"><div class="stat-bar__fill" @style="'width:' + _t.val + '%'"></div></div> <span class="stat-value"><<print _t.val>> (<<print _label>>)</span> </div> <</for>> <</widget>>
<h2>📊 Campus Reputation</h2> <p>How the campus sees you. Reputation builds over time from your actions and decays slowly.</p> <<showReputation>> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' "CampusMap">><</link>> </div> /* ═══════════════════════════════════════════════════ REPUTATION EVENT PASSAGES Named RepEvent_[track]_[threshold] ═══════════════════════════════════════════════════ */
<<set _catcalls = ["\"Hey baby, I heard you're... friendly!\"", "A group of guys elbow each other as you walk past. One whistles.", "\"Yo, you're that CCUMDUP girl, right? I've heard things.\"", "Someone shouts \"Nice ass!\" from across the quad. Their friends laugh."]>> <div class="alert alert--info">🔥 <<print _catcalls[random(0, _catcalls.length - 1)]>></div> <<modStat "stress" 3 "Catcalled">>
<<set _props = ["A stranger slides into the seat next to you. \"So... you available tonight? I can pay.\"", "A guy you've never met corners you in the hallway. \"Everyone says you're good. How much?\"", "Your phone buzzes. Unknown number: \"heard you give good head. meet me behind the gym?\""]>> <div class="alert alert--warning">🔥 <<print _props[random(0, _props.length - 1)]>></div> <<modStat "stress" 5 "Propositioned">> <<modStat "confidence" -3 "Slut reputation">>
<<set _events = ["You find \"CAMPUS SLUT\" written on your dorm whiteboard.", "Professor Chen pauses mid-lecture. \"Ms. <<print $pc.lastName>>, perhaps you could spend less time... socialising... and more time studying.\" The class snickers.", "Someone spray-painted your name and a phone number on the bathroom wall."]>> <div class="alert alert--warning">🔥 <<print _events[random(0, _events.length - 1)]>></div> <<modStat "stress" 8 "Public humiliation">> <<modStat "confidence" -5 "Campus slut rep">>
<<set _invites = ["Three different people invite you to parties this weekend.", "\"Yo, you HAVE to come to the Sigma house tonight. It's gonna be lit.\"", "Your phone is blowing up with party invites."]>> <div class="alert alert--info">🎉 <<print _invites[random(0, _invites.length - 1)]>></div> <<modStat "mood" 3 "Popular">>
<div class="alert alert--info">🎉 You can't walk ten feet without someone asking you to a party. "You're coming tonight, right? It's not a party without you."</div> <<modStat "mood" 5 "Party legend">> <<modRep "popular" 2>>
<<set _recog = ["A student does a double take in the cafeteria. \"Wait... are you... StreamLive? Oh my god.\"", "Someone whispers to their friend as you walk past. You catch: \"...that cam girl...\"", "A guy in your class keeps staring at you. When you make eye contact, he blushes and looks away. He knows."]>> <div class="alert alert--warning">📷 <<print _recog[random(0, _recog.length - 1)]>></div> <<modStat "stress" 5 "Recognized from cam">>
<div class="alert alert--warning">📷 A group of students recognises you openly. "Oh shit, you're <<print $pc.firstName>>_Cam! I subscribe! Can I get a selfie?" The attention is mortifying and exhilarating.</div> <<modStat "stress" 5 "Campus-wide recognition">> <<modStat "confidence" 3 "Fan encounter">>
<div class="alert alert--warning">💀 You receive an official letter from the Dean's office. <strong>"This is your final warning. Any further infractions will result in immediate expulsion from the CCUMDUP programme."</strong></div> <<modStat "stress" 15 "Expulsion warning">>
<<set _notices = ["Someone waves at you from across the quad. You don't recognise them, but they clearly know you.", "\"Hey, aren't you <<print $pc.firstName>>? I follow you on InstaGlam!\"", "A freshman asks for a selfie with you. You're... recognisable now."]>> <div class="alert alert--info">⭐ <<print _notices[random(0, _notices.length - 1)]>></div> <<modStat "mood" 3 "Recognised">>
<div class="alert alert--info">⭐ You're a campus celebrity. People point and whisper. Freshmen follow you on social media just because. You can't go anywhere without being noticed.</div> <<modStat "mood" 5 "Campus celebrity">> <<modStat "confidence" 5 "Famous">>
/* ═══════════════════════════════════════════════════ JOURNAL SYSTEM: Auto-generated diary entries Tone varies by femininity level ═══════════════════════════════════════════════════ */ /* ─── Generate end-of-day journal entry ─── */ <<widget "generateJournalEntry">> <<if $journal.autoGenerate && $journal.lastEntryDay !== $world.day>> <<set $journal.lastEntryDay = $world.day>> /* Build the entry from the day's events */ <<set _entry = {day: $world.day, semester: $world.semester, week: $world.week, dayOfWeek: $world.dayOfWeek, femininity: $pc.femininity, mood: $pc.mood}>> /* Title based on day */ <<set _dayNames = ["", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]>> <<set _entry.title = _dayNames[$world.dayOfWeek] + ", Week " + $world.week>> /* Generate body text based on what happened today */ <<set _lines = []>> /* Femininity-toned opening */ <<if $pc.femininity >= 67>> <<set _openers = ["Dear diary! ❤️", "OMG what a day!", "Okay so today was wild.", "Hiii diary~", "Sooo much happened today!"]>> <<elseif $pc.femininity >= 34>> <<set _openers = ["Another day.", "Today was... something.", "Journal entry.", "Well, here goes.", "So today happened."]>> <<else>> <<set _openers = ["Day " + $world.day + ".", "Still stuck in this body.", "Another day as a 'girl'.", "Christ.", "Logging today's events."]>> <</if>> <<run _lines.push(_openers[random(0, _openers.length - 1)])>> /* Service encounters */ <<if $scholarship.currentWeekServiced > 0>> <<if $pc.femininity >= 67>> <<run _lines.push("Had to do some service work for the scholarship. It's actually getting easier? Like, I don't hate it anymore.")>> <<elseif $pc.femininity >= 34>> <<run _lines.push("Did my CCUMDUP duties. It is what it is.")>> <<else>> <<run _lines.push("More degrading 'service' for the scholarship. I just need to get through this.")>> <</if>> <</if>> /* Pregnancy: the biggest thing happening to her, previously unmentioned */ <<if $pregnancy.isPregnant && $pregnancy.discovered>> <<set _pw = $pregnancy.weeksPregnant>> <<set _multi = ($pregnancy.babyCount || 1) > 1>> <<if _pw <= 4>> <<if $pc.femininity >= 67>> <<run _lines.push("I'm PREGNANT. Like, actually pregnant. I keep touching my stomach and there's nothing there yet but there will be. I don't know how to feel. Excited? Terrified? Both?")>> <<elseif $pc.femininity >= 34>> <<run _lines.push("Still processing the test. Pregnant. In a body I didn't have a year ago. I don't know what I'm going to do.")>> <<else>> <<run _lines.push("Pregnant. This body got me pregnant. I can't write any more about it tonight.")>> <</if>> <<elseif _pw <= 13>> <<run _lines.push("Week " + _pw + ". Threw up again this morning. The smell of the cafeteria did it. Nobody's noticed yet. I keep waiting for someone to look at me and just know.")>> <<elseif _pw <= 27>> <<if _multi>> <<run _lines.push("Week " + _pw + ". " + $pregnancy.babyCount + " of them. I've started showing properly and strangers have opinions about it. Everyone wants to touch. Nobody asks first.")>> <<else>> <<run _lines.push("Week " + _pw + ". I'm showing now. Properly. People's eyes drop to my belly before they meet my face, and half of them do the maths about the programme right in front of me.")>> <</if>> <<else>> <<run _lines.push("Week " + _pw + ". Everything aches, nothing fits, and I can feel " + (_multi ? "them" : "it") + " moving when I'm trying to sleep. Not long now. I'm not ready. I don't think you ever are.")>> <</if>> <<elseif $pregnancy.isPregnant && !$pregnancy.discovered && $pregnancy.weeksPregnant >= 4>> <<run _lines.push("Felt rough again today. Tired, queasy, off my food. Probably just stress. Probably.")>> <<elseif $pregnancy.children && $pregnancy.children.length > 0>> <<run _lines.push("Thought about " + (($pregnancy.children.length > 1) ? "them" : "the baby") + " today. Out of nowhere, in the middle of a lecture.")>> <</if>> /* Academic */ <<if $pc.intelligence >= 60>> <<run _lines.push("Studies are going well at least. Small mercies.")>> <<elseif $pc.intelligence < 30>> <<if $pc.femininity >= 67>> <<run _lines.push("Ugh, studying is SO hard. Why do I even need to know this stuff?")>> <<else>> <<run _lines.push("Can't seem to focus on studying. My mind keeps... wandering.")>> <</if>> <</if>> /* Mood-based */ <<if $pc.mood >= 80>> <<if $pc.femininity >= 67>> <<run _lines.push("Feeling amazing today! Everything just clicks. 💕")>> <<else>> <<run _lines.push("Oddly enough, I'm in a good mood. Not sure why.")>> <</if>> <<elseif $pc.mood <= 30>> <<run _lines.push("Feeling pretty low. This isn't the life I imagined for myself.")>> <</if>> /* Arousal */ <<if $pc.arousal >= 70>> <<if $pc.femininity >= 67>> <<run _lines.push("I've been SO horny all day. This body is... a lot.")>> <<else>> <<run _lines.push("The arousal is getting harder to manage. This body reacts to everything.")>> <</if>> <</if>> /* Jobs */ <<if $jobs.current.length > 0>> <<if $pc.femininity >= 67>> <<run _lines.push("Worked today. Gotta keep that money coming in! 💰")>> <<else>> <<run _lines.push("Worked a shift. At least I'm earning something.")>> <</if>> <</if>> /* Reputation-based reflection */ <<if $reputation.slut >= 60>> <<if $pc.femininity >= 67>> <<run _lines.push("People are definitely talking about me. Whatever, let them. 💅")>> <<else>> <<run _lines.push("My reputation is getting... complicated. People look at me differently now.")>> <</if>> <</if>> /* Femininity-based closing */ <<if $pc.femininity >= 67>> <<set _closers = ["Anyway, love ya diary! xoxo", "Gotta go do my skincare. Night! ✨", "Time for bed! Hopefully I dream of something nice~", "Kisses! 💋"]>> <<elseif $pc.femininity >= 34>> <<set _closers = ["That's about it for today.", "We'll see what tomorrow brings.", "One day at a time.", "Signing off."]>> <<else>> <<set _closers = ["End of log.", "Surviving. Barely.", "X more days until this is over.", "I miss my old life."]>> <</if>> <<run _lines.push(_closers[random(0, _closers.length - 1)])>> <<set _entry.text = _lines.join(" ")>> <<run $journal.entries.push(_entry)>> /* Keep only last 30 entries */ <<if $journal.entries.length > 30>> <<run $journal.entries.shift()>> <</if>> <</if>> <</widget>> /* ─── Display Journal ─── */ <<widget "showJournal">> <<if $journal.entries.length === 0>> <p><em>No entries yet. Your journal will fill as you live your new life.</em></p> <<else>> <<for _i = $journal.entries.length - 1; _i >= 0; _i-->> <<set _e = $journal.entries[_i]>> <div class="card"> <div class="card__title">📓 <<print _e.title>>: Day <<print _e.day>></div> <p><<print _e.text>></p> <p class="stat-value" style="font-size:0.75em; opacity:0.6">Femininity: <<print _e.femininity>> | Mood: <<print _e.mood>></p> </div> <</for>> <</if>> <</widget>>
<<if ($transformation.sideEffects.memoryLoss || 0) >= 2 && $pc.maleFirstName>> <p style="opacity:0.6;font-size:0.85em;"><em>The earliest entries are signed with a name you have to concentrate to recognise.</em></p> <</if>> <h2>📓 Journal</h2> <p>Your personal diary. Entries are generated automatically at the end of each day.</p> <div class="choice-group"> <<if $journal.autoGenerate>> <<link '<span class="choice-btn choice-btn--small">📝 Auto-generate: ON</span>' "JournalMenu">> <<set $journal.autoGenerate = false>> <</link>> <<else>> <<link '<span class="choice-btn choice-btn--small">📝 Auto-generate: OFF</span>' "JournalMenu">> <<set $journal.autoGenerate = true>> <</link>> <</if>> </div> <<divider "Entries">> <<showJournal>> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' `($ui.returnPassage || "CampusMap")`>><</link>> </div>
/* ═══════════════════════════════════════════════════ ACHIEVEMENT SYSTEM: ~30 milestone achievements ═══════════════════════════════════════════════════ */ /* ─── Achievement Definitions ─── */ <<widget "initAchievements">> <<if !$achievements>> <<set $achievements = { unlocked: [], definitions: [ /* Service */ {id: "firstService", name: "First Time", emoji: "🌟", desc: "Complete your first CCUMDUP service encounter", cat: "Service"}, {id: "service10", name: "Getting Used To It", emoji: "🔟", desc: "Complete 10 service encounters", cat: "Service"}, {id: "service50", name: "Veteran", emoji: "🏅", desc: "Complete 50 service encounters", cat: "Service"}, {id: "service100", name: "Campus Legend", emoji: "👑", desc: "Complete 100 service encounters", cat: "Service"}, {id: "fiveStarStreak", name: "Perfect 5", emoji: "⭐", desc: "Get 5 five-star ratings in a row", cat: "Service"}, {id: "firstGangbang", name: "Team Player", emoji: "👥", desc: "Survive your first gangbang", cat: "Service"}, {id: "allServiceTypes", name: "Full Menu", emoji: "📋", desc: "Perform every service type at least once", cat: "Service"}, /* Academic */ {id: "deansList", name: "Dean's List", emoji: "🎓", desc: "Achieve GPA 3.8 or higher", cat: "Academic"}, {id: "perfectAttendance", name: "Perfect Attendance", emoji: "📝", desc: "Attend every class for 4 weeks straight", cat: "Academic"}, {id: "surviveFinals", name: "Final Survivor", emoji: "📚", desc: "Survive finals week", cat: "Academic"}, /* Social */ {id: "joinSorority", name: "Sister!", emoji: "🏡", desc: "Join a sorority", cat: "Social"}, {id: "parties10", name: "Party Animal", emoji: "🎉", desc: "Attend 10 parties", cat: "Social"}, {id: "firstFrat", name: "Frat Party Rookie", emoji: "🍺", desc: "Attend your first frat party", cat: "Social"}, /* Jobs */ {id: "firstPaycheck", name: "First Paycheck", emoji: "💰", desc: "Earn money from any job", cat: "Jobs"}, {id: "firstCamShow", name: "Going Live", emoji: "📷", desc: "Complete your first cam show", cat: "Jobs"}, {id: "fansOnly100", name: "OnlyFamous", emoji: "💎", desc: "Reach 100 FansOnly subscribers", cat: "Jobs"}, {id: "firstArrest", name: "Busted", emoji: "🚔", desc: "Get arrested for the first time", cat: "Jobs"}, {id: "drugLord", name: "Drug Lord", emoji: "🧪", desc: "Earn $1000 from dealing", cat: "Jobs"}, /* Transformation */ {id: "fem50", name: "Halfway There", emoji: "🦋", desc: "Reach 50 femininity", cat: "Transform"}, {id: "fem80", name: "Embracing It", emoji: "💃", desc: "Reach 80 femininity", cat: "Transform"}, {id: "femMax", name: "True Woman", emoji: "👸", desc: "Reach 100 femininity", cat: "Transform"}, /* Style */ {id: "bimboMakeover", name: "Bimbo!", emoji: "💄", desc: "Full bimbo style: hair, makeup, outfit", cat: "Style"}, {id: "gothQueen", name: "Goth Queen", emoji: "🖤", desc: "Full goth style: hair, makeup, outfit", cat: "Style"}, {id: "tattooCollection", name: "Ink Canvas", emoji: "🖋️", desc: "Get 5 or more tattoos", cat: "Style"}, /* Reputation */ {id: "campusSlut", name: "Campus Slut", emoji: "🔥", desc: "Reach 80+ Slut reputation", cat: "Reputation"}, {id: "partyLegend", name: "Party Legend", emoji: "🎉", desc: "Reach 80+ Party Girl reputation", cat: "Reputation"}, {id: "scholar", name: "Scholar", emoji: "📚", desc: "Reach 80+ Good Student reputation", cat: "Reputation"}, {id: "celebrity", name: "Campus Celebrity", emoji: "⭐", desc: "Reach 80+ Popular reputation", cat: "Reputation"}, /* Other */ {id: "firstPregnancy", name: "Expecting", emoji: "🤰", desc: "Discover your first pregnancy", cat: "Other"}, {id: "blackoutDrunk", name: "Blackout", emoji: "🍻", desc: "Drink until you black out", cat: "Other"}, {id: "sororityInitiation", name: "Initiated", emoji: "🏡", desc: "Complete full sorority initiation", cat: "Other"} ] }>> <</if>> <</widget>> /* ─── Award an achievement ─── */ <<widget "awardAchievement">> <<set _id = _args[0]>> <<if $achievements && $achievements.unlocked.indexOf(_id) === -1>> <<run $achievements.unlocked.push(_id)>> <<set _def = $achievements.definitions.find(function(a) { return a.id === _id; })>> <<if _def>> <<run XCLC.Toast.show("🏆 Achievement Unlocked: " + _def.emoji + " " + _def.name, "info")>> <</if>> <</if>> <</widget>> /* ─── Check all achievement conditions ─── */ <<widget "checkAchievements">> <<if $achievements>> /* Service */ <<if $scholarship.totalServiced >= 1>><<awardAchievement "firstService">><</if>> <<if $scholarship.totalServiced >= 10>><<awardAchievement "service10">><</if>> <<if $scholarship.totalServiced >= 50>><<awardAchievement "service50">><</if>> <<if $scholarship.totalServiced >= 100>><<awardAchievement "service100">><</if>> /* Academic */ <<if $academic && $academic.classes.length > 0 && XCLC.Academic.getGPA() >= 3.8>><<awardAchievement "deansList">><</if>> /* Jobs */ <<if $finance.totalEarned > 0 && $jobs.current.length > 0>><<awardAchievement "firstPaycheck">><</if>> <<if $jobs.camGirl.shows >= 1>><<awardAchievement "firstCamShow">><</if>> <<if $jobs.fansOnly.subs >= 100>><<awardAchievement "fansOnly100">><</if>> <<if $jobs.hooker.arrested >= 1 || $jobs.dealer.heatLevel >= 10>><<awardAchievement "firstArrest">><</if>> <<if $jobs.dealer.earnings >= 1000>><<awardAchievement "drugLord">><</if>> /* Transformation */ <<if $pc.femininity >= 50>><<awardAchievement "fem50">><</if>> <<if $pc.femininity >= 80>><<awardAchievement "fem80">><</if>> <<if $pc.femininity >= 100>><<awardAchievement "femMax">><</if>> /* Style */ <<if $pc.tattoos && $pc.tattoos.length >= 5>><<awardAchievement "tattooCollection">><</if>> /* Reputation */ <<if $reputation.slut >= 80>><<awardAchievement "campusSlut">><</if>> <<if $reputation.partyGirl >= 80>><<awardAchievement "partyLegend">><</if>> <<if $reputation.goodStudent >= 80>><<awardAchievement "scholar">><</if>> <<if $reputation.popular >= 80>><<awardAchievement "celebrity">><</if>> /* Other */ <<if $pregnancy.totalPregnancies >= 1 && $pregnancy.discovered>><<awardAchievement "firstPregnancy">><</if>> <<if $substances.drunkLevel >= 5>><<awardAchievement "blackoutDrunk">><</if>> <<if $greekLife && $greekLife.hazingComplete>><<awardAchievement "sororityInitiation">><</if>> <<if $greekLife && $greekLife.member>><<awardAchievement "joinSorority">><</if>> /* Social */ <<if $greekLife && $greekLife.fratPartiesAttended >= 10>><<awardAchievement "parties10">><</if>> <<if $greekLife && $greekLife.fratPartiesAttended >= 1>><<awardAchievement "firstFrat">><</if>> <</if>> <</widget>> /* ─── Display achievements ─── */ <<widget "showAchievements">> <<if $achievements>> <<set _cats = ["Service", "Academic", "Social", "Jobs", "Transform", "Style", "Reputation", "Other"]>> <<for _ci = 0; _ci < _cats.length; _ci++>> <<set _cat = _cats[_ci]>> <<set _catAch = $achievements.definitions.filter(function(a) { return a.cat === _cat; })>> <<if _catAch.length > 0>> <div class="card"> <div class="card__title"><<print _cat>></div> <<for _ai = 0; _ai < _catAch.length; _ai++>> <<set _a = _catAch[_ai]>> <<set _unlocked = $achievements.unlocked.indexOf(_a.id) !== -1>> <p @style="'opacity: ' + (_unlocked ? 1 : 0.4)"> <<if _unlocked>>✅<<else>>🔒<</if>> <<print _a.emoji>> <strong><<print _a.name>></strong>: <<print _a.desc>> </p> <</for>> </div> <</if>> <</for>> <p><strong><<print $achievements.unlocked.length>></strong> / <<print $achievements.definitions.length>> unlocked</p> <</if>> <</widget>>
<h2>🏆 Achievements</h2> <<initAchievements>> <<checkAchievements>> <<showAchievements>> <<divider "">> <div class="choice-group"> <<link '<span class="choice-btn">🔙 Back</span>' `($ui.returnPassage || "CampusMap")`>><</link>> </div>
/* ═══════════════════════════════════════════════════ HEALTH: STD SYSTEM Contract → incubate → symptoms → test/treat ═══════════════════════════════════════════════════ */ /* ─── STD Risk Check ─── */ /* Called after any sexual act with a partner. Usage: <<stdRisk "vaginal" 2>> _args[0] = activity: "oral" | "vaginal" | "anal" _args[1] = risk multiplier (optional, default 1). anonymous partners / group scenes are riskier, condoms pass a fraction (e.g. 0.25) */ <<widget "stdRisk">> <<if !$health.hasSTD && !$transformation.addons.stdProtection>> <<set _act = _args[0] || "vaginal">> <<set _mult = Number(_args[1]) || 1>> <<set _bases = {oral: 2, vaginal: 4, anal: 6}>> <<set _chance = Math.min(50, Math.max(1, Math.round((_bases[_act] || 3) * _mult)))>> <<if random(1, 100) <= _chance>> /* Which one you catch is weighted. Chlamydia is much the most common, and is also the one that will not tell you it is there */ <<set _roll = random(1, 100)>> <<set _type = _roll <= 55 ? "chlamydia" : (_roll <= 80 ? "trichomoniasis" : "gonorrhea")>> <<set $health.hasSTD = true>> <<set $health.stdType = _type>> <<set $health.stdDay = $world.day>> <<set $health.stdSymptomatic = false>> <<set $health.stdComplication = "">> /* Some infections never announce themselves at all */ <<set $health.stdSilent = random(1, 100) <= XCLC.STD.def(_type).silentChance>> /* Silent for now: symptoms surface after incubation (stdDaily) */ <</if>> <</if>> <</widget>> /* ─── Menstrual Cycle ─── */ /* Called from the daily rollover. 28-day cycle, period on days 1-4. Disabled by the No Period add-on; suppressed by pregnancy (the missed period is the pregnancy discovery hint). */ <<widget "cycleDaily">> <<if !$transformation.addons.noPeriod && !$pregnancy.isPregnant>> <<set $health.cycleDay = ($health.cycleDay || 1) + 1>> <<if $health.cycleDay > 28>><<set $health.cycleDay = 1>><</if>> <<if $health.cycleDay === 1>> <<run XCLC.Toast.show("🩸 Your period started. Great. Another thing this body does.", "warning", 5000)>> <<modStat "mood" -5 "Period started">> <</if>> <<if $health.cycleDay <= 4>> /* Period days: cramps, low arousal */ <<set $pc.arousal = Math.max(0, $pc.arousal - 10)>> <<if $health.cycleDay <= 2>> <<modStat "mood" -3 "Cramps">> <<if random(1,100) <= 40>> <<run XCLC.Toast.show("🩸 Cramps. You dig through your bag for painkillers.", "info")>> <</if>> <</if>> <</if>> <</if>> <</widget>> /* ─── Weight Drift ─── */ /* Called from the weekly rollover. Gym habits pull weight down, total inactivity lets it creep up. Locked by Metabolism Control. */ <<widget "weightWeekly">> <<if !$transformation.addons.metabolismControl && $pc.weight>> <<set _order = ["slim", "average", "curvy", "chubby"]>> <<set _wIdx = _order.indexOf($pc.weight)>> <<if _wIdx !== -1>> <<set _gymThisWeek = ($gym ? $gym.totalVisits : 0) - ($health.lastWeekGymVisits || 0)>> <<set $health.lastWeekGymVisits = ($gym ? $gym.totalVisits : 0)>> <<if _gymThisWeek >= 3 && _wIdx > 0 && random(1,100) <= 30>> <<set $pc.weight = _order[_wIdx - 1]>> <<run XCLC.Toast.show("⚖️ All that gym time is showing. Your body has slimmed down to '" + State.variables.pc.weight + "'.", "success", 5000)>> <<elseif _gymThisWeek === 0 && _wIdx < _order.length - 1 && random(1,100) <= 20>> <<set $pc.weight = _order[_wIdx + 1]>> <<run XCLC.Toast.show("⚖️ Cafeteria food and zero gym... your jeans are getting snug. Weight is now '" + State.variables.pc.weight + "'.", "warning", 5000)>> <</if>> <</if>> <</if>> <</widget>> /* ─── Daily STD Processing ─── */ /* Called from the daily rollover in 31_time_widgets */ <<widget "stdDaily">> <<if $health.hasSTD>> <<set _def = XCLC.STD.def($health.stdType)>> <<set _daysSince = $world.day - ($health.stdDay || $world.day)>> /* Incubation varies by infection: and a silent one never shows at all */ <<if !$health.stdSymptomatic && !$health.stdSilent && _daysSince >= _def.incubation>> <<set $health.stdSymptomatic = true>> <<run XCLC.Toast.show(_def.icon + " " + _def.symptomText + " Get tested at the Health Centre.", "warning", 8000)>> <</if>> /* Symptomatic: drain scaled to how nasty this one is */ <<if $health.stdSymptomatic>> <<set $pc.health = Math.max(0, $pc.health - _def.dailyHealth)>> <<set $pc.mood = Math.max(0, $pc.mood - _def.dailyMood)>> <<if _def.hygienePenalty > 0>> <<set $hygiene.cleanliness = Math.max(0, $hygiene.cleanliness - _def.hygienePenalty)>> <</if>> <<if random(1, 100) <= 25>> <<run XCLC.Toast.show(_def.icon + " " + _def.name + ": treatment at the Health Centre is $" + _def.treatment + ".", "warning")>> <</if>> <</if>> /* Left long enough, each one leaves something behind */ <<if !$health.stdComplication && _daysSince >= _def.longTermDay && _def.longTerm !== "none">> <<set $health.stdComplication = _def.longTerm>> <<if _def.longTerm === "fertility">> <<set $transformation.sideEffects.fertility = Math.max(0, ($transformation.sideEffects.fertility || 0) - 1)>> <<run XCLC.Toast.show("🦠 Untreated for " + _daysSince + " days. The clinic will later describe the scarring as 'probably not reversible'.", "danger", 9000)>> <<elseif _def.longTerm === "health">> <<set $pc.health = Math.max(0, $pc.health - 20)>> <<run XCLC.Toast.show("🔥 You have let this run for " + _daysSince + " days. It has stopped being local.", "danger", 9000)>> <</if>> <</if>> <</if>> <</widget>>
/* ═══════════════════════════════════════════════════ THORNFIELD: CORE DISPLAY WIDGETS Stat bars, dividers, alerts, choice buttons ═══════════════════════════════════════════════════ */ /* ─── Stat Display Bar (inline) ─── */ <<widget "statBar">> /* Usage: <<statBar "Energy" $pc.energy 100 "energy">> */ <<set _label = _args[0]>> <<set _val = Math.round(_args[1])>> <<set _max = _args[2] || 100>> <<set _cls = _args[3] || "default">> <<set _pct = Math.min(100, Math.max(0, Math.round((_val / _max) * 100)))>> <div class="stat-bar-row"> <span class="stat-bar-label"><<print _label>></span> <div class="stat-bar-track"><div @class="'stat-bar-fill ' + _cls" @style="'width:' + _pct + '%;'"></div></div> <span class="stat-bar-val"><<print _val>></span> </div> <</widget>> /* ─── Section Divider ─── */ <<widget "divider">> /* Usage: <<divider "Section Title">> */ <div class="divider"> <<if _args[0]>> <span class="divider__text"><<print _args[0]>></span> <</if>> </div> <</widget>> /* ─── Alert Box ─── */ <<widget "alert">> /* Usage: <<alert "info" "This is a message">> */ <<set _type = _args[0] || "info">> <<set _msg = _args[1] || "">> <div class="alert alert--_type"><<print _msg>></div> <</widget>> /* ─── Choice Button (SugarCube link wrapper) ─── */ <<widget "choiceBtn">> /* Usage: <<choiceBtn "PassageName" "Button text">> */ <<set _passage = _args[0]>> <<set _text = _args[1]>> <div class="choice-group"> <<link _text _passage>><</link>> </div> <</widget>> /* ─── Toast Widget (calls JS) ─── */ <<widget "toast">> /* Usage: <<toast "Message text" "type">> */ <<set _msg = _args[0]>> <<set _type = _args[1] || "info">> <<run XCLC.Toast.show(_msg, _type)>> <</widget>> /* ─── Money Display ─── */ <<widget "showMoney">> /* Usage: <<showMoney>> */ <<if $finance.money >= 0>> <span class="money positive">$<<print $finance.money>></span> <<else>> <span class="money negative">-$<<print Math.abs($finance.money)>></span> <</if>> <</widget>> /* ─── Modify Cash ─── */ <<widget "addCash">> /* Usage: <<addCash 100 "Service payment">> */ <<set _amount = _args[0]>> <<set _reason = _args[1] || "Unknown">> <<set $finance.money += _amount>> <<if _amount > 0>> <<set $finance.totalEarned += _amount>> <<run XCLC.Toast.show('+$' + _amount + ': ' + _reason, 'money')>> <<else>> <<set $finance.totalSpent += Math.abs(_amount)>> <<run XCLC.Toast.show('-$' + Math.abs(_amount) + ': ' + _reason, 'warning')>> <</if>> <<set $finance.transactions.push({ amount: _amount, description: _reason, day: $world.day, time: $world.time })>> <</widget>> /* ─── Phone Overlay HTML (injected into StoryInterface via PassageDone if needed) ─── */ <<widget "initPhone">> <<if !document.getElementById('phone-overlay')>> <<run $(document.getElementById('xclc-app')).append('<div id="phone-overlay"><div id="phone-screen"></div></div>')>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ REASON CODA $pc.reason is chosen at the first real decision in the game and, before this, was read exactly once. This lands it where it matters: the last thing the player reads. <<reasonCoda "stayed">> completed three years <<reasonCoda "left">> expelled or dropped out ═══════════════════════════════════════════════════ */ <<widget "reasonCoda">> <<set _rcTone = _args[0] || "stayed">> <<set _rc = $pc.reason || "poverty">> <<if _rcTone === "stayed">> <<if _rc === "poverty">> <p><em>The debt is gone. That was the whole point and it worked exactly as advertised, and you have spent three years learning that a thing can work exactly as advertised and still take a payment nobody itemised for you in advance.</em></p> <<elseif _rc === "bet">> <p><em>Nobody from that kitchen has spoken to you in two years. The joke stopped being a joke somewhere in the first winter, and the people who made it were not around for the part where it stopped.</em></p> <<elseif _rc === "curious">> <p><em>You wanted to know. You know now. It turns out that is not the clean transaction you imagined at eighteen, because the answer arrived in pieces over three years and several of the pieces are still in your hands.</em></p> <<elseif _rc === "forced">> <p><em>You never agreed to any of it. You finished it anyway, which is a sentence you have turned over more than once. The person whose signature is on the form has never asked how it went, and you have stopped waiting for them to.</em></p> <<elseif _rc === "opportunist">> <p><em>You got the housing and the stipend and the free ride, precisely as calculated. The maths was correct. You are considerably less sure, now, that maths was the right instrument for the question.</em></p> <<else>> <p><em>You came here because it read as a door rather than a price. It was a door. You went through it, and it closed behind you, and at no point in three years have you wanted anybody to open it again.</em></p> <</if>> <<else>> <<if _rc === "poverty">> <p><em>The bills are still there. They were there before the letter arrived and they are there now, and the only thing that has changed is how much of yourself you spent finding that out.</em></p> <<elseif _rc === "bet">> <p><em>You could go back and tell them you did it. You have thought about that conversation a great deal and you are not going to have it, because there is no version of it where they understand what they are being told.</em></p> <<elseif _rc === "curious">> <p><em>You got enough of an answer. Not the whole of one, but enough, and there is something to be said for walking away from a question while you still recognise the person asking it.</em></p> <<elseif _rc === "forced">> <p><em>You left. After three years of arrangements made on your behalf by other people, that was the first decision in the whole business that belonged to you, and you are going to be holding onto it for a while.</em></p> <<elseif _rc === "opportunist">> <p><em>The perks stopped covering it. You are good enough with numbers to have seen that coming and you stayed anyway, longer than the numbers justified, which is worth thinking about at some point.</em></p> <<else>> <p><em>You found the part you came for. The rest of it was somebody else's programme, and you have discovered that you can take the first thing without staying for the second.</em></p> <</if>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ ENSURE SERVICE CONTEXT Backfills $temp.serviceRequest / $temp.serviceNPC when a passage in the Service*/Group* chain is entered cold: a stale link, a mid-scene save load, a dev jump. No-op when context already exists, so it is safe to call unconditionally at the top of any passage in the chain. ═══════════════════════════════════════════════════ */ <<widget "ensureServiceContext">> <<if !$temp.serviceNPC>> <<set $temp.serviceNPC = XCLC.NPC.generate({})>> <<set $temp.contextWasBackfilled = true>> <</if>> <<if !$temp.serviceRequest>> <<set $temp.serviceRequest = { npc: $temp.serviceNPC, serviceType: "oral", locationName: "the meeting point", locationDesc: "the address on your phone", locationPrivacy: "medium", dc: 3, credits: 1, isGroup: false, standalone: true }>> <<set $temp.contextWasBackfilled = true>> <</if>> /* Positions are read by ServicePositionSelect / the act chain. */ <<if !$temp.chosenPosition>> <<set $temp.chosenPosition = {id: "missionary", name: "Missionary", synergy: []}>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ RELATIONSHIP STRAIN Called after a service encounter. The quota does not pause because you met someone. ═══════════════════════════════════════════════════ */ <<widget "relationshipStrain">> <<if $relationship.stage !== "none">> <<set _rsUp = $relationship.knowsAboutProgramme ? 3 : 8>> <<set $relationship.tension = Math.min(100, $relationship.tension + _rsUp)>> <<if $relationship.tension >= 70 && $relationship.stage === "exclusive">> <div class="alert alert--danger">💔 <<print $relationship.partnerName>> has asked twice this week where you were. You are running out of versions of the answer.</div> <<elseif $relationship.tension >= 40>> <div class="alert alert--warning">💬 You check your phone on the walk back. <<print $relationship.partnerName>> messaged an hour ago and you have not decided what to say yet.</div> <</if>> <</if>> <</widget>> /* Relationship progress gate, read by Presence_Talk. */ <<widget "canAskOut">> <<set _cao = _args[0]>> <<set $temp.canAskOut = ($relationship.stage === "none" && _cao && (_cao.opinion || 0) >= 70 && (_cao.attraction || 0) >= 60 && (_cao.encounters || 0) >= 1)>> <</widget>> /* ═══════════════════════════════════════════════════ THE OLD NAME $pc.maleFirstName is captured at character creation and, before this, never appeared again anywhere. In a game with a memoryLoss side effect that is a waste of the best prop available. <<oldName>> prints it, or a memory-loss-degraded form <<oldNameNote>> a short beat about seeing it written down ═══════════════════════════════════════════════════ */ <<widget "oldName">> <<set _onLvl = $transformation.sideEffects.memoryLoss || 0>> <<set _onN = $pc.maleFirstName || "">> <<if _onN === "">><<print "[no record]">> <<elseif _onLvl >= 4>><<print _onN.charAt(0) + "\u2014\u2014\u2014">> <<else>><<print _onN>><</if>> <</widget>> <<widget "oldNameNote">> <<set _onL = $transformation.sideEffects.memoryLoss || 0>> <<if $pc.maleFirstName>> <<if _onL >= 4>> <p class="orientation-note"><em>The name on the form means nothing to you. You read it twice, the way you would read a stranger's, and feel absolutely nothing move.</em></p> <<elseif _onL >= 3>> <p class="orientation-note"><em><<print $pc.maleFirstName>>. You know it is yours the way you know a fact from a textbook. There is no picture attached to it any more.</em></p> <<elseif _onL >= 1>> <p class="orientation-note"><em><<print $pc.maleFirstName>>, in somebody's handwriting. It takes you a half second longer than it should to place it.</em></p> <<else>> <p class="orientation-note"><em><<print $pc.maleFirstName>> <<print $pc.lastName>>. Still your name on paper, in the places paper has not caught up yet.</em></p> <</if>> <</if>> <</widget>>
/* ═══════════════════════════════════════════════════ THORNFIELD: TIME SYSTEM WIDGETS ═══════════════════════════════════════════════════ */ /* ─── Advance Time ─── */ <<widget "advanceTime">> /* Usage: <<advanceTime 60>> (advances 60 minutes) */ <<set _minutes = _args[0] || 30>> <<set _oldPeriod = XCLC.Time.getPeriod($world.time)>> /* Advance the clock */ <<set $world.time += _minutes>> /* ─── Day Rollover ─── */ <<if $world.time >= 1440>> <<set $world.time -= 1440>> <<set $world.day++>> <<set $world.dayOfMonth++>> <<set $world.dayOfWeek++>> <<if $world.dayOfWeek > 7>> <<set $world.dayOfWeek = 1>> <</if>> /* Hair growth tick */ <<if !$transformation.addons.noHair>> <<set _daysSinceShave = $world.day - $pc.lastShaved>> <<if _daysSinceShave > 2 && $pc.legHair < 2>> <<set $pc.legHair = Math.min(2, $pc.legHair + 1)>> <</if>> <<if _daysSinceShave > 4 && $pc.pubicHair < 4>> <<set $pc.pubicHair = Math.min(4, $pc.pubicHair + 1)>> <</if>> <</if>> /* Beauty decay (gym) */ <<if $world.day - $pc.lastGymDay > 7 && $pc.beautyFitness > 0>> <<set $pc.beautyFitness = Math.max(0, $pc.beautyFitness - 2)>> <</if>> /* Grooming beauty recalc */ <<if $pc.legHair === 0>> <<set $pc.beautyGrooming = 10>> <<elseif $pc.legHair === 1>> <<set $pc.beautyGrooming = 3>> <<else>> <<set $pc.beautyGrooming = 0>> <</if>> <<if $pc.pubicHair === 1>><<set $pc.beautyGrooming += 3>><</if>> <<if $pc.pubicHair === 2>><<set $pc.beautyGrooming += 4>><</if>> <<if $pc.pubicHair === 3>><<set $pc.beautyGrooming += 2>><</if>> /* Hygiene decay (overnight) */ <<set $hygiene.cleanliness = Math.max(0, $hygiene.cleanliness - 5)>> /* Reset daily service request counter */ <<set $scholarship.requestsToday = 0>> /* Reset daily gym flag */ <<if $gym>><<set $gym.workedOutToday = false>><<set $gym.marcusTrainedToday = false>><</if>> /* Children: nursery fees, or a day nobody looked after them */ <<childrenDaily>> /* Rent, once the programme is behind you */ <<rentCheck>> /* Journal entry */ <<generateJournalEntry>> /* Reset daily rep event flag */ <<set $temp.repCheckedToday = false>> /* STD symptoms and daily effects */ <<stdDaily>> /* Menstrual cycle */ <<cycleDaily>> /* Prof. Drake retaliation: her marks bleed while this is unresolved. This is the thing she can eventually prove. */ <<if $academic.drakeCase.retaliating && !$academic.drakeCase.resolved>> <<if $academic.drakeCase.classIndex >= 0 && $academic.classes.length > $academic.drakeCase.classIndex>> <<set _dc = $academic.classes[$academic.drakeCase.classIndex]>> <<if $academic.drakeCase.earnedGrade === null>> <<set $academic.drakeCase.earnedGrade = _dc.grade>> <</if>> <<set _dc.grade = Math.max(35, _dc.grade - 1)>> <<if random(1, 100) <= 12>> <<run XCLC.Toast.show("📉 Another assignment back from Prof. " + State.variables.academic.professors[State.variables.academic.drakeCase.profIndex].lastName + ", bleeding red ink. The comments do not match the mark.", "warning", 6000)>> <</if>> <</if>> <</if>> /* Birth control prescription countdown */ <<if $health.birthControlActive>> <<set $health.birthControlDays-->> <<if $health.birthControlDays <= 0>> <<set $health.birthControlActive = false>> <<set $health.birthControlDays = 0>> <<run XCLC.Toast.show("💊 Your birth control prescription has run out. Refill at the Health Centre ($15).", "warning", 6000)>> <<elseif $health.birthControlDays === 3>> <<run XCLC.Toast.show("💊 Birth control: only 3 days left. Refill soon.", "warning")>> <</if>> <</if>> /* Achievement check */ <<initAchievements>> <<checkAchievements>> /* Substance sobering */ <<if $substances.drunkLevel > 0>> <<set $substances.drunkLevel = 0>> <<set $substances.drinksToday = 0>> <<if $substances.hangoverSeverity > 0>> <<set $substances.hangover = true>> <</if>> <</if>> <<if $substances.weed.high>> <<set $substances.weed.high = false>> <</if>> <<if $substances.cocaine.high>> <<set $substances.cocaine.high = false>> <</if>> <<if $substances.ecstasy.rolling>> <<set $substances.ecstasy.rolling = false>> <<set $substances.ecstasy.comedown = true>> <</if>> /* Month rollover */ <<set _daysInMonth = [0,31,28,31,30,31,30,31,31,30,31,30,31]>> <<if $world.dayOfMonth > _daysInMonth[$world.month]>> <<set $world.dayOfMonth = 1>> <<set $world.month++>> <<if $world.month > 12>> <<set $world.month = 1>> <<set $world.yearActual++>> <</if>> <</if>> /* ─── Weekly Rollover (Sunday midnight) ─── */ <<if $world.dayOfWeek === 1>> <<set $world.week++>> /* Quota check */ <<set _target = $scholarship.isFinalsWeek ? $scholarship.finalsQuota : $scholarship.weeklyQuota>> <<if $scholarship.currentWeekServiced < _target>> /* Missed quota: rating penalty */ <<set _penalty = (_target - $scholarship.currentWeekServiced) * 0.2>> <<set $scholarship.rating = Math.max(2.0, $scholarship.rating - _penalty)>> <<if $scholarship.rating < 4.0 && !$scholarship.onProbation>> <<set $scholarship.onProbation = true>> <<set $scholarship.probationWeeks = 0>> <</if>> <</if>> /* Store weekly history */ <<set $scholarship.weeklyHistory.push({ week: $world.week - 1, serviced: $scholarship.currentWeekServiced, credits: $scholarship.currentWeekCredits, avgRating: $scholarship.totalRatings > 0 ? $scholarship.ratingSum / $scholarship.totalRatings : 5.0 })>> /* Reset weekly counters */ <<set $scholarship.currentWeekServiced = 0>> <<set $scholarship.currentWeekCredits = 0>> <<set $scholarship.weekLog = []>> <<set $scholarship.rerollAvailable = true>> /* Probation tracking */ <<if $scholarship.onProbation>> <<set $scholarship.probationWeeks++>> <<if $scholarship.rating >= 4.5>> <<set $scholarship.onProbation = false>> <<set $scholarship.probationWeeks = 0>> <</if>> <</if>> /* ─── Weekly Job Processing ─── */ <<if $jobs>> /* FansOnly weekly revenue */ <<if $jobs.fansOnly.active && $jobs.fansOnly.subs > 0>> <<set _foRevenue = $jobs.fansOnly.subs * 5>> <<set $finance.money += _foRevenue>> <<set $finance.totalEarned += _foRevenue>> <<set $jobs.fansOnly.revenue += _foRevenue>> <</if>> /* Dealer heat decay */ <<if $jobs.dealer.active && $jobs.dealer.heatLevel > 0>> <<set $jobs.dealer.heatLevel = Math.max(0, $jobs.dealer.heatLevel - 1)>> <</if>> /* Cheerleader practice miss check (MWF) */ <<if $jobs.cheerleader.active>> <<set _daysSincePractice = $world.day - $jobs.cheerleader.practiceDay>> <<if _daysSincePractice > 3>> <<set $jobs.cheerleader.practicesMissed++>> <<if $jobs.cheerleader.practicesMissed >= 3>> <<quitJob "cheerleader">> <<set $jobs.cheerleader.hasOutfit = false>> <</if>> <</if>> <</if>> <</if>> /* Semester structure: 16 weeks */ <<if $world.week > 16>> /* Resolve finals: untaken finals auto-fail, 3+ failed = repeat */ <<set _semEnd = $academic.classesChosen ? XCLC.Academic.processSemesterEnd() : {repeat: false, failedCount: 0}>> <<set $world.week = 1>> <<if _semEnd.repeat>> <<set $temp.repeatedSemester = true>> <<run XCLC.Toast.show("📚 You failed " + _semEnd.failedCount + " finals. The registrar's letter is blunt: you're repeating the semester.", "error", 8000)>> <<modStat "stress" 20 "Held back">> <<modStat "confidence" -10 "Held back">> <<else>> <<set $world.semester++>> <<if $world.semester % 2 === 1>> /* New academic year: quota escalates, roommate ages with you, and the transition gets an actual beat instead of passing silently the way it used to. */ <<set $world.year = Math.ceil($world.semester / 2)>> <<set _qBase = $scholarship.baseWeeklyQuota || 5>> <<set $scholarship.weeklyQuota = Math.round((_qBase + ($world.year - 1)) * ($university.quotaMultiplier || 1))>> <<set $scholarship.finalsQuota = $scholarship.weeklyQuota * 2>> <<if $roommate.name && !$roommate.movedOut>> <<set $roommate.yearsWith = ($roommate.yearsWith || 1) + 1>> <</if>> <<set $temp.yearRolled = true>> <</if>> <<if $world.semester > 6>> /* Graduation! */ <<goto "Graduation">> <<elseif $temp.yearRolled>> <<set $temp.yearRolled = false>> <<goto "YearTransition">> <</if>> <</if>> <</if>> /* Check for special weeks */ <<set $world.isFinalsWeek = ($world.week >= 15)>> <<set $scholarship.isFinalsWeek = $world.isFinalsWeek>> <<set $world.isSpringBreak = ($world.semester % 2 === 0 && $world.week >= 12 && $world.week <= 13)>> /* Season */ <<if $world.month >= 9 && $world.month <= 11>> <<set $world.season = "autumn">> <<elseif $world.month === 12 || $world.month <= 2>> <<set $world.season = "winter">> <<elseif $world.month >= 3 && $world.month <= 5>> <<set $world.season = "spring">> <<else>> <<set $world.season = "summer">> <</if>> /* ─── Phase 7: Weekly Meta Systems ─── */ /* Pregnancy progression */ <<pregnancyProgress>> /* Weight drift from gym/eating habits */ <<weightWeekly>> /* Seasonal event check */ <<checkSeasonalEvent>> /* Housing review: rating buys you a better room, probation takes it back */ <<set _housing = XCLC.Housing.review()>> <<if _housing>> <<if _housing.up>> <<run XCLC.Toast.show(_housing.to.icon + " Housing upgraded: " + _housing.to.name + ".", "success", 7000)>> <<else>> <<run XCLC.Toast.show(_housing.to.icon + " Housing downgraded to " + _housing.to.name + ".", "danger", 7000)>> <</if>> <</if>> /* Weekly performance report flag */ <<set $temp.weeklyReportPending = true>> /* ─── Phase 9: Blackmail check ─── */ <<checkBlackmail>> <</if>> <</if>> /* ─── Period Change Processing ─── */ <<set _newPeriod = XCLC.Time.getPeriod($world.time)>> <<if _oldPeriod !== _newPeriod>> /* Side effect processing happens on period change */ <<processEffects>> /* Hygiene decay per period */ <<set $hygiene.cleanliness = Math.max(0, $hygiene.cleanliness - 3)>> /* Energy drain */ <<if _newPeriod === "late_night" && $pc.energy > 0>> <<set $pc.energy = Math.max(0, $pc.energy - 10)>> <</if>> /* Hangover clears at noon */ <<if $substances.hangover && $world.time >= 720>> <<set $substances.hangover = false>> <<set $substances.hangoverSeverity = 0>> <</if>> /* ─── Random Daily Events ─── */ <<checkRandomEvent>> /* ─── Body Writing visibility ─── */ <<if $bodyWriting.active && $bodyWriting.texts.length > 0>> <<if $hygiene.cleanliness >= 90>> /* Shower washed it off */ <<set $bodyWriting.active = false>> <<set $bodyWriting.texts = []>> <</if>> <</if>> <</if>> /* Recalculate beauty */ <<run XCLC.Beauty.recalculate()>> /* Service request expiry check */ <<run XCLC.Service.checkRequestExpiry()>> <</widget>> /* ─── Process Side Effects (called on period change) ─── */ <<widget "processEffects">> <<set _se = $transformation.sideEffects>> /* Internal Heat: arousal buildup */ <<if _se.internalHeat > 0>> <<set $pc.arousal = Math.min(100, $pc.arousal + (_se.internalHeat * 5))>> <</if>> /* Increased Sensitivity: arousal gains multiplied */ /* (handled contextually during encounters, but passive tick here) */ <<if _se.increasedSensitivity > 0>> <<set $pc.arousal = Math.min(100, $pc.arousal + (_se.increasedSensitivity * 2))>> <</if>> /* Submissive: willpower penalty (maintained, doesn't stack repeatedly) */ <<if _se.submissive > 0>> <<set $pc.willpower = Math.max(0, 60 - (_se.submissive * 5))>> <</if>> /* Random Orgasm: chance per period */ <<if _se.randomOrgasm > 0>> <<set _orgasmChance = _se.randomOrgasm * 10>> <<if random(1, 100) <= _orgasmChance>> <<set $pc.arousal = 100>> /* Orgasm will be narrated in context */ <</if>> <</if>> /* Sexual Fluid Addiction: withdrawal check */ <<if _se.sexualFluidAddiction >= 3>> /* At level 3+, need daily dose or mood penalty */ <<if $scholarship.currentWeekServiced === 0 && $world.dayOfWeek > 1>> <<set $pc.mood = Math.max(0, $pc.mood - (_se.sexualFluidAddiction * 5))>> <</if>> <</if>> /* Lactation: must express or pain */ <<if _se.lactation >= 2>> /* Handled contextually in routine passages */ <</if>> /* Exhibitionist: arousal from being dressed inappropriately */ <<if _se.exhibitionist >= 3>> <<set $pc.arousal = Math.min(100, $pc.arousal + 5)>> <</if>> /* Pheromones: arousal in crowded areas (location-dependent, passive tick) */ <<if _se.pheromones > 0>> <<set $pc.arousal = Math.min(100, $pc.arousal + _se.pheromones)>> <</if>> /* Erotic Dreams: handled at morning routine */ /* Bimbofication: intelligence decay */ <<if _se.bimbofication >= 2>> /* -1 intelligence per week (processed weekly, but check here) */ <<if $world.dayOfWeek === 1>> <<set $pc.intelligence = Math.max(0, $pc.intelligence - _se.bimbofication)>> <<if _se.bimbofication >= 4>> <<set $pc.intelligence = Math.min(30, $pc.intelligence)>> <</if>> <</if>> <</if>> /* Memory Loss: femininity boost */ <<if _se.memoryLoss >= 3>> <<set $pc.femininity = Math.min(100, $pc.femininity + 1)>> <</if>> /* ─── Add-on Enforcement ─── */ /* Metabolism Control: prevent weight/body changes */ <<if $transformation.addons.metabolismControl && $pc.bodyWeight>> <<set $pc.bodyWeight = $pc.bodyWeightBase || $pc.bodyWeight>> <</if>> /* No Period: skip period symptoms entirely */ <<if $transformation.addons.noPeriod && $pregnancy.periodDue>> <<set $pregnancy.periodDue = false>> <</if>> /* Orgasm Denial: frustration buildup */ <<if _se.orgasmDenial >= 2>> <<if $pc.arousal >= 80>> <<set $pc.stress = Math.min(100, $pc.stress + 3)>> <</if>> <</if>> /* Masturbation Denial: can't relieve via solo */ /* (enforcement is in the DormRoom_Masturbate passage check) */ /* Strong Orgasms: mood bonus from orgasm events, energy cost at high levels */ /* (triggered contextually during orgasm events, not per-period) */ <</widget>> /* ─── Display Time ─── */ <<widget "showTime">> <<print XCLC.Time.format($world.time)>> <</widget>> /* ─── Display Date ─── */ <<widget "showDate">> <<print XCLC.Time.dayNameFull($world.dayOfWeek)>>, <<print XCLC.Time.monthName($world.month)>> <<print $world.dayOfMonth>> <</widget>> /* ─── Display Period ─── */ <<widget "showPeriod">> <<print XCLC.Time.getPeriodName($world.time)>> <</widget>> /* ─── Advance to next day (skip to midnight rollover) ─── */ <<widget "advanceDay">> <<set _remaining = 1440 - $world.time>> <<if _remaining > 0>> <<advanceTime _remaining>> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ 📊 WEEKLY PERFORMANCE REPORT Shown on Monday morning ═══════════════════════════════════════════════════ */ /* ═══════════════════════════════════════════════════ YEAR AWARENESS $world.year is 1-3, derived from semester. Before this, nothing in the game read it except one clause in an ending, so all seasonal content replayed identically. ═══════════════════════════════════════════════════ */ /* Pick one of three strings by academic year. <<yearVariant "first year" "second year" "third year">> */ <<widget "yearVariant">> <<set _yv = $world.year || 1>> <<if _yv <= 1>><<print _args[0]>> <<elseif _yv === 2>><<print _args[1]>> <<else>><<print _args[2]>><</if>> <</widget>> /* Year noun. <<yearLabel>> -> "freshman" / "sophomore" / "junior" */ <<widget "yearLabel">> <<set _yl = $world.year || 1>> <<print ["freshman", "sophomore", "junior"][Math.min(2, Math.max(0, _yl - 1))]>> <</widget>> /* Ordinal. <<yearOrdinal>> -> "first" / "second" / "third" */ <<widget "yearOrdinal">> <<set _yo = $world.year || 1>> <<print ["first", "second", "third"][Math.min(2, Math.max(0, _yo - 1))]>> <</widget>> /* Small italic returning-student note, for the top of repeat events. */ <<widget "yearNote">> <<if ($world.year || 1) > 1>> <p style="opacity:0.7;font-size:0.9em;"><em><<print _args[0]>></em></p> <</if>> <</widget>>
<h2>📊 Weekly Report: Week <<print $world.week - 1>></h2> <<set $temp.weeklyReportPending = false>> /* CCUMDUP */ <div class="card"> <div class="card__title">🎀 CCUMDUP Service</div> <<set _target = $scholarship.isFinalsWeek ? $scholarship.finalsQuota : $scholarship.weeklyQuota>> <<set _lastWeek = $scholarship.weeklyHistory.length > 0 ? $scholarship.weeklyHistory[$scholarship.weeklyHistory.length - 1] : null>> <<if _lastWeek>> <p><strong>Serviced:</strong> <<print _lastWeek.serviced>> / <<print _target>> target</p> <p><strong>Credits earned:</strong> <<print _lastWeek.credits>></p> <p><strong>Avg rating:</strong> <<print Math.round(_lastWeek.avgRating * 10) / 10>> ⭐</p> <<if _lastWeek.serviced < _target>> <div class="alert alert--warning">⚠️ Quota not met! Rating penalty applied.</div> <</if>> <<else>> <p><em>No service data from last week.</em></p> <</if>> <p><strong>Current Rating:</strong> <<print Math.round($scholarship.rating * 10) / 10>> / 5.0 ⭐</p> <<if $scholarship.onProbation>><div class="alert alert--warning">⚠️ <strong>ON PROBATION</strong> (Week <<print $scholarship.probationWeeks>>)</div><</if>> </div> /* Finance */ <div class="card"> <div class="card__title">💰 Finances</div> <p><strong>Cash on hand:</strong> $<<print $finance.money>></p> <p><strong>Total earned (all time):</strong> $<<print $finance.totalEarned>></p> <p><strong>Total spent (all time):</strong> $<<print $finance.totalSpent>></p> <<if $jobs.fansOnly.active && $jobs.fansOnly.subs > 0>> <p><strong>FansOnly revenue this week:</strong> $<<print $jobs.fansOnly.subs * 5>> (<<print $jobs.fansOnly.subs>> subs)</p> <</if>> </div> /* Jobs */ <<if $jobs.current.length > 0>> <div class="card"> <div class="card__title">💼 Employment</div> <<set _jobNames = {barista: "☕ Barista", bartender: "🍸 Bartender", tutor: "📚 Tutor", cheerleader: "📣 Cheerleader", camGirl: "📷 Cam Girl", fansOnly: "💰 FansOnly", stripper: "💃 Stripper", hooker: "💋 Escort", dealer: "🧪 Dealer"}>> <<for _j = 0; _j < $jobs.current.length; _j++>> <<set _jid = $jobs.current[_j]>> <p><<print _jobNames[_jid] || _jid>></p> <</for>> </div> <</if>> /* Reputation movers */ <div class="card"> <div class="card__title">📊 Reputation</div> <<set _repTracks = [ {id: "slut", name: "🔥 Slut", val: $reputation.slut}, {id: "partyGirl", name: "🎉 Party Girl", val: $reputation.partyGirl}, {id: "goodStudent", name: "📚 Good Student", val: $reputation.goodStudent}, {id: "popular", name: "⭐ Popular", val: $reputation.popular} ]>> <<for _r = 0; _r < _repTracks.length; _r++>> <<set _rt = _repTracks[_r]>> <<if _rt.val > 0>> <p><<print _rt.name>>: <<print _rt.val>>/100</p> <</if>> <</for>> </div> /* Pregnancy */ <<if $pregnancy.isPregnant && $pregnancy.discovered>> <div class="card"> <div class="card__title">🤰 Pregnancy</div> <p><strong>Week <<print $pregnancy.weeksPregnant>></strong> of pregnancy.</p> <<if $pregnancy.weeksPregnant < 8>> <p>Not showing yet.</p> <<elseif $pregnancy.weeksPregnant < 20>> <p>Starting to show.</p> <<else>> <p>Very visibly pregnant.</p> <</if>> </div> <</if>> /* Seasonal event notice */ <<if $temp.seasonalEvent>> <div class="alert alert--info">🎉 <strong>Special Event This Week:</strong> Check the campus for seasonal activities!</div> <</if>> <<divider "">> <div class="choice-group"> <<if $temp.seasonalEvent>> <<set _eventNames = {freshmanWeek: "🎉 Freshman Week", homecoming: "🏟️ Homecoming", halloween: "🎃 Halloween", thanksgiving: "🦃 Thanksgiving", winterFormal: "❄️ Winter Formal", newYears: "🎆 New Year's Eve", valentines: "💘 Valentine's Day", springBreak: "🏖️ Spring Break", endOfYear: "🎓 End of Year"}>> <<link '<span class="choice-btn"><<print _eventNames[$temp.seasonalEvent] || "🎉 Seasonal Event">></span>' `("SeasonalEvent_" + $temp.seasonalEvent)`>><</link>> <</if>> <<link '<span class="choice-btn">🗺️ Start the Week</span>' "CampusMap">><</link>> </div>
/* ═══════════════════════════════════════════════════ THORNFIELD: STAT MODIFICATION WIDGETS ═══════════════════════════════════════════════════ */ /* ─── Modify Stat (with toast) ─── */ <<widget "modStat">> /* Usage: <<modStat "mood" 10 "Good service rating">> */ /* Usage: <<modStat "stress" -15 "Relaxing bath">> */ <<set _stat = _args[0]>> <<set _amount = _args[1]>> <<set _reason = _args[2] || "">> <<if _stat === "energy">> <<set $pc.energy = Math.min(100, Math.max(0, $pc.energy + _amount))>> <<elseif _stat === "mood">> <<set $pc.mood = Math.min(100, Math.max(0, $pc.mood + _amount))>> <<elseif _stat === "stress">> <<set $pc.stress = Math.min(100, Math.max(0, $pc.stress + _amount))>> <<elseif _stat === "arousal">> /* Apply sensitivity multiplier */ <<set _mult = 1>> <<if $transformation.sideEffects.increasedSensitivity > 0>> <<set _mult = 1 + ($transformation.sideEffects.increasedSensitivity * 0.5)>> <</if>> <<set $pc.arousal = Math.min(100, Math.max(0, $pc.arousal + Math.round(_amount * _mult)))>> <<elseif _stat === "confidence">> <<set $pc.confidence = Math.min(100, Math.max(0, $pc.confidence + _amount))>> <<elseif _stat === "willpower">> <<set $pc.willpower = Math.min(100, Math.max(0, $pc.willpower + _amount))>> <<elseif _stat === "intelligence">> <<set $pc.intelligence = Math.min(100, Math.max(0, $pc.intelligence + _amount))>> /* Bimbofication cap */ <<if $transformation.sideEffects.bimbofication >= 4>> <<set $pc.intelligence = Math.min(30, $pc.intelligence)>> <</if>> <<elseif _stat === "femininity">> <<set $pc.femininity = Math.min(100, Math.max(0, $pc.femininity + _amount))>> <<elseif _stat === "health">> <<set $pc.health = Math.min(100, Math.max(0, $pc.health + _amount))>> <</if>> /* Show toast */ <<if _amount > 0>> <<run XCLC.Toast.show(_stat.charAt(0).toUpperCase() + _stat.slice(1) + ' +' + _amount + (_reason ? ': ' + _reason : ''), 'stat')>> <<elseif _amount < 0>> <<run XCLC.Toast.show(_stat.charAt(0).toUpperCase() + _stat.slice(1) + ' ' + _amount + (_reason ? ': ' + _reason : ''), 'warning')>> <</if>> <</widget>> /* ─── Add XP to Skill ─── */ <<widget "addXP">> /* Usage: <<addXP "oral" 50>> */ <<set _skillName = _args[0]>> <<set _xp = Number(_args[1])>> <<if isNaN(_xp)>><<set _xp = 0>><</if>> <<set _skill = $skills[_skillName]>> <<if _skill>> /* Repair corrupted values from older saves (xp stored as string) */ <<if typeof _skill.xp !== 'number' || isNaN(_skill.xp)>><<set _skill.xp = parseInt(_skill.xp, 10) || 0>><</if>> <<if typeof _skill.xpNext !== 'number' || isNaN(_skill.xpNext) || _skill.xpNext <= 0>><<set _skill.xpNext = 100>><</if>> <<set _skill.xp += _xp>> <<run XCLC.Toast.show(_skill.icon + ' ' + _skill.name + ' +' + _xp + ' XP', 'xp')>> <<if _skill.xp >= _skill.xpNext>> <<set _skill.xp -= _skill.xpNext>> <<set _skill.level++>> <<set _skill.xpNext = Math.round(_skill.xpNext * 1.3)>> <<run XCLC.Toast.show('⬆️ ' + _skill.name + ' reached Level ' + _skill.level + '!', 'levelup', 5000)>> <</if>> <</if>> <</widget>> /* ─── Skill Check Widget ─── */ <<widget "skillCheck">> /* Usage: <<skillCheck "oral" 4>>: checks oral skill against DC 4 */ <<set _skillName = _args[0]>> <<set _dc = _args[1] || 3>> <<set _outcome = XCLC.Roll.doCheck(_skillName, _dc)>> <<set _result = $lastRoll>> <</widget>> /* ─── Roll Button (displays clickable button) ─── */ <<widget "rollButton">> /* Usage: <<rollButton "oral" 4 "Perform Oral" "PassageName">> */ <<set _skillName = _args[0]>> <<set _dc = _args[1] || 3>> <<set _label = _args[2] || "Roll">> <<set _targetPassage = _args[3] || "">> <<set _calc = XCLC.Roll.calcChance(_skillName, _dc)>> <<set _skill = $skills[_skillName]>> <div class="roll-btn-container"> /* SugarCube 2.37 rejects a concatenation expression as link text (it mis-parses the result into a <button>). Build the string first, then pass the variable. */ <<set _icon = _skill ? _skill.icon : '🎲'>> <<set _btnText = '<span class="roll-btn">' + _icon + ' ' + _label + ' <span class="roll-chance">(' + _calc.finalChance + '%)</span></span>'>> <<if _targetPassage>> <<link _btnText _targetPassage>> <<skillCheck _skillName _dc>> <</link>> <<else>> <<link _btnText>> <<skillCheck _skillName _dc>> <<run XCLC.DicePopup.show()>> <</link>> <</if>> </div> <</widget>> /* ─── Beauty Recalculation ─── */ <<widget "recalcBeauty">> <<run XCLC.Beauty.recalculate()>> <</widget>> /* ─── Modify Reputation ─── */ <<widget "modRep">> /* Usage: <<modRep "slut" 5 "Public encounter">> */ <<set _track = _args[0]>> <<set _amount = _args[1]>> <<set _reason = _args[2] || "">> <<if $reputation.hasOwnProperty(_track)>> <<set $reputation[_track] = Math.min(100, Math.max(0, $reputation[_track] + _amount))>> <<if Math.abs(_amount) >= 5>> <<run XCLC.Toast.show('Reputation: ' + _track + ' ' + (_amount > 0 ? '+' : '') + _amount + (_reason ? ': ' + _reason : ''), _amount > 0 ? 'info' : 'warning')>> <</if>> <</if>> <</widget>> /* ─── Modify Hygiene ─── */ <<widget "modHygiene">> /* Usage: <<modHygiene -15 "Service encounter">> */ <<set _amount = _args[0]>> <<set _reason = _args[1] || "">> <<set $hygiene.cleanliness = Math.min(100, Math.max(0, $hygiene.cleanliness + _amount))>> <</widget>> /* ─── Shower ─── */ <<widget "shower">> /* Usage: <<shower>> */ <<set $hygiene.cleanliness = 100>> <<set $hygiene.lastShower = $world.day>> <<set $hygiene.lastShowerTime = $world.time>> <<advanceTime 30>> <<run XCLC.Toast.show('🚿 Freshly showered!', 'success')>> <</widget>> /* ─── Sleep ─── */ <<widget "sleep">> /* Usage: <<sleep>>: sleeps until 7 AM */ <<set _sleepHours = $transformation.addons.rest ? 4 : 8>> <<set _wakeTime = 420>> /* 7:00 AM */ <<set _minutesUntilWake = 0>> <<if $world.time < _wakeTime>> <<set _minutesUntilWake = _wakeTime - $world.time>> <<else>> <<set _minutesUntilWake = (1440 - $world.time) + _wakeTime>> <</if>> /* Restore energy based on sleep hours */ <<set _energyRestore = Math.min(100, _sleepHours * 12)>> <<set $pc.energy = Math.min(100, $pc.energy + _energyRestore)>> /* Natural mood/stress recovery */ <<set $pc.mood = Math.min(100, $pc.mood + 10)>> <<set $pc.stress = Math.max(0, $pc.stress - 15)>> /* Advance time to morning */ <<advanceTime _minutesUntilWake>> /* Remove makeup overnight */ <<if $pc.makeupApplied>> <<set $pc.makeupApplied = false>> <<set $pc.makeupStyle = "none">> <<set $pc.beautyMakeup = 0>> <<run XCLC.Beauty.recalculate()>> <</if>> /* Reset daily flags */ <<if $roommate && $roommate.name>> <<set $roommate.talkedToday = false>> <</if>> /* Last night's drinking arrives in the morning. These were both defined but never called, so the hangover system never fired. */ <<resetDrinking>> <<applyHangover>> <<set $temp.morningAfterShown = false>> <<checkMorningAfter>> <</widget>>
/* ─── Morning Side Effect Processor ─── */ <<widget "processmorning">> <<run XCLC.SE.processMorning()>> <</widget>> /* ─── Night Side Effect Processor ─── */ <<widget "processnight">> <<run XCLC.SE.processNight()>> <</widget>> /* ─── Random Orgasm Check ─── */ /* Call during any time block: chance based on SE level */ <<widget "checkRandomOrgasm">> <<if $transformation.sideEffects.randomOrgasm > 0>> <<set _roChance = $transformation.sideEffects.randomOrgasm * 8>> <<if random(1,100) <= _roChance>> <<set _roResult = XCLC.SE.triggerRandomOrgasm()>> <<if _roResult.triggered>> <div class="alert alert--danger"><<print _roResult.text>></div> <<modStat "arousal" -40 "Orgasm">> <<if $transformation.sideEffects.squirting > 0>> <<if random(1,100) <= $transformation.sideEffects.squirting * 20>> <div class="alert alert--warning">💧 You squirt uncontrollably, soaking through your clothes.</div> <<modHygiene -25 "Squirting">> <</if>> <</if>> <<if $transformation.sideEffects.strongOrgasms >= 3>> <div class="alert alert--warning">💫 The orgasm is so powerful your knees buckle. You need a moment to recover.</div> <<modStat "energy" -10 "Overwhelming orgasm">> <</if>> <</if>> <</if>> <</if>> <</widget>> /* ─── Check Lactation Pressure ─── */ <<widget "checkLactation">> <<if $transformation.sideEffects.lactation > 0>> <<set _lactHours = ($world.time - ($temp.lastExpressed || 0)) / 60>> <<if _lactHours > (12 - $transformation.sideEffects.lactation * 2)>> <div class="alert alert--warning">🍼 Your breasts feel heavy and full. You need to express milk soon or this gets uncomfortable, and then it gets visible.</div> <</if>> <</if>> <</widget>> /* ─── Arousal Drift (Internal Heat) ─── */ <<widget "arousalDrift">> <<if $transformation.sideEffects.internalHeat > 0>> <<set _heatGain = $transformation.sideEffects.internalHeat * 3>> <<modStat "arousal" _heatGain "Internal heat">> <</if>> <<if $transformation.sideEffects.increasedSensitivity > 0>> <<if $pc.arousal > 30>> <<set _sensGain = $transformation.sideEffects.increasedSensitivity * 2>> <<modStat "arousal" _sensGain "Heightened sensitivity">> <</if>> <</if>> <</widget>> /* ─── Compelled Choice ────────────────────────────────────── Two-option choice where a side effect leans on one of them. The refusal is ALWAYS clickable. Above the threshold it is dimmed and costs willpower + stress; the other option is visually urged. Below the threshold both render normally. Usage: <<compelledChoice "oralLover" 2 "\U0001f6ab Say no" "SomePassage" "\U0001f633 Give in" "OtherPassage">> For branches needing extra logic in a link body, use the CSS classes directly rather than this widget: see ServiceCondomAsk. ─────────────────────────────────────────────────────────── */ <<widget "compelledChoice">> <<set _cKey = _args[0]>> <<set _cLvl = ($transformation.sideEffects[_cKey] || 0)>> <<set _cThresh = Number(_args[1]) || 2>> <<set _cOn = (_cLvl >= _cThresh)>> <<if _cOn>> <<set _cWp = _cLvl * 2>> <<set _cSt = _cLvl * 3>> <<compelNote _cKey _cLvl>> <<set _cRefuse = '<span class="choice-btn choice-btn--compelled">' + _args[2] + '</span>'>> <<set _cComply = '<span class="choice-btn choice-btn--urged">' + _args[4] + '</span>'>> <<else>> <<set _cRefuse = '<span class="choice-btn">' + _args[2] + '</span>'>> <<set _cComply = '<span class="choice-btn">' + _args[4] + '</span>'>> <</if>> <div class="choice-group"> <<link _cRefuse _args[3]>> <<if _cOn>> <<modStat "willpower" `-_cWp` "Went against the craving">> <<modStat "stress" `_cSt` "Went against the craving">> <</if>> <</link>> <<link _cComply _args[5]>><</link>> </div> <</widget>> /* ─── Compulsion flavour line ─────────────────────────────── The prose half of the pressure. Keyed by side effect. */ <<widget "compelNote">> <<set _nKey = _args[0]>> <<set _nLvl = Number(_args[1]) || 1>> <<set _nHard = (_nLvl >= 3)>> <<if _nKey === "oralLover">> <p class="compelled-note"><<if _nHard>>Your mouth is already watering and you have not decided anything yet. Saying no is going to take something out of you.<<else>>You want it. The wanting arrives before the thinking does.<</if>></p> <<elseif _nKey === "analLover">> <p class="compelled-note"><<if _nHard>>Your body has made its position clear and it is not interested in a debate. Refusing will cost you.<<else>>Something low in you leans toward yes before you have weighed it.<</if>></p> <<elseif _nKey === "submissive">> <p class="compelled-note"><<if _nHard>>Every instinct you have is telling you to fold, and the part of you that argues is very tired.<<else>>Going along with it would be so much easier than not.<</if>></p> <<elseif _nKey === "internalHeat">> <p class="compelled-note"><<if _nHard>>The want is a physical ache now, low and specific. Turning this down means walking away from it still aching.<<else>>Some part of you does not want the barrier there at all.<</if>></p> <<elseif _nKey === "sexualFluidAddiction">> <p class="compelled-note"><<if _nHard>>The craving is loud and it is not remotely subtle. It is still, in the end, only a craving.<<else>>You notice the pull. You notice yourself noticing it.<</if>></p> <<else>> <p class="compelled-note">Something in you leans hard toward yes.</p> <</if>> <</widget>> /* ═══════════════════════════════════════════════════ ORIENTATION NARRATION $pc.orientation is chosen at creation, priced (+10 bi, -5 lesbian), and before this was never read anywhere. The label NEVER changes. Only $pc.orientationDrift moves, and it only colours narration. She observes her own responses; the game does not correct her. <<orientationNote "male">> / <<orientationNote _npc.gender>> ═══════════════════════════════════════════════════ */ <<widget "orientationNote">> <<set _oPartner = _args[0] || "male">> <<set _oSelf = $pc.orientation || "heterosexual">> <<set _oDrift = $pc.orientationDrift || 0>> <<set _oMatch = (_oSelf === "bisexual") || (_oSelf === "lesbian" && _oPartner === "female") || (_oSelf === "heterosexual" && _oPartner === "male")>> <<if !_oMatch>> /* Mismatch. Tone softens as drift accumulates: not because she has been corrected, but because she notices it stopped costing her what it used to, and has feelings about that. */ <<if _oDrift < 4>> <<if _oSelf === "lesbian">> <p class="orientation-note"><em>You are not built for this. You have known that about yourself since you were fifteen and it has not changed just because the rest of you did.</em></p> <<else>> <p class="orientation-note"><em>This is not what you reach for, left to yourself. You are not left to yourself.</em></p> <</if>> <<elseif _oDrift < 12>> <p class="orientation-note"><em>The mismatch is still there. It has stopped announcing itself every time, which you are choosing not to examine tonight.</em></p> <<else>> <p class="orientation-note"><em>You wait for the old objection and it does not arrive. That absence is louder than the objection ever was, and you will be turning it over on the walk back.</em></p> <</if>> <<set $pc.orientationDrift = _oDrift + 1>> <<elseif _oSelf === "lesbian" && _oPartner === "female">> <p class="orientation-note"><em>This one is yours. Whatever else the programme has taken, it has not touched this.</em></p> <<elseif _oSelf === "bisexual">> /* No note: both directions are hers by definition. */ <</if>> <</widget>>
/* ─── Shave Legs ─── */ <<widget "shaveLegs">> <<if $inventory.razors > 0>> <<set $inventory.razors -= 1>> <<set $pc.legHair = 0>> <<set $pc.lastShaved = $world.day>> <<set $pc.beautyGrooming = Math.min(10, $pc.beautyGrooming + 3)>> <<run XCLC.Beauty.recalculate()>> <<advanceTime 10>> <<run XCLC.Toast.show('🪒 Legs shaved smooth. (-1 razor)', 'success')>> <<else>> <<run XCLC.Toast.show('🪒 No razors left! Buy more at the drugstore.', 'warning')>> <</if>> <</widget>> /* ─── Shave Pubic ─── */ <<widget "shavePubic">> <<if $inventory.razors > 0>> <<set $inventory.razors -= 1>> <<set $pc.pubicHair = 0>> <<set $pc.beautyGrooming = Math.min(10, $pc.beautyGrooming + 2)>> <<run XCLC.Beauty.recalculate()>> <<advanceTime 10>> <<run XCLC.Toast.show('🪒 Smooth down there. (-1 razor)', 'success')>> <<else>> <<run XCLC.Toast.show('🪒 No razors left!', 'warning')>> <</if>> <</widget>> /* ─── Apply Skincare ─── */ <<widget "applySkincare">> <<if $inventory.skincareUses > 0>> <<set $inventory.skincareUses -= 1>> <<set $pc.beautySkincare = Math.min(10, $pc.beautySkincare + 3)>> <<run XCLC.Beauty.recalculate()>> <<advanceTime 5>> <<run XCLC.Toast.show('✨ Skincare applied. Skin glowing!', 'success')>> <<else>> <<run XCLC.Toast.show('🧴 Out of skincare products!', 'warning')>> <</if>> <</widget>> /* ─── Apply Makeup ─── */ /* $args[0] = style: "none", "natural", "glam", "goth", "slutty" */ <<widget "applyMakeup">> <<set _style = _args[0] || "natural">> <<if _style === "none">> <<set $pc.makeupStyle = "none">> <<set $pc.makeupApplied = false>> <<set $pc.beautyMakeup = 0>> <<run XCLC.Beauty.recalculate()>> <<advanceTime 5>> <<run XCLC.Toast.show('💧 Makeup removed.', 'info')>> <<else>> <<set _uses = $inventory.makeupUses[_style] || 0>> <<if _uses > 0>> <<set $inventory.makeupUses[_style] -= 1>> <<set $pc.makeupStyle = _style>> <<set $pc.makeupApplied = true>> <<switch _style>> <<case "natural">> <<set $pc.beautyMakeup = 5>> <<advanceTime 10>> <<case "glam">> <<set $pc.beautyMakeup = 10>> <<advanceTime 20>> <<case "goth">> <<set $pc.beautyMakeup = 7>> <<advanceTime 15>> <<case "bimbo">> <<set $pc.beautyMakeup = 8>> <<advanceTime 20>> <<modStat "femininity" 3 "Bimbo makeup">> <<case "slutty">> <<set $pc.beautyMakeup = 12>> <<advanceTime 20>> <<modStat "femininity" 2 "Slutty makeup">> <</switch>> <<run XCLC.Beauty.recalculate()>> <<run XCLC.Toast.show('💄 ' + _style.charAt(0).toUpperCase() + _style.slice(1) + ' makeup applied!', 'success')>> <<else>> <<run XCLC.Toast.show('💄 No ' + _style + ' makeup left! Buy more.', 'warning')>> <</if>> <</if>> <</widget>> /* ─── Hair Growth (called daily) ─── */ <<widget "processHairGrowth">> <<if !$transformation.addons.noHair>> <<set _daysSinceShave = $world.day - $pc.lastShaved>> <<if _daysSinceShave >= 2 && $pc.legHair < 1>> <<set $pc.legHair = 1>> <<set $pc.beautyGrooming = Math.max(0, $pc.beautyGrooming - 2)>> <<run XCLC.Beauty.recalculate()>> <<elseif _daysSinceShave >= 5 && $pc.legHair < 2>> <<set $pc.legHair = 2>> <<set $pc.beautyGrooming = Math.max(0, $pc.beautyGrooming - 3)>> <<run XCLC.Beauty.recalculate()>> <</if>> <<if _daysSinceShave >= 3 && $pc.pubicHair < 1>> <<set $pc.pubicHair = 1>> <<elseif _daysSinceShave >= 7 && $pc.pubicHair < 2>> <<set $pc.pubicHair = 2>> <</if>> <</if>> <</widget>> /* ─── Hygiene Decay (called during advanceTime) ─── */ <<widget "hygieneDecay">> <<set _activity = _args[0] || "idle">> <<set _decay = 0>> <<switch _activity>> <<case "service">> <<set _decay = -15>> <<case "gym">> <<set _decay = -20>> <<case "sleep">> <<set _decay = -5>> <<case "period">> <<set _decay = -5>> <<case "gangbang">> <<set _decay = -40>> <<default>> <<set _decay = -2>> <</switch>> <<set $hygiene.cleanliness = Math.min(100, Math.max(0, $hygiene.cleanliness + _decay))>> <</widget>> /* ─── Show Hygiene Warning ─── */ /* Outputs NPC reaction text if hygiene is low. Insert in encounter passages. */ <<widget "showHygieneWarning">> <<if $hygiene.cleanliness < 30>> <div class="alert alert--warning">🤢 You smell terrible. NPCs visibly recoil. Interaction penalties apply.</div> <<elseif $hygiene.cleanliness < 50>> <div class="alert alert--info">😕 "You could use a shower..." Someone wrinkles their nose.</div> <</if>> <</widget>> /* ─── Hygiene Modifier for Jobs ─── */ /* Returns tip reduction multiplier based on cleanliness */ <<widget "hygieneJobModifier">> <<if $hygiene.cleanliness < 30>> <<set _hygieneMod = 0.5>> <<elseif $hygiene.cleanliness < 50>> <<set _hygieneMod = 0.8>> <<else>> <<set _hygieneMod = 1.0>> <</if>> <</widget>> /* ─── Hygiene Status Display ─── */ <<widget "showHygieneStatus">> <<set _clean = $hygiene.cleanliness>> <<set _label = "Sparkling ✨">> <<if _clean < 30>><<set _label = "Filthy 🤢">> <<elseif _clean < 50>><<set _label = "Grubby 😕">> <<elseif _clean < 70>><<set _label = "Okay">> <<elseif _clean < 90>><<set _label = "Clean">> <</if>> <div class="stat-row"> <span class="stat-label">🚿 Hygiene</span> <div class="stat-bar"><div class="stat-bar__fill" @style="'width:' + _clean + '%'"></div></div> <span class="stat-value"><<print _label>> (<<print _clean>>%)</span> </div> <</widget>>
/* ═══════════════════════════════════════════════════ DIALOGUE TONE SYSTEM Text varies by player femininity level: Low (0-33): reluctant, masculine, uncomfortable Mid (34-66): neutral, accepting, adjusting High (67+): enthusiastic, feminine, eager ═══════════════════════════════════════════════════ */ /* ─── General tone: 3-way text swap ─── */ /* Usage: <<tone "ugh, whatever" "it's fine I guess" "omg yay!">> */ <<widget "tone">> <<set _low = _args[0] || "">> <<set _mid = _args[1] || _low>> <<set _high = _args[2] || _mid>> <<if $pc.femininity >= 67>> <<print _high>> <<elseif $pc.femininity >= 34>> <<print _mid>> <<else>> <<print _low>> <</if>> <</widget>> /* ─── Reaction to sexual content ─── */ /* Usage: <<toneReact "disgusting" "not terrible" "amazing">> */ <<widget "toneReact">> <<set _low = _args[0] || "">> <<set _mid = _args[1] || _low>> <<set _high = _args[2] || _mid>> <<if $pc.femininity >= 67>> <em><<print _high>></em> <<elseif $pc.femininity >= 34>> <em><<print _mid>></em> <<else>> <em><<print _low>></em> <</if>> <</widget>> /* ─── Internal monologue ─── */ /* Usage: <<toneThink "I need to get through this" "maybe this isn't so bad" "I actually want this">> */ <<widget "toneThink">> <<set _low = _args[0] || "">> <<set _mid = _args[1] || _low>> <<set _high = _args[2] || _mid>> <<if $pc.femininity >= 67>> <p class="thought"><em><<print _high>></em></p> <<elseif $pc.femininity >= 34>> <p class="thought"><em><<print _mid>></em></p> <<else>> <p class="thought"><em><<print _low>></em></p> <</if>> <</widget>> /* ─── Gendered self-reference ─── */ /* Returns how the PC refers to themselves */ <<widget "toneSelf">> <<if $pc.femininity >= 80>> girl <<elseif $pc.femininity >= 50>> person <<else>> guy <</if>> <</widget>> /* ─── Gendered exclamation ─── */ <<widget "toneExclaim">> <<if $pc.femininity >= 67>> <<set _exclaims = ["Omg!", "Eee!", "Oh my god!", "Like, totally!", "Yaaas!", "So cute!"]>> <<elseif $pc.femininity >= 34>> <<set _exclaims = ["Oh!", "Wow.", "Huh.", "Nice.", "Okay then.", "Well..."]>> <<else>> <<set _exclaims = ["Whatever.", "Ugh.", "Christ.", "Seriously?", "Dude.", "Fuck."]>> <</if>> <<print _exclaims[random(0, _exclaims.length - 1)]>> <</widget>>
/* ═══════════════════════════════════════════════════ THORNFIELD: ROLL SYSTEM WIDGETS Adapted from Starlet with fairer mechanics ═══════════════════════════════════════════════════ */ /* ─── Service Rating Calculator ─── */ <<widget "calcServiceRating">> /* Usage: <<calcServiceRating "success" npcGenerosity>> Sets _serviceRating (1-5 stars) */ <<set _outcome = _args[0] || "success">> <<set _generosity = _args[1] || 3>> <<set _genBonus = (_generosity - 1) * 0.25>> <<switch _outcome>> <<case "crit_success">> <<set _serviceRating = 5.0>> <<case "success">> <<set _serviceRating = Math.min(5, 4.0 + (Math.random() * 1.0) + _genBonus)>> <<case "partial_fail">> <<set _serviceRating = Math.min(5, 3.0 + (Math.random() * 1.0) + _genBonus)>> <<case "crit_fail">> /* Minimum 2 stars (rating floor) */ <<set _serviceRating = Math.max(2.0, 2.0 + (Math.random() * 1.0) + _genBonus)>> <<default>> <<set _serviceRating = 3.5>> <</switch>> /* Flair from interactive act choices (bold technique, dirty talk, focus) */ <<set _serviceRating = _serviceRating + (($temp.actFlair || 0) * 0.15)>> <<set _serviceRating = Math.max(2.0, Math.min(5, _serviceRating))>> <<set _serviceRating = Math.round(_serviceRating * 10) / 10>> <</widget>> /* ─── Apply Service Rating ─── */ <<widget "applyServiceRating">> /* Usage: <<applyServiceRating 4.5>> Updates $scholarship.rating with weighted average */ <<set _newRating = _args[0]>> /* Defensive: fix NaN or missing values */ <<if typeof _newRating !== 'number' || isNaN(_newRating)>><<set _newRating = 3.5>><</if>> <<if typeof $scholarship.rating !== 'number' || isNaN($scholarship.rating)>><<set $scholarship.rating = 5.0>><</if>> <<if typeof $scholarship.totalRatings !== 'number' || isNaN($scholarship.totalRatings)>><<set $scholarship.totalRatings = 0>><</if>> <<if typeof $scholarship.ratingSum !== 'number' || isNaN($scholarship.ratingSum)>><<set $scholarship.ratingSum = 0>><</if>> <<set $scholarship.totalRatings++>> <<set $scholarship.ratingSum += _newRating>> /* Weighted average with recency bias */ /* Recent ratings count 2×: prevents old bad ratings from tanking forever */ <<if $scholarship.totalRatings <= 1>> <<set $scholarship.rating = _newRating>> <<else>> /* Weight: 70% existing average, 30% new rating */ <<set $scholarship.rating = ($scholarship.rating * 0.7) + (_newRating * 0.3)>> <</if>> /* Clamp to 2.0 - 5.0 and fix any NaN */ <<if isNaN($scholarship.rating)>><<set $scholarship.rating = 5.0>><</if>> <<set $scholarship.rating = Math.max(2.0, Math.min(5.0, $scholarship.rating))>> <<set $scholarship.rating = Math.round($scholarship.rating * 100) / 100>> <</widget>> /* ─── Complete Service Encounter ─── */ <<widget "completeService">> /* Usage: <<completeService "oral" npcObject outcome>> Handles credits, rating, quota, XP, stats */ <<set _serviceType = _args[0] || "oral">> <<set _npc = _args[1]>> <<set _outcome = _args[2] || "success">> /* Defensive: ensure all arrays and values exist FIRST */ <<if !Array.isArray($scholarship.weekLog)>><<set $scholarship.weekLog = []>><</if>> <<if !Array.isArray($scholarship.allTimeLogs)>><<set $scholarship.allTimeLogs = []>><</if>> <<if !Array.isArray($scholarship.weeklyHistory)>><<set $scholarship.weeklyHistory = []>><</if>> <<if typeof $scholarship.totalServices !== 'number' || isNaN($scholarship.totalServices)>><<set $scholarship.totalServices = 0>><</if>> <<if typeof $scholarship.currentWeekServiced !== 'number'>><<set $scholarship.currentWeekServiced = 0>><</if>> <<if typeof $scholarship.currentWeekCredits !== 'number'>><<set $scholarship.currentWeekCredits = 0>><</if>> <<if typeof $scholarship.totalServiced !== 'number'>><<set $scholarship.totalServiced = 0>><</if>> <<if typeof $scholarship.totalCredits !== 'number'>><<set $scholarship.totalCredits = 0>><</if>> /* Calculate credits */ <<set _credits = 1>> <<if _serviceType === "anal">> <<set _credits = 2>> <</if>> <<if _outcome === "crit_success">> <<set _credits += 1>> <<elseif _outcome === "crit_fail">> <<set _credits = Math.max(1, Math.floor(_credits / 2))>> <</if>> /* Calculate rating */ <<calcServiceRating _outcome `(_npc ? _npc.generosity : 3)`>> /* Apply */ <<applyServiceRating _serviceRating>> <<set $scholarship.currentWeekServiced += 1>> <<set $scholarship.currentWeekCredits += _credits>> <<set $scholarship.totalServiced += 1>> <<set $scholarship.totalCredits += _credits>> <<set $scholarship.totalServices += 1>> /* Mercy rule check */ <<if $scholarship.totalServices >= 5>> <<set $scholarship.mercyActive = false>> <</if>> /* Log: using <<run>> with try-catch for robustness */ <<run (function(){ var sv = State.variables; var tv = State.temporary; if (!sv.scholarship) sv.scholarship = {}; if (!Array.isArray(sv.scholarship.weekLog)) sv.scholarship.weekLog = []; try { sv.scholarship.weekLog.push({ npcId: (tv.npc ? tv.npc.id : 0), serviceType: tv.serviceType || 'unknown', credits: tv.credits || 1, rating: tv.serviceRating || 3.5, day: sv.world.day, time: sv.world.time }); } catch(e) { console.error('weekLog push failed:', e); } }())>> /* XP for the relevant skill */ <<set _xpAmount = XCLC.Roll.calcXP(_outcome, 3)>> <<if _serviceType === "oral">> <<addXP "oral" _xpAmount>> <<elseif _serviceType === "vaginal">> <<addXP "vaginal" _xpAmount>> <<elseif _serviceType === "anal">> <<addXP "anal" _xpAmount>> <</if>> <<addXP "stamina" `Math.round(_xpAmount / 2)`>> /* Stat effects */ <<if _outcome === "crit_success">> <<modStat "mood" 15 "Amazing performance!">> <<modStat "confidence" 10 "5-star service">> <<elseif _outcome === "success">> <<modStat "mood" 5 "Good service">> <<elseif _outcome === "partial_fail">> <<modStat "mood" -5 "Mediocre performance">> <<elseif _outcome === "crit_fail">> <<modStat "mood" -15 "Terrible performance">> <<modStat "confidence" -10 "Humiliating failure">> <</if>> /* Energy cost */ <<modStat "energy" -15 "Service encounter">> /* Hygiene */ <<modHygiene -15 "Service encounter">> /* Reputation */ <<modRep "slut" 2>> /* Femininity drift: doing service slowly increases femininity */ <<set $pc.femininity = Math.min(100, $pc.femininity + 1)>> /* Pregnancy risk for vaginal/anal with internal */ /* (handled separately in encounter passages) */ /* STD risk: condoms cut vaginal risk to a quarter */ <<stdRisk _serviceType `($temp.condomUsed ? 0.25 : 1)`>> /* NPC relationship update */ <<if _npc>> <<set _npc.encounters++>> <<set _npc.lastEncounter = $world.day>> <<if _npc.encounters >= 3 && !_npc.isRecurring>> <<set _npc.isRecurring = true>> <<run XCLC.Toast.show("💕 " + _npc.firstName + " is now a regular and will be requesting you again.", "info", 5000)>> <</if>> <<if _outcome === "crit_success" || _outcome === "success">> <<set _npc.opinion = Math.min(100, _npc.opinion + 5)>> <<set _npc.attraction = Math.min(100, _npc.attraction + 3)>> <</if>> /* Persist to the roster so they can re-request the player */ <<run XCLC.NPC.remember(State.temporary.npc)>> <</if>> /* Flair pays out a little extra XP for showmanship */ <<if ($temp.actFlair || 0) >= 3>> <<addXP _serviceType 10>> <</if>> /* Set temp results for display in passage */ <<set $temp.lastServiceCredits = _credits>> <<set $temp.lastServiceRating = _serviceRating>> <<set $temp.lastServiceOutcome = _outcome>> /* Reset act-choice state for the next encounter */ <<set $temp.actFlair = 0>> <<set $temp.actDcMod = 0>> <</widget>> /* ─── Re-roll Token ─── */ <<widget "useReroll">> /* Usage: <<useReroll>>: spends 20 confidence for a re-roll */ <<if $scholarship.rerollAvailable && $pc.confidence >= 20>> <<set $pc.confidence -= 20>> <<set $scholarship.rerollAvailable = false>> <<set $scholarship.rerollDay = $world.day>> <<run XCLC.Toast.show('🔄 Re-roll used! -20 Confidence', 'warning')>> <<else>> <<run XCLC.Toast.show('❌ Cannot re-roll (unavailable or not enough confidence)', 'error')>> <</if>> <</widget>>
<div id="xclc-app"> <!-- Top Bar --> <div class="top-bar"> <div class="top-bar__section"> <div class="top-bar__stat"> <span class="top-bar__stat-icon">🕐</span> <span class="top-bar__stat-value" id="topbar-time">8:00 AM</span> </div> <div class="top-bar__stat"> <span class="top-bar__stat-icon">📅</span> <span class="top-bar__stat-value" id="topbar-date">Mon, Sep 1</span> </div> <div class="top-bar__stat"> <span class="top-bar__stat-icon">📆</span> <span class="top-bar__stat-value" id="topbar-semester">Y1 Sem1 W1</span> </div> </div> <div class="top-bar__section"> <div class="top-bar__stat"> <div class="energy-bar"> <span class="top-bar__stat-icon">⚡</span> <div class="energy-bar__track"> <div class="energy-bar__fill high" id="topbar-energy-fill" style="width:100%"></div> </div> <span class="top-bar__stat-value" id="topbar-energy-val">100</span> </div> </div> <div class="top-bar__stat"> <span class="top-bar__stat-icon">💰</span> <span class="top-bar__stat-value" id="topbar-money">$0</span> </div> <div class="top-bar__stat"> <span class="top-bar__stat-icon">⭐</span> <span class="top-bar__stat-value" id="topbar-rating">5.0</span> </div> <div class="top-bar__stat"> <span class="top-bar__stat-icon">📋</span> <span class="top-bar__stat-value" id="topbar-quota" title="Weekly service quota: encounters completed of those required">0/5</span> </div> </div> <div class="top-bar__section"> <button class="phone-btn" id="phone-toggle" type="button"> 📱 Phone <span class="phone-badge" id="phone-badge"></span> </button> </div> </div> <!-- Left Panel (Navigation) --> <div class="left-panel" id="left-panel"> <nav class="left-panel__nav"> <button class="nav-item" data-nav="DormRoom" type="button">🏠 Dorm</button> <button class="nav-item" data-nav="CampusMap" type="button">🗺️ Campus</button> <div class="nav-separator"></div> <button class="nav-item" id="nav-skills" type="button">📋 Skills</button> <button class="nav-item" id="nav-character" type="button">👤 Character</button> <button class="nav-item" data-nav="WardrobeMenu" type="button">👗 Wardrobe</button> <div class="nav-separator"></div> <button class="nav-item" id="nav-journal" type="button">📒 Journal</button> <button class="nav-item" id="nav-achievements" type="button">🏆 Achievements</button> <div class="nav-separator"></div> <button class="nav-item" id="nav-wiki" type="button">📖 Wiki</button> <button class="nav-item" data-nav="SettingsMenu" type="button">⚙️ Settings</button> <div class="nav-separator"></div> <a class="nav-item nav-item--external" href="https://discord.gg/TKUP3U8rvF" target="_blank" rel="noopener">💬 Discord</a> </nav> </div> <!-- Main Content --> <main class="main-content" id="main-content"> <div id="passages"></div> </main> <!-- Right Panel (Stats) --> <div class="right-panel" id="right-panel"> <div class="right-panel__section"> <div class="right-panel__title">Active Effects</div> <div id="active-effects"></div> </div> <div class="right-panel__section"> <div class="right-panel__title">Quick Stats</div> <div id="quick-stats"></div> </div> </div> <!-- Phone Overlay --> <div id="phone-overlay"> <div id="phone-screen"></div> </div> </div>
/* Intentionally empty: custom UI replaces default sidebar */
/* Runs BEFORE every passage render */ <<run XCLC.UI.updateTopBar()>> /* Save migration: ensure new variables exist for old saves */ <<if typeof $inventory === 'undefined'>><<set $inventory = {wardrobe:[{id:"clinic_tshirt",name:"Clinic T-Shirt",type:"top",style:"vanilla",quality:"basic",sexy:0,beauty:0,price:0,description:"A plain white t-shirt.",icon:"top"},{id:"clinic_sweats",name:"Clinic Sweatpants",type:"bottom",style:"vanilla",quality:"basic",sexy:0,beauty:0,price:0,description:"Grey sweatpants.",icon:"bottom"},{id:"clinic_underwear",name:"Basic Cotton Underwear",type:"underwear",style:"vanilla",quality:"basic",sexy:0,beauty:0,price:0,description:"Plain white cotton briefs.",icon:"underwear"},{id:"clinic_bra",name:"Sports Bra",type:"bra",style:"vanilla",quality:"basic",sexy:0,beauty:0,price:0,description:"A basic sports bra.",icon:"bra"},{id:"clinic_sneakers",name:"White Sneakers",type:"shoes",style:"vanilla",quality:"basic",sexy:0,beauty:1,price:0,description:"Clean white sneakers.",icon:"shoes"}],currentOutfit:{top:"clinic_tshirt",bottom:"clinic_sweats",dress:null,bra:"clinic_bra",underwear:"clinic_underwear",shoes:"clinic_sneakers",accessories:[]},styleIdentity:"vanilla",razors:3,skincareUses:0,makeupUses:{natural:3,glam:0,goth:0,bimbo:0,slutty:0},hasLaptop:false,hasWebcam:false,hasCamera:false,hasRingLight:false,sexToys:[],condoms:0,pregnancyTests:0,onPill:false,hasIUD:false,drugs:{}}>><</if>> <<if typeof $pc.hairStyle === 'undefined'>><<set $pc.hairStyle = "straight">><</if>> /* Year-awareness fields (year 2/3 work) */ <<if typeof $scholarship.baseWeeklyQuota === 'undefined'>><<set $scholarship.baseWeeklyQuota = 5>><</if>> <<if typeof $roommate.yearsWith === 'undefined'>><<set $roommate.yearsWith = 1>><</if>> <<if typeof $roommate.movedOut === 'undefined'>><<set $roommate.movedOut = false>><</if>> <<if typeof $pc.orientationDrift === 'undefined'>><<set $pc.orientationDrift = 0>><</if>> <<if typeof $relationship === 'undefined'>><<set $relationship = {partnerId:null, partnerName:"", partnerGender:"", stage:"none", tension:0, knowsAboutProgramme:false, dates:0, startedDay:0, endedReason:""}>><</if>> <<if !$pc.firstName>><<set $pc.firstName = $pc.femaleFirstName || "Alex">><</if>> <<if typeof $pc.pubicStyle === 'undefined'>><<set $pc.pubicStyle = "natural">><</if>> <<if !Array.isArray($pc.piercings)>><<set $pc.piercings = []>><</if>> <<if !Array.isArray($pc.tattoos)>><<set $pc.tattoos = []>><</if>> <<if !Array.isArray($scholarship.weekLog)>><<set $scholarship.weekLog = []>><</if>> <<if !Array.isArray($scholarship.allTimeLogs)>><<set $scholarship.allTimeLogs = []>><</if>> <<if !Array.isArray($scholarship.weeklyHistory)>><<set $scholarship.weeklyHistory = []>><</if>> <<if typeof $scholarship.totalServices !== 'number'>><<set $scholarship.totalServices = $scholarship.totalServiced || 0>><</if>> <<if isNaN($scholarship.rating)>><<set $scholarship.rating = 5.0>><</if>> <<run (function() { var sv = State.variables; /* Deep-fill missing keys from defaults (repairs saves made before StoryInit consolidation) */ function fill(target, defs) { if (!target || typeof target !== 'object') return; Object.keys(defs).forEach(function(k) { if (typeof target[k] === 'undefined' || target[k] === null) { target[k] = defs[k]; } else if (defs[k] && typeof defs[k] === 'object' && !Array.isArray(defs[k]) && typeof target[k] === 'object') { fill(target[k], defs[k]); } }); } if (sv.jobs) { fill(sv.jobs, { onShift: false, shiftJob: "", barista: { active: false, shifts: 0, tips: 0, performance: 50, tier: 0 }, bartender: { active: false, shifts: 0, tips: 0, performance: 50, tier: 0 }, tutor: { active: false, sessions: 0, students: 0, performance: 50, tier: 0 }, cheerleader: { active: false, practicesMissed: 0, gamesAttended: 0, hasOutfit: false, teamRank: 0, practiceDay: 0 }, camGirl: { active: false, shows: 0, viewers: 50, tokens: 0, rating: 0, hasRingLight: false, tier: 0 }, fansOnly: { active: false, subs: 0, posts: 0, revenue: 0, lastPostDay: 0, contentTypes: [] }, stripper: { active: false, shifts: 0, tips: 0, regulars: 0, canBackRoom: false, tier: 0 }, hooker: { active: false, clients: 0, earnings: 0, arrested: 0, phoneUnlocked: false, tier: 0 }, escort: { active: false, clients: 0, earnings: 0, agencyRep: 0, tier: 0 }, brothel: { active: false, shifts: 0, earnings: 0, houseRep: 0, tier: 0 }, dealer: { active: false, stock: { weed: 0, ecstasy: 0, cocaine: 0 }, earnings: 0, heatLevel: 0, supplierUnlocked: false } }); } if (sv.pregnancy) { fill(sv.pregnancy, { isPregnant: false, weeksPregnant: 0, discovered: false, confirmed: false, confirmedDay: 0, riskFlag: false, riskDay: 0, periodDue: 0, terminated: false, fatherName: "", fatherId: "", fatherRace: "", babyCount: 1, babyGenders: [], roommateNoticed: false, profNoticed: false, decisions: [], outcome: "", children: [], totalPregnancies: 0 }); } if (sv.scholarship) { fill(sv.scholarship, { active: true, weeklyQuota: 5, finalsQuota: 10, housingTier: "standard", selfiesPending: 0, probationWeeks: 0, rerollAvailable: true, rerollDay: 0, lastServiceDay: 0 }); } if (sv.greekLife) { fill(sv.greekLife, { pledgeStage: 0, lastPartyDay: 0, rushAvailable: false, rushDeclined: false, eventsAttended: 0, fratPartiesAttended: 0 }); } if (sv.inventory) { fill(sv.inventory, { hasRingLight: false, hasBackdrop: false, sexToys: [], drugs: {}, wornPlug: null, toysOut: [], plugWornSince: 0, plugSpotted: 0, cigarettes: 0, hasVape: false, hasPurse: false, hasTote: false }); } if (sv.health) { fill(sv.health, { hasSTD: false, stdType: null, stdDay: 0, stdSymptomatic: false, birthControlActive: false, birthControlDays: 0, cycleDay: 14, lastWeekGymVisits: 0 }); } if (sv.substances) { fill(sv.substances, { dealerBuys: 0, dealerTrades: 0, dealerOffered: false, combosSeen: [], goggleLog: [], maskedDrunk: 0 }); } if (sv.health) { fill(sv.health, { stdSilent: false, stdComplication: "" }); } if (sv.social) { fill(sv.social, { propositions: 0, propositionsRefused: 0, propositionsAccepted: 0, lastPropositionDay: -1 }); } if (!sv.cheats) sv.cheats = { enabled: false, used: false, uses: 0 }; if (sv.world) { fill(sv.world, { postGrad: false, postGradDay: 0, rentDue: 0, rentOwed: 0 }); } if (sv.jobs && sv.jobs.fansOnly) { fill(sv.jobs.fansOnly, { rating: 0, ratingCount: 0, ratingSum: 0, lastRating: 0, requests: [], requestsFilled: 0, requestsDeclined: 0, lastRequestDay: 0 }); } if (sv.university) { var dem = sv.university.demographics || { white: 40, black: 25, asian: 15, latina: 15, other: 5 }; fill(sv.university, { splitDemographics: false }); if (!sv.university.demographicsMale) sv.university.demographicsMale = Object.assign({}, dem); if (!sv.university.demographicsFemale) sv.university.demographicsFemale = Object.assign({}, dem); } if (sv.pregnancy) { fill(sv.pregnancy, { birthPlan: "", children: [], totalPregnancies: 0 }); if (!sv.pregnancy.bodyChanges) { sv.pregnancy.bodyChanges = { breastStart: "", buttStart: "", breastSteps: 0, buttSteps: 0, resolved: false, kept: false }; } } if (!sv.children) { sv.children = { list: [], dayCare: false, dayCareOwed: 0, lastCareDay: -1, neglect: 0, welfareVisits: 0, removed: 0, bond: 0 }; /* Carry across any babies an older save already recorded */ if (sv.pregnancy && Array.isArray(sv.pregnancy.children)) { sv.pregnancy.children.forEach(function(c) { sv.children.list.push({ gender: c.gender, skin: c.skin, hair: c.hair, eyes: c.eyes, born: c.born || 0, semester: c.semester || 1, name: c.name || "" }); }); } } if (sv.academic && Array.isArray(sv.academic.classes)) { sv.academic.classes.forEach(function(cls) { fill(cls, { midtermDone: false, finalDone: false, midtermScore: null, finalScore: null }); }); fill(sv.academic, { researchBonus: 0, extraCredit: { stage: 0, lastOfferDay: 0 }, drakeCase: { stage: 0, profIndex: -1, classIndex: -1, lastOfferDay: -99, declined: false, retaliating: false, earnedGrade: null, evidence: [], confronted: false, reported: false, resolved: false } }); } if (!sv.notifications) sv.notifications = { items: [], unread: 0 }; if (sv.phone && sv.phone.chirpr) { fill(sv.phone.chirpr, { followers: 0, tweets: [], lastTweetDay: 0, lastTweetPeriod: "", lastReplyDay: 0, announcedPregnancy: false }); } if (sv.roommate) { fill(sv.roommate, { awarenessMilestone: (sv.roommate.isConfidant ? 100 : 0) }); } if (sv.hypnosis) { /* Crane arc reworked as an investigation storyline: retire the old fields */ fill(sv.hypnosis, { redFlags: 0, evidence: [], suspicious: false, confronted: false, reported: false, resolved: false, lingering: false, triggersPlanted: [] }); delete sv.hypnosis.conditioningLevel; delete sv.hypnosis.playerAware; delete sv.hypnosis.consenting; } /* Repair skill xp corrupted into strings by the old addXP bug */ if (sv.skills) { Object.keys(sv.skills).forEach(function(k) { var s = sv.skills[k]; if (!s) return; if (typeof s.xp !== 'number' || isNaN(s.xp)) s.xp = parseInt(s.xp, 10) || 0; if (typeof s.xpNext !== 'number' || isNaN(s.xpNext) || s.xpNext <= 0) s.xpNext = 100; if (typeof s.level !== 'number' || isNaN(s.level)) s.level = parseInt(s.level, 10) || 0; }); } }())>>
/* Runs AFTER every passage render */ <<script>> // Menu-like passages overlay normal play, so remember where the player was // so their Back buttons can return there instead of dumping to CampusMap. var menuRe = /^(Phone_|SettingsMenu|SkillsMenu|CharacterSheet|JournalMenu|AchievementsMenu|Wiki_|WardrobeMenu)/; function playMenu(passage) { var sv = State.variables; if (sv.ui && !menuRe.test(State.passage)) { sv.ui.returnPassage = State.passage; } Engine.play(passage); } // Wire up left-panel nav buttons $('#left-panel [data-nav]').off('click').on('click', function() { var passage = $(this).data('nav'); if (!passage) return; if (menuRe.test(passage)) { playMenu(passage); } else { Engine.play(passage); } }); // Skills page $('#nav-skills').off('click').on('click', function() { playMenu('SkillsMenu'); }); // Character shortcut $('#nav-character').off('click').on('click', function() { playMenu('CharacterSheet'); }); // Phone button: navigate to passage-based phone $('#phone-toggle').off('click').on('click', function() { playMenu('Phone_Home'); }); // Journal $('#nav-journal').off('click').on('click', function() { playMenu('JournalMenu'); }); // Achievements $('#nav-achievements').off('click').on('click', function() { playMenu('AchievementsMenu'); }); // Wiki $('#nav-wiki').off('click').on('click', function() { playMenu('Wiki_Home'); }); // Render animated stat bars in right panel (function() { var sv = State.variables; if (!sv || !sv.pc) return; var el = document.getElementById('quick-stats'); if (!el) return; var stats = [ { icon: '⚡', label: 'Energy', val: sv.pc.energy, max: 100, cls: 'energy' }, { icon: '😊', label: 'Mood', val: sv.pc.mood, max: 100, cls: 'mood' }, { icon: '😰', label: 'Stress', val: sv.pc.stress, max: 100, cls: 'stress' }, { icon: '💗', label: 'Arousal', val: sv.pc.arousal, max: 100, cls: 'arousal' }, { icon: '💪', label: 'Confidence', val: sv.pc.confidence, max: 100, cls: 'confidence' }, { icon: '🛡️', label: 'Willpower', val: sv.pc.willpower, max: 100, cls: 'willpower' }, { icon: '🧠', label: 'Intelligence', val: sv.pc.intelligence, max: 100, cls: 'intelligence' }, { icon: '💄', label: 'Femininity', val: sv.pc.femininity, max: 100, cls: 'femininity' }, { icon: '✨', label: 'Beauty', val: sv.pc.beautyTotal, max: 100, cls: 'beauty' } ]; var html = ''; for (var i = 0; i < stats.length; i++) { var s = stats[i]; var pct = Math.min(100, Math.max(0, Math.round((s.val / s.max) * 100))); html += '<div class="stat-bar-row">' + '<span class="stat-bar-icon">' + s.icon + '</span>' + '<span class="stat-bar-label">' + s.label + '</span>' + '<div class="stat-bar-track"><div class="stat-bar-fill ' + s.cls + '" style="width:' + pct + '%;"></div></div>' + '<span class="stat-bar-val">' + Math.round(s.val) + '</span>' + '</div>'; } el.innerHTML = html; })(); // Render active side effects (function() { var sv = State.variables; if (!sv || !sv.transformation) return; var el = document.getElementById('active-effects'); if (!el) return; var effects = sv.transformation.sideEffects; var icons = { memoryLoss: '🧠', randomOrgasm: '💥', sexualFluidAddiction: '💦', bimbofication: '🎀', squirting: '💧', orgasmDenial: '🚫', lactation: '🍼', increasedSensitivity: '⚡', submissive: '🔒', strongOrgasms: '💫', fertility: '🤰', internalHeat: '🔥', exhibitionist: '👀', pheromones: '🌸', oralLover: '👄', analLover: '🍑', eroticDreams: '🌙', masturbationDenial: '✋' }; var names = { memoryLoss: 'Memory Loss', randomOrgasm: 'Random Orgasm', sexualFluidAddiction: 'Fluid Addiction', bimbofication: 'Bimbofication', squirting: 'Squirting', orgasmDenial: 'Orgasm Denial', lactation: 'Lactation', increasedSensitivity: 'Sensitivity', submissive: 'Submissive', strongOrgasms: 'Strong Orgasms', fertility: 'Fertility', internalHeat: 'Internal Heat', exhibitionist: 'Exhibitionist', pheromones: 'Pheromones', oralLover: 'Oral Lover', analLover: 'Anal Lover', eroticDreams: 'Erotic Dreams', masturbationDenial: 'Masturb. Denial' }; var html = ''; var keys = Object.keys(effects); for (var i = 0; i < keys.length; i++) { var k = keys[i]; if (effects[k] > 0) { var dots = ''; for (var j = 0; j < 4; j++) { dots += '<span class="effect-dot ' + (j < effects[k] ? 'active' : '') + '"></span>'; } html += '<div class="effect-row">' + '<span class="effect-icon">' + (icons[k] || '❓') + '</span>' + '<span class="effect-name">' + (names[k] || k) + '</span>' + '<span class="effect-dots">' + dots + '</span>' + '</div>'; } } if (html === '') { html = '<div class="effect-row effect-none">No active effects</div>'; } el.innerHTML = html; })(); // Hygiene indicator (function() { var sv = State.variables; if (!sv || !sv.hygiene) return; var c = sv.hygiene.cleanliness; var el = document.getElementById('topbar-hygiene'); if (!el) return; if (c >= 80) el.textContent = '🚿'; else if (c >= 60) el.textContent = '😐'; else if (c >= 40) el.textContent = '😓'; else el.textContent = '🤢'; })(); // Phone frame: add status bar and home bar to Phone_ passages (no wrapping, no content moving) (function() { var passageName = State.passage; if (passageName.indexOf('Phone_') !== 0) return; var content = $('#passages .passage'); if (!content.length || content.find('.phone-statusbar').length) return; var sv = State.variables; var timeStr = 'N/A'; try { timeStr = XCLC.Time.format(sv.world.time); } catch(e) { timeStr = sv.world.time + ':00'; } var battery = Math.max(20, Math.round(sv.pc.energy || 100)); // Only prepend/append, never move existing content content.prepend( '<div class="phone-statusbar">' + '<span class="phone-statusbar__left">' + timeStr + '</span>' + '<span class="phone-statusbar__right">📶 Thornfield WiFi 🔋 ' + battery + '%</span>' + '</div>' ); content.append('<div class="phone-homebar"><div class="phone-homebar__pill"></div></div>'); })(); <</script>>
<div class="wiki"> <div class="wiki-header"> <h1>📖 Thornfield University Wiki</h1> <p class="wiki-subtitle">Your comprehensive guide to surviving the CCUMDUP programme.</p> </div> <div class="wiki-search"> <input type="text" id="wiki-search" placeholder="🔍 Search wiki pages..." oninput="XCLC.Wiki.filter(this.value)"> </div> <div class="wiki-toc" id="wiki-toc"> <<divider "🏫 Getting Started">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">📜</span><span class="wiki-card-title">Game Overview</span><span class="wiki-card-desc">What is CCUMDUP?</span></span>' "Wiki_Overview">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🎨</span><span class="wiki-card-title">Character Creation</span><span class="wiki-card-desc">Building your character</span></span>' "Wiki_CharacterCreation">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">📊</span><span class="wiki-card-title">Stats & Skills</span><span class="wiki-card-desc">All stats, skills & rolls</span></span>' "Wiki_Stats">><</link>> </div> <<divider "🗺️ World & Locations">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">🏫</span><span class="wiki-card-title">Campus Locations</span><span class="wiki-card-desc">On-campus & off-campus</span></span>' "Wiki_Locations">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🍸</span><span class="wiki-card-title">Bar District</span><span class="wiki-card-desc">Nightlife venues</span></span>' "Wiki_BarDistrict">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🏖️</span><span class="wiki-card-title">Playa Caliente</span><span class="wiki-card-desc">Spring Break resort</span></span>' "Wiki_SpringBreak">><</link>> </div> <<divider "🎮 Core Systems">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">🎀</span><span class="wiki-card-title">Service System</span><span class="wiki-card-desc">CCUMDUP encounters</span></span>' "Wiki_Service">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">📚</span><span class="wiki-card-title">Academics</span><span class="wiki-card-desc">Classes, exams & GPA</span></span>' "Wiki_Academics">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">💼</span><span class="wiki-card-title">Jobs</span><span class="wiki-card-desc">All 9 employment paths</span></span>' "Wiki_Jobs">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🎭</span><span class="wiki-card-title">Reputation</span><span class="wiki-card-desc">7 reputation axes</span></span>' "Wiki_Reputation">><</link>> </div> <<divider "💊 Transformation">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">⚗️</span><span class="wiki-card-title">Side Effects</span><span class="wiki-card-desc">X-Change side effects</span></span>' "Wiki_SideEffects">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">💃</span><span class="wiki-card-title">Femininity</span><span class="wiki-card-desc">Transformation progression</span></span>' "Wiki_Femininity">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">✨</span><span class="wiki-card-title">Beauty & Hygiene</span><span class="wiki-card-desc">Looking your best</span></span>' "Wiki_Beauty">><</link>> </div> <<divider "🔞 Advanced Content">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">🖤</span><span class="wiki-card-title">Velvet Room</span><span class="wiki-card-desc">BDSM club guide</span></span>' "Wiki_VelvetRoom">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">📱</span><span class="wiki-card-title">Blackmail</span><span class="wiki-card-desc">The blackmail arc</span></span>' "Wiki_Blackmail">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🌀</span><span class="wiki-card-title">Hypnosis</span><span class="wiki-card-desc">Dr. Crane sessions</span></span>' "Wiki_Hypnosis">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">😈</span><span class="wiki-card-title">Corruption</span><span class="wiki-card-desc">Corruption & fetish content</span></span>' "Wiki_Corruption">><</link>> </div> <<divider "🌍 Life Systems">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">🤰</span><span class="wiki-card-title">Pregnancy</span><span class="wiki-card-desc">Risk, progression & outcomes</span></span>' "Wiki_Pregnancy">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🩺</span><span class="wiki-card-title">Health</span><span class="wiki-card-desc">Infections, cycle & weight</span></span>' "Wiki_Health">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">👶</span><span class="wiki-card-title">Children</span><span class="wiki-card-desc">Nursery, care & neglect</span></span>' "Wiki_Children">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🍺</span><span class="wiki-card-title">Substances</span><span class="wiki-card-desc">Alcohol & drugs</span></span>' "Wiki_Substances">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">👥</span><span class="wiki-card-title">Social & Greek Life</span><span class="wiki-card-desc">Roommate, sororities</span></span>' "Wiki_Social">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">📱</span><span class="wiki-card-title">Phone</span><span class="wiki-card-desc">Apps & features</span></span>' "Wiki_Phone">><</link>> </div> <<divider "📅 Events & Endings">> <div class="wiki-toc-grid"> <<link '<span class="wiki-card"><span class="wiki-card-icon">🎃</span><span class="wiki-card-title">Seasonal Events</span><span class="wiki-card-desc">Halloween, Homecoming & more</span></span>' "Wiki_Seasonal">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🎲</span><span class="wiki-card-title">Random Events</span><span class="wiki-card-desc">Daily encounters & dreams</span></span>' "Wiki_RandomEvents">><</link>> <<link '<span class="wiki-card"><span class="wiki-card-icon">🎓</span><span class="wiki-card-title">Endings</span><span class="wiki-card-desc">All 8 endings & how to get them</span></span>' "Wiki_Endings">><</link>> </div> </div> </div> /* ═══════════════════════════════════════════════════ 📜 GAME OVERVIEW ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>📜 Game Overview</h1> <div class="wiki-section"> <h2>What is Thornfield University?</h2> <p>A text-based RPG built in SugarCube. You play as a male college student who accepts the <strong>CCUMDUP scholarship</strong>, the <em>College Campus Unity & Morale Development Uplift Program</em>. In exchange for full tuition, housing, and a stipend, you take X-Change Petite and live as a woman for three years while performing "service encounters" for other students.</p> </div> <div class="wiki-section"> <h2>Core Game Loop</h2> <div class="wiki-code"> Wake up → Routine → Classes → Free time → Service encounters → Socialise → Sleep ↓ Weekly quota check ← Day advances → Random events </div> <p>The game spans <strong>6 semesters</strong> (3 academic years), each ~15 in-game weeks. Your choices determine your <<link "reputation" "Wiki_Reputation">><</link>>, <<link "femininity" "Wiki_Femininity">><</link>>, relationships, and <<link "ending" "Wiki_Endings">><</link>>.</p> </div> <div class="wiki-section"> <h2>Key Systems</h2> <ul> <li><<link "🎀 CCUMDUP Service System" "Wiki_Service">><</link>>: your core obligation</li> <li><<link "📚 Academics" "Wiki_Academics">><</link>>: classes, exams, GPA</li> <li><<link "💼 Jobs" "Wiki_Jobs">><</link>>: 9 employment paths</li> <li><<link "⚗️ Side Effects" "Wiki_SideEffects">><</link>>: X-Change complications</li> <li><<link "🎭 Reputation" "Wiki_Reputation">><</link>>: 7 axes that shape how NPCs treat you</li> <li><<link "📱 Phone" "Wiki_Phone">><</link>>: your hub for CampusHub, social media, messages</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🎨 CHARACTER CREATION ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🎨 Character Creation</h1> <div class="wiki-section"> <h2>Stage 1: Motivation</h2> <p>Why are you joining CCUMDUP? Your reason affects starting stats and dialogue:</p> <table class="wiki-table"> <tr><th>Reason</th><th>Description</th><th>Effect</th></tr> <tr><td>💸 Poverty</td><td>Can't afford tuition</td><td>None</td></tr> <tr><td>🎲 Bet</td><td>Lost a frat bet</td><td>None</td></tr> <tr><td>🔍 Curious</td><td>Genuinely wondering</td><td>+5 starting <<link "femininity" "Wiki_Femininity">><</link>></td></tr> <tr><td>👨👩👦 Forced</td><td>Parents signed you up</td><td>+10 starting stress</td></tr> <tr><td>🏠 Opportunist</td><td>In it for the perks</td><td>None</td></tr> <tr><td>🌈 Identity</td><td>Already questioning gender</td><td>+15 starting <<link "femininity" "Wiki_Femininity">><</link>></td></tr> </table> </div> <div class="wiki-section"> <h2>Stage 2-3: Names</h2> <p>Enter your <strong>male name</strong> (original identity) and <strong>female name</strong> (what everyone calls you).</p> </div> <div class="wiki-section"> <h2>Stage 4: Appearance (Point-Buy)</h2> <p>Design your female body. Some choices cost points, others earn them. Points from appearance + <<link "side effects" "Wiki_SideEffects">><</link>> are spent on add-ons.</p> <table class="wiki-table"> <tr><th>Category</th><th>Options</th><th>Notes</th></tr> <tr><td>Race</td><td>White, Black, Asian, Latina, Mixed</td><td>Varies cost</td></tr> <tr><td>Orientation</td><td>Hetero, Bi, Gay</td><td>Gay = +4 points</td></tr> <tr><td>Body Type</td><td>Petite, Slender, Athletic, Curvy, Thick</td><td>Varies</td></tr> <tr><td>Breasts</td><td>A → F cup</td><td>Larger = more cost</td></tr> <tr><td>Butt</td><td>Small → Large</td><td>Varies</td></tr> <tr><td>Hair</td><td>Colour, length, style</td><td>Varies</td></tr> </table> </div> <div class="wiki-section"> <h2>Stage 5: Side Effects</h2> <p>See the full <<link "⚗️ Side Effects" "Wiki_SideEffects">><</link>> page. Higher levels = more points but stronger ongoing effects.</p> <p>💀 <strong>"Just Fuck My Shit Up"</strong> button maxes ALL side effects for maximum points.</p> </div> <div class="wiki-section"> <h2>Stage 6: Add-ons (Spend Points)</h2> <table class="wiki-table"> <tr><th>Add-on</th><th>Cost</th><th>Benefit</th></tr> <tr><td>Birth Control</td><td>3</td><td>Built-in contraception (see <<link "Pregnancy" "Wiki_Pregnancy">><</link>>)</td></tr> <tr><td>STD Protection</td><td>2</td><td>Immune to STDs</td></tr> <tr><td>No Gag Reflex</td><td>2</td><td>Better deep throat in <<link "services" "Wiki_Service">><</link>></td></tr> <tr><td>Intelligence Boost</td><td>3</td><td>+2 Intelligence levels (see <<link "Academics" "Wiki_Academics">><</link>>)</td></tr> <tr><td>Flexibility</td><td>2</td><td>+2 Flexibility levels</td></tr> <tr><td>No Body Hair</td><td>1</td><td>Never need to shave (see <<link "Beauty" "Wiki_Beauty">><</link>>)</td></tr> <tr><td>Metabolism Control</td><td>2</td><td>Weight stays stable</td></tr> <tr><td>Wet</td><td>1</td><td>Always lubricated</td></tr> </table> </div> <div class="wiki-section"> <h2>Stage 7: University Settings</h2> <p><strong>Difficulty</strong>: Easy / Normal / Hard / Extreme, affects the weekly <<link "service quota" "Wiki_Service">><</link>>.</p> <p><strong>Demographics</strong>: Adjust racial distribution and male/female ratio of NPCs.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 📊 STATS & SKILLS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>📊 Stats & Skills</h1> <div class="wiki-section"> <h2>Primary Stats (0-100)</h2> <table class="wiki-table"> <tr><th>Stat</th><th>Start</th><th>Effect</th></tr> <tr><td>⚡ Energy</td><td>100</td><td>Depleted by activities, restored by sleep. Below 20 = exhaustion warnings.</td></tr> <tr><td>😊 Mood</td><td>70</td><td>Affects dialogue tone options and dream content.</td></tr> <tr><td>😰 Stress</td><td>10</td><td>High stress = penalties, breakdown events, poor performance.</td></tr> <tr><td>🔥 Arousal</td><td>0</td><td>Increased by <<link "side effects" "Wiki_SideEffects">><</link>>, encounters, drugs. High = embarrassment/urges.</td></tr> <tr><td>💪 Confidence</td><td>50</td><td>Affects social checks, self-image dialogue.</td></tr> <tr><td>🧠 Willpower</td><td>60</td><td>Resistance to submission. Reduced by <<link "hypnosis" "Wiki_Hypnosis">><</link>> and <<link "Velvet Room" "Wiki_VelvetRoom">><</link>>.</td></tr> <tr><td>🧠 Intelligence</td><td>50</td><td><<link "Academic" "Wiki_Academics">><</link>> performance. Reduced by bimbofication SE.</td></tr> <tr><td>💃 Femininity</td><td>10</td><td>Core transformation tracker. See <<link "Femininity" "Wiki_Femininity">><</link>>.</td></tr> </table> </div> <div class="wiki-section"> <h2>Skills (Level 0-10, XP-based)</h2> <h3>Sexual Skills</h3> <table class="wiki-table"> <tr><th>Skill</th><th>Start</th><th>Trained By</th></tr> <tr><td>💋 Oral</td><td>1</td><td><<link "Service" "Wiki_Service">><</link>> encounters, <<link "glory holes" "Wiki_Corruption">><</link>></td></tr> <tr><td>🔥 Vaginal</td><td>1</td><td><<link "Service" "Wiki_Service">><</link>> encounters</td></tr> <tr><td>🍑 Anal</td><td>0</td><td><<link "Service" "Wiki_Service">><</link>> encounters (anal type)</td></tr> <tr><td>✋ Handjob</td><td>1</td><td><<link "Service" "Wiki_Service">><</link>> encounters</td></tr> <tr><td>💪 Stamina</td><td>1</td><td>Gym workouts, service encounters</td></tr> <tr><td>🤸 Flexibility</td><td>1</td><td>Gym yoga, <<link "Velvet Room" "Wiki_VelvetRoom">><</link>></td></tr> <tr><td>🗣️ Dirty Talk</td><td>0</td><td><<link "Cam shows" "Wiki_Jobs">><</link>>, high-rep encounters</td></tr> <tr><td>😮 Deep Throat</td><td>0</td><td>Oral encounters, <<link "glory holes" "Wiki_Corruption">><</link>></td></tr> </table> <h3>Academic / Social / Performance</h3> <table class="wiki-table"> <tr><th>Skill</th><th>Start</th><th>Trained By</th></tr> <tr><td>🧠 Intelligence</td><td>3</td><td>Classes, studying, <<link "library" "Wiki_Locations">><</link>></td></tr> <tr><td>📚 Studying</td><td>1</td><td>Library sessions</td></tr> <tr><td>✨ Charm</td><td>1</td><td>Social events, <<link "bar" "Wiki_BarDistrict">><</link>> interactions</td></tr> <tr><td>🤝 Persuasion</td><td>1</td><td>Confrontations (<<link "blackmail" "Wiki_Blackmail">><</link>>)</td></tr> <tr><td>📷 Cam Work</td><td>0</td><td><<link "Cam girl job" "Wiki_Jobs">><</link>></td></tr> <tr><td>💃 Dance</td><td>0</td><td>Club dancing, <<link "cheerleading" "Wiki_Jobs">><</link>></td></tr> </table> </div> <div class="wiki-section"> <h2>The Roll System</h2> <p>Skill checks use a d100 against a difficulty threshold:</p> <table class="wiki-table"> <tr><th>Outcome</th><th>Condition</th><th>Effect</th></tr> <tr><td>🌟 Critical Success</td><td>Roll ≤ 10</td><td>Best outcome + bonus XP</td></tr> <tr><td>✅ Success</td><td>Roll ≤ threshold</td><td>Positive outcome + XP</td></tr> <tr><td>⚠️ Partial Fail</td><td>Roll ≤ threshold + 20</td><td>Middling outcome</td></tr> <tr><td>❌ Fail</td><td>Roll > threshold + 20</td><td>Negative outcome</td></tr> <tr><td>💀 Critical Fail</td><td>Roll ≥ 95</td><td>Worst outcome</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🏫 LOCATIONS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🏫 Campus Locations</h1> <div class="wiki-section"> <h2>On Campus</h2> <table class="wiki-table"> <tr><th>Location</th><th>Key Activities</th></tr> <tr><td>🏠 Dorm Room</td><td>Sleep, shower, change clothes, talk to <<link "roommate" "Wiki_Social">><</link>></td></tr> <tr><td>📚 Lecture Halls</td><td>Attend <<link "classes" "Wiki_Academics">><</link>></td></tr> <tr><td>📖 Library</td><td>Study (3 modes), <<link "glory hole" "Wiki_Corruption">><</link>> (discoverable)</td></tr> <tr><td>💪 Gym</td><td>Cardio, weights, yoga, boosts <<link "beauty" "Wiki_Beauty">><</link>></td></tr> <tr><td>🍽️ Cafeteria</td><td>Eat (free), socialise</td></tr> <tr><td>🏛️ Admin Building</td><td>Dean's office, Health Centre, <<link "Dr. Crane" "Wiki_Hypnosis">><</link>></td></tr> <tr><td>💼 Job Board</td><td>Apply for <<link "employment" "Wiki_Jobs">><</link>></td></tr> <tr><td>🎭 Student Center</td><td>Clubs, events</td></tr> <tr><td>🏡 Greek Row</td><td><<link "Sorority" "Wiki_Social">><</link>> rushing, parties</td></tr> </table> </div> <div class="wiki-section"> <h2>Off Campus</h2> <table class="wiki-table"> <tr><th>Location</th><th>Travel</th><th>Activities</th></tr> <tr><td>🛍️ Mall</td><td>30 min</td><td>Clothing, accessories, beauty products</td></tr> <tr><td>🍸 <<link "Bar District" "Wiki_BarDistrict">><</link>></td><td>30 min</td><td>4 bars + <<link "Velvet Room" "Wiki_VelvetRoom">><</link>></td></tr> <tr><td>🖋️ Ink & Iron</td><td>30 min</td><td>Tattoos and piercings</td></tr> <tr><td>💇 Hair Salon</td><td>30 min</td><td>Hair changes</td></tr> <tr><td>💊 Drugstore</td><td>20 min</td><td>Razors, skincare, pregnancy tests</td></tr> <tr><td>🏢 Downtown</td><td>40 min</td><td>Various services</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🍸 BAR DISTRICT ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🍸 Bar District</h1> <p>Opens in the evening. Four venues plus hidden locations.</p> <div class="wiki-section"> <h2>Venues</h2> <table class="wiki-table"> <tr><th>Venue</th><th>Vibe</th><th>Entry</th><th>Notable</th></tr> <tr><td>🍺 The Rusty Nail</td><td>Dive bar</td><td>None</td><td>Drug dealer spawns (30%), <<link "glory hole" "Wiki_Corruption">><</link>> in bathroom</td></tr> <tr><td>🍸 Velvet Lounge</td><td>Upscale cocktails</td><td><<link "Beauty" "Wiki_Beauty">><</link>> 50+ or charm roll</td><td>Sugar daddies, expensive drinks</td></tr> <tr><td>🎵 Pulse</td><td>Dance club</td><td>Open</td><td>Dancing, <<link "drugs" "Wiki_Substances">><</link>>, hookups</td></tr> <tr><td>💋 Candy Bar</td><td>Strip club</td><td>Open</td><td><<link "Stripper job" "Wiki_Jobs">><</link>> location</td></tr> <tr><td>🖤 <<link "The Velvet Room" "Wiki_VelvetRoom">><</link>></td><td>BDSM club</td><td>Hidden</td><td>Unlocks at slut rep ≥30 or submissive SE ≥2</td></tr> </table> </div> <div class="wiki-section"> <h2>Drinks</h2> <p>See <<link "🍺 Substances" "Wiki_Substances">><</link>> for full alcohol mechanics.</p> <table class="wiki-table"> <tr><th>Drink</th><th>Price</th><th>Location</th></tr> <tr><td>Beer</td><td>$4</td><td>Rusty Nail</td></tr> <tr><td>Shot</td><td>$5</td><td>Rusty Nail</td></tr> <tr><td>Cocktail</td><td>$12</td><td>Velvet Lounge</td></tr> <tr><td>Wine</td><td>$8</td><td>Velvet Lounge</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🎀 SERVICE SYSTEM ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🎀 Service System</h1> <div class="wiki-section"> <h2>How It Works</h2> <ol> <li><strong>CampusHub</strong> generates requests throughout the day</li> <li>You have <strong>30 minutes</strong> to accept before expiry</li> <li>Meet the NPC → skill-checked encounter → rating (1-5 ⭐)</li> <li>Meet your <strong>weekly quota</strong> or face probation</li> </ol> </div> <div class="wiki-section"> <h2>Service Credits</h2> <table class="wiki-table"> <tr><th>Service Type</th><th>Credits</th><th>Skills Used</th></tr> <tr><td>Oral</td><td>1</td><td>Oral, Deep Throat</td></tr> <tr><td>Vaginal</td><td>1</td><td>Vaginal, Stamina</td></tr> <tr><td>Anal</td><td>2</td><td>Anal, Stamina</td></tr> <tr><td>Internal Completion</td><td>+1 bonus</td><td><<link "Pregnancy risk!" "Wiki_Pregnancy">><</link>></td></tr> <tr><td>Handjob</td><td>0.5</td><td>Handjob</td></tr> <tr><td>Group (2–3 clients)</td><td>×1.5 per extra client</td><td>Multiple, +1 DC each</td></tr> </table> </div> <div class="wiki-section"> <h2>Rating System</h2> <table class="wiki-table"> <tr><th>Average</th><th>Effect</th></tr> <tr><td>4.7+</td><td>Ashford Suite: en-suite, study, best sleep</td></tr> <tr><td>4.2–4.6</td><td>Renovated Double: better sleep, less stress</td></tr> <tr><td>4.0-4.9</td><td>Normal standing</td></tr> <tr><td>3.0-3.9</td><td>Probation warning</td></tr> <tr><td>< 3.0</td><td>Scholarship review → <<link "expulsion" "Wiki_Endings">><</link>></td></tr> </table> </div> <div class="wiki-section"> <h2>Tips</h2> <ul> <li>Higher <<link "sexual skills" "Wiki_Stats">><</link>> = better ratings</li> <li><<link "Side effects" "Wiki_SideEffects">><</link>> like Random Orgasm can boost OR hurt your rating</li> <li>Finals Week doubles your quota to 10</li> <li><<link "Glory holes" "Wiki_Corruption">><</link>> give 0.5 credits (anonymous)</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 📚 ACADEMICS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>📚 Academics</h1> <div class="wiki-section"> <h2>Classes</h2> <ul> <li>Choose <strong>3 classes</strong> per semester</li> <li>Each has a professor with personality traits</li> <li>Attending lectures = Intelligence XP</li> <li>Skipping = attendance penalty → GPA hit</li> </ul> </div> <div class="wiki-section"> <h2>Finals Week</h2> <ul> <li>Occurs at weeks 14-15 each semester</li> <li><<link "Service quota" "Wiki_Service">><</link>> <strong>DOUBLES</strong> (to 10)</li> <li>Exams use Intelligence + Studying skill checks</li> <li>Study at the <<link "Library" "Wiki_Locations">><</link>> to prepare</li> </ul> </div> <div class="wiki-section"> <h2>GPA & Probation</h2> <p>Low GPA + low <<link "service rating" "Wiki_Service">><</link>> = <<link "expulsion" "Wiki_Endings">><</link>> risk. The bimbofication <<link "side effect" "Wiki_SideEffects">><</link>> reduces intelligence, making exams harder.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 💼 JOBS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>💼 Jobs & Employment</h1> <div class="wiki-section"> <h2>Campus Jobs</h2> <table class="wiki-table"> <tr><th>Job</th><th>Pay</th><th>Requirements</th></tr> <tr><td>☕ Barista</td><td>$12/hr + tips</td><td>Job Board</td></tr> <tr><td>📚 Tutor</td><td>$20/session</td><td>Intelligence ≥ 4</td></tr> <tr><td>📣 Cheerleader</td><td>Perks only</td><td>Flexibility check</td></tr> </table> </div> <div class="wiki-section"> <h2>Off-Campus Jobs</h2> <table class="wiki-table"> <tr><th>Job</th><th>Pay</th><th>Requirements</th></tr> <tr><td>🍸 Bartender</td><td>$15/hr + tips</td><td>Job Board</td></tr> <tr><td>💃 Stripper</td><td>$50-200/shift tips</td><td><<link "Beauty" "Wiki_Beauty">><</link>> ≥ 50</td></tr> <tr><td>📷 Cam Girl</td><td>Token-based</td><td>Laptop + webcam</td></tr> <tr><td>🔞 FansOnly</td><td>Subscriber revenue</td><td>Create account</td></tr> <tr><td>🤫 Hooker</td><td>$50-200/client</td><td><<link "Rep" "Wiki_Reputation">><</link>> or bar contact</td></tr> <tr><td>💊 Drug Dealer</td><td>Variable</td><td>Meet supplier at <<link "Rusty Nail" "Wiki_BarDistrict">><</link>></td></tr> </table> </div> <div class="wiki-section"> <h2>Progression</h2> <p>Most jobs have <strong>tier systems</strong> (0-3) with better pay, special options, and unlock conditions at higher tiers.</p> <p>Having 2+ active jobs contributes to the <<link "Professional ending" "Wiki_Endings">><</link>>.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🎭 REPUTATION ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🎭 Reputation</h1> <div class="wiki-section"> <h2>7 Reputation Axes</h2> <table class="wiki-table"> <tr><th>Reputation</th><th>Start</th><th>How It Grows</th><th>Milestones</th></tr> <tr><td>🔥 Slut</td><td>0</td><td><<link "Services" "Wiki_Service">><</link>>, public sex, <<link "glory holes" "Wiki_Corruption">><</link>>, thirst traps</td><td>40: catcalls · 60: propositions · 80: free-use</td></tr> <tr><td>🎉 Party Girl</td><td>0</td><td><<link "Bar" "Wiki_BarDistrict">><</link>> visits, parties, drunk events</td><td>60: invites · 80: legend</td></tr> <tr><td>📚 Good Student</td><td>50</td><td><<link "Classes" "Wiki_Academics">><</link>>, studying, good grades</td><td>60: study groups · professor praise</td></tr> <tr><td>📷 Cam Girl</td><td>0</td><td><<link "Cam shows" "Wiki_Jobs">><</link>>, FansOnly posts</td><td>60: campus recognition · 80: internet fame</td></tr> <tr><td>💕 Sweetheart</td><td>30</td><td>Kind actions, helping others</td><td>None</td></tr> <tr><td>💀 Troublemaker</td><td>0</td><td><<link "Drug dealing" "Wiki_Jobs">><</link>>, arrests, rule-breaking</td><td>80: <<link "expulsion" "Wiki_Endings">><</link>> risk</td></tr> <tr><td>⭐ Popular</td><td>20</td><td>Social events, InstaGlam</td><td>40: fans · 80: celebrity</td></tr> </table> </div> <div class="wiki-section"> <h2>Reputation & Endings</h2> <p>Your dominant reputation at graduation determines your <<link "ending" "Wiki_Endings">><</link>>:</p> <ul> <li>📚 Good Student ≥ 60 → Scholar ending</li> <li>⭐ Popular ≥ 60 or 📷 Cam Girl ≥ 60 → Celebrity ending</li> <li>🔥 Slut ≥ 80 + 💀 Troublemaker ≥ 40 → Underground ending</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ ⚗️ SIDE EFFECTS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>⚗️ Side Effects</h1> <p>Chosen during <<link "character creation" "Wiki_CharacterCreation">><</link>>. Each has 4 levels. Higher means more points, but stronger ongoing effects.</p> <div class="wiki-section"> <h2>All Side Effects</h2> <table class="wiki-table"> <tr><th>Side Effect</th><th>Levels</th><th>Effect</th></tr> <tr><td>🧠 Memory Loss</td><td>0-4</td><td>Gradually forget male memories</td></tr> <tr><td>💥 Random Orgasm</td><td>0-4</td><td>Spontaneous public orgasms (2%-20% per period)</td></tr> <tr><td>💦 Fluid Addiction</td><td>0-4</td><td>Crave semen, withdrawal symptoms</td></tr> <tr><td>🎀 Bimbofication</td><td>0-4</td><td>Intelligence drain, giggly speech (hurts <<link "academics" "Wiki_Academics">><</link>>)</td></tr> <tr><td>💧 Squirting</td><td>0-4</td><td>Squirt during arousal peaks</td></tr> <tr><td>🚫 Orgasm Denial</td><td>0-4</td><td>Harder to reach orgasm</td></tr> <tr><td>🍼 Lactation</td><td>0-4</td><td>Breasts produce milk, visible stains</td></tr> <tr><td>⚡ Sensitivity</td><td>0-4</td><td>Everything feels more intense</td></tr> <tr><td>🔒 Submissive</td><td>0-4</td><td>Natural submission (unlocks <<link "Velvet Room" "Wiki_VelvetRoom">><</link>> early)</td></tr> <tr><td>💫 Strong Orgasms</td><td>0-4</td><td>Devastating, disabling orgasms</td></tr> <tr><td>🤰 Fertility</td><td>0-4</td><td>Higher <<link "pregnancy" "Wiki_Pregnancy">><</link>> risk</td></tr> <tr><td>🔥 Internal Heat</td><td>0-4</td><td>Constant low-level arousal (+5-20/period)</td></tr> <tr><td>👀 Exhibitionist</td><td>0-4</td><td>Aroused by exposure</td></tr> <tr><td>🌸 Pheromones</td><td>0-4</td><td>NPCs more attracted to you</td></tr> <tr><td>👄 Oral Lover</td><td>0-4</td><td>Enjoy giving oral more</td></tr> <tr><td>🍑 Anal Lover</td><td>0-4</td><td>Enjoy anal more</td></tr> <tr><td>🌙 Erotic Dreams</td><td>0-4</td><td>Vivid sexual <<link "dreams" "Wiki_RandomEvents">><</link>></td></tr> <tr><td>✋ Masturb. Denial</td><td>0-4</td><td>Can't satisfy yourself</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 💃 FEMININITY ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>💃 Femininity</h1> <div class="wiki-section"> <h2>Progression Tiers</h2> <table class="wiki-table"> <tr><th>Tier</th><th>Range</th><th>Themes</th></tr> <tr><td>💀 Resistance</td><td>0-25</td><td>Dysphoria, fighting the change, nightmares</td></tr> <tr><td>😕 Confusion</td><td>26-50</td><td>Mixed feelings, automatic feminine gestures, guilt</td></tr> <tr><td>💕 Acceptance</td><td>51-75</td><td>Beauty routines feel natural, enjoying attention</td></tr> <tr><td>🌸 Embrace</td><td>76-100</td><td>Full identity shift, self-acceptance, can't remember being male</td></tr> </table> </div> <div class="wiki-section"> <h2>What Increases Femininity</h2> <ul> <li><<link "Side effect" "Wiki_SideEffects">><</link>> processing (each period change)</li> <li><<link "Random events" "Wiki_RandomEvents">><</link>> (gendered language, reflections)</li> <li><<link "Dream" "Wiki_RandomEvents">><</link>> content</li> <li>Social acceptance, being called feminine names</li> <li><<link "Service" "Wiki_Service">><</link>> encounters, romantic/sexual experiences</li> <li><<link "Hypnosis" "Wiki_Hypnosis">><</link>> conditioning</li> </ul> </div> <div class="wiki-section"> <h2>Impact on Endings</h2> <p>Femininity ≥ 80 + mood ≥ 50 unlocks the <strong>Embraced</strong> <<link "ending" "Wiki_Endings">><</link>>, choosing permanent transformation.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ ✨ BEAUTY & HYGIENE ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>✨ Beauty & Hygiene</h1> <div class="wiki-section"> <h2>Beauty Score (Composite)</h2> <table class="wiki-table"> <tr><th>Component</th><th>Source</th><th>Max</th></tr> <tr><td>Base</td><td><<link "Character creation" "Wiki_CharacterCreation">><</link>></td><td>~60</td></tr> <tr><td>Grooming</td><td>Shaving (legs + pubic)</td><td>~14</td></tr> <tr><td>Makeup</td><td>Applied style</td><td>0-15</td></tr> <tr><td>Clothing</td><td>Outfit quality + sexiness</td><td>Variable</td></tr> <tr><td>Skincare</td><td>Skincare products</td><td>~10</td></tr> <tr><td>Fitness</td><td>Gym visits</td><td>~15</td></tr> </table> <p>Beauty affects: <<link "Velvet Lounge" "Wiki_BarDistrict">><</link>> entry, NPC attraction, <<link "InstaGlam" "Wiki_Phone">><</link>> followers, <<link "job" "Wiki_Jobs">><</link>> performance.</p> </div> <div class="wiki-section"> <h2>Hygiene (0-100)</h2> <ul> <li>Decays -5/day, -3/period</li> <li>Restored by showering (+100)</li> <li>Below 40: NPCs comment, beauty penalty</li> <li>Body writing washes off at 90+</li> </ul> </div> <div class="wiki-section"> <h2>Grooming</h2> <ul> <li><strong>Leg hair</strong>: Grows every 2+ days (0=smooth, 2=hairy)</li> <li><strong>Pubic hair</strong>: Grows every 4+ days (multiple styles)</li> <li><strong>Razors</strong>: consumable, buy more at the drugstore</li> <li>"No Body Hair" <<link "add-on" "Wiki_CharacterCreation">><</link>> eliminates shaving</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🖤 VELVET ROOM ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🖤 The Velvet Room</h1> <p>A hidden BDSM club in the <<link "Bar District" "Wiki_BarDistrict">><</link>>.</p> <div class="wiki-section"> <h2>Discovery</h2> <p>Appears as "🚪 An unmarked door..." when:</p> <ul> <li><<link "Slut reputation" "Wiki_Reputation">><</link>> ≥ 30, <strong>OR</strong></li> <li>Submissive <<link "side effect" "Wiki_SideEffects">><</link>> ≥ 2</li> </ul> </div> <div class="wiki-section"> <h2>Membership</h2> <table class="wiki-table"> <tr><th>Tier</th><th>Cost</th><th>Access</th></tr> <tr><td>Visitor</td><td>Free (first time)</td><td>Watch only</td></tr> <tr><td>Regular</td><td>$100 or earn via demo</td><td>All standard activities</td></tr> <tr><td>VIP</td><td>10+ sessions</td><td>Private suite, specials</td></tr> </table> </div> <div class="wiki-section"> <h2>Activities</h2> <table class="wiki-table"> <tr><th>Activity</th><th>Unlocks At</th><th>Effect</th></tr> <tr><td>🧎 Sub Training</td><td>Immediate</td><td>4 depth levels, +composure, pays $50</td></tr> <tr><td>🪢 Bondage</td><td>Immediate</td><td>Flexibility check, mood boost</td></tr> <tr><td>🐾 Pet Play</td><td>3 sessions</td><td>Collar/ears, stress reduction, willpower loss</td></tr> <tr><td>👋 Impact Play</td><td>5 sessions</td><td>Stamina check, endorphin rush</td></tr> <tr><td>🕯️ Sensation Play</td><td>7 sessions</td><td>Blindfolded, amplified by Sensitivity SE</td></tr> </table> <p>All activities increase <<link "corruption" "Wiki_Corruption">><</link>> score.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 📱 BLACKMAIL ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>📱 Blackmail Arc</h1> <div class="wiki-section"> <h2>Trigger Conditions (checked weekly)</h2> <ul> <li><<link "FansOnly" "Wiki_Jobs">><</link>> active + <<link "popular rep" "Wiki_Reputation">><</link>> ≥ 40 (10% chance)</li> <li><<link "Cam girl" "Wiki_Jobs">><</link>> active + viewers ≥ 200 (8% chance)</li> <li><<link "Spring break" "Wiki_SpringBreak">><</link>> photos ≥ 3 (5% chance)</li> </ul> </div> <div class="wiki-section"> <h2>Stages</h2> <ol> <li><strong>Stage 1:</strong> Anonymous message with compromising photo. Demands $500.</li> <li><strong>Stage 2:</strong> Demands escalate to a physical meeting behind the gym.</li> <li><strong>Stage 3:</strong> total control: dictates clothing, behaviour, daily compliance.</li> </ol> </div> <div class="wiki-section"> <h2>Resolution Paths</h2> <table class="wiki-table"> <tr><th>Path</th><th>How</th><th>Outcome</th></tr> <tr><td>⚡ Confront</td><td>Find 3 clues via investigation, then face them</td><td>+15 confidence, achievement</td></tr> <tr><td>🏛️ Report</td><td>Go to Dean Harrison</td><td>Investigation, some exposure</td></tr> <tr><td>💪 Refuse</td><td>Call their bluff</td><td>Content leaks, campus moves on</td></tr> <tr><td>😰 Comply</td><td>Do what they say</td><td>Ongoing degradation loop</td></tr> <tr><td>🤷 Ignore</td><td>Don't respond</td><td>Escalation, eventual partial leak</td></tr> </table> <p>Investigation uses <<link "Intelligence" "Wiki_Stats">><</link>> checks. Confrontation uses <<link "Persuasion" "Wiki_Stats">><</link>>.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🌀 HYPNOSIS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🌀 Hypnosis: Dr. Crane</h1> <p>Found via the notice board at the <<link "Health Centre" "Wiki_Locations">><</link>>.</p> <div class="wiki-section"> <h2>Phases</h2> <table class="wiki-table"> <tr><th>Phase</th><th>Sessions</th><th>What Happens</th></tr> <tr><td>1. Relaxation</td><td>1-2</td><td>Legitimate stress reduction. Builds trust.</td></tr> <tr><td>2. Deeper Trance</td><td>3-5</td><td>Phrases planted: <<link "femininity" "Wiki_Femininity">><</link>> acceptance, obedience seeds</td></tr> <tr><td>3. Conditioning</td><td>6-8</td><td>Triggers implanted: "bloom" (pleasure), "good girl" (compliance), "kneel"</td></tr> <tr><td>4. Deep</td><td>9+</td><td>Complete trance, instant pleasure/compliance on trigger</td></tr> </table> </div> <div class="wiki-section"> <h2>Player Awareness</h2> <ul> <li><<link "Intelligence" "Wiki_Stats">><</link>> check each session (difficulty increases)</li> <li>Critical success → realise you're being conditioned</li> <li><strong>End conditioning</strong>: Remove all triggers, +10 willpower</li> <li><strong>Consent to continue</strong>: +10 <<link "corruption" "Wiki_Corruption">><</link>>, deeper conditioning</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 😈 CORRUPTION ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>😈 Corruption, Glory Holes & Body Writing</h1> <div class="wiki-section"> <h2>Corruption System (0-100)</h2> <table class="wiki-table"> <tr><th>Tier</th><th>Range</th><th>Effects</th></tr> <tr><td>😇 Innocent</td><td>0-19</td><td>Default state</td></tr> <tr><td>😏 Tempted</td><td>20-39</td><td>Dialogue shifts, new options</td></tr> <tr><td>😈 Compromised</td><td>40-59</td><td>Dream changes, NPC behaviour shifts</td></tr> <tr><td>💀 Corrupted</td><td>60-79</td><td>Deep submission, altered self-image</td></tr> <tr><td>🖤 Fallen</td><td>80-100</td><td>Unlocks <<link "corruption ending" "Wiki_Endings">><</link>></td></tr> </table> <p><strong>Sources:</strong> <<link "BDSM" "Wiki_VelvetRoom">><</link>> (2-5), glory holes (3-4), <<link "blackmail" "Wiki_Blackmail">><</link>> compliance (5-10), <<link "hypnosis" "Wiki_Hypnosis">><</link>> (5-8), public use events (3-5)</p> </div> <div class="wiki-section"> <h2>🚻 Glory Holes</h2> <h3>Library</h3> <ul> <li><strong>Discovery:</strong> Random chance in <<link "library" "Wiki_Locations">><</link>> bathroom (week ≥ 3)</li> <li><strong>Schedule:</strong> Tuesdays & Thursdays, 9pm only</li> <li><strong>Options:</strong> Participate (oral XP + 0.5 <<link "service credits" "Wiki_Service">><</link>>) or watch</li> </ul> <h3>Bar (Rusty Nail)</h3> <ul> <li><strong>Discovery:</strong> Drunk level ≥ 2 with <<link "slut rep" "Wiki_Reputation">><</link>> ≥ 20</li> <li><strong>Schedule:</strong> Always available evenings</li> <li><strong>Options:</strong> Participate (oral/deepthroat XP, sometimes tipped $20)</li> </ul> </div> <div class="wiki-section"> <h2>✍️ Body Writing</h2> <ul> <li>Marks applied during some <<link "service" "Wiki_Service">><</link>> encounters and <<link "BDSM" "Wiki_VelvetRoom">><</link>> sessions</li> <li>Visible until showering (<<link "cleanliness" "Wiki_Beauty">><</link>> ≥ 90)</li> <li>+3 corruption and +2 <<link "slut rep" "Wiki_Reputation">><</link>> per application</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🤰 PREGNANCY ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🤰 Pregnancy</h1> <div class="wiki-section"> <h2>Risk Factors</h2> <ul> <li>Internal completion during <<link "service" "Wiki_Service">><</link>> encounters</li> <li>Fertility <<link "side effect" "Wiki_SideEffects">><</link>> level increases chance</li> <li>The Birth Control <<link "add-on" "Wiki_CharacterCreation">><</link>>, the pill, or an IUD <strong>block conception entirely</strong>, unless Fertility is at level 4, which overrides all three</li> <li>Condoms = reduced risk (buy at drugstore)</li> </ul> </div> <div class="wiki-section"> <h2>Progression</h2> <ol> <li>Risk flag set after unprotected encounter</li> <li>Missed period at week 2; morning sickness from week 4</li> <li>Confirm via pregnancy test (Health Centre or drugstore)</li> <li>Decision: <strong>Keep</strong>, <strong>Abort</strong> ($200), or <strong>Adopt</strong></li> <li>If carried: 36 weeks. Breasts fill out at weeks 10 and 22, hips widen at 16 and 28, kept or reversed after the birth as you choose</li> <li>From week 30 you choose where to deliver: hospital ($400) or a home birth in the dorm (free, but riskier)</li> </ol> </div> <div class="wiki-section"> <h2>Genetics</h2> <p>Baby appearance influenced by both parents' race and traits, so it depends on your <<link "character creation" "Wiki_CharacterCreation">><</link>> race and the father's procedurally generated race.</p> </div> <<include "Wiki_Footer">> </div>
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🩺 Health</h1> <div class="wiki-section"> <h2>Infections</h2> <p>Three infections exist and they are <strong>not interchangeable</strong>. Which one you catch changes how long it hides, how bad it feels, what it costs to treat, and what it does to you if you leave it.</p> <table class="wiki-table"> <tr><th>Infection</th><th>Shows after</th><th>Chance of no symptoms</th><th>Treatment</th></tr> <tr><td>Chlamydia</td><td>10 days</td><td><strong>55%</strong></td><td>$50</td></tr> <tr><td>Gonorrhoea</td><td>3 days</td><td>5%</td><td>$70</td></tr> <tr><td>Trichomoniasis</td><td>6 days</td><td>25%</td><td>$45</td></tr> </table> <p>Chlamydia is both the most common and the quietest. Over half the time it never announces itself at all, which means the only way to find it is to get tested.</p> </div> <div class="wiki-section"> <h2>Living with one</h2> <ul> <li><strong>Gonorrhoea</strong> is by far the worst day to day: it drains health and mood four times faster than chlamydia. That is also why it rarely goes untreated.</li> <li><strong>Trichomoniasis</strong> carries a hygiene penalty of 6 per day. It is the one other people notice.</li> <li><strong>Chlamydia</strong> costs you almost nothing daily. That is the trap.</li> </ul> </div> <div class="wiki-section"> <h2>Leaving it too long</h2> <table class="wiki-table"> <tr><th>Infection</th><th>After</th><th>Permanent effect</th></tr> <tr><td>Gonorrhoea</td><td>30 days</td><td>Spreads. Costs 20 health outright.</td></tr> <tr><td>Chlamydia</td><td>45 days</td><td><strong>Scarring. Fertility drops a level and does not come back.</strong></td></tr> <tr><td>Trichomoniasis</td><td>never</td><td>Unpleasant, but no lasting damage.</td></tr> </table> <p>The infection least likely to tell you it is there is the one that does permanent harm. Test regularly.</p> </div> <div class="wiki-section"> <h2>Catching and avoiding</h2> <ul> <li>Base risk per act: oral 2%, vaginal 4%, anal 6%</li> <li>Anonymous and group encounters carry a multiplier</li> <li>Condoms pass only a fraction of the risk</li> <li>The <<link "STD Protection" "Wiki_CharacterCreation">><</link>> add-on blocks infection entirely</li> <li>Testing at the Health Centre is free. Treatment is not.</li> </ul> </div> <div class="wiki-section"> <h2>Menstrual cycle</h2> <p>A 28 day cycle. Days 1 to 4 are your period: mood penalty, suppressed arousal, and cramps on the first two days.</p> <p>Disabled by the No Period add-on. Suppressed while pregnant, which is why a missed period is the first hint of <<link "pregnancy" "Wiki_Pregnancy">><</link>>.</p> </div> <div class="wiki-section"> <h2>Weight</h2> <p>Weight drifts along a ladder: slim, average, curvy, chubby.</p> <ul> <li>Three or more gym visits in a week: 30% chance to move down</li> <li>No gym at all that week: 20% chance to move up</li> <li>Locked entirely by the Metabolism Control add-on</li> </ul> <p>This is separate from the body changes pregnancy causes, which have their own track.</p> </div> <<include "Wiki_Footer">> </div>
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>👶 Children</h1> <div class="wiki-section"> <h2>The obligation</h2> <p>If you keep a baby, it needs looking after <strong>every day</strong>, and the game notices when it is not. There are two ways to cover that and you need one of them running at all times.</p> </div> <div class="wiki-section"> <h2>The campus nursery</h2> <ul> <li><strong>$25 per child per day</strong>, charged automatically, eight until five</li> <li>Covers the day entirely: your time is your own</li> <li>If you cannot pay, the fee goes on account instead</li> <li>Fall <strong>$150 behind</strong> and your place is suspended and the balance lands on your debt</li> </ul> <p>Expensive, and usually the difference between attending your classes and not.</p> </div> <div class="wiki-section"> <h2>Looking after them yourself</h2> <ul> <li>Three hours, plus energy scaling with how many children you have</li> <li>Builds <strong>bond</strong>, which changes how the scenes read and feeds your ending</li> <li>Clears a point of neglect</li> <li>Lactation makes the feeding easier</li> </ul> </div> <div class="wiki-section"> <h2>Neglect</h2> <p>Two full days with nobody looking after them adds a neglect point.</p> <table class="wiki-table"> <tr><th>Neglect</th><th>What happens</th></tr> <tr><td>3</td><td>A visit from the university family support office. A warning, and notes taken.</td></tr> <tr><td>6</td><td>The same officer, considerably cooler, reading the previous dates back to you.</td></tr> <tr><td>9</td><td><strong>The children are removed into care.</strong></td></tr> </table> <p>Removal is not a fail state you retry. It is permanent, it is recorded, and the game carries on afterwards.</p> </div> <div class="wiki-section"> <h2>Where to find it</h2> <ul> <li><strong>Your room:</strong> "Look after the baby"</li> <li><strong>Campus map:</strong> "Campus Nursery"</li> </ul> <p>Both appear only once you actually have a child. Note that graduating changes nothing here: see <<link "Endings" "Wiki_Endings">><</link>>.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🍺 SUBSTANCES ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🍺 Substances</h1> <div class="wiki-section"> <h2>Alcohol</h2> <table class="wiki-table"> <tr><th>Level</th><th>State</th><th>Effects</th></tr> <tr><td>0</td><td>Sober</td><td>None</td></tr> <tr><td>1</td><td>Tipsy</td><td>+5 mood, -5 composure</td></tr> <tr><td>2</td><td>Drunk</td><td>+10 arousal, -15 composure</td></tr> <tr><td>3</td><td>Wasted</td><td>Stumbling, <<link "glory hole" "Wiki_Corruption">><</link>> discovery possible</td></tr> <tr><td>4+</td><td>Blackout</td><td>Skip to morning, no memory</td></tr> </table> <p>Drinks available at <<link "Bar District" "Wiki_BarDistrict">><</link>> venues.</p> </div> <div class="wiki-section"> <h2>Drugs</h2> <table class="wiki-table"> <tr><th>Drug</th><th>Effect</th><th>Risk</th><th>Source</th></tr> <tr><td>🌿 Weed</td><td>+mood, -stress</td><td>Tolerance</td><td><<link "Dealer" "Wiki_Jobs">><</link>> or buy</td></tr> <tr><td>💊 Ecstasy</td><td>Euphoria, heightened sensation</td><td>Comedown, tolerance</td><td><<link "Clubs" "Wiki_BarDistrict">><</link>></td></tr> <tr><td>❄️ Cocaine</td><td>Energy, confidence</td><td>Addiction!</td><td><<link "Rusty Nail" "Wiki_BarDistrict">><</link>> dealer</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 👥 SOCIAL & GREEK LIFE ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>👥 Social & Greek Life</h1> <div class="wiki-section"> <h2>Roommate</h2> <p>Procedurally generated in Hamilton Hall. Two key meters:</p> <ul> <li><strong>Opinion (0-100):</strong> Small talk, weekend hangouts, sharing clothes</li> <li><strong>Trust (0-100):</strong> Confiding secrets, spending quality time</li> </ul> <p>High trust → becomes confidant. Walking in on you → awareness increases.</p> </div> <div class="wiki-section"> <h2>Sorority / Greek Life</h2> <ol> <li>Attend Rush Week mixer (<<link "Freshman Week" "Wiki_Seasonal">><</link>>)</li> <li>Choose a sorority to pledge</li> <li>Survive <strong>Hazing Week</strong> (escalating challenges)</li> <li>Full membership → sisterhood events, frat party access</li> </ol> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 📱 PHONE ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>📱 Phone</h1> <p>Access via 📱 Phone on the campus map or top bar.</p> <div class="wiki-section"> <h2>Apps</h2> <table class="wiki-table"> <tr><th>App</th><th>Function</th></tr> <tr><td>🟣 CampusHub</td><td><<link "Service" "Wiki_Service">><</link>> quota tracking, active requests</td></tr> <tr><td>📸 InstaGlam</td><td>Post selfies for followers and <<link "popularity" "Wiki_Reputation">><</link>></td></tr> <tr><td>🐦 Chirpr</td><td>Procedural campus gossip (reacts to your <<link "reputation" "Wiki_Reputation">><</link>>)</td></tr> <tr><td>📅 Calendar</td><td><<link "Seasonal events" "Wiki_Seasonal">><</link>>, finals, job schedules</td></tr> <tr><td>👥 Contacts</td><td>NPC directory: roommate, sorority, <<link "Dr. Crane" "Wiki_Hypnosis">><</link>></td></tr> <tr><td>💬 Messages</td><td>Inbox, used by <<link "blackmail" "Wiki_Blackmail">><</link>>, roommate, dean</td></tr> <tr><td>🗺️ Maps</td><td>Quick travel to any <<link "campus location" "Wiki_Locations">><</link>></td></tr> <tr><td>⚙️ Settings</td><td>Save/load (5 slots), export, game stats</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🎃 SEASONAL EVENTS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🎃 Seasonal Events</h1> <div class="wiki-section"> <h2>Fall Semester</h2> <table class="wiki-table"> <tr><th>Week</th><th>Event</th><th>Content</th></tr> <tr><td>1</td><td>🎉 Freshman Week</td><td>Mixer, meeting people, first parties</td></tr> <tr><td>5</td><td>🏟️ Homecoming</td><td>Game, dance, after-party, Homecoming Queen vote</td></tr> <tr><td>8</td><td>🎃 Halloween</td><td>Costume party, themed encounters</td></tr> <tr><td>12</td><td>🦃 Thanksgiving</td><td>Stay on campus event</td></tr> <tr><td>14</td><td>📝 Finals</td><td>Double <<link "service quota" "Wiki_Service">><</link>>, <<link "exams" "Wiki_Academics">><</link>></td></tr> <tr><td>15</td><td>❄️ Winter Formal</td><td>Dance, date options, hotel room</td></tr> </table> </div> <div class="wiki-section"> <h2>Spring Semester</h2> <table class="wiki-table"> <tr><th>Week</th><th>Event</th><th>Content</th></tr> <tr><td>6</td><td>💘 Valentine's</td><td>Mixer, romantic encounters</td></tr> <tr><td>12</td><td>🏖️ <<link "Spring Break" "Wiki_SpringBreak">><</link>></td><td>Playa Caliente resort</td></tr> <tr><td>14</td><td>📝 Finals</td><td>Double quota, exams</td></tr> <tr><td>16</td><td>🎓 End of Year</td><td>Year-end or <<link "graduation" "Wiki_Endings">><</link>></td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🏖️ SPRING BREAK ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🏖️ Playa Caliente: Spring Break</h1> <div class="wiki-section"> <h2>Locations</h2> <table class="wiki-table"> <tr><th>Location</th><th>Activities</th></tr> <tr><td>🏖️ Beach</td><td>Tanning, volleyball, drinking games</td></tr> <tr><td>🏊 Pool</td><td>Body shots, chicken fights, dancing</td></tr> <tr><td>🏨 Hotel</td><td>Sleep, change, recover</td></tr> <tr><td>🍹 Bar</td><td><<link "Drinks" "Wiki_Substances">><</link>>, flirting, hookups</td></tr> <tr><td>🌊 Hidden Cove</td><td>Skinny dipping, threesome encounters</td></tr> <tr><td>🎤 Club</td><td>Dancing, VIP access</td></tr> <tr><td>💆 Spa</td><td>Relaxation, "special" massage</td></tr> <tr><td>🏆 Contests</td><td>Wet T-shirt, bikini, Spring Break Queen</td></tr> <tr><td>🎰 VIP Area</td><td>Sugar daddy encounters</td></tr> </table> </div> <div class="wiki-section"> <h2>Spring Break Queen</h2> <p>Multi-day competition: enter contests → accumulate points → crowned SBQ. Boosts <<link "popularity" "Wiki_Reputation">><</link>> and unlocks achievement.</p> <p>Photos from spring break (≥3) can trigger the <<link "blackmail arc" "Wiki_Blackmail">><</link>>.</p> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🎲 RANDOM EVENTS & DREAMS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🎲 Random Events & Dreams</h1> <div class="wiki-section"> <h2>Random Events</h2> <p>Fire during period changes (8% base chance). 6 categories:</p> <table class="wiki-table"> <tr><th>Category</th><th>Gate</th><th>Examples</th></tr> <tr><td>🚶 Campus</td><td>Always</td><td>Catcalls, selfie requests, secret admirers</td></tr> <tr><td>📱 Phone</td><td>Always</td><td>Quota reminders, roommate texts, spam</td></tr> <tr><td>🎭 Reputation</td><td><<link "Rep" "Wiki_Reputation">><</link>>-gated</td><td>Whispers, study invites, propositions</td></tr> <tr><td>😳 Transformation</td><td>Always</td><td>Body awareness, name shifts, attraction</td></tr> <tr><td>🔞 Sexual</td><td>Slut ≥ 30</td><td>Groping, bathroom notes (scales with rep)</td></tr> <tr><td>🌧️ Ambient</td><td>Always</td><td>Rain, campus cat, sunset, power outage</td></tr> </table> </div> <div class="wiki-section"> <h2>Dreams</h2> <p>Fire during sleep (30% base + 15% per Erotic Dreams <<link "SE" "Wiki_SideEffects">><</link>> level). 20 unique dreams across 4 <<link "femininity" "Wiki_Femininity">><</link>> tiers:</p> <table class="wiki-table"> <tr><th>Tier</th><th>Femininity</th><th>Themes</th></tr> <tr><td>💀 Resistance</td><td>0-25</td><td>Nightmares, dysphoria, body horror</td></tr> <tr><td>😕 Confusion</td><td>26-50</td><td>Mixed feelings, guilt, enjoyment</td></tr> <tr><td>💕 Acceptance</td><td>51-75</td><td>Erotic dreams, lingerie, romance</td></tr> <tr><td>🌸 Embrace</td><td>76-100</td><td>Vivid sex dreams, domestic fantasies</td></tr> </table> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ 🎓 ENDINGS ═══════════════════════════════════════════════════ */
<div class="wiki"> <<include "Wiki_Breadcrumb">> <h1>🎓 Endings</h1> <div class="wiki-section"> <h2>Graduation Epilogues (Semester 6+)</h2> <table class="wiki-table"> <tr><th>Ending</th><th>Conditions</th><th>Summary</th></tr> <tr><td>📚 The Scholar</td><td><<link "Good Student" "Wiki_Reputation">><</link>> ≥ 60, Intelligence ≥ 60</td><td>Graduate school, quiet life</td></tr> <tr><td>💃 Embraced</td><td><<link "Femininity" "Wiki_Femininity">><</link>> ≥ 80, Mood ≥ 50</td><td>Permanent transformation</td></tr> <tr><td>⭐ Celebrity</td><td><<link "Popular" "Wiki_Reputation">><</link>> ≥ 60 or Cam Girl ≥ 60</td><td>Influencer/performer career</td></tr> <tr><td>💼 Professional</td><td>2+ <<link "jobs" "Wiki_Jobs">><</link>>, Intel ≥ 50, GoodStudent ≥ 40</td><td>Corporate career</td></tr> <tr><td>😈 Underground</td><td>Slut ≥ 80, Troublemaker ≥ 40</td><td>Criminal connections</td></tr> <tr><td>🏠 Moving On</td><td>Default (no dominant path)</td><td>Normal life, haunted by memories</td></tr> </table> </div> <div class="wiki-section"> <h2>Non-Graduation Endings</h2> <table class="wiki-table"> <tr><th>Ending</th><th>Trigger</th><th>Notes</th></tr> <tr><td>🚫 Expelled</td><td><<link "Service" "Wiki_Service">><</link>> probation + continued failure</td><td>Can appeal (charm crit success)</td></tr> <tr><td>🏃 Dropout</td><td>Voluntary: visit the Dean's office</td><td>Forfeit scholarship</td></tr> </table> </div> <div class="wiki-section"> <h2>Tips</h2> <ul> <li>Each ending has <<link "femininity" "Wiki_Femininity">><</link>>-reactive variations</li> <li>High femininity characters get more wistful/accepting epilogues</li> <li>The ending stats screen shows your complete 3-year history</li> </ul> </div> <<include "Wiki_Footer">> </div> /* ═══════════════════════════════════════════════════ SHARED WIDGETS: Breadcrumb & Footer ═══════════════════════════════════════════════════ */
<div class="wiki-breadcrumb"> <<link "📖 Wiki Home" "Wiki_Home">><</link>> › <span class="wiki-breadcrumb-current"><<print passage()>></span> </div>
<div class="wiki-footer"> <div class="wiki-footer-nav"> <<link '<span class="choice-btn wiki-back-btn">📖 Back to Wiki Home</span>' "Wiki_Home">><</link>> <<link '<span class="choice-btn wiki-back-btn">🗺️ Back to Game</span>' `($ui.returnPassage || "CampusMap")`>><</link>> </div> </div>