Skip to content
 
 

Repository files navigation

IVA Forge

🇪🇸 Léelo en español — this page, in Spanish.

Edit the interior (IVA) of your Kerbal Space Program cockpits in your browser — no Unity needed.

IVA Forge bakes a 3D catalog of the crew cabins already installed in your game, lets you drag, rotate and scale props onto the real cockpit hull with what-you-see-is-what-you-get feedback, and writes your changes back as a ModuleManager patch — with a backup and one-click undo. It never touches the original files of Squad or any mod.

The catalog lists the crew cabins of your install, mod by mod; for a part with several interiors, the IVA Switch subtype your game loads is marked in green

A cabin as your game builds it: the real interior, and the exterior hull of the part drawn around it — fly out through the hull and back in

Selecting, deleting and placing props: pick one from the library and drop it on the console — it goes in facing you and magnetizes to the interior skin — and Ctrl+Z brings back whatever you deleted

Moving, rotating and scaling with the gizmos: grid snap, the ratio toggle that keeps the prop's proportions, and the magnet that keeps it on the visible skin

Status: v1.0.0 releaseddownload. Windows-only, KSP 1.12.x. Tested against a limited modlist — please report cabins that fail to bake (see Troubleshooting).


Why this exists

Today the only way to re-decorate an IVA is Unity 2019.4.18f1 + PartTools: a heavy, fragile setup that the community itself calls "extremely tedious", or editing the .cfg by hand and relaunching the game to see every change. IVA Forge replaces that loop with a browser editor and a game-accurate 3D preview, so you iterate without opening Unity and without restarting KSP for each tweak.

Features

  • 3D cabin viewer — walk any installed crew cabin from the pilot's eye. Real hull, real props, real prop textures and RPM/MAS labels baked from your install.
  • WYSIWYG prop editor — drag-and-drop from a searchable prop library sorted into 16 shelves by what a prop is (monitors, annunciators, knobs, flight controls, seats, hatches…); move/rotate/scale gizmos with snap and a ratio toggle that keeps a prop's proportions while you resize it; props go in facing you and magnetize to the visible interior skin, so they sit on the wall instead of floating or sinking into it. Copy, cut and paste with Ctrl+C/Ctrl+X/Ctrl+V — a whole selection pastes as one block, keeping its relative layout, even in a different cabin.
  • Nothing is committed until you say so — the editor's buttons are grouped into Design (save · load saved · restore original · clear all) and Apply & share. Restore original puts the cabin back exactly as its mod ships it, without touching your saved design or the game.
  • IVA Switch aware — every interior in a part's IVA Switch menu is baked and listed with the same name the game shows, with the one your install currently loads marked. Open a variant your game is not loading and the viewer says so, before you spend an evening editing an interior that never appears in flight — and Activate this variant makes it the one the part is created with, from the browser, with an undo (it takes effect next time you start KSP).
  • Apply with backup & undo — one button writes a ModuleManager patch to GameData/IVAForge/patches/. Every write is backed up first; undo from the toast, or revert everything later. Optionally launches KSP for you.
  • .ivalayout sharing — export a cabin layout as a small JSON file (like a .craft), share it on the forum, import someone else's. No assets inside — only references by prop name, with a report of which mods you are missing.
  • Share your whole setup — one file with the interior each part loads, your calibrations, your cabin layouts and your favourites, plus the mods it needs and the version you have. Importing it shows a report first (missing mods, different versions, your own edits that would be replaced), applies only what differs, and has a clean undo. Format: docs/setup-format.md.
  • Favourites — a star next to any cabin marks the ones you actually work on. It changes nothing in the game and it travels inside the shared setup file.
  • i18n (English / Spanish) — full UI and messages, switchable in the app. English is the base and fallback.
  • 100% local, no network access — everything runs on 127.0.0.1; the tool never phones home. Nothing you edit leaves your machine.

No asset redistribution

Everything you see is generated from YOUR install. IVA Forge ships only its own code and calibration data — no meshes, no textures, no cockpit .cfgs from Squad or any mod. The first time you run it, it bakes the catalog by reading the GameData you already own. Nothing from Squad, ASET, RPM, MAS, SSPX or any other mod is included in the download or the repository. This keeps the tool legal and respects the licenses of the props it renders.

Requirements

  • Windows. (Linux/macOS are not supported in v1 — the pipeline uses Windows paths and APIs. Ask if you want them.)
  • Kerbal Space Program 1.12.x. This is the final KSP 1 release; no other version is targeted.
  • ModuleManager installed in your GameData. IVA Forge writes MM patches; it does not bundle ModuleManager — install it from its thread or via CKAN. The tool detects it and warns if it is missing.
  • Disk space: ~1.5 GB free where you unzip it. The tool itself is small, but the catalog it bakes from your install is not: about 1 GB for a typical modded GameData (cabin bundles, the shared texture atlas and the prop library), all of it under catalog/ and deletable at any time — it is regenerated on demand.
  • No Python needed. The release ships its own embedded Python runtime (bundled in the zip, under runtime/), so double-clicking IVAForge.bat just works — nothing to install, no terminal. Running from source (developers/contributors) is the only path that needs your own Python 3 + pip install -r requirements.txt — see Running from source.

Install

  1. Download the latest release and unzip it anywhere (Documents, Desktop — not inside GameData).
  2. Make sure ModuleManager is in your KSP GameData.
  3. That's it. There is no installer, and no Python to install — the runtime is inside the zip.

Quickstart

  1. Double-click IVAForge.bat. It starts the local bridge (a minimized console window you can close to quit) and opens the catalog in your browser. You never touch a terminal.
  2. First run: point it at KSP. If your install isn't auto-detected, a config page opens in the browser — pick your KSP folder (the one that contains GameData/ and buildID.txt).
  3. First bake. The tool bakes the catalog from your GameData with a progress bar ("N/M cabins · current · estimated time"), then bakes the prop library. Budget roughly 10-15 minutes and ~1 GB of disk for a typical modded install — it runs once, and later runs only re-bake what actually changed (seconds).
  4. Edit. Open a cabin, switch to editor mode, drag props onto the hull, tweak with the gizmos.
  5. Apply. Click Apply to game. IVA Forge backs up, writes the MM patch to GameData/IVAForge/patches/, and shows a toast with an Undo button. Launch KSP (optionally from the same button) and check your IVA.

Running from source

Contributors and anyone who prefers their own interpreter can skip the bundled runtime:

pip install -r requirements.txt        # numpy, Pillow, matplotlib
python src/serve_catalog.py            # start the bridge, then open http://127.0.0.1:8760/index.html

IVAForge.bat also falls back to your system Python automatically when no runtime/ folder is present (developer checkout). To rebuild the shippable embedded runtime from python.org's official embeddable package, run python packaging/make_runtime.py (Windows; downloads ~11 MB and installs the deps into runtime/). The runtime/ folder is git-ignored — it is built, not committed.

Uninstall

Delete the folder GameData/IVAForge/ from your KSP install. That removes every patch IVA Forge wrote; the original Squad/mod files were never modified. Your backups live in the tool's own backups/ folder (outside GameData) and are never deleted automatically — remove them by hand if you want. To remove the tool itself, delete the folder you unzipped.

Troubleshooting

  • KSP not detected → the browser opens a config page. Enter the KSP folder that contains GameData/ and buildID.txt. It's saved for next time.
  • A cabin shows "unsupported" → its bake failed (an unusual shader or texture format in that mod). The catalog keeps working; that one cabin is skipped. The full error is in catalog/bake_log.txt — please open an issue and attach it (see Contributing).
  • A cabin is marked ⚠ out of date → its baked data is older than the current generator or than its own source files (a partial or interrupted bake). The red bar at the top counts them and tells you how to fix it: re-bake. If the badge survives a re-bake, it is your browser's cache — reload with Ctrl+F5.
  • "ModuleManager not found" warning → install ModuleManager in GameData and re-bake.
  • The bridge window closed / port busy → close any leftover minimized "IVA Forge" console and double-click IVAForge.bat again.

Contributing

Thanks for helping. There are four low-friction ways to contribute that don't require touching the tool's code: calibration data, prop-face corrections, translations, and unsupported-cabin reports. Code PRs are welcome too — be honest about the modlist you tested against so issues can be reproduced.

The code is GPLv3; the calibration data is CC-BY-4.0. By contributing you agree your contribution ships under the same license as the part of the project it lands in.

1. Calibrate a cabin (data, no code)

Calibration data tells the viewer how to place and orient a cabin's exterior hull and its skin texture so the interior renders correctly. These 95 tuned cabins are the project's shared asset, and they live as versioned JSON — you can contribute one without touching any code.

The tool writes the file for you. You do not have to hand-write JSON:

  1. Calibrate a cabin in the viewer with the usual controls (hull orientation / scale / position, skin texture). Every click is remembered in your browser, cabin by cabin.
  2. Go back to the catalog (the page that lists mods and parts). A blue contribute bar appears at the top as soon as you have something to send, and it tells you how much: "You have 3 calibration(s) that this catalog does NOT ship yet, from 1 mod(s)." Type your nick there once — the data ships under CC-BY-4.0, so it needs attribution. It's remembered and lands in the file (and in the credits).
  3. Export the whole mod — each mod you have calibrated shows a 3 to send badge next to its name and an export calibrations button, so you calibrate 12 Bluedog cabins and send one file, not twelve — or one cabin, from its own row in the catalog and from the viewer's Contribute calibration block, right after tuning it. If a mod or cabin has nothing calibrated in your browser, no button is drawn: there is nothing to send.
  4. The counter only asks for what is still missing. Once a maintainer merges your calibration and you update, the value the catalog bakes matches yours and that cabin stops counting — the badge turns into a quiet N already included. (The catalog knows because every bake publishes its effective calibration per cabin in manifest.js.) When the values differ, the bar names the cabin and shows both, yours and the catalog's, so you can judge before sending. The newer value wins: if the catalog took in a different value after you calibrated that cabin — one you never got to see — nothing is asked, the cabin is marked superseded by the catalog and your measurement is kept. What is asked about is the opposite case: you saw the catalog's value and changed it deliberately. That is a real conflict, it is named, and a keep the catalog's button lets you drop your own note instead.
  5. Drop the file into calibrations/ to use it immediately, and attach it to an issue or pull request so it ships with the next release.

Both routes produce exactly the same file for the same data (they share one code path), and the export lives in localStorage, so it is per-browser and per-origin: what you calibrate opening index.html directly (file://) is not the same store as what you calibrate through the local server (http://127.0.0.1). Export before switching.

Only what you actually adjusted is exported. A cabin is included only if you pressed a calibration control in it — opening it, looking at it or flying around inside does not count. Within a cabin, only the field groups you touched are emitted, and a value that is the default and was already the default is dropped as a no-op. Reason: an entry full of default values would claim that somebody checked that cabin and found it fine. Nobody did, and that false entry would be treated as verified forever. A missing cabin is recoverable; a fabricated one is not.

The exported numbers come from the same code path as the on-screen readouts, and the button validates the schema (types, ranges, legal 90° steps and texture letters) before the download — and again on the serialized text — so a hull_scale: "1.02" fails on your screen instead of on someone else's bake.

Where the data lives

calibrations/ holds one .json per source mod (e.g. squad.json, nearfuturespacecraft.json). That's the natural unit of contribution: whoever calibrates a mod's cabins edits a single file. The loader reads all .json files in the directory, in alphabetical order, and the last file that defines a field wins — so the filename matters:

Filename What it is Rule
<mod>.json Canonical repo file One mod, one file. Two canonical files defining the same field of the same INTERNAL is a collision and is reported as an error.
zz-contrib-<mod>[-<internal>]-<nick>.json Contribution (what the export button produces) The zz- prefix sorts last, so it deliberately overrides the bundled data — you can test a calibration somebody sent you without editing anything. Every field it overrides is reported.

Audit the directory with python src/build_catalog.py --check-calib (collisions, schema, missing mods; exit code 2 if anything is wrong). A normal bake prints the same report but never aborts.

The exported file also declares which mod its cabins come from (required_mods, same pattern as .ivalayout). Without that mod installed the file is inert: its keys are INTERNAL names that don't exist in that GameData, so nothing matches — no effect, no error, no polluted catalog. The mod version is recorded when available, so it's visible when a mod re-exports its models and the calibration goes stale.

The format

Each file is:

{
  "_format": "ivaforge-calibration/2",
  "_mod": "SquadExpansion",
  "_mod_label": "Making History",
  "_license": "CC-BY-4.0",
  "cabins": {
    "<INTERNAL name>": {
      "hull_orient": ["Z+"],
      "hull_recenter": true,
      "hull_scale": 1.126,
      "hull_offset": [-0.08, 0.0, 0.04],
      "cam_up": [0.0, 0.0, 1.0],
      "note": "why this was calibrated this way"
    }
  }
}

The key of each cabin is its INTERNAL name (the cabin id). Every field is optional — a cabin lists only what it needs; anything missing uses the sane default. Common fields:

Field Meaning
hull_orient Extra 90° steps (X+ X- Y+ Y- Z+ Z-) on top of the base orientation, for hulls that still come out rotated. Most cabins need none.
hull_recenter Re-center the hull on the interior skin's centroid.
hull_scale Scale the hull to swallow interior-liner corners that poke through.
hull_offset [x,y,z] position nudge, in metres, applied last.
cam_up Force the camera "up" when the seat-derived heuristic fails.
deploy_clip Name of the deploy animation clip for expandable habitats.
skin_hide_mesh Skin transforms to hide (packed-state geometry).
skin_uv_xform Skin texture orientation (AI; A = identity).
note Provenance — why you chose these values. Informational.

All axes are scene axes (Z already mirrored), in metres. A full field reference lives in calibrations/README.md.

Format version. _format is ivaforge-calibration/2. Files written for /1 are migrated automatically when loaded (/1 assumed the part-to-interior base rotation was Rx(-90), so every cabin had to patch KSP's extra 180° spin by hand; /2 puts that spin in the base, where it belongs). The migration is a pure re-expression: same hull, same pose. Cabins that had no hull_orient are left alone on purpose — a missing field means "nobody checked", not "checked, nothing needed".

By hand (only if you need a field the buttons don't cover)

cam_up, deploy_clip, skin_hide_mesh and skin_xf_live have no live control, so they can only be written by hand. In that case: add or edit the cabin's entry (by its INTERNAL name) in the matching <mod>.json, fill only the fields you need, add a note explaining the values, and open a PR with just the data — no code changes.

The loader degrades gracefully: a missing directory or a corrupt file emits a warning and is skipped (those cabins fall back to default behaviour), never a crash.

2. Correct which way a prop faces (data, no code)

When you drag a prop in, IVA Forge turns its useful face — screen, buttons, printed labels — towards you. It works that out from the prop's own config: the screen transform of an RPM/MAS monitor, or the transform of its label, because the text is painted on the side you are meant to read. About a third of the library declares neither, and for those the tool has to guess.

When a prop comes in backwards, the fix belongs in propfaces/, and it is data, not code:

{
  "_format": "ivaforge-propfaces/1",
  "props": {
    "ALCORFoodStation": { "face": "-Z", "up": "+Y", "note": "checked in the editor, both sides" }
  }
}

face is the axis that must point at the viewer (+X … -Z); up is optional and only needed if the prop also comes in sideways. Every *.json in the folder is read in alphabetical order and later files win field by field, so you can keep your own next to the shipped ones without editing them. Full reference and the rules in propfaces/README.md.

An entry is a statement that somebody looked. Never fill it in from a hunch: a listed prop ignores the evidence its config actually had, so a wrong entry is worse than no entry. A prop nobody has checked keeps the old behaviour rather than being flipped on a guess. Editing this folder re-bakes only the props you touched, in about a second — cabins are not re-baked.

3. Add a language

The UI and messages are driven by one pair of dictionaries: locales/en.json (the base and fallback) and locales/es.json. To add a language:

  1. Copy locales/en.json to locales/<code>.json (e.g. de.json, fr.json).

  2. Translate the values. Do not change the keys. Leave technical game names, prop/part identifiers, and machine/protocol strings untranslated — they are identifiers, not prose.

  3. Keep parity: every language must have exactly the same keys as English. Run the parity check and make sure it passes:

    python src/i18n.py
    

    It prints the key count per language and fails if the sets differ.

  4. Open a PR with the new locale file (and the parity check green).

English remains the fallback: any key you leave untranslated shows the English text rather than a blank.

4. Report an unsupported cabin

If a cabin bakes as unsupported, the pipeline hit a shader or texture format it didn't expect in that mod. That's a bug worth reporting:

  1. Reproduce the bake (or just open the index — the cabin has an "unsupported" badge with a tooltip).
  2. Grab catalog/bake_log.txt — it has the full traceback for the failed cabin.
  3. Open an issue with: the mod and cabin name, your KSP version, and the relevant slice of the bake log attached. Mention any unusual texture/shader mods in your GameData.

These reports are how the pipeline learns to handle GameData combinations beyond the ones already tested.

5. Working on the tool itself

Touching the viewer's code invalidates every cabin, so a one-line change means a full re-bake (~9 minutes on a typical modded install) before you can look at it. The working set cuts that to seconds:

python src/build_catalog.py --work <internal>[,<internal>...]   # from now on, bake only these
python src/build_catalog.py --work-add <internal>[,...]         # add to the set and bake
python src/build_catalog.py --work-show                         # what is in the set (does not bake)
python src/build_catalog.py --work-clear                        # drop it (next bake is full again)
python src/build_catalog.py --all                               # one-off full bake, set untouched

With three cabins in the set the edit-look cycle is about 30 seconds. The set is deliberately loud about what it skips: every cabin it leaves behind is flagged ⚠ out of date in the index, so a partially baked catalog can never be mistaken for a complete one. Clear the set before measuring anything about the catalog as a whole.

Both READMEs are one document in two languages: any change here goes into README.es.md in the same commit.

Licensing

  • Code: GPLv3. Distributed forks must stay open — consistent with the IVA niche (ModuleManager, RPM and FreeIVA are GPL). The full license text ships in the download.
  • Calibration data (calibrations/): CC-BY-4.0. Open data with attribution; contribute yours by PR.
  • Bundled third party: three.js r128, MIT. The 3D renderer behind the viewer, shipped unmodified in vendor/three.min.js (its license header travels inside the file) and copied into the baked catalog at build time.

Credits

Built for the KSP IVA-modding community. Calibration data for 95 cabins across Squad, Making History, Near Future Spacecraft, SSPX and KPBS is the shared asset of the project — see Contributing to calibrate a cabin, add a language, or report an unsupported cabin. Bug reports and PRs welcome; be honest about your modlist so we can reproduce.

Calibrating a cabin takes two clicks to export: the tool writes the data file for you. The catalog shows how many cabins of each mod you have calibrated and exports them all in one file from the mod row (single cabins export from their own row, or from the viewer right after tuning them), with your nick in it. Send it in and it ships with the next release.

Calibration contributors (CC-BY-4.0)

Nick Mods calibrated
LetalDark Squad, SquadExpansion (Making History), Near Future Spacecraft, SSPX, KPBS

(Send a calibration and your nick goes here — that's the attribution CC-BY-4.0 asks for.)

See docs/user-guide.md for the full workflow, docs/ivalayout-format.md for the .ivalayout spec and docs/setup-format.md for the shared-setup package.

About

editing

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages