Developer Diary #7 - The Economic Model

The past week I spent a lot of time reading through papers and literature on urban economics - I want the economy in Citybound to be as closely implemented to actual research as possible.

There are many approaches and methodologies - but one struck me as the most simple and elegant: the tried and true Monocentric city model.

The Monocentric city model is the cornerstone of urban economics since its formulation in the decade of 1960 by Alonso, Muth and Mills. Source

I wasn't quite sure if I could trust such comparatively old research, but many modern approaches refer to this model and still praise its accuracy:

The implications of the monocentric model, especially for the relations between distance to the Central Business District (CBD) and population density, housing prices, land rent and capital/land ratio are widely known and have been tested many times for a great number of cities and countries. Source

When I started to read about how the model works in detail, and how that could be represented in gameplay in Citybound, I became very excited!

  • Consider a city in a featureless plain
  • The optimal, cost-minimizing shape of a city is a circle
  • The city has a fixed population level N
  • All workers must commute to the central business district (CBD),
    which is assumed to be a point Source

Citybound: 2D is enough!

This allowed for some radical simplifications for Citybound:

  • since the terrain is considered featureless, we can switch from 3D to 2D graphics, which will make a lot of things in the game engine easier and will make future development much quicker
  • roads can only be drawn directly to the CBD or in concentric circles around it - greatly simplifying the road geometry code and pathfinding
  • there are only two types of zones: CBD and residential. You can only zone CBD in the center of the map.

Here is an early screenshot of my first iteration of Citybound towards this new model:

2D

Even better than 2D: 1D

Soon, I found an even more drastic simplification, as described by Ogawa and Fujita:

[...] with the assumption of a linear or circular city, the spatial characteristics of each location in the city can be described simply by the distance from the CBD. Source

A whole city - described by just a line!
Suddenly my dream of simulating multi-million resident cities fluently, even on old hardware, became graspable!

Porting all of our graphics and game logic to 1D will take some time, but I was able to create an already impressive sneak-preview of the transition progress: a full-scale, 1D, monocentric representation of zoning and traffic in a 3 million resident city, running smoothly in Citybound:

1D

Citybound - pure minimalistic gameplay

The shift to 1D is not everything. In accordance to the model, the number of citizens and jobs is considered constant. Gameplay thus reaches its minimalist peak: you simply set the size of your city, number of residents and number of jobs, and watch the city reach its economic equilibrium. A truly zen-like experience.

What Michael's been up to

As always, Michael quickly adapted to this shift in vision for the game and is already porting his polygon-skeleton algorithm (and the whole geometry library!) to 1D.

This means that we will be able to have fully procedurally generated, complex buildings in Citybound, even in one dimension!

I hope you're all as excited about these changes as I am - you will hear from me soon!


Discussion on Reddit · on Simtropolis · on Something Awful

or follow @CityboundSim on Twitter

Any amount supports the development ♥

Developer Diary #6: Zoning, Struggling, Parceling

Time flies by, my last dev diary seems like a couple days ago, but it's actually more than two weeks - woops!

Let me tell you what Michael and I did in the meantime and what our plans are.

Zoning is everything

After some brainstorming, we decided to radically simplify the Citybound user interface. Sounds like empty PR lingo, but actually has a great impact on how the game will work, look and feel.

The interface for building roads is already really simple, powerful and versatile and will combine more in a single tool than other citybuilders offer altogether.

Michael had the idea to give the zoning tool as much power - some of the things he suggested I already had played with in my head, but he tied it all together nicely and even came up with a user interface to support that:

Instead of selecting a zone and then drawing it, you first draw some zone shapes and then select which zone types they should have.

Note how I said zone types, plural - this immediately allows to naturally have combined zones at will.

I really wanted to try this out quickly and decided to combine it with my old implementation of a zoning brush that snaps to roads, but this time based on actual geometry and not just bitmaps.

I started working on it in a livestream (livestream review, full livestream) and worked on it for many more days, it still doesn't always work flawlessly, but when it does, it feels really smooth:

zoning

The zoning brush will be enhanced later, to allow quick zoning of several shapes at once, of a whole block or freeform zoning away from roads.

But our ideas go further than just comfortably placing zones:

If you want, you will be able to set detailed regulations, ordinances and policies on a per-zone-shape level. This could include stuff like maximum building height, amount of required parking or green, maximum pollution, etc. ...

Furthermore, all city buildings will also be zones - police and fire stations, landfills, schools, airports, everything. You just zone a shape for them, set a budget and maybe additional parameters (prison cells vs. police office space for example) and the civic building will be constructed accordingly. Later you can change those parameters and extend the allotted shape if necessary.

Intermission: Version (out of) Control Systems

the monster merge

(skip this section if you know about VCS and don't want to hear our sob story, don't skip if you want to get an impression of the harsh everyday difficulties of programmers)

In this last time period, it happened two times that we were completely blocked by having to deal with issues with Git. We use Git to collaboratively work on the code for Citybound and to develop new areas of the code in branches, which allow you to work on stuff in parallel, independent of each other, each with their own version of reality.

This is really useful most of the time: Michael could work on his geometry code while I was working on game code, without each of us having to worry about accidentally breaking the code on the other side. From time to time, we would merge changes from one side into the other side (and temporarily have a common reality again).

Unfortunately I did kind of a bad job of keeping track of Michael's progress: I was using an old version of his geometry branch and even started to extend it with my own stuff, so our two realities diverged more and more.

For the zoning user interface I needed some of his most recently implemented geometry features, however, so I was finally forced to merge all of his changes into my branch and deal with the ensuing chaos. It took me 2 or 3 days just to resolve all the conflicts and get everything working again.

A little later Michael wanted to merge some new progress from my side to his, saw that it didn't work immediately, wanted to cancel it to do it properly from scratch, but accidentally made Git think that his old version of my files is actually newer than my new progress.

When we tried to merge his side into mine, Git would overwrite my new stuff with his old stuff. (This sounds really bad, but rest assured that with Git you can almost always undo).

He was forced to create a new fresh branch from my state and then had to reintroduce all of his recent changes manually, which also took quite some time.

Parceling

I couldn't make the first version of the user interface for zoning work completely, because it would have required some yet-to-be-completed code by Michael, so I decided to move on to the next step and come back later.

The next step was parceling, the process of subdividing a zoned shape into individual building lots, or parcels.

Again, after a couple days I ended up with something that works okay most of the time, but fails completely some of the time.

My subdivision algorithm often produces weird slices, but can already look really beautiful. Here are some animated examples:

(Note that the algorithm is much faster, I slowed it down to make it visually understandable)

parceling 1

parceling 2

parceling 3

(Parcels that are smaller than the requested minimum size end up unallotted)

With that same highly-anticipated yet-to-be-completed code by Michael (hint, hint) and some collaboration on the subdivision, it will look even more reasonable and nice.

What's next

Now that parceling is in place, well, kinda, I wanted to start putting buildings in those parcels. This was a good excuse to think about the economy and demand modeling, since that's what causes buildings to appear.

I had a look at my existing implementation of the economy and was kinda disappointed that demand and supply are implemented two times: once for the global macro-economy and once for each individual agent. And from both implementations the concept of localized demand was completely missing.

These are the issues I want to address next, and I already have a couple ideas how to do that. Stay tuned!


Discussion on Reddit
Discussion on Simtropolis
Discussion on Something Awful


Want to be notified when there's development news? Subscribe to the Newsletter!

You can also follow @CityboundSim on Twitter

If you want, you can already show your support. Any amount is highly appreciated!

Bitcoin address: 1KQR42DR9UP7WGrS98fcTpkgYPYxqwMZeu
Dogecoin address: DPkZosjgtAFnbXtDgauUJnyiPacfr8SLbz

Developer Diary #5: Back to Business

Finishing my bachelor's thesis.
Marrying the girl of my dreams.
Going on honeymoon.

All three very good excuses to not do something very important: work on Citybound.
But now I'm back. For three days I've already been working fulltime on the game again.
I couldn't be more thrilled and motivated - this blog post will give an overview of the progress I made.

Day 1: traffic lights, roads, T-intersections

My goal for this day was to finally implement something that I kept postponing: traffic lights.
But since all lower-level traffic behaviour (basic collision avoidance) was in place, I had no excuse to not do it. Pretty soon I came up with a generic algorithm for figuring out traffic light timings, which I roughly modeled after my experience:

traffic lights (animation sped-up by a factor of 10, ignore the bad loop at the end)

Then I wanted to test the algorithm with intersections of different sizes, so I quickly added keybindings to increase or decrease the number of lanes per road:

roads One-way and two-way roads of different widths.

My traffic-light-timing-algorthim seemed to produce reasonable-ish results for all kinds of intersections:

complex traffic lights

(static image)

This first implementation of the algortithm was just to make sure no conflicting directions get green at the same time. There still are a lot of cases where it could give green to more directions at once though.

Finally I started to implement T-intersections, something that I didn't pay attention to at all so far. This still kinda broken T-intersection is all I got before I called it a day:

broken T-intersection

Day 2: cars & traffic lights, t-intersections

I decided to start this day with a livestream:

Full livestream

In the livestream, we made cars react to traffic lights:

cars and a traffic light (ignore the cars with glitchy color)

Later that day, I made a little more progress on T-intersections. They are still slightly wrong though, and their traffic light timings are very weird.

t-intersections

Day 3: lane changing & merging behaviour

Today I was able to implement something in one day, that took me more than one week, the first time I tried it: cars changing lanes and reacting to other cars while merging. It is also not perfect yet, but already works pretty well:

lane changing

Three lanes worth of cars trying to turn right.

That's all! I'm quite proud of the progress during those 3 first days and I hope to continue with this speed :)

What Michael has been up to

Michael started doing livestreams of his own, make sure to follow his Twitch.tv channel as well!

Lately he has been working on something called Straight Polygon Skeletons, which is an algorithm to find something like the "spine" of arbitrary polygons:

straight skeleton

It will be useful in a lot of places in Citybound, two important application examples are roof geometries and parcelling of irregular road blocks into building lots.

He said he will start working on the latter soon - I can't wait!


Discussion on Reddit
Discussion on Simtropolis
Discussion on Something Awful


Want to be notified when there's development news? Subscribe to the Newsletter!

You can also follow @CityboundSim on Twitter

If you want, you can already show your support. Any amount is highly appreciated!

Bitcoin address: 1KQR42DR9UP7WGrS98fcTpkgYPYxqwMZeu
Dogecoin address: DPkZosjgtAFnbXtDgauUJnyiPacfr8SLbz

Developer Diary #4: Traffic Anarchy

Today I decided to start making use of my lane overlap detection and made cars aware of overlaps.

Before tackling higher-level traffic rules like right-before-left, yielding or traffic lights, it was important to just get basic collision avoidance going (because you will need it if the higher level rules fail to do their job).

This was my first result:

gif1

(Sorry for the low-fps GIFs, they are the quickest to produce)

You can see cars on the intersection noticing each other (yellow dots) and using the overlap data to find the place where to stop in order to avoid crashing into other cars (red dots).

It's quite interesting to see that giving cars just this basic collision advoidance results in barbaric but kinda fair "whoever comes first, goes first" traffic patterns.

There was still a bug in the calculation, causing some crashes to still occur (because one car wrongly assumed that the other one already left the overlap).

After fixing that, the behaviour became even more stable - cars could even somewhat reasonably handle this chaotic situation:

gif2

For low speeds it already worked really well, but for high speeds there was the problem that cars only started to care about overlaps once they entered the intersection, which was often too late.

So the last thing I worked on today was to make cars think about overlaps even before, when approaching an intersection. It is unfnished, because I have to sleep now, but this is its current state:

gif3

(Dark red dots show stopping location determined before even entering the intersection. They seem to be correct, but for some reason, cars don't appropriately slow down yet, only once they enter the intersection)

Two small asides:

a) for people who worry about performance of such detailed simulation, it is important to realize that only the very first cars in each lane have to do this slightly complicated obstacle detection. But even for them, most of the work has already be done by figuring out the overlap intervals beforehand. All that needs to be done is some lookup and simple mapping of car positions from one lane to another.

Note: all that the other cars have to do is stupidly follow the vehicle in front of them and not crash into it. Their next-vehicle-ahead changes very infrequently!

b) I really noticed that the reimplementation of the road system starts to pay off. With the old road system I worked on the same problem for at least a week and didn't get as far. Today: just one day!

That's all! I hope you enjoyed it, see you soon!


Discussion on Reddit
Discussion on Simtropolis
Discussion on Something Awful


Want to be notified when there's development news? Subscribe to the Newsletter!

You can also follow @CityboundSim on Twitter

If you want, you can already show your support. Any amount is highly appreciated!

Bitcoin address: 1KQR42DR9UP7WGrS98fcTpkgYPYxqwMZeu
Dogecoin address: DPkZosjgtAFnbXtDgauUJnyiPacfr8SLbz

Developer Diary #3: The Struggle

Last time, I thought that there was not much missing until lane overlaps would work properly.

Boy was I wrong!

I have a collection of screenshots on my desktop, telling the story of my efforts today and yesterday. Let me share it with you.

Having almost lost hope of finding a solution to my problems the day before, I decided to tell Michael about it, as the first thing to do today.

First I showed him all the lanes that exist on an intersection - it is their overlap intervals that I wanted to find:

screenshot1

For debug purposes, I decided to show the detected overlap intervals on top of that, orange being merging overlaps, red being head-on overlaps:

screenshot2

As can be seen, some overlaps that should have been detected are completely missing (see white sections where there should be merging overlaps). Also the red, head-on overlaps were much too long. They started at the right point, but went on for too long.

Also in many places, overlaps could ...well... overlap - basically an overlap with one lane started inside an overlap with another lane. But because they had the same color, it looked like it was just one continous overlap.

(I'm not sure if you can follow me here...)

Michael had the great idea of vertically distributing the colored lines for each overlap, so you could see their actual lengths, even if they were on top of each other.

He also suggested to make the lane shapes that are tested for overlaps thinner than the lanes visually were, resulting in hopefully smaller and more understandable overlap intervals.

I did that and first just gave each unique overlap on the intersection its own height, resulting in this extremely unhelpful image:

screenshot3

Then, after giving only overlaps of the same lane different heights, it became more understandable:

screenshot4

If you look closely at the red overlaps, you can see that they start at the right place, but go on until the end of the intersection.

Simplyfing things further, I disabled overlap tests for all lanes but the innermost ones, making everything even clearer:

screenshot5

After nearly going mad for the first time, I discovered that the overlap intervals were actually completely fine, but there was a bug in the code that drew their colored lines!

screenshot6

Much better! (the perspective warps everything bit)

So I decided to make everything flat and try a full intersection with all lanes again:

screenshot7

There was still some weird stuff going on with merging overlaps - some were just missing, others mutated into these strange red circle-arcs.

The latter was easily fixed, the first, however almost drove me mad a second time, over the course of some additional hours.

In the end it turned out to be due to a beginner-level programming error that I made somewhere, as is the case so often :)

screenshot8

Beautiful. Everything is there.
To celebrate that some more, here is a slightly higher-res picture of a normal intersection next to one with a one-way road:

screenshot9

I hope you enjoyed this, see you soon! :)

Edit: after looking at these pictures some more, I noticed that there are in fact still some missing merging overlaps. Back to work...

Edit 2: turned out to just be a display bug again. Now really everything is there!


Discussion on Reddit
Discussion on Simtropolis
Discussion on Something Awful


Want to be notified when there's development news? Subscribe to the Newsletter!

You can also follow @CityboundSim on Twitter

If you want, you can already show your support. Any amount is highly appreciated!

Bitcoin address: 1KQR42DR9UP7WGrS98fcTpkgYPYxqwMZeu
Dogecoin address: DPkZosjgtAFnbXtDgauUJnyiPacfr8SLbz

Developer Diary #2: Intersection soup

Since last time, I managed to make cars follow multisegment roads properly!

multisegment cars

One interesting problem was that cars suddenly sped up and slowed down in narrow corners, since their linear progress on a lane bundle segment was measured just relative to the lane bundle center line. On the outermost lanes of roads this was particularly noticeable.

So I created all kinds of geometry code to convert between lengths and offsets on different adjacent lanes - and made sure that car progress and velocity were always measured relative to the lane they were actually on.

All of that works now.

Then, I started working on detecting lane overlaps on intersections - something that I already implemented once for the old road system.

After getting stuck on a bug that was entirely due to me forgetting about Javascript's function-only-scope, I got a first version of overlap detection going. I just displayed the starts of overlaps in red and ends of overlaps in green:

stupid overlaps

So clear what's happening!

But seriously, it looked kinda fine at that stage.

I wanted to make sure however, so I implemented a module for displaying arbitrary paths for debug purposes.

This time, connections on the intersection are drawn as white lines, merging overlaps in orange, crossing overlaps in red:

line overlaps

Well, still kinda a little bit broken, turns out!

And that's where I had to stop today, since it is late night now and I should get sleep :)

Let me know what you think!


Discussion on Reddit
Discussion on Simtropolis
Discussion on Something Awful


Want to be notified when there's development news? Subscribe to the Newsletter!

You can also follow @CityboundSim on Twitter

If you want, you can already show your support. Any amount is highly appreciated!

Bitcoin address: 1KQR42DR9UP7WGrS98fcTpkgYPYxqwMZeu
Dogecoin address: DPkZosjgtAFnbXtDgauUJnyiPacfr8SLbz