Decompiling the Cities: Skylines II code

To be able to view the source code code of Cities: Skylines 2, we need a few tools.

Visual Studio

Visual Studio Community edition is a free IDE to write .NET code in C# and other languages.

Decompiler

To decompile the game code to the source code, we will use the ILSpy Visual Studio extension.

  • Search for the link to the latest version on the ILSpy GitHub page at ILSpy
  • At the time of writing, ILSpy 2022 is the latest version, download it from ILSpy 2022
  • Double-click the downloaded .vsix file
  • Restart Visual Studio if it was running at the time of the extension installation

Decompiling Cities: Skylines II

  • Start Visual Studio
  • Select Continue without code to start a new project
  • In the Tools menu select ILSpy
  • In the ILSpy window select File, Open
  • Select Game.dll in the “C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II\Cities2_Data\Managed” directory
  • On the left side expand the Game node

Save the game code

To save the game code as a Visual Studio project

  • Right-click the Game node and select Save Code…

Examining the original game code

  • In the Visual Studio File menu select Open, Project/Solution
  • Open the Game.csproj C# project
  • To search for words in the game source code press CTRL-F or open the Quick Find dialog box

How to stop the rain and snow in Cities: Skylines II

The snow makes it hard to see the image overlay in Cities: Skylines II. To stop the rain and snow we can

  • use the Weather+ mod or
  • make temporary changes in Developer mode.

Weather+ mod

  • Install the Weather+ mod in the main menu

Temporary change in Developer mode

The Override Precipitation setting in Developer Mode is not saved in the city, so every time you open the city, you need to set it again.

  • Enable Developer mode, see https://pinter.org/archives/15586
  • Start the game and open the city
  • Press the Tab key to open the Developer menu
  • On the Climate tab check Override Precipitation, the Precipitation value should automatically set to zero.
  • Close the Developer menu with the Tab key
  • To melt the snow, click the fast forward icon to forward to summer

Argument of type ‘(number | null)[]’ is not assignable to parameter of type ‘(err: Error, result: QueryResult) => void’

The latest “npm install @types/pg –save-dev” command changed the “@types/pg” Node.js module version in the package.json file from to “^8.11.4”.

Since that, the build of my TypeScript applications fail with the error message below, if the PostgreSQL .query function contains mixed “value” types, like this:

const query = "INSERT INTO ..."
const values = [string, number, stringArray, nullableValue]
const result = await conn.query(
      query,
      values
    );   

The error message is:

.. : error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type ‘(number | null)[]’ is not assignable to parameter of type ‘(err: Error, result: QueryResult) => void’.
Type ‘(number | null)[]’ provides no match for the signature ‘(err: Error, result: QueryResult): void’.

or

…: error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type ‘(string | number)[]’ is not assignable to parameter of type ‘(err: Error, result: QueryResult) => void’.

or

… : error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type ‘(string | number | null)[]’ is not assignable to parameter of type ‘(err: Error, result: QueryResult) => void’.
Type ‘(string | number | null)[]’ provides no match for the signature ‘(err: Error, result: QueryResult): void’.

Solution

I can see two solutions:

Make sure all elements of the array have the same data type

If possible, make sure the type of all value elements is the same, the simplest is to

  • convert numeric values to strings,
  • specify default values for “null” values,
  • convert string arrays to strings, or get the first element if only that has value.
const values = [number.toString(), canBeNullString || '' (canBeNullNumber || 0).toString(), stringArray[0]]

A better solution is to centralize the database access

If the database access is centralized in a function, and the values are passed in as “any” type, the TypeScript compiler will not reject it, because it does not iterate through all references of the function.

This is an example of the centralized PostgreSQL database call.
Install the required Node.js packages with

npm install typescript --save-dev
npm install @types/node --save-dev
npm install dotenv
npm install pg
npm install @types/pg --save-dev

The centralized PostgreSQL access file

// db.js

import * as dotenv from "dotenv";
dotenv.config()
import pg from 'pg'

// Create the reusable pool to the PostgreSQl database
// Read config values from environment variables
let conn = new pg.Pool({
  user: process.env.USER_NAME,
  password: process.env.PASSWORD,
  host: process.env.HOST,
  port: parseInt(process.env.PORT || "5432"),
  database: process.env.DATABASE,
});

// Call the "query" method of the pool to execute the text of the query with optional parameters
export const query = async (text: string, params: any) => {
  let res;

  try{

    if (params) {
      // There are parameters, send them with the query text
      res = await conn.query(text, params)
    } else {
      // There are no parameters
      res = await conn.query(text)
    }

  } catch (e) {
    // There is an error executing the query, log the error, the text of the query and the parameters
    console.log('error', e)
    console.log('query', text)
    console.log('params', params)
  }

  return res
}
  
export default query ;

Call the centralized function with

// selectData.ts

import * as conn from './db';

export async function selectData (id: string) {

  let result;
  let query;
  let values;

  try {
    
    // Build the query
    const baseQuery = "SELECT * FROM table";  

      query = baseQuery + ' ' + "WHERE id = $1";
      values = [id]

    // Query the database
    result = await conn.query(
        query
        , values
    );

    return result?.rows[0];

  } catch ( error ) {
    console.log("In selectData", error);
    console.log("result: ", result);
    console.log("query: ", query);
    console.log("values: ", values)
    return null;
    }
};

Cities: Skylines II Developer Mode

WARNING: MAKING CHANGES IN DEVELOPER MODE CAN CREATE UNFORESEEN RESULTS AND CAN CORRUPT THE SAVE FILE. USE DEVELOPER MODE WITH CAUTION!!!

In developer mode we can gain access to more tools than what the regular user interface provides. We can

  • Adjust the concrete surface area around buildings

To start Cities: Skylines II in developer mode from the Steam app

  • Start the Steam app
  • In the Library right-click Cities: Skylines II and select Properties
  • On the General tab, enter -developerMode into the Launch Options field
  • There is no Save button, so close the panel in the upper right corner

Using Developer Mode

Changing the Game play

Changes in this area can create unforeseen results and can break the change file.

  • To open the game setting developer menu press the Tab key on the keyboard
  • Press the Tab key again to close the game play developer menu

Object developer menu

  • To open the Object developer menu, press the Home key on the keyboard

‘CSII_MANAGEDPATH’ has incorrect path(s) when building Cities: Skylines II mod

When we try to build a new Cities: Skylines II code mod, and we get the following error message:

Error User environment variable ‘CSII_MANAGEDPATH’ has incorrect path(s) ‘C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II’ set. Please update the Modding toolchain in-game to reset its value or modify its value to a suitable path SmoothRoads C:\Users\lpint\AppData\LocalLow\Colossal Order\Cities Skylines II.cache\Modding\Mod.targets

During the project setup the template asked for the directory where the game is installed, but we need to point that value to the Cities2_Data\Managed subdirectory of the game folder. To update the value:

  • Right-click the mod project name
  • In the menu select Edit Project File
  • Update the value of <CustomManagedPath> to
    C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II\Cities2_Data\Managed

Using Cities: Skylines II mods

If mods don’t load during the first load of the game

  • Exit to Desktop
  • Start the game again

Recommended Cities: Skylines 2 mods

ModDepends onDescription
Image Overlay LiteTo Overlay an image on the game map. It works in the game and the Map Editor.
Extended Road Upgrades
Upgrade your roads using the game’s built-in tool to transform them into quays, retaining walls, or even elevate them.
AnarchyUnified Icon LibraryDisables error checks for tools in a way that the errors are not shown at all. Allows you to build next on in water, create tight curves and steep slopes for roads and other networks.

Installing and using Thunderstore mod manager

Thunderstore is an application that manages mods for Cities: Skylines 2. It is very convenient to use, even allows you to run the game in “vanilla” mode without any mods, but not all mods are available through it. To install Thunderstore

Installing and using BepInEx

BepInEx, the mod launcher for Unity games, including Cities: Skylines 2 has multiple versions. At the time of writing, version 5 is in long term support, and version 6 is already available.

Only one version of BepInEx can be added to the game at a time, and unfortunately, mods target a specific version of BepInEx, so only those mods can run together which use the same version of BepinEx.

Installation

Install BepInEx version 6

To install BepInEx version 6

  • Navigate to from https://paradoxmods.net/files/12-bepinex/
  • Click the Download this file button
  • Download BepInEx-Unity.Mono-win-x64-6…
  • Extract the contents of the ZIP file
  • Copy all files of the top level directory to “C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II”
  • Start the game once, so BepInEx can create the “config” and “plugins” directories in the BepInEx folder
  • Exit the game to the Desktop
  • Place the mod directories into the “C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II\BepInEx\plugins” directory

Install BepInEx version 5

  • Navigate to https://paradoxmods.net/files/12-bepinex/
  • Click the Download this file button
  • Download BepInEx_x64_5…
  • Extract the ZIP archive
  • Copy all files of the top level directory to “C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II”
  • Start the game once, so BepInEx can create the “config” and “plugins” directories in the BepInEx folder
  • Exit the game to the Desktop
  • Place the mod directories into the “C:\Program Files (x86)\Steam\steamapps\common\Cities Skylines II\BepInEx\plugins” directory

Image overlay in Cities: Skylines 2

Image overlay enables us to display a transparent map over our layout in the game and in the Editor.

In the Editor this makes is easy to place outside connections to the correct locations, so when we build our city replica, the roads start at the right place.

In the game it makes it possible to follow the original city layout.

Installation

In the Main Menu of Cities: Skylines II select Paradox Mods

Subscribe to the Image Overlay mod

Configuration

Disable image movement

On laptops without dedicated PgUp and PgDown keys we usually have to use the Fn + cursor keys to have the same effect. For the Fn key to work, we first have to press the Fn key and only after the Ctrl, Shift and other keys. If we miss pressing the Fn key first, the cursor function will be executed instead of the PgUp or PgDwn. The Image Overlay mod uses the Ctrl-Up, Ctrl-Down, Ctrl-Left, Ctrl-Right keys to move the image horizontally. If for any reason our computer does not recognize the press of the Fn key, instead of moving the image up and down, we move the image horizontally out of the center position causing frustrating alignment errors. To disable the horizontal image movement

  • On the KEYS tab of the Image Overlay options page click the X next to all Move… keyboard shortcuts

Usage

Overlay file location

To make the overlay image file available to the mod

  • Create the Overlays directory at “%LocalAppData%Low\Colossal Order\Cities Skylines II”
  • Place the .png overlay files into the Overlays directory. The image size has to be a multiply of 2, up to 16,384×16,384 pixels.

Image selection and transparency setting

To select the image, and set the transparency in the game or in the Editor

  • In the Main Menu of Cities: Skylines II select Options
  • On the Image Overlay page select the image file and set the transparency

Creating an AWS Q AI application

To use an AWS Q application we need two components:

  • An AWS Q AI application
  • A SAML 2.0 compliant identity provider

AWS Q application

To set up the AWS Q AI application

  • Search for Q in the AWS console

  • Click the Get started button

  • Click the Create application button

  • Enter the name of the application
    If your user account has rights to create service roles, select Create and use a new service role option
    If your company administrators created a service role for the application, choose Use an existing service role, and select the role.
    Click the Create button

  • Stay on the page until the new role propagates through the system

  • When it becomes available, click the Next button
  • On the Connect data sources page select the source where the custom data is located. To index a web site, select the “Web crawler” data source, and specify the URL of the home page, or the location of the site map. For WordPress sites, the site map is located at https://MY_WEBSITE/sitemap.xml

For more information see Configuring an Amazon Q application

Identity Provider

AWS Q is a paid service based on the number of users.

To control access to AWS Q, we need to configure it with a SAML 2.0 compliant identity provider, like Azure AD, Okta, or we can use the AWS Identity Center, which is accessible through your AWS Console.

Using the AWS IAM Identity Center

IMPORTANT: As AWS Q is not an AWS “managed application”, if we use IAM Identity Center, we need to create an IAM Identity Center “organizations” instance to be able to connect “custom applications”.

For the complete list of steps, see Setting up Amazon Q with IAM Identity Center as identity provider

Amazon Q API

The Amazon Q API documentation is at https://docs.aws.amazon.com/amazonq/latest/api-reference/Welcome.html