181 lines
6.4 KiB
Markdown
181 lines
6.4 KiB
Markdown
# Half-Earth Citybuilder Prototype
|
|
|
|
## TODO
|
|
|
|
* Zoning demand
|
|
* Journey Pathfinding
|
|
* Resident health
|
|
* Education
|
|
* Supply chains
|
|
|
|
## Clock
|
|
|
|
Ticks can be applied manually or they can be applied over time.
|
|
There is a tick counter UI debug element.
|
|
|
|
## Diffusion
|
|
|
|
### Grid
|
|
|
|
Add a 10x10 grid.
|
|
Tiles are highlighted a different colour when the player hovers over them with the cursor.
|
|
Tiles in the grid contain floating point values.
|
|
These values propogate to neighbouring cells a tick happens.
|
|
|
|
#### Diffusion Algorithm
|
|
|
|
Diffusion is modelled as two-dimensional steady-state heat conduction.
|
|
This means that the amount of a value does not change between the start and end of the computation of the diffusion step.
|
|
The value at one 2D location is calculated based on the values of itself and its neighbours in the previous step.
|
|
A diffusion coefficient controls the rate of diffusion.
|
|
|
|
[Video explanation](https://www.youtube.com/watch?v=RGbV7T_iWT8)
|
|
[Derivation](https://www.tec-science.com/thermodynamics/heat/heat-equation-diffusion-equation/)
|
|
|
|
Implementation:
|
|
|
|
```cs
|
|
private float TransferHeat(float t0, float alpha, float nx, float ny, float px, float py)
|
|
{
|
|
float d2tdx2 = nx - 2 * t0 + px;
|
|
float d2tdy2 = ny - 2 * t0 + py;
|
|
return t0 + alpha * (d2tdx2 + d2tdy2);
|
|
}
|
|
```
|
|
|
|
Diffusing uses 'pull' operations; tiles pull values from surrounding tiles.
|
|
This is an attempt to think forwards to parallelising computation of diffusiong - ideally using the GPU.
|
|
|
|
## Overlays
|
|
|
|
The current overlay can be cycled with a UI button or by pressing `tab`.
|
|
Overlays display tile information by displaying tiles in different colours.
|
|
Normally, tile colours are displayed depending on their type and health.
|
|
This is the 'normal' view with no overlay.
|
|
|
|
Other overlays include:
|
|
|
|
* [Heat overlay](#heat-overlay)
|
|
|
|
## Build Mode
|
|
|
|
Build mode can be entered by pressing the `b` key.
|
|
Build the cursor will start flashing when entering build mode.
|
|
|
|
Once in build mode, a tile type must be selected to build anything.
|
|
Tiles cab be selected with the buttons along the bottom of the screen or by keyboard shortcuts.
|
|
The keyboard shortcut to select a tile type is indicated on the button.
|
|
|
|
To deselect a tile type, press `esc`.
|
|
Press `esc` again to exit build mode.
|
|
|
|
## Tile Types
|
|
|
|
Tiles start as wild tiles.
|
|
The player can use a UI element or a keyboard shortcut to enable build mode.
|
|
In build mode, the player can click on a wile tile to turn it into a developed tile.
|
|
|
|
* Wild tiles are green
|
|
* Developed tiles are grey
|
|
|
|
## Heat
|
|
|
|
Developed tiles produce heat while wild tiles absorb it.
|
|
Every tile has a floating-point heat value which diffuses to its neighbours.
|
|
|
|
### Heat overlay
|
|
|
|
A heat map view can be toggled or cycled to.
|
|
It is possible to cycle the view using a UI element.
|
|
Tile colours are displayed as a value along a gradient from cold to hot tiles.
|
|
|
|
## Tile Health
|
|
|
|
Add another value to wild tiles: health.
|
|
A wild tile can accept a certain amount of heat each tick from surrounding tiles.
|
|
If it receives more heat than threshold it takes damage based on the surplus.
|
|
|
|
A wild tile should be able to safely absorb heat from 3 surrounding developed cells, but take damage from 4.
|
|
A wild tile's health impacts its ability to absorb heat.
|
|
The amount of heat input required to damage a wild tile is known as its damage threshold.
|
|
|
|
damage taken = max((heat received - damage threshold), 0)
|
|
|
|
Its effectiveness at absorbing heat scales with its remaining health.
|
|
|
|
heat absorbed = health * base absorbtion rate
|
|
|
|
Diffusion still occurs to move heat away from depleted wild tiles.
|
|
|
|
## Rewilding
|
|
|
|
Add a rewilding mode option to the UI.
|
|
In rewilding mode, the player can click on a developed tile to turn in into a wild tile.
|
|
The wild tile starts with 0 health.
|
|
|
|
## Wild Recovery
|
|
|
|
Depleted wile tiles can recover health each tick.
|
|
The recovery rate is based on the difference between the damage threshold and the actual amount they received.
|
|
The recovery rate is increased if the tile has wild neighbours.
|
|
|
|
neighbour multiplier = lerp(1, max, number of neighbours / 4)
|
|
health restored = max((damage threshold - heat received), 0) * neighbour multiplier.
|
|
|
|
## Developed tile types
|
|
|
|
Split developed tiles into 3 types:
|
|
|
|
* Residential
|
|
* Commercial
|
|
* Industrial
|
|
|
|
When placing developed tiles, the player can select which type they want to place.
|
|
These types generate different amounts of heat:
|
|
|
|
industrial > commercial > residential
|
|
|
|
## Journeys
|
|
|
|
Developed tiles have a chance to generate journeys between them.
|
|
A journey instances a vehicle which traverses the map at a constant speed from its origin to its destination tile.
|
|
A vehicle adds a constant amount of heat to every tile it traverses.
|
|
|
|
## Moving In
|
|
|
|
Residential tiles have two new integer resources, current residents and maximum residents.
|
|
Every tick there is a chance for residents to move in to a residential tile if the current number is less than the maximum number of residents.
|
|
The initial number of maximm residents per residential tile is 4.
|
|
|
|
## Jobs
|
|
|
|
Industrial and commercial tiles have two new integer resources, available jobs and occupied jobs.
|
|
The chance for residents to move in depends on there being being fewer occupied than available jobs.
|
|
Industrial and commercial tiles can only generate journeys if they have at least 1 occupied job.
|
|
Their chance of generating a journey is proportional to
|
|
|
|
occupied jobs / available jobs .
|
|
|
|
## Commutes
|
|
|
|
A resident moves in to a residential tile and gets a job at an industrial or commercial 'job' tile.
|
|
The residential tile regularly generates journeys to the job tile, and the job tile regularly generates journeys in the other direction.
|
|
|
|
## Comfortable Living Temperatures
|
|
|
|
If a residential tile is too hot, people will not want to live there.
|
|
Residential tiles have a critical temperature at which the chance of someone moving into a tile becomes negative, becoming a chance that someone moves out.
|
|
This should not be implemented as a multiplication of other factors, but should rather contribute to an additive modifier to the move-in chance.
|
|
This is to avoid the situation where an extremely attractive locations becomes extremely unattractive due to a slight over-temperature multiplying a large number.
|
|
|
|
When someone moves out, one of the jobs associated with that residential tile is removed.
|
|
|
|
# Not critical
|
|
|
|
## Wealth
|
|
|
|
Journeys generate a new integer tile resource, wealth.
|
|
When a journey is completed, the destination tile accrues 1 wealth.
|
|
Wealth is lost if a tile is rewilded; only developed tiles have wealth.
|
|
|