Skip to content
Dominic Maas edited this page Dec 27, 2017 · 12 revisions

Project Tango

Introduction

Project Tango (name to change later) is an experimental Cities Skylines multiplayer mod based on Gurkenplayer. The mod will provide an experience where everything is synced between players (using the client-server model). Players will share money, costs, roads, resources etc. In the future it would be nice to add the ability to players to control individual cities, but this is a HUGE if.

I'm currently developing this in my free-free time (most of my time being spent studying/working and developing SoundByte) so I'd love help! The following information aims to help understand how this mod works and will work in the future, how to set it up, how to use it and how to help develop it.

Installation

Setting up the mod is very easy. You will need to have Visual Studio 2017 installed (free version works), have not tested on older versions. Simply build the project, this will build the required files, and move these files into your Cities Skylines mod directory. (This is done using Build Events, right click the project -> Properties-> Build Events -> Post-build event command line).

You can manually setup the mod by performing the following

  1. Build the project.
  2. Create a new folder in your cities skylines mod directory (%LOCALAPPDATA%\Colossal Order\Cities_Skylines\Addons\Mods) called Tango.
  3. Copy the Tango.dll file into this folder.
  4. Copy Lidgren.Network.dll from the Assemblies folder into the newly created Tango folder.
  5. Run cities skylines and enable the mod.

Usage

  1. Create a new game / open an existing game.
  2. Click the Show Multiplayer Menu button in the top-left of your screen.

Client-Server Model

This mod uses the client-server model. A user will setup their game as a server and transmit information like currency, roads, needs etc. to all connected clients. Clients will connect to the server and retrieve currency, roads, needs etc. from the server, updating the client UI.

This is all done by running a UDP server alongside Cities Skylines. This UDP server will interact with the extension methods in the ICities DLL. It is important that we extend and override the base methods for these extensions (as we override some values).

ICities.dll Extensions

Here is a list of extensions that can be used in the ICities.dll (not much documentation elsewhere).

DemandExtensionBase

This extension will allow us to synchronize demand across all connected clients. More research is required, but from what I understand, we need to override the OnCalculate*Demmand methods to grab the calculated demand from the server. On the server we will access the demand manager to get the current demand. The OnUpdateDemand method will also be used for server-client syncing.

Method Return
OnCalculateResidentialDemand(int originalDemand) originalDemand
OnCalculateCommercialDemand(int originalDemand) originalDemand
OnCalculateWorkplaceDemand(int originalDemand) originalDemand
OnUpdateDemand(int lastDemand, int nextDemand, int targetDemand) nextDemand

EconomyExtensionBase

Currently looking at implementing OnUpdateMoneyAmount to sync money between clients. Some basic testing showed that this was only updating the UI? Need to look further into it.

Method Return
OnAddResource(EconomyResource resource, int amount, Service service, SubService subService, Level level) amount
OnFetchResource(EconomyResource resource, int amount, Service service, SubService subService, Level level) amount
OnPeekResource(EconomyResource resource, int amount) amount
OnGetConstructionCost(int originalConstructionCost, Service service, SubService subService, Level level) amount
OnGetMaintenanceCost(int originalMaintenanceCost, Service service, SubService subService, Level level) amount
OnGetRelocationCost(int constructionCost, int relocationCost, Service service, SubService subService, Level level) amount
OnGetRefundAmount(int constructionCost, int refundAmount, Service service, SubService subService, Level level) amount
OnUpdateMoneyAmount(long internalMoneyAmount) internalMoneyAmount

Clone this wiki locally