ZenGM Documentation

repository·master·Indexed 19 days ago

https://github.com/zengm-games/zengm

A suite of single-player sports simulation games (Basketball, Football, Baseball, and Hockey) implemented as client-side web applications. ZenGM uses a Shared Worker architecture to separate core game logic from a React-based UI, utilizing IndexedDB for persistent storage and a custom cache layer for performance. The repository includes tools for simulation analysis, player rating (OVR) modeling, and manual name pool expansion.

Tokens
17.9K
Snippets
58
Records
84
Agent score
66%

What's inside ZenGM

  1. Understand the basketball team overall (team-ovr) analysis datasets

    master

    The analysis/team-ovr-basketball directory contains two JSON datasets used for analyzing basketball team overall performance. These datasets are generated from simulations of 750 seasons.

    • data.json: Contains simulation data for 750 seasons where no playoffs, injuries, deaths, or trades occurred.
    • data-playoffs.json: Contains the same simulation data as data.json, but the game simulation was modified to treat regular season games as if they were playoff games.
  2. Understand the basketball player OVR analysis dataset

    master

    The analysis/player-ovr-basketball directory contains a dataset used for analyzing player overall ratings (OVR). The primary data source is data.csv, which contains over 2000 seasons of exported statistics.

    Note on Data Generation: To ensure the statistical analysis is robust and captures a wide variety of lineup combinations, the seasons in this dataset were simulated using an elevated injury rate of 0.0006. This higher injury rate results in richer +/- (plus/minus) statistics by forcing more frequent changes in player lineups.

  3. Understand the data1.json simulation parameters

    master

    The data1.json dataset used for hockey team overall (ovr) analysis is generated using a specific simulation environment. When interpreting results from this file, note the following simulation constraints:

    • Duration: 100 seasons simulated.
    • No Injuries: Players do not suffer injuries during the simulation.
    • No Deaths: Player mortality is disabled.
    • No Trades: Player movement via trades is disabled.
    • Game Length: Quarters are set to 200 minutes.
  4. Understand the structure of football team overall data files

    master

    The data*.json files used in the analysis/team-ovr-football directory contain simulated data for 200 seasons. Each season consists of 82 games to ensure Margin of Victory (MOV) stability. The exported JSON files are filtered to include only two primary datasets:

    1. players
    2. all team data

    Note that these simulations were performed with no injuries, deaths, or trades.

  5. Understand the ZenGM architecture

    master

    ZenGM games are single-page applications (SPAs) that run almost entirely client-side, using IndexedDB for data storage. The architecture is split into two main parts:

    1. Core Game Logic (src/worker): Runs inside a Shared Worker (or a Web Worker as a fallback). This handles the heavy lifting and data management.
    2. UI Layer (src/ui): Built with React and Bootstrap. Each open browser tab runs only the UI code, which communicates with the Shared Worker using toUI and toWorker functions.

    Data Management and Caching

    While data is stored in IndexedDB, a cache layer implemented in src/worker/db/Cache.ts sits on top of the database for performance.

    Important Caching Rules:

    • The cache is used for simulating games and viewing current data; IndexedDB is reserved for uncommon tasks like viewing historical stats.
    • Cache values are mutable. Avoid accidental mutations.
    • When you intentionally mutate a value (e.g., updating player stats), you must manually write it back to the cache using idb.cache.*.put.
  6. Generate overunder.json using process.py

    master

    The process.py script is used to analyze league data and produce overunder.json. This output file identifies teams that overachieve or underachieve relative to their team ratings. The last two teams in the resulting JSON represent the overachieving and underachieving teams, respectively.

    To achieve accurate results, the process requires multiple 10-year league exports (formatted as FBGM_League_*.json) containing all box scores. Using approximately 6 of these files provides high-quality results for identifying team performance deviations.

    # Note: The script is process.py
    # Input files: FBGM_League_*.json (10-year exports with box scores)
    # Output file: overunder.json
  7. Add new names for a country or group

    master

    To expand the name pool for a specific country or a shared group (e.g., Hispanic names), create two CSV files in the tools/names-manual/ directory. These files provide additional names that are merged with the existing built-in names.

    File Naming Convention

    • For a country: Use country-<Name>-first.csv and country-<Name>-last.csv (replace <Name> with the country name).
    • For a group: Use group-<Name>-first.csv and group-<Name>-last.csv (replace <Name> with the group name).

    CSV Format

    Each file must contain two columns: Name and Frequency. The Frequency represents the relative popularity of the name.

    NameFrequency
    Bob1
    Sam5
    Carl4

    In this example, Sam is 5x as common as Bob, and Carl is 4x as common as Bob.

    Best Practices

    • Frequency: If you are unsure of popularity, set all frequencies to 1.
    • Quantity: To keep the web-based game's file size small, avoid adding more than 500 names per file unless the country is exceptionally large.
    Name,Frequency
    Bob,1
    Sam,5
    Carl,4
  8. Run linting and tests

    master

    The project uses TypeScript and ESLint for code quality. You can run linting and tests for the default sport (basketball) or specify a different sport using the SPORT environment variable.

    • Linting: Runs TypeScript and ESLint checks across the codebase.
    • Testing: Runs integration and unit tests located in *.test.ts files.
    # Run linting
    node --run lint
    
    # Run tests for basketball
    node --run test
    
    # Run tests for football
    SPORT=football node --run test
  9. Analyze player value vs. contract amount

    master

    This analysis is used to inform the trade value algorithm by determining the relationship between a player's contract amount and their overall value (OVR).

    Note on Data Stability: The data used for this analysis is derived from simulations spanning 5 seasons to ensure the values have stabilized.

    Statistical Reference (Rough Visualization Only): The following mean and standard deviation values for player OVR are provided for visualization purposes and should not be used to set algorithm parameters directly.

    Basketball:

    • local.playerOvrMean: 44.88120567375886
    • local.playerOvrStd: 11.120793951909148

    Football:

    • local.playerOvrMean: 45.66901027582477
    • local.playerOvrStd: 12.94063146944189