UNPKG

sandhill-road

Version:

A narrative-driven startup simulation game where you guide a founder from garage to exit

204 lines 6.54 kB
"use strict"; // Game state manager for Sandhill Road // Tracks all mutable game values Object.defineProperty(exports, "__esModule", { value: true }); exports.advanceWeek = exports.endGame = exports.loadGame = exports.saveGame = exports.updateGameState = exports.getGameState = exports.initGame = exports.createInitialGameState = exports.GameStage = void 0; const fileStorage_1 = require("../utils/fileStorage"); var GameStage; (function (GameStage) { GameStage["Garage"] = "Garage"; GameStage["DemoDay"] = "Demo Day"; GameStage["Fundraising"] = "Fundraising"; GameStage["PMF"] = "PMF"; GameStage["Scaling"] = "Scaling"; GameStage["Crisis"] = "Crisis"; GameStage["Exit"] = "Exit"; })(GameStage || (exports.GameStage = GameStage = {})); // Default starting values for a new game const createInitialGameState = (founderName, companyName, initialPersonalCash = 30000) => { return { founderName, companyName, founderStats: { health: 8, morale: 10, hustle: 5, tech: 5, luck: 5, stamina: 10, maxStamina: 10, staminaRegen: 3, personalCash: initialPersonalCash }, companyStats: { runway: 12, // weeks burnRate: 5000, // per week users: 0, productProgress: 0, companyCash: 10000, revenue: 0, investorTrust: 5 }, stageProgress: { currentStage: GameStage.Garage, week: 1, completedEvents: [], availableEvents: [], completedExclusiveGroups: [] }, companyFlags: { hasCoFounder: false, coFounderEquity: 0, inAccelerator: false, acceleratorName: undefined, hasRaisedSeed: false, hasRaisedSeriesA: false, hasPMF: false, hasFirstEmployee: false, hasOffice: false, hasBoard: false, majorCrisisSurvived: false, exitOffersReceived: 0 }, gameOver: false }; }; exports.createInitialGameState = createInitialGameState; // Game state singleton let gameState = null; // Game state methods const initGame = (founderName, companyName, initialCash = 30000) => { gameState = (0, exports.createInitialGameState)(founderName, companyName, initialCash); return gameState; }; exports.initGame = initGame; const getGameState = () => { if (!gameState) { throw new Error("Game state not initialized. Call initGame first."); } return gameState; }; exports.getGameState = getGameState; const updateGameState = (updater) => { if (!gameState) { throw new Error("Game state not initialized. Call initGame first."); } gameState = updater(gameState); return gameState; }; exports.updateGameState = updateGameState; const saveGame = () => { if (!gameState) { throw new Error("No game to save"); } try { // Check if we're in a browser or Node environment if (typeof window !== 'undefined' && window.localStorage) { localStorage.setItem('sandhillRoadSave', JSON.stringify(gameState)); } else { // In Node.js, use file storage (0, fileStorage_1.saveToFile)(gameState); } } catch (error) { console.error("Failed to save game:", error); } }; exports.saveGame = saveGame; const loadGame = () => { try { let savedGame = null; // Check if we're in a browser or Node environment if (typeof window !== 'undefined' && window.localStorage) { savedGame = localStorage.getItem('sandhillRoadSave'); if (savedGame) { gameState = JSON.parse(savedGame); return gameState; } } else { // In Node.js, use file storage const data = (0, fileStorage_1.loadFromFile)(); if (data) { gameState = data; return gameState; } } } catch (error) { console.error("Failed to load game:", error); } return null; }; exports.loadGame = loadGame; const endGame = (reason) => { if (!gameState) return; (0, exports.updateGameState)(state => ({ ...state, gameOver: true, gameOverReason: reason })); }; exports.endGame = endGame; // Weekly update function const advanceWeek = () => { if (!gameState || gameState.gameOver) return; (0, exports.updateGameState)(state => { // Update week counter const newWeek = state.stageProgress.week + 1; // Calculate new values const newStamina = Math.min(state.founderStats.maxStamina, state.founderStats.stamina + state.founderStats.staminaRegen); const newCompanyCash = state.companyStats.companyCash - state.companyStats.burnRate; const newRunway = Math.floor(newCompanyCash / state.companyStats.burnRate); // Check for game over conditions if (newCompanyCash <= 0) { return { ...state, companyStats: { ...state.companyStats, companyCash: 0, runway: 0 }, stageProgress: { ...state.stageProgress, week: newWeek }, gameOver: true, gameOverReason: "Your company ran out of money." }; } if (state.founderStats.health <= 0) { return { ...state, stageProgress: { ...state.stageProgress, week: newWeek }, gameOver: true, gameOverReason: "Your health deteriorated completely. You had to step down." }; } // Normal weekly update return { ...state, founderStats: { ...state.founderStats, stamina: newStamina }, companyStats: { ...state.companyStats, companyCash: newCompanyCash, runway: newRunway }, stageProgress: { ...state.stageProgress, week: newWeek } }; }); }; exports.advanceWeek = advanceWeek; //# sourceMappingURL=gameState.js.map