Skip to main content

Overview

Utopia Fleet Builder stores all Star Trek Attack Wing game data as JavaScript modules in src/data/. During the build process, these modules are compiled into a single data.json file that the application loads.
The data generation process is defined in src/data/index.js and executed via npm run data.

Data Architecture

Data Modules

The data directory contains the following modules:
src/data/
├── index.js                  # Data generation script
├── sets.js                   # Expansion sets and releases
├── rulings.js                # Official game rulings
├── missionSets.js            # Mission set definitions
├── missions.js               # Mission cards
├── ships.js                  # Ship cards (239 KB)
├── ship_classes.js           # Ship class definitions
├── captains.js               # Captain cards (180 KB)
├── admirals.js               # Admiral cards
├── ambassadors.js            # Ambassador cards
├── upgrades.js               # Upgrade cards (701 KB)
├── starship_construction.js  # Construction rules
├── resources.js              # Resource cards
└── others.js                 # Miscellaneous cards

Data Generation Process

The src/data/index.js script compiles all data modules:
src/data/index.js
var fs = require("fs");
var path = require("path");

var data = {
  sets: require("./sets"),
  rulings: require("./rulings"),
  missionSets: require("./missionSets"),
  missions: require("./missions"),
  ships: require("./ships"),
  shipClasses: require("./ship_classes"),
  captains: require("./captains"),
  admirals: require("./admirals"),
  ambassadors: require("./ambassadors"),
  upgrades: require("./upgrades"),
  starship_construction: require("./starship_construction"),
  resources: require("./resources"),
  others: require("./others")
};

let dataDir = path.resolve(__dirname, "../../staw-utopia/data");
let filepath = path.resolve(__dirname, `${dataDir}/data.json`);

// Create the folder if it doesn't exist
if(!fs.existsSync(dataDir)) {
  fs.mkdirSync(dataDir, { recursive: true });
}

fs.writeFileSync(filepath, JSON.stringify(data));
Process:
  1. Requires each data module
  2. Combines them into a single object
  3. Creates staw-utopia/data/ directory if needed
  4. Writes the complete data as JSON

Card Data Structure

Ships

Ship cards contain specifications and abilities:
Example Ship Card
{
  type: "ship",
  id: "S415",                          // Unique identifier
  gameId: 1,                            // Game system ID
  set: ["75016"],                       // Expansion set(s)
  name: "U.S.S. Atlas",                 // Ship name
  image: "https://i.imgur.com/w2HBtk3.png",
  class: "Sovereign Class",
  actions: [                            // Available actions
    "evade",
    "target-lock",
    "scan",
    "battlestations"
  ],
  upgrades: [                           // Upgrade slots
    "tech",
    "weapon",
    "weapon",
    "crew",
    "crew"
  ],
  attack: 5,                            // Attack value
  agility: 1,                           // Agility value
  hull: 5,                              // Hull points
  shields: 5,                           // Shield points
  cost: 29,                             // Squadron points
  text: "<b>WHENEVER THIS SHIP...</b>", // Card text with HTML
  unique: true,                         // Unique card (one per fleet)
  alliance: false,                      // Alliance card
  factions: ["federation"],             // Allowed factions
  intercept: {                          // Special rules
    ship: {},
    fleet: {}
  },
  squadron: false                       // Squadron card
}
PropertyTypeDescription
idstringUnique identifier (e.g., “S415”)
namestringShip name
classstringShip class
attacknumberAttack value
agilitynumberAgility value
hullnumberHull points
shieldsnumberShield points
costnumberSquadron point cost
actionsarrayAvailable actions
upgradesarrayUpgrade slot types
factionsarrayAllowed faction(s)
Standard actions available to ships:
  • evade - Evade action
  • target-lock - Target Lock action
  • scan - Scan action
  • battlestations - Battle Stations action
  • cloak - Cloak action
  • sensor-echo - Sensor Echo action
  • regenerate - Regenerate action
Types of upgrade slots:
  • weapon - Weapon upgrades
  • crew - Crew upgrades
  • tech - Tech upgrades
  • talent - Talent upgrades
  • borg - Borg upgrades
  • admiral - Admiral slot
  • ambassador - Ambassador slot

Captains

Captain cards define ship commanders:
Example Captain
{
  type: "captain",
  id: "C123",
  set: ["75001"],
  name: "Jean-Luc Picard",
  image: "https://i.imgur.com/...",
  skill: 8,                    // Captain skill
  talent: 3,                   // Talent slots
  cost: 6,
  text: "Captain ability...",
  unique: true,
  factions: ["federation"],
  restrictions: {
    // Card restrictions
  }
}

Upgrades

Upgrade cards enhance ships:
Example Upgrade
{
  type: "upgrade",
  upgradeType: "weapon",       // Type of upgrade
  id: "U456",
  set: ["75001"],
  name: "Photon Torpedoes",
  image: "https://i.imgur.com/...",
  attack: 5,                   // Attack value (if weapon)
  range: "2-3",                // Range (if weapon)
  cost: 6,
  text: "Weapon ability...",
  unique: false,
  factions: ["federation", "klingon"],
  restrictions: {
    // Restrictions on usage
  }
}

Faction System

Cards belong to one or more factions:
Factions
[
  "federation",
  "klingon",
  "romulan",
  "dominion",
  "borg",
  "independent",
  "bajoran",
  "kazon",
  "vulcan",
  "species-8472"
]
Multi-faction cards can be used by any of their listed factions.

Set System

Each card references expansion sets by ID:
Example Set Definition
{
  id: "75016",
  name: "Sovereign Class Enterprise-E",
  wave: "Wave 16",
  releaseDate: "2015-09-01",
  type: "expansion"
}

Adding New Data

1

Choose the Correct Module

Determine which data file to edit:
  • Ships → ships.js
  • Captains → captains.js
  • Upgrades → upgrades.js
  • etc.
2

Follow the Structure

Copy an existing entry and modify it. Ensure all required fields are present:
{
  type: "ship",           // Required
  id: "S999",             // Required: Unique ID
  name: "New Ship",       // Required
  cost: 30,               // Required
  // ... other properties
}
3

Use Proper ID Format

Follow the ID conventions:
  • Ships: S### (e.g., S415)
  • Captains: C### (e.g., C123)
  • Upgrades: U### (e.g., U456)
  • Resources: R### (e.g., R001)
4

Include HTML in Text

Card text supports HTML formatting:
text: "<b>ACTION:</b> Discard this card to ..."
Use <b> for bold, <br> for line breaks, <hr> for separators.
5

Lint and Generate

Run the data build process:
npm run data
This will:
  1. Run ESLint to check syntax
  2. Generate data.json
  3. Report any errors
6

Test the Changes

Build the application and verify the new card appears:
npm start
npm run serve
Check that the card displays correctly in the builder.

Data Validation

ESLint Configuration

Data files are linted with ESLint using the configuration in src/data/.eslintrc:
npm run lint-data
ESLint automatically fixes many issues (semicolons, quotes, etc.). Check the output for unfixable errors.

Common Validation Errors

Error: Card is missing id, name, type, or cost.Solution: Ensure all required fields are present.
Error: Two cards have the same ID.Solution: Use a unique ID for each card. Check existing cards to avoid conflicts.
Error: Faction name is misspelled or not recognized.Solution: Use exact faction names from the list above.
Error: ESLint reports parsing errors.Solution: Check for:
  • Missing commas between properties
  • Unclosed brackets or braces
  • Unescaped quotes in strings

Data File Sizes

The data files are substantial:

upgrades.js

701 KBLargest data file

ships.js

240 KBSecond largest

captains.js

180 KBThird largest
When editing large data files, use an editor with good JavaScript support to avoid performance issues.

Viewing Generated Data

The compiled staw-utopia/data/data.json file is minified (no formatting). To inspect it:

Using jq (Command Line)

jq . staw-utopia/data/data.json | less

Using Online Tools

  1. Copy the contents of data.json
  2. Paste into a JSON formatter like:

Using Code Editor

Most editors can format JSON:
  • VS Code: Right-click → “Format Document”
  • Notepad++: Plugins → JSTool → JSFormat

Performance Considerations

1

Keep Data Normalized

Avoid duplicating information across cards. Reference sets, classes, and other shared data by ID.
2

Optimize Images

Use external image URLs rather than embedding images in the data.
3

Minimize Text Length

Keep card text concise while maintaining clarity.
4

Use Efficient Formats

Arrays are more efficient than objects for lists of cards.

Next Steps

Contributing

Learn how to submit your data changes

Build Process

Understanding how data is built

Build docs developers (and LLMs) love