Cities: Skylines (the Sim City we deserve)

  • Thread starter Akira AC
  • 1,530 comments
  • 129,941 views
Something that has been bugging me for a while is how to create realistic curvature transitions. In real life when designing roads, there are two basic criteria for corners:

1. The tangent needs to be continuous (i.e. if you want to change direction you need to use a curve)
2. The curvature needs to be continuous

It's pretty easy to achieve (1) in the game, but (2) is hard. Whenever you have a curve with a constant radius and connect it to a straight (or worse, to a curve heading in the other direction) you'll get a big jump in curvature at the point where they meet. The transition between the curvatures basically represent how quickly you need to turn the wheel in order to stay on the road. When the transition is instant that means that the wheel has to be turned instantly as well - not good for road safety!

So the curvature has to change gradually, the best way to do this is with a clothoid, since the curvature of a clothoid is proportional to the curve length. That means that if a car is driving at a constant speed along the road, then the driver can turn the wheel at a constant speed when entering the corner.

The figure below illustrates the difference between a road where two constant radius curves are directly attached to each other, and one where there's a segment of linear change in curvature in between the two curves.

curvecomp.png

In the game we can't really make clothoids, but we can approximate them. The roads are basically Bézier curves, where the straights are linear Béziers (two control points) and the corners are quadratic Bézier (three control points). With the corners we have a start vector, an end vector and the vector length for each of those (those are what we draw with the curve tool). The figure below illustrates how the clothoid approximation is created: Given a target radius R of the curve and an angle v that we want the transition to cover we can calculate the vector lengths a and b.

clothoidapproximation.png

The actual calculation is done by adding lots and lots of circle segments of constant curve length together, where each circle segment has a smaller and smaller radius, then adding their x and y coordinates together to get the coordinates for the endpoint. Then it's just a matter of trigonometry to solve for the lengths a and b. The greater the number of circle segments, the better the precision, I found that around 1000 segments provides a good balance between accuracy and speed of calculation.

I don't know how to make mods for the game, but I created a Python script that can perform these calculations.

Code:
from math import tan, sin, cos, pi, radians

def psum(n):
    return n*(n+1)/2

def easing(v, R, n=1000):
    vtot = radians(v)
    k = 1/R
    arclength = l = vtot*n/(k*psum(n))
    y = 0
    x = 0
    startangle = 0
    stopangle = 0
    for i in range(1, n+1):
        ki = k/n*i
        vi = ki*l
        Ri = 1/ki
        stopangle = startangle+vi
        dy = -Ri*(cos(stopangle)-cos(startangle))
        dx = Ri*(sin(stopangle)-sin(startangle))
        y += dy
        x += dx
        startangle = stopangle

    a = x-y/tan(vtot)
    b = y/sin(vtot)

    print("a = %.1f m, b = %.1f m" %(a, b))
    return a, b

I have only done some basic tests yet, and only for small angles (30 degrees or less) so not sure how well this holds up for greater angles. I'll make some tests in the game and report back :D
 
Last edited:
Something that has been bugging me for a while is how to create realistic curvature transitions. In real life when designing roads, there are two basic criteria for corners:

1. The tangent needs to be continuous (i.e. if you want to change direction you need to use a curve)
2. The curvature needs to be continuous

It's pretty easy to achieve (1) in the game, but (2) is hard. Whenever you have a curve with a constant radius and connect it to a straight (or worse, to a curve heading in the other direction) you'll get a big jump in curvature at the point where they meet. The transition between the curvatures basically represent how quickly you need to turn the wheel in order to stay on the road. When the transition is instant that means that the wheel has to be turned instantly as well - not good for road safety!

So the curvature has to change gradually, the best way to do this is with a clothoid, since the curvature of a clothoid is proportional to the curve length. That means that if a car is driving at a constant speed along the road, then the driver can turn the wheel at a constant speed when entering the corner.

The figure below illustrates the difference between a road where two constant radius curves are directly attached to each other, and one where there's a segment of linear change in curvature in between the two curves.

View attachment 979167
In the game we can't really make clothoids, but we can approximate them. The roads are basically Bézier curves, where the straights are linear Béziers (two control points) and the corners are quadratic Bézier (three control points). With the corners we have a start vector, an end vector and the vector length for each of those (those are what we draw with the curve tool). The figure below illustrates how the clothoid approximation is created: Given a target radius R of the curve and an angle v that we want the transition to cover we can calculate the vector lengths a and b.

View attachment 979166
The actual calculation is done by adding lots and lots of circle segments of constant curve length together, where each circle segment has a smaller and smaller radius, then adding their x and y coordinates together to get the coordinates for the endpoint. Then it's just a matter of trigonometry to solve for the lengths a and b. The greater the number of circle segments, the better the precision, I found that around 1000 segments provides a good balance between accuracy and speed of calculation.

I don't know how to make mods for the game, but I created a Python script that can perform these calculations.

Code:
from math import tan, sin, cos, pi, radians

def psum(n):
    return n*(n+1)/2

def easing(v, R, n=1000):
    vtot = radians(v)
    k = 1/R
    arclength = l = vtot*n/(k*psum(n))
    y = 0
    x = 0
    startangle = 0
    stopangle = 0
    for i in range(1, n+1):
        ki = k/n*i
        vi = ki*l
        Ri = 1/ki
        stopangle = startangle+vi
        dy = -Ri*(cos(stopangle)-cos(startangle))
        dx = Ri*(sin(stopangle)-sin(startangle))
        y += dy
        x += dx
        startangle = stopangle

    a = x-y/tan(vtot)
    b = y/sin(vtot)

    print("a = %.1f m, b = %.1f m" %(a, b))
    return a, b

I have only done some basic tests yet, and only for small angles (30 degrees or less) so not sure how well this holds up for greater angles. I'll make some tests in the game and report back :D
Whoosh! That was all that going over my head. :eek: And I learnt a new word too, "clothoid". ;) :lol:

Hope you get it to work how you want eran.
 
Last edited:
First test in-game and I love it already :D

I made three versions of the same basic S-corner: 80° left followed by 80° right:

Skärmbild (120).png


At top is just two basic corners mashed together. The change in curvature where they meet is so sharp that you can see exactly where it is.

The middle one is with the clothoid transitions. It’s 20° clothoid, 40° constant radius, 20° clothoid. The curvature transition is so smooth that you can hardly tell when the straight ends and the corner begins.

The third one is the method I usually do, where I use constant radius corners but add a short straight in between the turns so that a corner is not immediately followed by another corner. In my opinion it’s much better than the top version, but not as nice as the middle one.

So with this test done, next step will be to create an algorithm for parametric curve design, where I just enter two vectors and have Python return a complete blueprint. From that point it should be possible to create a mod that brings the tool to the game. It should be especially helpful for building realistic railways and highways.

Here you can see a bit better how each S-turn is constructed. My computer decided to crop the image weirdly, so half the top is missing.

Skärmbild (124).png


Perspective view of the clothoid transitions (middle road), smooth as silk:
Skärmbild (122).png


I decided to pave the road and keep it in my city as Euler Lane, in honour of the 18th century mathematician who explored this kind of spiral.
Skärmbild (125).png
 
Very interesting @eran0004 . Can't say I really understand the maths but I certainly have noticed how curved roads always join so jankily.

I keep thinking in my next city I would try to build by looking up real world planning guidelines for placement of stuff, but then I just realise how tedious it would probably be.
 
I got the curve construction algorithm working, and installed an app that lets me run python on my phone, so now I can use it to design curves while playing the game. The input values are the angle v between start vector and end vector and either the vector length l or a desired minimum radius R. You can also set the proportion of the angle that are to be covered by the circle segment (v2/v).
The output values are the lengths a and b and angle v1 of the transition curve, as well as length c and angle v2 of the circle segment.


curveConstruct.png

It's quite hard to build these curves in the game if you want to connect two pre-existing straights, because the Precision Engineering mod doesn't show any decimals for the distances and I think I need at least one decimal to make sure that the segments line up nicely. It's doable, but it takes a long time. Hopefully I can create a mod from this (or sell in the idea to someone who can) and have it construct these curves with perfect precision.

My first proper use of this has been to reshape a couple of curves of the metro line, for example this segment that runs next to the oval racetrak. I planned on recording the first-person view from a train (seeing the curve gradually straighten out in first-personis pretty cool), but for some reason Windows doesn't want to record my gameplay anymore.

Skärmbild (126).png
Skärmbild (128).png
 
I installed the Measure It mod, which provides measurement precision down the to centimeter (and also angles down to 1/100 degrees). That makes it possible to build really precise transition curves, although it takes a bit of time due to having to construct every length and angle manually. It takes around five minutes or so to build a single curve :D

It's worth it though, just to see the line flow when it's finished. I've rebuilt about half of the curves of my metro and railroad so far, but only 2-3 roads.

Skärmbild (136).png
Skärmbild (132).png


The python script for the calculator is available here. I run it on my iPhone with an app called Pyto, it's not a free app but it's pretty cheap. The script is made so that you don't need to know any Python coding to run it, just load it in the app, start it and follow the instructions. It asks for the following input data from the figure in my previous post:

1. The angle v, called "vector angle". it's basically the angle of the corner, i.e. a 60 degree corner would have v = 60. There is no difference between turning left or right. This angle can't be 180 degrees because that will result in a division by zero.

2. The angle v1, called "transition angle", this is the angle that should be covered by the transition curve in the beginning and end of the corner. Each of the two transition curves cover this angle, so the total angle covered by both transitions is 2*v1. That means that the circle segment (the bit with constant radius in between the transitions) will have the angle v2 = v-2*v1. Angle v1 can't be more than v/2.

It also asks for either of these, depending on which mode you're working in:

3. The length l, called "vector length", this is the distance from the start of the curve to the point where the tangent intersects with the tangent of the other end of the curve, it's basically the distance to the point where the two straights would intersect. Vector length mode is for when you have two non-parallel straights and want to build a curve between them.

4. The radius R, which is the radius of the circle segment and also the minimum radius of the curve. Radius mode is for when you're building a new road or railroad and know what minimum radius you want.

As for the actual construction, I'll be back with a tutorial for that.
 
Had a bit of a break from CS, creative juices weren't flowing. Fired it back up a few days ago and continued on my city. Did a few things but I still feel like these are just "base" ideas for now to fill in areas, that i'll come back to later to improve/tweak.

The lorewise first island is progressing with a road network and next settlement the other side of the mountain, although I think I'll have to re-jig the bottom two highway junctions, they feel too close. The mountain is now a tree covered park with camping areas and a couple of viewing points looking across the main area.

Cities_ Skylines_20201222132740.jpg

Cities_ Skylines_20201202093119.jpg

Cities_ Skylines_20201222134430.jpg



Funny though one area I did on the bigger island, there was a pocket of land left with the highway on one edge, the edge of my land on the other and a train line. So I thought i'd build a little community within it, turned out pretty nice I thought. Few curvy roads, cul-de-sacs with a footbridge out over the railway and small hill, into the WIP office park over the road. There was one minor thing I only realised I overlooked when I looked at it again the next day:

Cities_ Skylines_20201222122805.jpg


See if you can spot the issue. :lol:
 
Last edited:
VXR
I can see a few plucky motorists trying to two-wheel across that footbridge to move in :D

Heh, the paths are actually pretty wide aren't they, and the AI a bit wild.

Also I suppose any who make it over will have the outer loop to themselves as a racetrack.
 
Last edited:
Technically I think the residents are fine with just a pedestrian bridge, but they might not be so happy with the garbage collection service :lol:

Sometimes I wish the garbage management was a bit more dynamic. Rather than the simulation breaking down due to no garbage collection, I think it would be better if the citizens just dumped their trash around the neighbourhood (and that would in turn have a negative impact on land value and happiness). I would also like to have recycling centers that the citizens go to with their garbage, rather than expecting a truck to come around and collect it for them.
 
Last edited:
Quite a few of the services and events are a bit annoying in how they function, mainly in regards to the vehicles they generate. The post offices they added in one of the DLC for example, neat idea to add some more unique buildings and activity but they just spawn way too many vans, your city is swarmed with them, and imports increase by 3000 with just two or three plus the sorting depot.

Or football stadiums, which attract an ungodly amount of traffic for each game.

Makes them undesirable in a city.
 
Here is a couple of screenshots to show the workflow for creating the transition curves. To get some accuracy in the measurements I'm using the Measure It mod. You also need Road Anarchy and Fine Road Tools.

Skärmbild (140).png Skärmbild (143).png Skärmbild (147).png

1. Starting with two intersecting straights, measure the angle between the straights and calculate the dimensions of the curve with the calculator (see post #667).
2. From the point of intersection, measure the vector length l as given by the calculator along each straight and draw a short perpendicular segment to mark the length.
3. Remove everyting between the peripendicular marks, then draw the segment lengths a, as given by the calculator.

Skärmbild (156).png Skärmbild (161).png Skärmbild (164).png

4. Draw the new segment b with the angle v1 relative to segment a. The length of b and angle v1 is given by the calculator.
5. You now have the framework needed to draw the transition curve with the curve tool. Start from the perpendicular mark, extend to the intersection between segments a and b, end the curve at the endpoint of segment b. Repeat at the other end of the curve.
6. Use the free form tool to draw the circular arc between the transition curves. Then remove segments a and b on both sides of the curve. Use the Move It mod to adjust the elevation if required.

The final result, after adjusting the elevation and upgrading some segments to elevated rail:

Skärmbild (165).png


Unfortunately it's not practical to do this for all of your roads or railroads. I've done around 25-30 corners so far and I'm so sick of it :lol:
Hopefully I can find some mod developer who is willing to automate the entire process. I've taken a look at the source code of some road-building mods but haven't figured out how they do it.
 
Quite a few of the services and events are a bit annoying in how they function, mainly in regards to the vehicles they generate. The post offices they added in one of the DLC for example, neat idea to add some more unique buildings and activity but they just spawn way too many vans, your city is swarmed with them, and imports increase by 3000 with just two or three plus the sorting depot.

Or football stadiums, which attract an ungodly amount of traffic for each game.

Makes them undesirable in a city.
Post and Taxi's I leave out because of the extra traffic. ;)
 
I've not really done much in C:S for a couple of weeks. Just messing about...



... I'm still trying to figure out the look I'm going for.

The service cubes are still required as my population of 2000 or so is still struggling to support commercial, and some stuff I just haven't got around to building yet.
 
Post and Taxi's I leave out because of the extra traffic. ;)

Yeah, same with buses once I unlock other transport. Well, buses can be OK so long as you reduce the numbers on a line, otherwise two or three long routes and you've got 70+ buses clogging up your roads.

It's a shame because in vanilla game the more unique items to fill out your city the better, but some are just unfeasible. It's like a lot of the unique buildings you can't really make good use of because of their big noise range.
 
I've not really done much in C:S for a couple of weeks. Just messing about...



... I'm still trying to figure out the look I'm going for.

The service cubes are still required as my population of 2000 or so is still struggling to support commercial, and some stuff I just haven't got around to building yet.


So cool to see something British and in video. Looks amazing. Particularly like the cul-de-sac behind the roundabout towards the start.
 
Yep... mental what CWCW has achieved.

As for my exploits.

Spent about 4 hours today putting in a railway line, a station, and trying to build a remotely sensible pedestrian underpass (unlike the vanilla methods - I'd rather it was not visible from space)... and at some point, the Lane Marking Tool junked ALL my junctions... every ******* last ******* one of the ********. Pretty sure it's still quicker to rebuild them all than go back to the last good save.

****.
 
and at some point, the Lane Marking Tool junked ALL my junctions... every ******* last ******* one of the ********. Pretty sure it's still quicker to rebuild them all than go back to the last good save.

****.

Ouch! :banghead:

Yeah, that's a big problem with mods, they're not always working properly. But if you have a lot of similar junctions then you could always copy-paste between them, should speed up the process a lot.
 
Yeah, that's a big problem with mods, they're not always working properly

In all fairness, I think the LMT is pretty solid, my suspicion is that it's something to do with plopable asphalt/grass etc. A bunch a quay walls that were always glitched "suddenly" started working at the same time that use that mod. I'm wondering if whilst going on a subscribe-to-asset-spree, I've subscribed to a mod at the same time.

Yep, with the copy/paste and template functions it's not that bad.

Anyhow...

In the town of Stanley, Cooper County.

This took a while. Doesn't look like much but I wanted to make the area surrounding the station seem more functional, so I wanted to add some 'engine sheds', these of course, repurposed for the electric age of rail, and now just servicing carriages. The second shed may once have housed loco's, but is now the goods entrance for the business. The building is a warehouse converted to a PO then manipulated to be 2 sheds instead of 3, that took a while, so did making the fact it's all built on a hill look plausible...

upload_2020-12-30_21-45-20.png


The station itself is fairly bog-standard... I need to edit the vanilla Taxi depot to replace this one. The asset looks fine but the fence around it is a pain, as are the random spawn trees.

upload_2020-12-30_21-50-12.png


upload_2020-12-30_21-54-16.png


Also, in an area I'm developing to try and satiate demand for R to support I, C & O.. I notice the people got themselves an RV... (or, many of them)

upload_2020-12-30_21-57-34.png


.. and, eventually this is going to be something, after lots more massaging - up to the castle and down the other side. I think given the attention to gradients and curvature it will require I'm going to name it Eran pass... and I've not even sorted out levelling the railway properly yet...

upload_2020-12-30_21-59-17.png


... thank the maker for the Flatten option on the node controller.

And.. in taking these shots I realise, all changes to default surfaces were lost too.

****.
 
New year, new city :D

I went for a snowfall theme (although this theme is a variant from the workshop - I don't like the yellow snow of the fertile land in the original snowfall theme). The map is Vanilla Valley, by Mr Miyagi. For this project I want to make an American style grid, I haven't really done that before.

Skärmbild (173).png


I also aim for a green city, trying to get as little pollution as possible. The city only has agricultural industry for now, I'll expand with forestry industry once the city has grown a bit.

Skärmbild (175).png


Quite spectacular sunsets on this map.

Skärmbild (174).png
 
Last edited:
I'm starting to increase the density, as the city expands towards the water. I built a cemetery as well.

Skärmbild (187).png


Started planning for trains. The connection at the top is supposed to be for cargo and the one at the bottom is for passenger trains.

Skärmbild (185).png


My favourite build of the day: The curving bridge over the railroad. This road will connect to the cargo train station.

Skärmbild (184).png


The watertower at night.

Skärmbild (180).png


As for the transition curves modding adventure, I realised I've been blind all this time. Turns out that the Move It mod have a tool for manually setting the coordinates of a node. So I changed my Python script so that it now outputs the necessary coordinates and as a result, building these transition curves is now pretty fast.
 
Now I can record videos again, I assume my previous project got so busy that I didn't have enough processing power left to do the video capture. I made a little transition curve showcase video in the form of a first person drive around a short test track. In honour of @MatskiMonk I made a couple of spiral turns (I've set up the script so you can specify how many loops you want), there is also an S-curve and one regular corner. The thing to pay attention to is the smooth transition from straight to curve at the beginning of the curves, and then back to straight again at the end of the curves. Using the Node Controller mod I gave the curves some banking as well, turns out that the transition segments are great for transitioning between banking as well.



The test track from above:

Skärmbild (191).png
 
Lol, nice.

Been a while since I made a spiral... I wanted to keep my current map slightly more plausible but it could really do with a couple of Karazu-Nanadaru style loop bridges to get up and down some of the steeper gradients...

... shame I'm too busy trying to make never-ending amounts low density residential look anything other than really boring.

Might start a second map and go back to zoning things for a bit, might not look as good, but it's way less tedious.
 
I started on a new project, to build Special Stage City, the proposed combination of SSR5 and SSR11 from Gran Turismo :D

I took the picture below and used AutoCad to adjust the scale, sketch the vector of each straight and get the coordinates of the points of intersection. I used Move It to recreate those vectors in the game and then the last step is to build the curves.

SpecialStageCity1.png


Here's the progress so far: The layout of SSR5 is complete, while SSR11 is still in raw vector form. (The river is not supposed to go straight across the track, I'll have to move it somewhere else).

Skärmbild (192).png


Map view:

Skärmbild (193).png
 
Back