> Code Tycoon
Modding Legal notice Privacy DE | EN

Modding Guide

Availability: Mod support ships with an upcoming Code Tycoon update. This guide documents the format ahead of release — the layout described below is final, so you can start preparing mods now.

Code Tycoon loads mods from a local folder and from subscribed Steam Workshop items at startup. A mod can change or add game content (programming languages, contract templates, frameworks), override translations, and replace entire UI panels — all data-driven through JSON files, no code required.

Quick start

  1. Open the mods folder (created automatically on first launch): ~/.code-tycoon/mods/ (Windows: C:\Users\<name>\.code-tycoon\mods\) — in general, the mods/ folder next to the game's saves/ directory
  2. Create a subfolder, e.g. mods/my-first-mod/
  3. Add the manifest mod.json (see below)
  4. Put content next to it and start the game — the boot screen shows LOAD MODS ... 1
my-first-mod/
mod.json          required: manifest
data/             optional: balancing content (merged key-wise)
  languages.json
  project_templates.json
  frameworks.json
locales/          optional: translations (merged key-wise)
  en.json
  de.json
ui/               optional: panel layouts (replace the original wholesale)
  desktop.ui.json

mod.json

{
  "id": "my-first-mod",
  "name": "My First Mod",
  "version": "1.0",
  "loadOrder": 0
}
FieldRequiredMeaning
idyesUnique identifier, only a-z A-Z 0-9 _ -. Stamped into savegames — never change it after release!
namenoDisplay name (default: id)
versionnoFree-text version, stamped into savegames
loadOrdernoLoad order, lower loads earlier (default: 0)

Rules: load order, conflicts, errors

  • Order: local mods load first (sorted by loadOrder, then folder name), Workshop mods after them. Later overrides earlier.
  • Duplicate ids: the first loaded mod wins — local mods beat same-id Workshop mods.
  • Broken mods never kill the game start. Invalid files are skipped, logged (game.log in the game directory) and reported in-game as a warning.
  • Savegames record the active mod list. Loading a save without those mods shows a warning.
  • Steam: while mods are active, Steam achievements and leaderboard uploads are disabled. In-game achievements keep working.

Modding content: data/

The three files in data/ are merged key-wise over the base data (the originals live in resources/data/ inside the game installation — use them as a reference for all default values):

  • Patch a known id: specify only the fields you change; the rest stays.
  • Add a new id: the entry must be complete (all fields).
  • Deleting is not possible — entries can only be rebalanced (e.g. an absurd unlockCost).

languages.json — programming languages

{
  "assembler": { "unlockCost": 250 },

  "zig": {
      "name": "Zig", "symbol": "Zg", "level": 0, "xp": 0,
      "unlocked": false, "unlockCost": 9000,
      "releaseYear": 2016, "devSpeed": 1.0, "bugProb": 0.1,
      "learnDifficulty": 7, "maxComplexity": 90, "priceMult": 1.9
  }
}
FieldMeaning
nameDisplay name (a proper name, not a locale key)
symbolShort tag on the language card (2–3 ASCII characters)
level, xpStarting values for a new game (usually 0/0; starter languages 1/0)
unlockedUnlocked from the start?
unlockCostUnlock cost
releaseYearAvailable from this year; also counts toward era goals
devSpeedDevelopment speed multiplier (base data: 0.3–1.4)
bugProbBug probability 0..1 (lower is better)
learnDifficultyLearning effort 1–10 (higher = slower XP progress)
maxComplexityHighest project complexity the language can handle
priceMultPayment multiplier for contracts in this language

New languages appear in the Languages panel automatically. For contracts to use them, at least one template must list them in compatibleLanguages.

project_templates.json — contract templates

A JSON list, matched by id. Field names must match exactly — a row with an unknown field name or missing required fields is skipped and reported in-game as a warning.

[
  { "id": "tpl_website", "basePayment": 2000 },

  { "id": "tpl_gamedev_studio",
    "name": "tpl.gamedev_studio.name", "description": "tpl.gamedev_studio.desc",
    "projectType": "game",
    "minFeatures": 4, "maxFeatures": 8,
    "baseDeadlineDays": 40, "deadlinePerFeature": 4,
    "basePayment": 8000, "paymentPerFeature": 900,
    "earlyCompletionBonus": 500, "lateCompletionPenalty": 400,
    "minComplexity": 5, "maxComplexity": 9,
    "possibleFeatures": [],
    "compatibleLanguages": ["cpp", "csharp", "rust"],
    "availableFromYear": 2000,
    "minOfficeRank": 2, "maxOfficeRank": 4 }
]
FieldMeaning
name, descriptionLocale keys (tpl.<x>.name / .desc) — the texts themselves go into locales/
projectTypeDomain (web, game, ai, mobile, cloud, security, …) — drives specialization bonuses
minFeatures / maxFeaturesFeature range per contract
baseDeadlineDays + deadlinePerFeatureDeadline = base + features × perFeature (game days)
basePayment + paymentPerFeaturePayment = base + features × perFeature + complexity × 100
earlyCompletionBonus / lateCompletionPenaltyBonus/penalty for early/late delivery
minComplexity / maxComplexityComplexity range 1–10
compatibleLanguagesLanguage ids the contract can be built with
availableFromYearAppears on the market from this year
minOfficeRank / maxOfficeRankOffice tiers 0–4 (garage → headquarters)

frameworks.json — frameworks

[
  { "id": "react", "speedBonus": 0.2 },

  { "id": "phpolygon", "languageId": "php", "name": "PHPolygon",
    "year": 2025, "speedBonus": 0.2, "unlockCost": 5000,
    "popularityPeak": 2030, "popularityDecline": 10 }
]
FieldMeaning
languageIdWhich language the framework belongs to
yearAvailable from
speedBonusDevelopment bonus (base data: 0.05–0.20), scales with experience and popularity
unlockCostUnlock cost
popularityPeakYear of peak popularity (full bonus)
popularityDeclineYears after the peak until the bonus starts decaying ~5%/year (floor: 30%)

Modding translations: locales/

locales/<language>.json merges key-wise over the game's translation — same structure as resources/locales/*.json in the game. Use it to add texts for your own content (a new template needs its tpl.* keys) or to override any existing game text.

{
  "tpl": {
      "gamedev_studio": {
          "name": "Game Studio Contract",
          "desc": "A AAA studio needs reinforcements."
      }
  }
}
  • Placeholders in the :name / :count format must be preserved.
  • Untranslated keys fall back to English — for a small mod a single en.json is enough.
  • Supported are the 31 game locales (en, de, fr, …, zh-CN, zh-TW).
  • ASCII-friendly symbols only in UI texts — the engine does not render symbol glyphs (★ ✓ ⚠ become empty boxes).

Modding UI: ui/

ui/<panel>.ui.json replaces the same-named layout from the game's resources/ui/ wholesale (no merge; with several mods, the last one wins). Best practice: copy the original file and modify it. Layouts are declarative widget trees with {"$bind": "..."} data bindings and {"$on": {...}} events — bindings and event names must be preserved; layout, sizes, colors and static texts are yours to change. The design space is 1280×720. Good for rearranging/reskinning existing panels; new panels with new logic are not possible.

Steam Workshop

  • Subscribing (players): subscribe to an item in the Workshop → Steam downloads it to steamapps/workshop/content/4347780/<publishedfileid>/ → on the next game start it loads like a local mod. Unsubscribing removes it again.
  • Publishing (modders): a Workshop item is exactly the mod folder (with mod.json at the top level), uploaded via steamcmd using a VDF build config:
// workshop_item.vdf
"workshopitem"
{
  "appid"           "4347780"
  "publishedfileid" "0"              // 0 = new item, otherwise the assigned id to update
  "contentfolder"   "C:\\path\\to\\my-first-mod"
  "previewfile"     "C:\\path\\to\\preview.png"   // JPG/PNG/GIF, max 1 MB
  "visibility"      "0"              // 0 public, 1 friends only, 2 private, 3 unlisted
  "title"           "My First Mod"
  "description"     "Adds Zig."
  "changenote"      "Initial version"
}

steamcmd +login <account> <password> +workshop_build_item C:\path\to\workshop_item.vdf +quit

Field names and order follow Steam's build config; the VDF path in the call must be absolute. On the first upload Steam prints a publishedfileid — put it into the VDF to update the same item later (rather than re-uploading a new one).

What can't be modded (yet)

AreaWhy
Deleting entriesThe merge can only patch/add; workaround: make it unreachably expensive or availableFromYear: 9999
Skills, eras, events, achievements, officesTheir effects live in game code, not data
New panels / new game logicNo scripting/hook API
Graphics, sounds, fontsNo resource overlay wired up for these

Troubleshooting

SymptomCause / fix
LOAD MODS ... NONEFolder in the wrong place (must be mods/<mod>/mod.json) or invalid manifest
"Mod could not be loaded"mod.json missing / not valid JSON / id invalid or duplicate — details in game.log
"Invalid data file ignored"JSON error (commas, quotes — JSON has no comments) or a typo in a field name
Template shows tpl.x.nameLocale keys missing — add them to locales/en.json
Language without contractsNo template lists the language id in compatibleLanguages
Boxes instead of special charactersSymbol glyphs are not rendered — use ASCII
Steam achievements don't popIntentional while mods are active

Note: list fields (e.g. compatibleLanguages) are replaced wholesale when patching — include the existing values.

> Code Tycoon
Modding Legal notice Privacy

© 2026 Code Tycoon