### Send Messages to Worker (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt Demonstrates how to send messages from the UI layer to the game worker using the `toWorker` function. This includes examples for generating draft prospects, initiating trades, and simulating free agency days. It requires importing the `toWorker` utility. ```typescript import toWorker from "./ui/util/toWorker"; // Generate new draft prospects await toWorker('core', 'draft.genPlayers', { draftYear: 2024, scoutingLevel: 2.5 }); // Start a trade with another team await toWorker('core', 'trade.create', { teams: [ { tid: 0, pids: [123, 456], dpids: [789] }, // User's team { tid: 5, pids: [234, 567], dpids: [] } // Other team ] }); // Simulate a day of free agency await toWorker('core', 'freeAgents.play', { numDays: 7 }); ``` -------------------------------- ### Create New League with Custom Settings (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt This function allows for the creation of a new game league with a comprehensive set of customizable attributes. It takes input for game settings, starting season, team information, user ID, and database version. The output is a GameAttributes object which is then cached. ```typescript import { league } from "./worker/core"; const gameAttributes = await league.createGameAttributes({ gameAttributesInput: { difficulty: 0.5, // 0-1 scale stopOnInjuryGames: 20, numGames: 82, // regular season games quarterLength: 12, // minutes per quarter minRosterSize: 13, maxRosterSize: 17, salaryCap: 120000, // in thousands minPayroll: 90000, luxuryPayroll: 145000, luxuryTax: 1.5, minContract: 1000, maxContract: 40000, hardCap: false, numGamesPlayoffSeries: [7, 7, 7, 7], draftType: "nba2019", // or "random", "noLottery", etc numSeasonsFutureDraftPicks: 4, foulRateFactor: 1, foulsNeededToFoulOut: 6, // ... many more settings }, startingSeason: 2024, teamInfos: teams, userTid: 0, version: LEAGUE_DATABASE_VERSION }); // Save game attributes for (const [key, value] of Object.entries(gameAttributes)) { await idb.cache.gameAttributes.add({ key, value }); } ``` -------------------------------- ### Database Cache Operations (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt Provides examples of common IndexedDB cache operations using the `idb` utility. This includes retrieving, filtering, and updating data for players, draft picks, and events. It also shows how to perform a transaction with multiple operations on different object stores. Requires importing `idb` from './worker/db'. ```typescript import { idb } from "./worker/db"; // Retrieve a player by ID const player = await idb.cache.players.get(123); // Get all players on a specific team const teamPlayers = await idb.cache.players.indexGetAll( 'playersByTid', 5 // team ID ); // Get draft picks for a season const draftPicks = await idb.cache.draftPicks.indexGetAll( 'draftPicksBySeason', 2024 ); // Update a player and write back to cache player.ratings[0].ovr = 85; await idb.cache.players.put(player); // Add a new event to the log await idb.cache.events.add({ season: 2024, type: "trade", text: "The Lakers traded LeBron James to the Heat.", pids: [123], tids: [5, 10] }); // Transaction example with multiple operations const tx = idb.league.transaction(['players', 'teams'], 'readwrite'); await Promise.all([ tx.objectStore('players').put(updatedPlayer), tx.objectStore('teams').put(updatedTeam), tx.done ]); ``` -------------------------------- ### Send Messages to UI (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt Illustrates how the game worker can send updates back to the UI layer using the `toUI` function. Examples include notifying the UI about player movements, displaying event log messages, and triggering a full UI refresh. This function requires importing the `toUI` utility. ```typescript import toUI from "./worker/util/toUI"; // Update UI with player movement notification await toUI('realtimeUpdate', [['playerMovement']], {}); // Display event log message to user await toUI('updateLocal', [{ games: updatedGames, events: newEvents }], {}); // Trigger full UI refresh await toUI('realtimeUpdate', [['firstRun']], {}); ``` -------------------------------- ### Initialize Game Configuration and Browser Checks Source: https://github.com/zengm-games/zengm/blob/master/public/index.html Sets up global variables for game version, mobile detection, theme management, and logging. It also includes functions to load CSS, determine the correct theme (dark/light) based on user preference or system settings, and checks for browser compatibility. ```javascript window.bbgmVersion = "VERSION_NUMBER"; window.useSharedWorker = typeof SharedWorker !== 'undefined'; window.mobile = window.screen.width < 768 || window.screen.height < 768; function loadCSS(filename){ var el = document.createElement("link"); el.setAttribute("rel", "stylesheet"); el.setAttribute("href", filename); document.getElementsByTagName("head")[0].appendChild(el); return el; } function getTheme() { var dark = "dark-CSS_HASH_DARK"; var light = "light-CSS_HASH_LIGHT"; try { var local = localStorage.getItem("theme"); if (local !== null) { return local === "dark" ? "dark" : "light"; } return matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; } catch (error) { return "light"; } } function getThemeFilename(theme) { // Updates the scrollbar in Chrome - from the demo https://color-scheme-demo.glitch.me/ // from https://web.dev/articles/color-scheme#demo document.documentElement.style.colorScheme = theme; if (theme === "dark") { return "/gen/dark-CSS_HASH_DARK.css"; } return "/gen/light-CSS_HASH_LIGHT.css"; } window.themeCSSLink = loadCSS(getThemeFilename(getTheme())); window.enableLogging = location.host.indexOf("GOOGLE_ANALYTICS_COOKIE_DOMAIN") >= 0; if (window.enableLogging) { var s = document.createElement("script"); s.async = true; s.src = "https://www.googletagmanager.com/gtag/js?id=GOOGLE_ANALYTICS_ID"; s.type = "text/javascript"; document.head.appendChild(s); window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('consent', 'default', { ad_storage: 'granted', ad_user_data: 'granted', ad_personalization: 'granted', analytics_storage: 'granted' }); gtag('js', new Date()); gtag('config', 'GOOGLE_ANALYTICS_ID', { cookie_domain: 'GOOGLE_ANALYTICS_COOKIE_DOMAIN', send_page_view: false }); } window.releaseStage = "unknown"; if (location.host.indexOf("localhost") === 0) { window.releaseStage = "development"; } else if (location.host.indexOf("BETA_SUBDOMAIN") === 0) { window.releaseStage = "beta"; } else if (location.host.indexOf("PLAY_SUBDOMAIN") === 0) { window.releaseStage = "production"; } window.bugsnagKey = "BUGSNAG_API_KEY"; ``` -------------------------------- ### Manage Game Startup UI and Worker Loading Source: https://github.com/zengm-games/zengm/blob/master/public/index.html Handles the initial loading sequence of the game, displaying messages to the user about loading progress. It includes a timeout for detecting slow loading and provides user-friendly error messages or debugging links. It also dynamically loads the main UI script. ```javascript var startupUI = document.getElementById("startup-ui"); var startupWorker = document.getElementById("startup-worker"); var doneUI = false; var doneWorker = false; var timeoutID = setTimeout(function () { var errorMsg; if (doneUI && !doneWorker) { // From user reports in Chrome, possibly related to Chrome version updates in the background errorMsg = '

This should only take a few seconds on a fast connection.

If it\'s stuck loading the backend, try restarting your browser, sometimes that helps.

'; } else if (!doneUI && !doneWorker) { errorMsg = '

This should only take a few seconds on a fast connection.

If it gets stuck for a while, read the debugging instructions and ask for help if it still isn\'t working.

'; } var startupError = document.getElementById("startup-error"); startupError.innerHTML = errorMsg; startupError.style.display = "block"; }, 6000); function withGoodBrowser() { document.getElementById("startup-browser").innerHTML += " done!"; startupUI.innerHTML = "Loading UI..."; startupWorker.innerHTML = "Loading backend..."; var body = document.getElementsByTagName('body').item(0); var script = document.createElement('script'); script.type = "module"; // Needs to be module for modulepreload script.src = "/gen/ui-" + bbgmVersion + ".js"; body.appendChild(script); } var count = 0; function withGoodUI() { startupUI.innerHTML += " done!"; doneUI = true; count += 1; if (count === 2) { clearTimeout(timeoutID); } } function withGoodWorker() { startupWorker.innerHTML += " done!"; doneWorker = true; count += 1; if (count === 2) { clearTimeout(timeoutID); } } function checkBrowser() { // Chrome <71, Firefox <105, Safari <14.1 if (typeof TextDecoderStream === "undefined") { return false; } // Chrome <85 if (!String.prototype.replaceAll) { return false; } // Safari <15.4 if (typeof BroadcastChannel === "undefined") { // Actually it still works down to Safari 14.1 currently, just no longer "officially" supported so might as well not explicitly check here. Eventually when actually using worker modules, uncomment this //return false; } return true; }; ``` -------------------------------- ### Initialize IndexedDB and Handle Errors Source: https://github.com/zengm-games/zengm/blob/master/public/index.html This JavaScript code attempts to open an IndexedDB database. It defines error handlers for aborted or full quota errors, and a success handler. If the database opening fails, it determines the type of error (e.g., quota error, browser incompatibility) and updates the UI to inform the user. ```javascript openRequest.onerror = function (evt) { console.error(evt.target.error); if (evt.target.error.message.indexOf("aborted") >= 0 || evt.target.error.message.indexOf("full") >= 0) { // Error like "Version change transaction was aborted in upgradeneeded event handler." is probably quota error - try to continue loading BBGM and hope for the best cb("good"); } else { cb("open-failed"); } } openRequest.onsuccess = function (evt) { cb("good"); }; }; goodIDB(function (idbResult) { if (idbResult !== "good") { var errorMsg; if (idbResult === "open-failed") { errorMsg = '

Error! Cannot store data.

If you have disabled cookies in your browser, you must enable them to play GAME_NAME.

'; } else { errorMsg = '

Error! Your browser is not modern enough to run GAME_NAME. Current supported browsers include:

'; } var startupError = document.getElementById("startup-error"); startupError.innerHTML = errorMsg; startupError.style.display = "block"; document.getElementById("loading-icon").style.animationPlayState = "paused"; clearTimeout(timeoutID); } else { localStorage.setItem("goodIDB", "1") withGoodBrowser(); } }); ``` -------------------------------- ### Check Browser Compatibility for IndexedDB Source: https://github.com/zengm-games/zengm/blob/master/public/index.html Checks if the browser supports IndexedDB and meets other compatibility requirements necessary for the game. This function uses various browser APIs and localStorage to determine compatibility and caches the result. ```javascript // Browser compatibility checks! Used to be like https://gist.github.com/jensarps/15f270874889e1717b3d but now the buggy old IE/Safari IndexedDB implementations are not supported for other reasons, like checkBrowser. function goodIDB(cb) { if (typeof indexedDB === "undefined" || !checkBrowser()) { cb("bad"); return; } if (localStorage.getItem("goodIDB")) { cb("good"); return; } var openRequest = indexedDB.open('\__detectIDB_' ``` -------------------------------- ### Generate Player (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt Shows how to generate a new player with customizable attributes using the `player.generate` function from the core worker module. It includes parameters for age, draft year, scouting level, and optional player details. The generated player object contains extensive information including ratings, contract, and draft details. Requires importing `player` from './worker/core' and using `idb` for saving. ```typescript import { player } from "./worker/core"; // Generate a 19-year-old player for team 5 const p = player.generate( 5, // tid: team ID 19, // age 2024, // draftYear false, // newLeague 2.5, // scoutingLevel (0-3) { college: "Duke University", country: "USA", firstName: "John", lastName: "Smith", race: "white" } ); // Player object includes: // - ratings: array of MinimalPlayerRatings with skills like speed, strength // - contract: { amount: number, exp: number } // - draft: { round, pick, tid, year, pot, ovr, skills } // - face: generated face data // - born: { year, loc } // - injury: { type, gamesRemaining } // Save to database and update values await idb.cache.players.add(p); await player.addRelatives(p); await player.updateValues(p); ``` -------------------------------- ### Generate Team (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt Demonstrates the creation of a new team object using the `team.generate` function from the core worker module. This function takes parameters for team identification, location, name, and other attributes. The generated team object includes budget, colors, and strategy. Requires importing `team` from './worker/core' and using `idb` for saving. ```typescript import { team } from "./worker/core"; const newTeam = team.generate({ tid: 15, cid: 1, // conference ID did: 3, // division ID region: "Seattle", name: "SuperSonics", abbrev: "SEA", imgURL: "https://example.com/logo.png", pop: 3.5, // population in millions stadiumCapacity: 18000, strategy: "rebuilding", // or "contending", "rebuilding" popRank: 15 // population rank for budget calculations }); // Team object includes: // - budget: { coaching, facilities, health, scouting, ticketPrice } // - colors: [primary, secondary, accent] // - jersey: design configuration // - depth: position-specific depth charts (sport-dependent) // - retiredJerseyNumbers: [] // - adjustForInflation: true // - keepRosterSorted: true await idb.cache.teams.add(newTeam); ``` -------------------------------- ### Generate Draft Prospects for Upcoming Draft Source: https://context7.com/zengm-games/zengm/llms.txt Generates draft prospects for a specified year. It handles checking for existing prospects, creating new ones, adding them to the database, and assigning initial stats. It also includes a rare chance for special player generation. ```typescript import { draft } from "./worker/core"; // Generate players for 2024 draft await draft.genPlayers( 2024, // draftYear 2.5, // scoutingLevel (affects quality/scouting accuracy) false // forceScrubs - force all players to be low quality ); // This automatically: // 1. Checks for existing draft prospects in that year // 2. Generates appropriate number of new players // 3. Adds them to the database with UNDRAFTED tid // 4. Adds player relatives // 5. Updates player values (ovr, pot, value) // // Note: Has easter eggs - 1/100000 chance to generate special players // like LaVar Ball (if basketball sport is active) // View generated draft prospects const prospects = await idb.cache.players.indexGetAll( 'playersByTid', PLAYER.UNDRAFTED ); const thisYearProspects = prospects.filter(p => p.draft.year === 2024); ``` -------------------------------- ### Extract Surnames from Forebears.io (JavaScript) Source: https://github.com/zengm-games/zengm/blob/master/tools/names-manual/README.md This JavaScript snippet, designed for browser console execution, extracts surname data from a table on forebears.io. It captures names and their frequencies, formatting them into a CSV string. The script limits the output to a specified number of names and normalizes frequencies based on the lowest frequency encountered. ```javascript { const MAX_NUM_NAMES = 50; const rows = document.querySelectorAll(".forename-table tbody tr"); const output = []; for (const row of rows) { if (row.children.length > 1) { const name = row.children[1].textContent; const frequency = Number.parseInt(row.children[2].textContent.replaceAll(",", "")); output.push({ name, frequency, }); if (output.length >= MAX_NUM_NAMES) { break; } } } const minFrequency = Math.min(...output.map(row => row.frequency)); console.log(`Name,Frequency\n${output.map(row => `${row.name},${Math.round(row.frequency / minFrequency)} `).join("")}`); } ``` -------------------------------- ### Extract Forenames from Forebears.io (JavaScript) Source: https://github.com/zengm-games/zengm/blob/master/tools/names-manual/README.md This JavaScript snippet, intended for use in a browser's JS console, extracts forename data from a table on forebears.io. It identifies names with at least 75% male usage, their frequencies, and formats them into a CSV string. It limits the output to a maximum number of names and normalizes frequencies relative to the minimum frequency found. ```javascript { const MAX_NUM_NAMES = 50; const rows = document.querySelectorAll(".forename-table tbody tr"); const output = []; for (const row of rows) { if (row.children.length > 1) { const name = row.children[2].textContent; const frequency = Number.parseInt(row.children[3].textContent.replaceAll(",", "")); const malePct = Number.parseInt(row.children[1].querySelector(".m")?.textContent ?? "0"); if (malePct >= 75) { output.push({ name, frequency, }); if (output.length >= MAX_NUM_NAMES) { break; } } } } const minFrequency = Math.min(...output.map(row => row.frequency)); console.log(`Name,Frequency\n${output.map(row => `${row.name},${Math.round(row.frequency / minFrequency)} `).join("")}`); } ``` -------------------------------- ### Develop Player Ratings Over Time (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt This function simulates player development over one or more seasons, adjusting ratings based on age, peak years, decline years, and potential convergence. It also includes options for season-long development and updating calculated player values. Changes are persisted to the database. ```typescript import { player } from "./worker/core"; // Develop player for one year const p = await idb.cache.players.get(123); await player.develop( p, 1, // years true // newLeague - affects development rates ); // Development affects: // - Ratings improve/decline based on age // - Peak years: faster improvement // - Decline years: gradual decline // - Potential (pot) slowly converges toward ovr // - Random variation each year // Season-long development (called once per season) await player.developSeason(p, 1); // Update calculated values after development await player.updateValues(p); // Save changes await idb.cache.players.put(p); ``` -------------------------------- ### Simulate Basketball Game Source: https://context7.com/zengm-games/zengm/llms.txt Simulates a single basketball game. It takes detailed team and player data as input and outputs comprehensive game statistics for both teams and individual players. ```typescript import GameSim from "./worker/core/GameSim.basketball"; // Create game simulator instance const game = new GameSim({ gid: 1234, day: 5, team: [homeTeamData, awayTeamData], // Team data includes: // { // id: number, // pace: number, // stat: {}, // compositeRating: {}, // player: PlayerGameSim[], // synergy: { def, off, reb } // } }); // Run simulation await game.run(); // Access game results const boxScore = { teams: [ { pts: game.team[0].stat.pts, fg: game.team[0].stat.fg, fga: game.team[0].stat.fga, // ... all team stats } ], players: game.team[0].player.map(p => ({ name: p.name, pts: p.stat.pts, reb: p.stat.orb + p.stat.drb, ast: p.stat.ast, // ... all player stats })) }; ``` -------------------------------- ### Progress Through Game Season Phases Source: https://context7.com/zengm-games/zengm/llms.txt Manages the progression of a game season through different phases. Each phase triggers specific game logic, such as scheduling, simulation enablement, playoff bracket generation, or free agency processing. ```typescript import { phase } from "./worker/core"; import { PHASE } from "./common/constants"; // Advance to regular season await phase.newPhase( PHASE.REGULAR_SEASON, {} // conditions object ); // Phases available: // PHASE.PRESEASON // PHASE.REGULAR_SEASON // PHASE.AFTER_TRADE_DEADLINE // PHASE.PLAYOFFS // PHASE.DRAFT_LOTTERY // PHASE.DRAFT // PHASE.AFTER_DRAFT // PHASE.RESIGN_PLAYERS // PHASE.FREE_AGENCY // PHASE.FANTASY_DRAFT // PHASE.EXPANSION_DRAFT // Each phase triggers appropriate game logic: // - PRESEASON: Generate schedule, reset stats // - REGULAR_SEASON: Enable game simulation // - PLAYOFFS: Generate playoff bracket // - DRAFT: Run draft lottery and draft // - FREE_AGENCY: Process free agent signings ``` -------------------------------- ### Simulate Free Agency Period Source: https://context7.com/zengm-games/zengm/llms.txt Simulates the free agency period, during which player contract demands decrease over time and teams sign free agents. It can be advanced by a number of days or manually triggered actions like auto-signing. ```typescript import { freeAgents } from "./worker/core"; // Play 7 days of free agency await freeAgents.play( 7, // numDays {}, // conditions true // start - is this a new user request? ); // This process: // 1. Decreases player contract demands over time // 2. Auto-signs free agents to teams with needs // 3. Processes AI team trades // 4. Updates daysLeft counter // 5. Triggers preseason when free agency ends // Manually auto-sign free agents await freeAgents.autoSign(); // Decrease all free agent demands await freeAgents.decreaseDemands(); ``` -------------------------------- ### Create and Manage Player Trades Source: https://context7.com/zengm-games/zengm/llms.txt Facilitates the creation and management of trades between teams in the game. This includes initiating a trade, proposing it to the AI, and handling the outcome of the trade proposal. ```typescript import { trade } from "./worker/core"; // Start a new trade await trade.create({ teams: [ { tid: 0, // User's team pids: [123, 456], // Player IDs to trade away dpids: [789] // Draft pick IDs to trade away }, { tid: 5, // Other team pids: [234], dpids: [890, 891] } ] }); // Get current trade const currentTrade = await trade.get(); // Propose trade to AI const tradeResult = await trade.propose({ teams: currentTrade.teams }); // tradeResult includes: // - success: boolean // - message: string explanation // - ai_mood: numeric trade difficulty // Clear trade await trade.clear(); ``` -------------------------------- ### Automatically Sort Roster by Player Quality (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt This function automatically reorders a team's roster based on player quality and position. It ranks players by their calculated value for each position, sets the optimal depth chart, and updates player orderings. This process is applicable across different sports like basketball, football, hockey, and baseball, with sport-specific depth chart considerations. ```typescript import { team } from "./worker/core"; // Auto-sort basketball team roster await team.rosterAutoSort( 5, // tid: team ID false // onlyNewPlayers - only sort newly acquired players ); // This automatically: // 1. Gets all players on team // 2. Ranks players by value at each position // 3. Sets optimal depth chart // 4. Updates rosterOrder field for each player // 5. Ensures starters are listed first // 6. Saves all changes to database // For football, includes position-specific depth charts: // QB, RB, WR, TE, OL, DL, LB, CB, S, K, P, KR, PR // For hockey: F (forward), D (defense), G (goalie) // For baseball: L (lineup), LP (lineup vs LHP), // D (defense), DP (defense vs LHP), P (pitchers) ``` -------------------------------- ### Calculate Player Market Value (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt This function calculates the estimated market value of a player based on their current ratings, potential, age, and contract status. It supports options to add randomness, ignore potential, consider contract details, and value for specific positions. The output is a numerical representation of market value. ```typescript import { player } from "./worker/core"; // Calculate player value based on ratings and age const p = await idb.cache.players.get(123); const value = player.value(p, { fuzz: true, // Add randomness to value noPot: false, // Ignore potential, only current ability withContract: false, // Consider contract in valuation onlyPos: undefined // Only value for specific position }); // Value returned is a number representing market value // Higher values = more valuable players // Factors considered: // - Overall rating (ovr) // - Potential rating (pot) // - Age // - Skills // - Contract (if withContract=true) // Calculate composite rating for specific skill const usageRating = player.compositeRating( p.ratings[p.ratings.length - 1], ['hgt', 'spd', 'jmp', 'drb', 'pss'], // component ratings [1, 1, 0.5, 0.5, 0.5], // weights 1.0 // modifier ); ``` -------------------------------- ### Calculate Team Overall Rating (TypeScript) Source: https://context7.com/zengm-games/zengm/llms.txt This function calculates the overall strength of a team based on its roster of players. It considers factors like top player performance at each position, team depth, player synergy, and position balance. It can also calculate strength metrics for specific positions and differentiate between regular season and playoff performance. ```typescript import { team } from "./worker/core"; // Get all players on team const players = await idb.cache.players.indexGetAll( 'playersByTid', 5 // team ID ); // Calculate team overall rating const teamOvr = team.ovr(players, { playoffs: false, // Use playoff rotations? }); // Returns numeric overall rating (0-100 scale typically) // Considers: // - Top players at each position // - Depth // - Synergy between players // - Position balance // Calculate position-specific strength const ovrByPos = team.ovrByPos(players); // Returns object like: // { // C: 75, // PF: 82, // SF: 88, // SG: 79, // PG: 85 // } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.