2021-01-04

Egregoria Devblog #7

If you want to know what Egregoria is about, here's the first post.

Hello and happy new year! According to the commit history, this is also the first anniversary of the project. Crazy to think that I've been working on this for a whole year, although the pandemic gave me the opportunity to make great progress!

Anniversary

To celebrate this, here's a few screenshots to show the progress over the last year. You might also read the previous blog posts to get a better idea.

It's very satisfying to see the evolution, although since I got a full-time job recently, progress definitely took a hit. :-)
Luckily, there's no big hype/marketing or big promises so I don't feel bad about the slowing down. Also, motivation isn't gone yet so I hope I can still move forward.

Egregoria's ambition

Since this is the end of the year and the anniversary, some discussion about this project's ambition and direction seems fitting.
Reading about A/BStreet's identity crisis really resonated with me.
What do I want out of Egregoria?

  • A city-builder game?
  • A realistic city simulation?
  • A weird mix of the two?

After a year of work, there's no core gameplay loop or simulation objective, so the project really is mostly graphics and ui code, with a very cool road system that I'm very proud of.
The original objective was "a realistic city simulation explored from a god view in the browser". But now, I realise that this is just too hard, making a non-interactive simulation interesting requires a change of perspective.

Recently, a discord user came onto Egregoria's server and asked what would happen if he just started Egregoria on a raspberry pi and left the simulation running.
As of today, nothing would happen because a lot of input is required to make things happen, but I really like the idea.

The first time I conceputalized the project was when reading "Les Fourmis" (Empire of the Ants) by Bernard Werber.
(spoiler alert!) In the third book, one of the characters develops a realistic life simulation to test out marketing strategies. However at the end, the simulated universe ends up understanding what they are and their purpose, therefore collectively deciding to end themselves by turning off the computer running the simulation.

Obviously, this is fiction. But this is my vision. A simulation complex enough to be like a "playground" for social expriments.
I feel like the main way to "play" should be a petri dish mode where things just evolve on their own on a raspberry pi once the rules are set.

Audio

For a long time, I didn't add audio to the game because of a weird bug between winit and cpal, but luckily there's now a workaround! Just disable drag and drop on windows and voilĂ !

So I dug down the audio rabbit hole, spending hours upon hours on sound libraries and learning to modulate sounds in different ways.
After rewriting most of rodio's code, I ended up with an AudioContext struct that does everything I might want. Start sounds, stop sounds, accelerate sounds or change the volume. All of this as efficiently as possible to avoid underruns.
However, for the audio backend, I might switch to oddio which shows a lot of potential.

Rust's audio story is surprisingly not so good compared to graphics for example, where wgpu is nothing short of amazing.
Rodio gives me underruns with very few sources, has a ton of weird features and the design doesn't feel super pleasing.

Anyway, there's now music, wind sounds, forest sounds, and most importantly car sounds! (spent a long time on this one, Doppler effect yes!)
Here's a video :D


I forgot to show the music, but it's the same as the latest youtube update.

Economy

Two months ago, I thought I had an idea of what economy I wanted.
I couldn't have been more wrong.

I spent about a month and a half stuck on what I wanted for the economy. I tried to read on the subject, I watched khan academy's introduction to economy and talked to people about how the world works. I discovered that the way money is distributed is purely political and that labor is a kind of commodity.
This dive was troubling because it really changed the way I view the world. Economics is weird.

Anyway, after weeks of turmoil I ended up deciding that money was too complicated for the moment and go full utilitarist. The (current) economy won't be based on money but on communism, a bit like Anno 1800. Buildings produce things, and offer it on the market. Then, if anyone wants anything they asks for it to be delivered to them.

So for example the chain Farm -> Flour factory -> Bakery can work without any money or offer/demand dynamic. It's up to the mayor to use its ressources efficiently.
I did this not to be realistic but because it really simplifies the process, and there's still the option to change it later.
It's also very stable. There's no risk of crash or hyperinflation or some big crisis. People go to work and make their things and everyone's happy. At least until I implement hunger.

Gridlock detection

Gridlocks are terrifying, they seem unavoidable and unescapable. It really impresses me that I never encountered one or that city traffic actually works.

Here's a basic example of a gridlock appearing pretty often in Egregoria that doesn't really appear in real life.

The white car waits for the blue car,
the blue car waits for the gray car,
the gray car waits for the white car.

In the real world, they will recognize that someone has to come forward and for example the blue car will just accelerate and things will be solved.
However in Egregoria this is not possible, since the collision detection is pair based, 3-way gridlocks (or more) cannot be detected like this.

So I started looking for an algorithm that:

  • Detected gridlocks
  • Didn't require any global coordination
  • Didn't require to build the collision/intersection graph
  • Wasn't too expensive
  • Could take a few frames to work

Not building the graph means that I cannot use classic cycle detection like the tortoise and hare algorithm.

For months, I thought this was impossible. That this was a classic network problem that couldn't be solved.
But turns out I was wrong! After thinking about it for the 10th time, I found a solution that fits all the criteria. The idea is simple:

When a car stops, it firsts displays its id on its roof (that can be read by other cars). Then, it displays what's on the roof of the car blocking itself.
Eventually, if a car sees its own ID, then there must be a cycle involving this car!

Here's a schema to explain the different steps:

Furthermore, for small cycles, this only takes a few frames (for a cycle of size n, it takes n+1 frames).

However, it only detects the cycles but does not solve them. It's not like I can nuke the offending cars out of existence. :D
Thankfully for small cases, the rule "when you're in a gridlock, ignore other cars for a few seconds" should work well enough.

There's also the small issue of false positives if a long snake ends up biting its tail, but it should be rare enough to not be a problem.

I haven't implemented this algorithm yet but it shouldn't be too hard, and fun to look at.

What next ?

I guess continuing to grow the economy as I think it is the center pillar of a good simulation. It is also intimately related to people's behavior so it needs to be robust and interesting.

I'll also start to think about this petri dish mode, letting the city develop itself.

I also want to ditch the Island and turn it into a big coast, to make it easier to import ressources from the exterior.

Thank you for reading to the end!

< Back to list