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





Overview [ edit ]

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.

In summary, a C# mod can achieve the following things:

Gameplay: Affect in-game economy and building levels; Data Interoperability: Read and save city data (e.g. create map drawing exports); Editing: Dynamically create and destroy buildings.

What the API cannot do:

(Pending...)

More overview information is also available in Category:Programming.

File Location [ edit ]

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"; } } } }

For snippets on more practical examples, see Basic Snippets.

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

//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.

Debugging [ edit ]

By adding a reference to ColossalManaged.dll and Assembly-CSharp.dll , we can use DebugOutputPanel.AddMessage() to add debug message to our mod.

Use F7 to open the in-game console.

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, Disaster }

Enumeration for service types



SubService [ edit ]

enum SubService { None, ResidentialLow, ResidentialLowEco, ResidentialHigh, ResidentialHighEco, CommercialEco, CommercialLeisure, CommercialTourist, CommercialLow, CommercialHigh, IndustrialGeneric, IndustrialForestry, IndustrialFarming, IndustrialOil, IndustrialOre, PublicTransportBus, PublicTransportCableCar, PublicTransportMetro, PublicTransportMonorail, PublicTransportTaxi, PublicTransportTrain, PublicTransportShip, PublicTransportPlane, PublicTransportTram, PublicTransportTours, OfficeGeneric, OfficeHightech, }

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, NewScenarioFromGame, NewScenarioFromMap, LoadScenario, UpdateScenarioFromGame, UpdateScenarioFromMap, NewTheme, LoadTheme, }

Enumeration for supported load modes



AppMode [ edit ]

enum AppMode { Game, MapEditor, AssetEditor, ScenarioEditor, ThemeEditor, }

Enumeration for application modes



Expansion [ edit ]

enum Expansion { None, AfterDark, Snowfall, NaturalDisasters, InMotion, GreenCities, Parks, Industry }

Enumeration for game expansions



NaturalResource [ edit ]

enum NaturalResource { Ore, Sand, Oil, Fertility, Forest, Pollution, Burned, Destroyed }

Enumeration of the resources in the Industries expansion



IAreas [ edit ]

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



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



IBuilding [ edit ]

IBuilding [ edit ]

IManagers managers { get ; }

Thread: Any

Gets global managers interfaces

For more info on IManagers, see #IManagers

IEnumerable < string > BuildingTypes();

Thread: Main

Description follows..



void CreateBuilding( UnityEngine.Vector3 position, float angle, string buildingType);

Thread: Main

Description follows..



void ReleaseBuilding( ushort id);

Thread: Main

Description follows..



void RelocateBuilding( ushort id, UnityEngine.Vector3 position, float angle);

Thread: Main

Description follows..



BuildingExtensionBase [ edit ]

IManagers managers { get ; }

Thread: Any

Gets global managers interfaces

For more info on IManagers, see #IManagers

IBuilding buildingManager { get ; set ; }

Thread: Any

Gets the building manager interface



void OnBuildingCreated( ushort id);

Thread: Main

Description follows..



void OnBuildingReleased( ushort id);

Thread: Main

Description follows..



void OnBuildingRelocated( ushort id);

Thread: Main

Description follows..



ICities.SpawnData OnCalculateSpawn( UnityEngine.Vector3 location, ICities.SpawnData spawn);

Thread: Main

Description follows..



void OnCreated( ICities.IBuilding building);

Thread: Main

Description follows..



void OnReleased();

Thread: Main

Invoked when the extension deinitializes



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



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



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



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



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



IResource [ edit ]

IResource [ edit ]

IManagers managers { get ; }

Thread: Any

Gets global managers interfaces



int gridResolution { get ; } float cellSize { get ; } int maxDirt { get ; } void WorldToGridPosition( UnityEngine.Vector3 pos, out int x, out int z); UnityEngine.Vector3 GridToWorldPosition( int x, int z); byte GetResource( int x, int z, NaturalResource type); void SetResource( int x, int z, NaturalResource type, byte value, bool refresh); int GetDirt(); void SetDirt( int dirt);

IResourceExtension [ edit ]

void OnCreated( IResource resource);

Thread: Main

Invoked when the extension initializes



void OnReleased();

Thread: Main

Invoked when the extension deinitializes



int OnGetDirt(); void OnAfterResourcesModified( int x, int z, NaturalResource type, int amount); void OnBeforeResourcesModified( int x, int z, NaturalResource type, int desiredAmount);

ResourceExtensionBase [ edit ]

IManagers managers { get ; }

Thread: Any

Gets global managers interfaces



IResource resourceManager { get ; }

Thread: Any

Gets the resource manager interface



void OnCreated( IResource resource);

Thread: Main

Invoked when the extension initializes



int OnGetDirt(); void OnAfterResourcesModified( int x, int z, NaturalResource type, int amount); void OnBeforeResourcesModified( int x, int z, NaturalResource type, int desiredAmount);

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



ICamera [ edit ]

ICamera [ edit ]

Interface to control cinematic camera. When your cinematic camera script starts, an ICamera handle will be passed to your ICameraExtension's OnStart implementation, which can be used to call camera control methods. This API is also mirrored in CameraExtensionBase, so you can just call the corresponding base class methods instead.

All methods in this class are to be called from OnStart routine, or any routines started from it with StartRoutine.

Instant Low level controls [ edit ]

Used to instantly control the camera. Often used with timeDelta to smooth any camera movement over variable-length frames, and "yield return WaitForNextFrame();" when finished for current frame.

void SetPosition(float x, float y, float z, bool dodgeObjects = false);

Set camera position in world space. Use dodgeObjects to automatically elevate the camera above any trees, buildings, and other objects.

void SetRotation(float horizontal, float vertical, float tilt);

Set camera rotation in world space.

void FaceTowards(float x, float y, float z);

Face camera towards given coordinates.

void SetCameraTarget(float x, float y, float z, float distance = 50.0f, float verticalAngle = 45.0f, float horizontalAngle = 0.0f);

Set the camera position with given distance and angle from target point, face towards the point, and focus to it.

void SetFade(float amount);

Set the camera fade-to-black effect's amount. 1.0 for fully black, 0.0 for no fade.

void SetFocusDistance(float distance);

Focus the camera to given distance.

void SetAperture(float aperture);

Set the aperture of the camera. Smaller values will increase the amount of blur in out-of-focus areas).

void MoveCamera(float x, float y, float z, bool relativeAngle = true);

Move camera from current position by given values. Set relativeAngle to true to move relative to camera's current rotation instead of world space (x for sideways, z for forward/backward).

void RotateCamera(float horizontal, float vertical, float tilt);

Rotate the camera from its current rotation.

float timeDelta { get; }

Get the time delta for current frame.

void GetCameraPosition(out float x, out float y, out float z); void GetCameraAngle(out float horizontal, out float vertical, out float tilt);

Get the current camera position and angle.

Routine Handling [ edit ]

The camera script can have multiple routines running at the same time. Use these to start, end, and temporarily halt routines.

int StartRoutine(IEnumerator routine);

Start a new custom routine. Routines will always start on the following frame. Returns the routine ID.

void AbortRoutine(int routineID = 0);

Abort a routine with given ID. Use 0 to abort the whole script and return to game.

object WaitForRoutineToFinish(int routineID);

"yield return WaitForRoutineToFinish(id);" to halt current routine until the other finishes.

object WaitForNextFrame();

"yield return WaitForNextFrame();" when finished for current frame. The script will continue from this on the next frame.

object Wait(float seconds);

"yield return Wait(5);" to halt the current routine for 5 seconds.

World Objects [ edit ]

Used to get information about any objects such as buildings, vehicles, etc.

ushort GetRandomBuilding(Service service = Service.None, SubService subService = SubService.None, Level level = Level.None); ushort GetBuildingWithName(string name); ushort GetNearestBuilding(float x, float y, float z); bool GetBuildingPosition(ushort id, out float x, out float y, out float z, out float angle); ushort GetRandomVehicle(Service service = Service.None, SubService subService = SubService.None, Level level = Level.None); ushort GetVehicleWithName(string name); ushort GetNearestVehicle(float x, float y, float z); bool GetVehiclePosition(ushort id, out float x, out float y, out float z, out float angle); uint GetRandomCitizen(); uint GetCitizenWithName(string name); uint GetNearestCitizen(float x, float y, float z); bool GetCitizenPosition(uint id, out float x, out float y, out float z, out float angle); ushort GetRandomRoad(); ushort GetRoadWithName(string name);

Get IDs for random objects, and use them to fetch their position and horizontal angle. Use Service.None, SubService.None, or Level.None to accept objects with any service type, subservice type, or service level. Only objects with custom given names will be fetched when searching by name. GetXPosition will return false if the object with given ID doesn't exist.

Built-in Routines [ edit ]

These methods will start built-in routines and return their IDs. Using duration of 0.0 or less will cause the routine to run indefinitely or until manually aborted. Using negative speeds will reverse the direction of the routine.

int OrbitBuilding(ushort id, float speed = 10.0f, float duration = 0.0f, float distance = 100.0f, float verticalAngle = 45.0f, float horizontalAngle = 0.0f);

Start a routine that will orbit the camera around the building with given ID. Use negative speed for counter-clockwise orbit. Use horizontalAngle to control the starting point around the building.

int FollowCitizen(uint id, float duration = 0.0f, float distance = 50.0f, float verticalAngle = 45.0f, float horizontalAngle = 0.0f, bool relativeAngle = false);

Start a routine that will follow the citizen with given ID. Use duration of 0.0 or less to run the routine indefinitely or until manually aborted. Set relativeAngle to true to use horizontal angle relative to target citizen's angle instead of world space (for example to always follow the citizen from behind when using 0 horizontal angle).

int FollowVehicle(ushort id, float duration = 0.0f, float distance = 50.0f, float verticalAngle = 45.0f, float horizontalAngle = 0.0f, bool relativeAngle = false);

Start a routine that will follow the car with given ID.

int FollowRoad(ushort roadID, float speed = 20.0f, float duration = 0.0f, float distance = 50.0f, float verticalAngle = 30.0f, float horizontalAngle = 0.0f, bool relativeAngle = true, RoadJunctionHandler junctionCallback = null);

Start a routine that will move along the given road. Use a custom RoadJunctionHandler to manually resolve which way to go when facing crossroads (the camera will take random turns by default).

int FadeIn(float seconds = 1f);

Start a routine that will fade the screen in from black over given time.

int FadeOut(float seconds = 0.5f);

Start a routine that will fade the screen out to black over given time.

int Dolly(float startX, float startY, float startZ, float endX, float endY, float endZ, float duration);

Start a routine that will move the camera from start point to end point over given duration in seconds.

int SetApertureSmooth(float aperture, float speed = 1.0f);

Start a routine that will change the aperture from current to target with given speed of stops per second.

int SetFocusDistanceSmooth(float focusDistance, float speed = 100.0f);

Start a routine that will change the focus distance from current to target with given speed of meters per second.

void GetCameraPosition(out float x, out float y, out float z);

ICameraExtension [ edit ]

Implement this or CameraExtensionBase which contains the same methods but also mirrors the ICamera methods in base class.

void OnCreated(ICamera Camera);

Invoked when the camera script initializes.

void OnReleased();

Invoked when the camera script is released.

IEnumerator OnStart(ICamera camera);

Invoked as a routine when the camera script is started by the player. This is the "entry point" of your cinematic camera script.

void OnAbort();

Invoked when the camera script is aborted by the player.

string Name();

The name of your script as shown in the in-game cinematic camera menu.

Misc [ edit ]

public delegate ushort RoadJunctionHandler(ushort[] roadIDs);

For creating custom intersection handler for the built-in FollowRoad-routine, which can be used to select which way to go in an intersection. Receives a list of road segment IDs leading out from the intersection. Return one of the IDs. Returning an invalid ID will cause the camera to take a random turn. This might get invoked long before the camera reaches the intersection.

IAssetData [ edit ]

This extension API is used for saving and reading custom data in asset packages. OnAssetSaved and OnAssetLoaded will only be called once for the main asset in the package, so for example prop variations and sub-buildings don't get a call separately. All calls to the extension from the game happen in main thread.

IAssetDataExtension [ edit ]

void OnCreated(IAssetData assetData);

Called when the extension initializes.

void OnReleased();

Called when the extension is released.

void OnAssetSaved(string name, object asset, out Dictionary<string, byte[]> userData);

Called when an asset is being saved. The asset-parameter contains the boxed asset PrefabInfo. Save any custom data to userData dictionary.

void OnAssetLoaded(string name, object asset, Dictionary<string, byte[]> userData);

Called after an asset has been loaded and added to collections. The userData-parameter contains previously saved custom data.

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.