A TypeScript SDK for programmatically generating Civilization VII mods with strongly-typed builders and comprehensive game data modeling.
- Strongly typed builders for units, civilizations, constructibles, and more
- Full control over XML generation and mod structure
- Comprehensive constants for game entities (units, abilities, effects, etc.)
- Localization support with multiple language options
- Import utilities for SQL files and custom assets
bun add @mateicanavra/civ7-sdkimport { Mod, UnitBuilder, ACTION_GROUP_BUNDLE, UNIT_CLASS, UNIT } from '@mateicanavra/civ7-sdk';
const mod = new Mod({
id: 'my-first-mod',
version: '1.0.0',
});
const unit = new UnitBuilder({
actionGroupBundle: ACTION_GROUP_BUNDLE.AGE_ANTIQUITY,
typeTags: [UNIT_CLASS.RECON, UNIT_CLASS.RECON_ABILITIES],
unit: {
unitType: 'UNIT_CUSTOM_SCOUT',
baseMoves: 2,
baseSightRange: 10,
},
unitCost: { cost: 20 },
unitStat: { combat: 0 },
unitReplace: { replacesUnitType: UNIT.SCOUT },
visualRemap: { to: UNIT.ARMY_COMMANDER },
localizations: [
{ name: 'Custom Scout', description: 'An enhanced scout unit' }
],
});
mod.add([unit]).build('./my-mod');UnitBuilder- Create custom units with stats, costs, and abilitiesCivilizationBuilder- Define new civilizations with unique traitsCivilizationUnlockBuilder- Set civilization-specific unlocksLeaderUnlockBuilder- Configure leader bonuses and abilitiesConstructibleBuilder- Create buildings and improvementsUniqueQuarterBuilder- Design unique districtsProgressionTreeBuilder- Build civic and tech treesTraditionBuilder- Add new policy cardsModifierBuilder- Create game modifiers and effectsImportFileBuilder- Import SQL files and custom assets
- Great People builders
- Wonder builders
- Unit ability builders
All builders follow a consistent pattern:
const builder = new SomeBuilder({
// Configuration options
});
// Add to mod
mod.add([builder]);
// Or get the generated nodes for manual manipulation
const nodes = builder.getNodes();For complete control, you can work directly with nodes:
import {
Mod,
UnitNode,
DatabaseNode,
TypeNode,
XmlFile,
KIND,
ACTION_GROUP,
ACTION_GROUP_ACTION
} from '@mateicanavra/civ7-sdk';
const mod = new Mod({
id: 'manual-mod',
version: '1.0.0',
});
const unit = new UnitNode({
unitType: 'UNIT_CUSTOM_SCOUT',
baseMoves: 2,
baseSightRange: 10,
});
const database = new DatabaseNode({
types: [
new TypeNode({ type: unit.unitType, kind: KIND.UNIT })
],
units: [unit]
});
const unitFile = new XmlFile({
path: `/units/${unit.unitType}.xml`,
name: 'unit.xml',
content: database.toXmlElement(),
actionGroups: [ACTION_GROUP.AGE_ANTIQUITY_CURRENT],
actionGroupActions: [ACTION_GROUP_ACTION.UPDATE_DATABASE]
});
mod.addFiles([unitFile]).build('./my-mod');import { CivilizationBuilder } from '@mateicanavra/civ7-sdk';
const gondor = new CivilizationBuilder({
civilization: {
civilizationType: 'CIVILIZATION_GONDOR',
name: 'Gondor',
// ... configuration
},
// ... traits, city names, etc.
});import { ImportFileBuilder } from '@mateicanavra/civ7-sdk';
const icon = new ImportFileBuilder({
source: './assets/my-icon.png',
destination: 'UI/Icons/my-icon.dds',
});import { ProgressionTreeBuilder } from '@mateicanavra/civ7-sdk';
const civicsTree = new ProgressionTreeBuilder({
tree: {
treeType: 'PROGRESSIONTREE_CIVICS_GONDOR',
age: 'AGE_ANTIQUITY',
// ... configuration
},
nodes: [
// ... tree nodes
],
});The SDK provides comprehensive type definitions for all game constants:
import {
UNIT, // All unit types
ABILITY, // All abilities
EFFECT, // All effects
TERRAIN, // All terrain types
RESOURCE, // All resources
CIVILIZATION_DOMAIN, // Civilization domains
// ... many more
} from '@mateicanavra/civ7-sdk';Built-in support for multiple languages:
const builder = new UnitBuilder({
// ... configuration
localizations: [
{ language: 'en_US', name: 'Custom Unit', description: 'Description' },
{ language: 'fr_FR', name: 'Unité Personnalisée', description: 'Description' },
],
});Map-loader entries opt into the Civ7 runtime through the ESM-only
@mateicanavra/civ7-sdk/mapgen subpath. A recipe with product-owned initial
state must declare the exact generated Civ7 option descriptors it needs and
provide a projector from the detached one-shot capture into its inferred setup
input:
import { createMap } from "@mateicanavra/civ7-sdk/mapgen";
createMap({
id: "my-map",
name: "My Map",
recipe,
config,
initialSetup: {
requestedMapOptions,
requestedGameOptions,
requestedPlayerOptions,
project: projectInitialSetup,
},
});The requested arrays contain the generated Civ7 setup-option descriptors from
@civ7/map-policy/setup, not manually maintained configuration-key strings.
Evidence remains keyed by the authored parameter ID while the adapter uses each
descriptor's admitted physical read key. Player evidence contains one row per
alive-major player in the engine's observed order and never invents unavailable
leader, civilization, team, difficulty, or memento values.
The SDK compiles the recipe before constructing its execution context, then
inspects its exact admitted initial setup and behavior fingerprint, emits that
plan evidence, and executes the same compiled plan. Failed compilation emits no
run evidence. Recipes that use only Core's physical map setup may omit
initialSetup; the SDK projects map seed, dimensions, and latitude bounds
directly.
For detailed API documentation, see:
- TECHNICAL_GUIDE.md - In-depth technical documentation
- TypeScript API - Full type definitions
This SDK is part of the civ7-modding-tools monorepo. Contributions are welcome!
MIT