sandhill-road
Version:
A narrative-driven startup simulation game where you guide a founder from garage to exit
204 lines • 6.54 kB
JavaScript
;
// 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