Modding API

From Cities: Skylines Wiki
Jump to: navigation, search

This article is timeless and should be accurate for any version of the game.


The Modding API is an interface for programmers to override and extend game features. It is presently minimalistic and aims to be so. The available features will evolve alongside user wishes in the future.

The game ships with a C# compiler which allows for automatic script compiling at game start.

The mod user folder is located at:

  • On Windows C:\Users\<username>\AppData\Local\Colossal Order\Cities_Skylines\Addons\Mods
  • On Mac /Users/<username>/Library/Application Support/Colossal Order/Cities_Skylines/Addons/Mods
  • On Linux /home/<username>/.local/share/Colossal Order/Cities_Skylines/Addons/Mods/

Each mod is implemented in a sub-folder of the name of the mod. The sub-folder contains a Source folder where the C# script is situated. When the game starts, it will compile all the files within the Source folder and create a .dll file at the root of the Mod folder. That dll in turn is loaded at runtime and implements the custom behaviors.
The mod implements a set of interfaces defined in the ICities assembly. It is possible to use Microsoft Visual Studio or another programming IDE to compile a dll and bypass the automatic compilation the game provides. The ICities.dll file located at <SteamFolder>\SteamApps\common\Cities_Skylines\Cities_Data\Managed\ICities.dll contains interface definitions. This assembly can be added as a reference to projects within Visual Studio, allowing developers to leverage intellisense when writing mods. Visual Studio can also be used to compile code into assemblies which allows more advanced modding techniques to be used.

The full set of the C# 3.0 language and a subset of the features of C# 4.0 are available, as well as all the functionalities provided by the UnityEngine assembly. When using Visual Studio for compilation, any language version that can be compiled to target .NET Framework 3.5 will do.

Mod can be shared through the Content Manager just like other assets. A check box allows the source code to be embedded in the Workshop item if desired.

Security considerations[edit]

The code in Mods for Cities: Skylines is not executed in a sandbox.
While we trust the gaming community to know how to behave and not upload malicious mods that will intentionally cause damage to users, what is uploaded on the Workshop cannot be controlled.
Like with any files acquired from the internet, caution is recommended when something looks very suspicious.

You can always disable Mods by setting --disableMods in the launch options of the game in your Steam library>Game settings.
This toggle will prevent the game from compiling and loading modded code. However, it might make more sense to just not download any Mods in the first place.
The toggle only applies to Mods involving custom code; assets and non-executable content remain accessible.

Custom options/settings for mods[edit]

Please refer to the page Mod Options Panel if you are looking for details on exposing options/settings in the Options panel for your mod.

Starting a mod[edit]

The first step to creating a mod is to add these lines to the C# file :

using ICities;
using UnityEngine;

Once done, you will want to add a name and a description of the mod.

To do so, the definition class must inherit from IUserMod from the namespace ICities.

Here is an example of a mod definition :


namespace UnlockAllMod {

	public class MyCustomMod : IUserMod {

		public string Name {
			get { return "My mod name"; }
		}

		public string Description {
			get { return "Here is where I define my mod"; }
		}
	}
}


The next step is to implement what you want by overriding the methods provided in the following interfaces: IUserMod, IAreasExtension, IChirperExtension, IDemandExtension, IEconomyExtension, ILevelUpExtension, ILoadingExtension, IMilestonesExtension, ISerializableDataExtension, ITerrainExtension, IThreadingExtension. The created classes and method must inherit from the needed classes. Each interface provides the OnCreated() and OnReleased() callback. These methods are invoked at creation and destruction time but also when recompiling a mod while the game is running. Each interface, targeted for the purpose their name describes also provides an interface to a "manager" in OnCreated() which allows to interact with the game managers directly. So implementing an extension interface provides the callbacks mechanic and the manager reference handle interacting with the game. It can be frustrating to work to the base interfaces as it is required to overload every single method even though you may only need one or just a few of them, for convenience we provide a non-pure abstract implementation of most extensions. IThreadingExtension non-pure counterpart would be ThreadingExtensionBase in example. Inheriting one base class instead of the pure interface will allow you to only override the required methods as well as get access to a IManagers type which links you to all managers, regardless which interface you are in.

Here are the interfaces and a description of what is proposed :

General[edit]

//Thread: Main void OnCreated(<IRelatedManager> instance);

//Thread: Main void OnReleased();

//Thread: Any IManagers managers [] { get; } These functions are in each base class at the exception of IUserMod, and are called respectively at the creation and the destruction of an instance.
The managers getter returns a global storage for each managers available across different extensions.

Official Modding API[edit]

DataTypes[edit]

Service[edit]

enum Service
{
	None,
	Residential,
	Commercial,
	Industrial,
	Citizen,
	Tourism,
	Office,
	Road,
	Electricity,
	Water,
	Beautification,
	Garbage,
	HealthCare,
	PoliceDepartment,
	Education,
	Monument,
	FireDepartment,
	PublicTransport,
}

Enumeration for service types

SubService[edit]

enum SubService
{
	None,
	ResidentialLow,
	ResidentialHigh,
	CommercialLow,
	CommercialHigh,
	IndustrialGeneric,
	IndustrialForestry,
	IndustrialFarming,
	IndustrialOil,
	IndustrialOre,
	PublicTransportBus,
	PublicTransportMetro,
	PublicTransportTrain,
	PublicTransportShip,
	PublicTransportPlane,
}

Enumeration for sub-service types

Level[edit]

enum Level
{
	None,
	Level1,
	Level2,
	Level3,
	Level4,
	Level5,
}

Enumeration for building levels

LoadMode[edit]

enum LoadMode
{
	NewMap,
	LoadMap,
	NewGame,
	LoadGame,
	NewAsset,
	LoadAsset,
}

Enumeration for supported load modes

AppMode[edit]

enum AppMode
{
	Game,
	MapEditor,
	AssetEditor,
}

Enumeration for application modes

IAreas[edit]

IAreas[edit]

Areas/tiles manager

IManagers managers { get; } Thread: Any
Gets global managers interfaces
For more info on IManagers, see #IManagers

int startTileX { get; } Thread: Any
Gets the starting tile X index

int startTileZ { get; } Thread: Any
Gets the starting tile Z index

int unlockedAreaCount { get; } Thread: Any
Gets the current amount of unlocked tiles

int maxAreaCount { get; set; } Thread: Any
Gets/Sets the maximum unlockable tile count. Ranges from 1 to 25

bool IsAreaUnlocked(int x, int z); Thread: Any
Checks if the tile at the given index is unlocked

bool CanUnlockArea(int x, int z); Thread: Any
Checks if the tile at the given index can be unlocked

int GetAreaPrice(int x, int z); Thread: Any
Gets the calculated price of the tile at the given index

void UnlockArea(int x, int z, bool requireMoney); Thread: Any
Unlocks the tile at the given index and specify if money is required to perform unlocking

IAreasExtension[edit]

Pure interface to modify areas/tiles unlocking behaviour

void OnCreated(IAreas areas); Thread: Main
Invoked when the extension initializes
For more info on IAreas, see #IAreas

void OnReleased(); Thread: Main
Invoked when the extension deinitializes

bool OnCanUnlockArea(int x, int z, bool originalResult); Thread: Any
Invoked when the game checks if a tile can be unlocked
Returns true if it can otherwise false
originalResult contains the default estimation from the game

int OnGetAreaPrice(uint ore, uint oil, uint forest, uint fertility, uint water, bool road, bool train, bool ship, bool plane, float landFlatness, int originalPrice); Thread: Any
Invoked when the game calculates the price of a tile
The parameters provide information on resources and outgoing connections service to allow overriding the cost calculation
originalResult contains the default estimation from the game

void OnUnlockArea(int x, int z); Thread: Simulation
Invoked when the game unlocks a tile
Notifies which tile index is being unlocked

AreasExtensionBase[edit]

Base class to derive from to modify areas/tiles unlocking behaviour

IManagers managers { get; } Thread: Any
Gets global managers interfaces
For more info on IManagers, see #IManagers

IAreas areaManager { get; set; } Thread: Any
Gets the area manager interface
For more info on IAreas, see #IAreas

void OnCreated(IAreas areas); Thread: Main
Invoked when the extension initializes

void OnReleased(); Thread: Main
Invoked when the extension deinitializes

bool OnCanUnlockArea(int x, int z, bool originalResult); Thread: Any
Invoked when the game checks if an area can be unlocked
Returns true if it can otherwise false
originalResult contains the default estimation from the game

int OnGetAreaPrice(uint ore, uint oil, uint forest, uint fertility, uint water, bool road, bool train, bool ship, bool plane, float landFlatness, int originalPrice); Thread: Any
Invoked when the game calculates the price of a tile
The parameters provide information on resources and outgoing connections service to allow overriding the cost calculation
originalResult contains the default estimation from the game

void OnUnlockArea(int x, int z); Thread: Simulation
Invoked when the game unlocks a tile
Notifies which tile index is being unlocked

IChirper[edit]

IChirperMessage[edit]

Chirper message

 string senderName { get; }

Name of the sender

 string text { get; }

Content of the chirp message

 uint senderID { get; }

Citizen id of the sender

IChirper[edit]

A lightweight interface to interact with the Chirper

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 Vector2 builtinChirperPosition { get; set; }

Thread: Main
Gets/Sets the position of the Chirper in UI screen coordinates

 bool DestroyBuiltinChirper();

Thread: Main
Exterminate the Chirper :(

 bool ShowBuiltinChirper(bool show);

Thread: Main
Temporarily show or hide the Chirper panel

 bool SetBuiltinChirperFree(bool free);

Thread: Main
Default chirper configuration is to remain centered on the screen, call this method to turn this behaviour on or off

 bool SetBuiltinChirperAnchor(ChirperAnchor anchor);

Thread: Main
Allows to set the anchor of the chirper panel, it will expand considering the anchor does not move
TopLeft causes the chirper to expand toward the BottomRight, BottomCenter toward TopCenter and so forth...

 void SyncMessages();

Thread: Main
Causes the Chirper to synchronize the messages. Will trigger OnMessagesUpdated()

 void DeleteMessage(IChirperMessage message);

Thread: Main
Deletes a Chirper message

IChirperExtension[edit]

Pure interface to modify the Chirper behaviour

 void OnCreated(IChirper chirper);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnUpdate();

Thread: Main
Called once per frame.

 void OnMessagesUpdated();

Thread: Main
Invoked when the Chirper synchronize messages (after loading a save i.e)

 void OnNewMessage(IChirperMessage message);

Thread: Main
Invoked when the Chirper receives a new message

ChirperExtensionBase[edit]

Base class to derive from to modify the Chirper behaviour

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 IChirper chirper { get; set; }

Thread: Any
Gets the chirper manager interface

 void OnCreated(IChirper c);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnMessagesUpdated();

Thread: Main
Invoked when the Chirper synchronize messages (after loading a save i.e)

 void OnUpdate();

Thread: Main
Called once per frame.

 void OnNewMessage(IChirperMessage message);

Thread: Main
Invoked when the Chirper receives a new message

ChirperAnchor[edit]

 enum ChirperAnchor
 {
   TopLeft,
   TopCenter,
   TopRight,
   BottomLeft,
   BottomCenter,
   BottomRight,
 }

Supported chirper anchors

IDemand[edit]

IDemand[edit]

Demand manager

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

IDemandExtension[edit]

Pure interface to modify demand logic

 void OnCreated(IDemand demand);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 int OnCalculateResidentialDemand(int originalDemand);

Thread: Simulation
Invoked when the game calculates residential demand
originalDemand is the demand calculated by the game, return a different value to override it
The demand is in the range 0 to 100

 int OnCalculateCommercialDemand(int originalDemand);

Thread: Simulation
Invoked when the game calculates commercial demand
originalDemand is the demand calculated by the game, return a different value to override it
The demand is in the range 0 to 100

 int OnCalculateWorkplaceDemand(int originalDemand);

Thread: Simulation
Invoked when the game calculates workplace demand
originalDemand is the demand calculated by the game, return a different value to override it
The demand is in the range 0 to 100

 int OnUpdateDemand(int lastDemand, int nextDemand, int targetDemand);

Thread: Simulation
Returns a smoothed demand for each demand type

DemandExtensionBase[edit]

Base class to derive from to modify demand logic

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 IDemand demandManager { get; set; }

Thread: Any
Gets the demand manager interface

 void OnCreated(IDemand demand);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 int OnCalculateResidentialDemand(int originalDemand);

Thread: Simulation
Invoked when the game calculates residential demand
originalDemand is the demand calculated by the game, return a different value to override it
The demand is in the range 0 to 100

 int OnCalculateCommercialDemand(int originalDemand);

Thread: Simulation
Invoked when the game calculates commercial demand
originalDemand is the demand calculated by the game, return a different value to override it
The demand is in the range 0 to 100

 int OnCalculateWorkplaceDemand(int originalDemand);

Thread: Simulation
Invoked when the game calculates workplace demand
originalDemand is the demand calculated by the game, return a different value to override it
The demand is in the range 0 to 100

 int OnUpdateDemand(int lastDemand, int nextDemand, int targetDemand);

Thread: Simulation
Returns a smoothed demand for each demand type

IEconomy[edit]

IEconomy[edit]

Economy manager

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 long currentMoneyAmount { get; }

Thread: Main
Returns the current money amount being displayed in the UI

 long internalMoneyAmount { get; }

Thread: Simulation
Returns the current money amount internally used by the simulation thread

IEconomyExtension[edit]

Pure interface to modify economy logic

 bool OverrideDefaultPeekResource { get; }

Thread: Simulation
This override must return true to take control of OnPeekResource

 void OnCreated(IEconomy economy);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 long OnUpdateMoneyAmount(long internalMoneyAmount);

Thread: Simulation
Invoked once every four seconds with the simulation set to normal speed. Triggers every time the Economy Manager updates the current money amount.

 int OnPeekResource(EconomyResource resource, int amount);

Thread: Simulation
Invoked when the simulation evaluates if a resource is available.
The amount parameter specifies the amount being evaluated, a return value not equal to the amount parameter notifies the system the player does not have enough resource available.

 int OnFetchResource(EconomyResource resource, int amount, Service service, SubService subService, Level level);

Thread: Simulation
Invoked when the simulation uses resources. Return value is the actual amount to be reduced from money amount.

 int OnAddResource(EconomyResource resource, int amount, Service service, SubService subService, Level level);

Thread: Simulation
Invoked when the simulation adds resources. Return value is the actual amount to be added to money amount.

 int OnGetConstructionCost(int originalConstructionCost, Service service, SubService subService, Level level);

Thread: Any
Return value is construction cost for anything player can build.

 int OnGetMaintenanceCost(int originalMaintenanceCost, Service service, SubService subService, Level level);

Thread: Any
Return value is maintenance cost for anything player can build. This is reduced from money amount 16 times per week.

 int OnGetRelocationCost(int constructionCost, int relocationCost, Service service, SubService subService, Level level);

Thread: Any
Return value is relocation cost for buildings owned by player.

 int OnGetRefundAmount(int constructionCost, int refundAmount, Service service, SubService subService, Level level);

Thread: Any
Return value is refund amount when bulldozing recently build buildings or roads.

EconomyExtensionBase[edit]

Base class to derive from to modify economy logic

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 IEconomy economyManager { get; set; }

Thread: Any
Gets the economy manager interface

 bool OverrideDefaultPeekResource { get; }

Thread: Simulation
This override must return true to take control of OnPeekResource

 void OnCreated(IEconomy economy);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 long OnUpdateMoneyAmount(long internalMoneyAmount);

Thread: Simulation
Invoked once every four seconds with the simulation set to normal speed. Triggers every time the Economy Manager updates the current money amount.

 int OnPeekResource(EconomyResource resource, int amount);

Thread: Simulation
Invoked when the simulation evaluates if a resource is available.
The amount parameter specifies the amount being evaluated, a return value not equal to the amount parameter notifies the system the player does not have enough resource available.

 int OnFetchResource(EconomyResource resource, int amount, Service service, SubService subService, Level level);

Thread: Simulation
Invoked when the simulation uses resources. Return value is the actual amount to be reduced from money amount.

 int OnAddResource(EconomyResource resource, int amount, Service service, SubService subService, Level level);

Thread: Simulation
Invoked when the simulation adds resources. Return value is the actual amount to be added to money amount.

 int OnGetConstructionCost(int originalConstructionCost, Service service, SubService subService, Level level);

Thread: Any
Return value is construction cost for anything player can build.

 int OnGetMaintenanceCost(int originalMaintenanceCost, Service service, SubService subService, Level level);

Thread: Any
Return value is maintenance cost for anything player can build. This is reduced from money amount 16 times per week.

 int OnGetRelocationCost(int constructionCost, int relocationCost, Service service, SubService subService, Level level);

Thread: Any
Return value is relocation cost for buildings owned by player.

 int OnGetRefundAmount(int constructionCost, int refundAmount, Service service, SubService subService, Level level);

Thread: Any
Return value is refund amount when bulldozing recently build buildings or roads.

EconomyResource[edit]

 enum EconomyResource
 {
   None,
   ConstructionCost,
   MaintenanceCost,
   LoanAmount,
   LoanPayment,
   PrivateIncome,
   CitizenIncome,
   TourismIncome,
   PublicIncome,
   RewardAmount,
   PolicyCost,
   BailoutAmount,
   RefundAmount,
   LandPrice,
   All,
 }

ILevelUp[edit]

ILevelUp[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

ILevelUpExtension[edit]

 void OnCreated(ILevelUp LevelUp);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 ResidentialLevelUp OnCalculateResidentialLevelUp(ResidentialLevelUp levelUp, int averageEducation, int landValue, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for a residential building

 CommercialLevelUp OnCalculateCommercialLevelUp(CommercialLevelUp levelUp, int averageWealth, int landValue, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for a commercial building

 IndustrialLevelUp OnCalculateIndustrialLevelUp(IndustrialLevelUp levelUp, int averageEducation, int serviceScore, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for an industrial building

 OfficeLevelUp OnCalculateOfficeLevelUp(OfficeLevelUp levelUp, int averageEducation, int serviceScore, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for an office building

LevelUpExtensionBase[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 ILevelUp levelUpManager { get; set; }
 void OnCreated(ILevelUp levelUp);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 ResidentialLevelUp OnCalculateResidentialLevelUp(ResidentialLevelUp levelUp, int averageEducation, int landValue, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for a residential building

 CommercialLevelUp OnCalculateCommercialLevelUp(CommercialLevelUp levelUp, int averageWealth, int landValue, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for a commercial building

 IndustrialLevelUp OnCalculateIndustrialLevelUp(IndustrialLevelUp levelUp, int averageEducation, int serviceScore, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for an industrial building

 OfficeLevelUp OnCalculateOfficeLevelUp(OfficeLevelUp levelUp, int averageEducation, int serviceScore, ushort buildingID, Service service, SubService subService, Level currentLevel);

Thread: Simulation
Update levelup data for an office building

ResidentialLevelUp[edit]

Levelup data for residential buildings

 Level targetLevel;

If target level is greater than current level, building tries to level up

 int educationProgress;

Current education progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 int landValueProgress;

Current landvalue progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 bool landValueTooLow;

Set to true if landvalue is too low for current building level.
Triggers notification icon and eventually causes building to be abandoned

CommercialLevelUp[edit]

Levelup data for commercial buildings

 Level targetLevel;

If target level is greater than current level, building tries to level up

 int wealthProgress;

Current wealth progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 int landValueProgress;

Current landvalue progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 bool landValueTooLow;

Set to true if landvalue is too low for current building level.
Triggers notification icon and eventually causes building to be abandoned

IndustrialLevelUp[edit]

Levelup data for industrial buildings

 Level targetLevel;

If target level is greater than current level, building tries to level up

 int educationProgress;

Current education progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 int serviceProgress;

Current service progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 bool tooFewServices;

Set to true if service coverage is too low for current building level.
Triggers notification icon and eventually causes building to be abandoned

OfficeLevelUp[edit]

Levelup data for office buildings

 Level targetLevel;

If target level is greater than current level, building tries to level up

 int educationProgress;

Current education progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 int serviceProgress;

Current service progress to reach next level.
Range 1..15 or 0 if it cannot be calculated right now

 bool tooFewServices;

Set to true if service coverage is too low for current building level.
Triggers notification icon and eventually causes building to be abandoned

ILoading[edit]

ILoading[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 bool loadingComplete { get; }

Thread: Any
Returns true when the loading of a map/save is completed, otherwise false

 AppMode currentMode { get; }

Thread: Any
Returns the current application mode
Allows to know if the game state is currently in-game, in map editor or in asset editor

 string currentTheme { get; set; }

Thread: Any
Forces a new theme to be applied to the next save. Will only become active when reloading
Options are: "Sunny", "North", "Tropical"

ILoadingExtension[edit]

 void OnCreated(ILoading loading);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnLevelLoaded(LoadMode mode);

Thread: Main
Invoked when a level has completed the loading process
The mode defines what kind of level was just loaded

 void OnLevelUnloading();

Thread: Main
Invoked when the level is unloading (typically when going back to the main menu or prior to loading a new level)

LoadingExtensionBase[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 ILoading loadingManager { get; set; }

Thread: Any
Gets the loading manager interface

 void OnCreated(ILoading loading);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnLevelLoaded(LoadMode mode);

Thread: Main
Invoked when a level has completed the loading process
The mode defines what kind of level was just loaded

 void OnLevelUnloading();

Thread: Main
Invoked when the level is unloading (typically when going back to the main menu or prior to loading a new level)

IManagers[edit]

IManagers[edit]

Helper interface which stores getter to all available game managers

 IAreas areas { get; }

Thread: Any
Gets the areas/tiles manager

 IDemand demand { get; }

Thread: Any
Gets demand manager

 IEconomy economy { get; }

Thread: Any
Gets the economy manager

 ILevelUp levelUp { get; }

Thread: Any
Gets the levelup manager

 IMilestones milestones { get; }

Thread: Any
Gets the milestones manager

 ISerializableData serializableData { get; }

Thread: Any
Gets the serialization manager

 ITerrain terrain { get; }

Thread: Any
Gets the terrain manager

 IThreading threading { get; }

Thread: Any
Gets the threading manager

 ILoading loading { get; }

Thread: Any
Gets the loading manager

IMilestones[edit]

IMilestones[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 string[] EnumerateMilestones();

Thread: Any
Returns an array of string containing the name of all the unlockable milestones

 void UnlockMilestone(string name);

Thread: Simulation
Unlocks the Milestone designated by the name parameter. Use EnumerateMilestones() to list all the available milestone strings

IMilestonesExtension[edit]

 void OnCreated(IMilestones milestones);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnRefreshMilestones();

Thread: Simulation
Called every time the game checks updates the user progression status

 int OnGetPopulationTarget(int originalTarget, int scaledTarget);

Thread: Any
Returns the number of citizens needed to reach to the next milestone
The originalTarget parameter is the number of citizens desired to pass the milestone as foreseen by the developers
The scaledTarget parameter is the number of citizens expected to pass the milestone as calculated by the game accounting for the buildable area

MilestonesExtensionBase[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 IMilestones milestonesManager { get; set; }

Thread: Any
Gets the milestone manager interface

 void OnCreated(IMilestones milestones);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnRefreshMilestones();

Thread: Simulation
Called every time the game checks updates the user progression status

 int OnGetPopulationTarget(int originalTarget, int scaledTarget);

Thread: Any
Returns the number of citizens needed to reach to the next milestone
The originalTarget parameter is the number of citizens desired to pass the milestone as foreseen by the developers
The scaledTarget parameter is the number of citizens expected to pass the milestone as calculated by the game accounting for the buildable area

ISerializableData[edit]

ISerializableData[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 string[] EnumerateData();

Thread: Any
Returns an array containing the name of the keys for the serialized data

 byte[] LoadData(string id);

Thread: Any
Load the data associated to the key as a byte array

 void SaveData(string id, byte[] data);

Thread: Any
Serialize the data from the byte array under the key id

 void EraseData(string id);

Thread: Any
Removes the data associated to the key id

 bool SaveGame(string saveName);

Thread: Main
Serialize the current game with the name saveName in the default Save user data folder

 bool LoadGame(string saveName);

Thread: Main
Deserialize the save game with the name saveName from the default Save user data folder and set it active

ISerializableDataExtension[edit]

 void OnCreated(ISerializableData serializedData);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnLoadData();

Thread: Simulation
Invoked when the save game is deserialized
Gives an opportunity to deserialize custom data if needed

 void OnSaveData();

Thread: Simulation
Invoked when the save game is serialized
Gives an opportunity to serialize custom data if needed

SerializableDataExtensionBase[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 ISerializableData serializableDataManager { get; set; }

Thread: Any
Gets the serialization manager interface

 void OnCreated(ISerializableData serializableData);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnLoadData();

Thread: Simulation
Invoked when the save game is deserialized
Gives an opportunity to deserialize custom data if needed

 void OnSaveData();

Thread: Simulation
Invoked when the save game is serialized
Gives an opportunity to serialize custom data if needed

ITerrain[edit]

ITerrain[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 int heightMapResolution { get; }

Thread: Any
Returns the size of the heightmap (1080)

 float cellSize { get; }

Thread: Any
Returns the distance between two texels of the heightmap in meters (16)

 float RawToHeight(ushort rawHeight);

Thread: Any
Converts an unsigned short raw height to an internal float representation of that height

 ushort HeightToRaw(float height);

Thread: Any
Converts an internal float representation of that height to an unsigned short raw height

 void PositionToHeightMapCoord(float x, float z, int heightX, int heightZ);

Thread: Any
Converts a worldspace XZ position to its position in the heightmap

 void HeightMapCoordToPosition(int heightX, int heightZ, float x, float z);

Thread: Any
Converts a position in the heightmap to its worldspace XZ position

 void GetHeights(int heightX, int heightZ, int heightWidth, int heightLength, ushort[] rawHeights);

Thread: Simulation
Gets an array representing the raw heights for the area starting at (heightX, heightZ) and of size (heightWidth, heightLength)
The array needs to be allocated prior to calling the method

 void SetHeights(int heightX, int heightZ, int heightWidth, int heightLength, ushort[] rawHeights);

Thread: Simulation
Sets the raw heights for the area starting at (heightX, heightZ) and of size (heightWidth, heightLength)

 float SampleTerrainHeight(float x, float z);

Thread: Any
Gets the terrain height at the XZ worldspace position

 float SampleWaterHeight(float x, float z);

Thread: Any
Gets the water height at the XZ worldspace position

ITerrainExtension[edit]

 void OnCreated(ITerrain terrain);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnAfterHeightsModified(float minX, float minZ, float maxX, float maxZ);

Thread: Simulation
Invoked after the terrain heights have been modified
The parameters defines the area which was modified

TerrainExtensionBase[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 ITerrain terrainManager { get; set; }

Thread: Any
Gets terrain manager interface

 void OnCreated(ITerrain terrain);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnAfterHeightsModified(float minX, float minZ, float maxX, float maxZ);

Thread: Simulation
Invoked after the terrain heights have been modified
The parameters defines the area which was modified

IThreading[edit]

IThreading[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 DateTime renderTime { get; }

Thread: Main
Simulation date/time that is smoothly interpolated to be used from main thread

 uint renderFrame { get; }

Thread: Main
Simulation frame that is used for current rendering frame

 float renderFrameOffset { get; }

Thread: Main
Offset between current and next simulation frame that is used to interpolate current rendering frame
Range: 0..1

 DateTime simulationTime { get; }

Thread: Simulation
Current simulation date/time

 uint simulationFrame { get; }

Thread: Simulation
Current simulation frame. Updated 60 times per second on normal (1x) speed

 uint simulationTick { get; }

Thread: Simulation
Current simulation tick. This is updated 60 times per second even when simulation is paused

 bool simulationPaused { get; set; }

Thread: Simulation
Is simulation paused

 int simulationSpeed { get; set; }

Thread: Simulation
Simulation speed. Range: 1..3
Actual simulation speed is 1x/2x/4x in game, or 1x/3x/9x in map editor

 TimeSpan timePerFrame { get; }

Thread: Any
How much one frame changes simulationTime

 void QueueMainThread(Action action);

Thread: Any
Add an action to be executed in main thread

 void QueueSimulationThread(Action action);

Thread: Any
Add an action to be executed in simulation thread

IThreadingExtension[edit]

 void OnCreated(IThreading threading);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnUpdate(float realTimeDelta, float simulationTimeDelta);

Thread: Main
Called once per rendered frame
realTimeDelta is seconds since previous frame
simulationTimeDelta is smoothly interpolated to be used from main thread. On normal speed it is roughly same as realTimeDelta

 void OnBeforeSimulationTick();

Thread: Simulation
Called before simulation tick, 60 times per second

 void OnBeforeSimulationFrame();

Thread: Simulation
Called before simulation frame, 60 times per second on normal (1x) speed

 void OnAfterSimulationFrame();

Thread: Simulation
Called after simulation frame, 60 times per second on normal (1x) speed

 void OnAfterSimulationTick();

Thread: Simulation
Called after simulation tick, 60 times per second

ThreadingExtensionBase[edit]

 IManagers managers { get; }

Thread: Any
Gets global managers interfaces

 IThreading threadingManager { get; set; }
 void OnCreated(IThreading threading);

Thread: Main
Invoked when the extension initializes

 void OnReleased();

Thread: Main
Invoked when the extension deinitializes

 void OnUpdate(float realTimeDelta, float simulationTimeDelta);

Thread: Main
Called once per rendered frame
realTimeDelta is seconds since previous frame
simulationTimeDelta is smoothly interpolated to be used from main thread. On normal speed it is roughly same as realTimeDelta

 void OnBeforeSimulationTick();

Thread: Simulation
Called before simulation tick, 60 times per second

 void OnBeforeSimulationFrame();

Thread: Simulation
Called before simulation frame, 60 times per second on normal (1x) speed

 void OnAfterSimulationFrame();

Thread: Simulation
Called after simulation frame, 60 times per second on normal (1x) speed

 void OnAfterSimulationTick();

Thread: Simulation
Called after simulation tick, 60 times per second

IUserMod[edit]

IUserMod[edit]

Interface to derive from to get a mod for Cities: Skylines to display in the Content Manager

 public void OnEnabled();
 public void OnDisabled();

OnEnable and OnDisabled are special methods and not part of the base class. Hence it is not necessary to override them. If declared in your class, the game will invoke them whenever the mod is enabled/disabled (at game start/end and when toggle the active checkbox). This is particularly handy to run initialization and cleanup code which can't wait for an in-game callback to trigger.

 public void OnSettingsUI(UIHelperBase helper);

OnSettingsUI is a special methods which is not part of the base class. If implemented, it will add your mod to the Options panel categories and you will be able to customize a dedicated space for your mod options/settings. More info can be found here.

 string Name { get; }

Name of the mod

 string Description { get; }

Short description of the mod


Prefabs[edit]

To retrieve the possible prefab indices try code such as this:

   public class LoadingExtension : LoadingExtensionBase {
       public override void OnCreated(ILoading loading) {
           base.OnCreated(loading);
           for (uint i = 0; i < PrefabCollection<NetInfo>.PrefabCount(); ++i) {
               string name = PrefabCollection<NetInfo>.PrefabName(i);
               DebugOutputPanel.AddMessage(PluginManager.MessageType.Message, i + ":" + name);
           }
   }

Interfacing with the Unity Engine[edit]

By including the Unity Engine namespace with using UnityEngine; direction, it is possible to access Unity's scripting API. http://docs.unity3d.com/ScriptReference/
Only the API from UnityEngine is available (Editor and others will not be).
It is possible to create GameObjects dynamically, as well as MonoBehaviours and use the standard callback mechanic Unity provides.

Examples[edit]