genworldvoronoi

package module
v0.0.0-...-17a2a95 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 27, 2024 License: Apache-2.0 Imports: 37 Imported by: 2

README

genworldvoronoi: Graph based planetary map generator

It simulates (somewhat) global winds and attempts to calculate precipitation and temperature for more intricate simulations in the future. It features SVG, PNG, and Wavefront OBJ output.

This is based on https://www.redblobgames.com/x/1843-planet-generation/ and a port of https://github.com/redblobgames/1843-planet-generation to Go.

I draw further inspiration from various other projects such as https://github.com/weigert/SimpleHydrology and https://github.com/mewo2/terrain

... if you haven't noticed yet, this is a placeholder for when I feel less lazy and add more information :D

Dev notes

This thing needs a use, and I think the major drawback right now is the time that it takes to generate a reasonably complex planet with enough detail to be interesting. So here are tne following important points that need to be addressed:

  • Generation speed
    • Use concurrency where sensible
    • Introduce a cache for fitness functions
  • Export / import of generated data
    • Separate generation steps into
      • Geology, Climate
      • Biology, Species, Survivability
      • Civilization, Cities, Empires
    • Binary format for writing to / reading from disk
  • Simulation
    • Seasons, Weather, Disasters
    • Biology, Species, Migrations
    • Population Growth, Migrations
    • Wars, Diplomacy
    • Founding, Development, Abandonment, Fall of Cities, Empires, Religions
    • Written History, Legends

TODO

  • Use cached temperature instead of getRegTemperature every single time
  • Climate
  • Elevation
    • Move away from linear interpolation
    • Add improved noise
  • Winds
    • Push temperature around [DONE]
    • Push dry air around, not just humid air
    • Re-evaluate rainfall and moisture distribution
  • Civilization
    • Industry and trade
      • Introduce industry
      • Introduce production / harvesting of goods
      • Improve trade routes
    • Cities
      • Better city fitness functions
      • Separate world generation better from everything else
      • Assign goods and resources to cities (for trade)
    • Empires
      • Introduce empires with capitals [DONE]
      • Provide simpler means to query information on an empire
    • Cultures
      • Add fitness function for "natural" population density estimates
  • Resources
    • Improve resource distribution
      • Fitness functions
      • Amount / quality / discoverability?
    • Add more resource types
  • Species
    • Allow for overlapping populations
    • Allow for species migration

Here some old pictures what it does...

SVG export with rivers, capital city placement and stuff.

alt text

Leaflet server (and sad flavor text).

alt text

Poor man's relief map.

alt text

Slightly wealthier man's relief map.

alt text

Does political maps.

alt text

Simulates climate (-ish)

alt text

Simulates seasons (-ish)

alt text

Exports to Wavefront OBJ

alt text

Webglearth sample

alt text

Cesium sample

alt text

Documentation

Overview

Package genworldvoronoi is a port of redblobgames' amazing planet generator. See: https://www.redblobgames.com/x/1843-planet-generation And: https://github.com/redblobgames/1843-planet-generation

Index

Constants

View Source
const (
	SkillSurvival  = "survival"
	SkillGeneric   = "generic"
	SkillRiverNav  = "river navigation"
	SkillSeafaring = "seafaring"
	SkillFishery   = "fishery"
	SkillHunting   = "hunting"
	SkillNomadic   = "nomadic"
	SkillClimbing  = "climbing"
)
View Source
const (
	// Expansion modes.
	ReligionExpGlobal  = genreligion.ReligionExpGlobal
	ReligionExpState   = genreligion.ReligionExpState
	ReligionExpCulture = genreligion.ReligionExpCulture
)
View Source
const (
	ObjectTypeCity = iota
	ObjectTypeCityState
	ObjectTypeEmpire
	ObjectTypeCulture
	ObjectTypeReligion
	ObjectTypeRegion
	ObjectTypeMountain
	ObjectTypeRiver
	ObjectTypeLake
	ObjectTypeSea
	ObjectTypeVolcano
	ObjectTypePerson
)

Variables

View Source
var (
	GenderFemale = geneticshuman.GenderFemale
	GenderMale   = geneticshuman.GenderMale
)
View Source
var GenLanguage = genlanguage.GenLanguage
View Source
var GetAdjective = genlanguage.GetAdjective

GetAdjective get adjective form from noun

View Source
var GetNounPlural = genlanguage.GetNounPlural

GetNounPlural returns the plural form of a noun. This takes in account "witch" and "fish" which are irregular.

IsVowel returns true if the given rune is a vowel.

TrimVowels remove vowels from the end of the string.

Functions

func P

func P(probability float64) bool

probability shorthand

Types

type City

type City struct {
	ID                    int                   // Region where the city is located
	Name                  string                // Name of the city
	Type                  TownType              // Type of city
	Score                 float64               // Score of the fitness function
	Population            int                   // Population of the city
	MaxPopulation         int                   // Maximum population of the city
	Culture               *Culture              // Culture of the city region
	Language              *genlanguage.Language // Language of the city
	Religion              *Religion             // Religion originating from the city
	Founded               int64                 // Year when the city was founded
	PotentialEconomic     float64               // Economic potential of the city (DYNAMIC)
	PotentialTrade        float64               // Trade value of the city (DYNAMIC)
	PotentialResources    float64               // Resources value of the city (PARTLY DYNAMIC)
	PotentialAgricultural float64               // Agriculture value of the city (STATIC)
	Attractiveness        float64               // Attractiveness of the city (STATIC)
	TradePartners         []int                 // IDs of cities within trade range
	People                []*Person             // People living in the city
}

City represents a city in the world.

func (*City) MaxPopulationLimit

func (c *City) MaxPopulationLimit() int

MaxPopulationLimit returns the maximum population sustainable by the city.

func (*City) PopulationGrowthRate

func (c *City) PopulationGrowthRate() float64

PopulationGrowthRate returns the population growth rate per year.

func (*City) Ref

func (c *City) Ref() ObjectReference

Ref returns the object reference of the city.

func (*City) String

func (c *City) String() string

String returns a string representation of the city.

type CityState

type CityState struct {
	ID      int      // Region where the city state originates
	Capital *City    // Capital city
	Culture *Culture // Culture of the city state
	Cities  []*City  // Cities within the city state
	Founded int64    // Year when the city state was founded

	// TODO: DO NOT CACHE THIS!
	Regions []int
	*geo.Stats
}

CityState represents a territory governed by a single city.

func (*CityState) Log

func (c *CityState) Log()

type Civ

type Civ struct {
	*CivConfig
	*geo.Geo
	*History

	People            []*Person    // People in the world
	Empires           []*Empire    // (political) Empires
	RegionToEmpire    []int        // (political) Point / region mapping to territory / empire
	CityStates        []*CityState // (political) City states
	RegionToCityState []int        // (political) Point / region mapping to city / city state
	Cities            []*City      // (political) City seed points / regions
	RegionToCulture   []int        // (cultural) Point / region mapping to culture
	Cultures          []*Culture   // (cultural) Culture seed points / regions
	RegionToReligion  []int        // (cultural) Point / region mapping to religion
	Religions         []*Religion  // (cultural) Religion seed points / regions
	Settled           []int64      // (cultural) Time of settlement per region
	// SettledBySpecies []int // (cultural) Which species settled the region first
	NameGen     *genlandmarknames.NameGenerators
	TradeRoutes [][]int
	// contains filtered or unexported fields
}

func NewCiv

func NewCiv(g *geo.Geo, cfg *CivConfig) *Civ

func (*Civ) CalcCityScore

func (m *Civ) CalcCityScore(sf func(int) float64, distSeedFunc func() []int) []float64

CalcCityScore calculates the fitness value for settlements for all regions.

'sf': Fitness function for scoring a region. 'distSeedFunc': Returns a number of regions from which we maximize the distance.

func (*Civ) CalcCityScoreWithDistanceField

func (m *Civ) CalcCityScoreWithDistanceField(sf func(int) float64, regDistanceC []float64) []float64

func (*Civ) ExpandCultures

func (m *Civ) ExpandCultures()

ExpandCultures expands the cultures on the map based on their expansionism, terrain preference, and distance to other cultures.

func (*Civ) ExpandReligions

func (m *Civ) ExpandReligions()

func (*Civ) GenerateCivilization

func (m *Civ) GenerateCivilization()

func (*Civ) GenerateTimeOfSettlement

func (m *Civ) GenerateTimeOfSettlement()

func (*Civ) GetCity

func (m *Civ) GetCity(r int) *City

GetCity returns the city at the given region / with the given ID.

func (*Civ) GetCityState

func (m *Civ) GetCityState(id int) *CityState

func (*Civ) GetCityStates

func (m *Civ) GetCityStates() []*CityState

func (*Civ) GetCulture

func (m *Civ) GetCulture(r int) *Culture

GetCulture returns the culture of the given region (if any).

func (*Civ) GetEmpire

func (m *Civ) GetEmpire(id int) *Empire

func (*Civ) GetEmpires

func (m *Civ) GetEmpires() []*Empire

func (*Civ) GetReligion

func (m *Civ) GetReligion(r int) *Religion

GetReligion returns the religion of the given region (if any).

func (*Civ) GetTradeRoutes

func (m *Civ) GetTradeRoutes() ([][]int, [][]int)

func (*Civ) LogPopulationStats

func (m *Civ) LogPopulationStats(people []*Person)

func (*Civ) PlaceCity

func (m *Civ) PlaceCity(cType TownType, scoreFunc func(int) float64, distSeedFunc func() []int) *City

PlaceCity places another city at the region with the highest fitness score.

func (*Civ) PlaceCityStateAt

func (m *Civ) PlaceCityStateAt(r int, c *City) *CityState

func (*Civ) PlaceCulture

func (m *Civ) PlaceCulture(regCultureFunc func(int) CultureType, scoreFunc func(int) float64, distSeedFunc func() []int) *Culture

PlaceCulture places another culture on the map at the region with the highest fitness score.

func (*Civ) PlaceCultureAt

func (m *Civ) PlaceCultureAt(r int) *Culture

PlaceCultureAt places a culture at the given region. TODO: Allow specifying the culture type?

func (*Civ) PlaceNCities

func (m *Civ) PlaceNCities(n int, cType TownType)

PlaceNCities places n cities with the highest fitness scores.

func (*Civ) PlaceNCityStates

func (m *Civ) PlaceNCityStates(n int)

func (*Civ) PlaceNCultures

func (m *Civ) PlaceNCultures(n int)

PlaceNCultures places n cultures on the map. This code is based on: https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/modules/cultures-generator.js

func (*Civ) PlaceNEmpires

func (m *Civ) PlaceNEmpires(n int)

func (*Civ) PlaceNFolkReligions

func (m *Civ) PlaceNFolkReligions(n int) []*Religion

PlaceNFolkReligions generates folk religions.

func (*Civ) PlaceNOrganizedReligions

func (m *Civ) PlaceNOrganizedReligions(n int) []*Religion

PlaceNOrganizedReligions generates organized religions.

func (*Civ) Tick

func (m *Civ) Tick()

func (*Civ) TickCity

func (m *Civ) TickCity(c *City, gDisFunc func(int) geo.GeoDisasterChance, cf func(int) *Culture)

type CivConfig

type CivConfig struct {
	NumCultures              int  // (Min) Number of generated cultures
	NumOrganizedReligions    int  // (Min) Number of generated religions
	NumEmpires               int  // Number of generated territories
	NumCities                int  // Number of generated cities (regions)
	NumCityStates            int  // Number of generated city states
	NumMiningTowns           int  // Number of generated mining towns
	NumMiningGemsTowns       int  // Number of generated (gem) mining towns
	NumQuarryTowns           int  // Number of generated quarry towns
	NumFarmingTowns          int  // Number of generated farming towns
	NumTradingTowns          int  // Number of generated trading towns
	NumDesertOasis           int  // Number of generated desert oases
	EnableCityAging          bool // Enable city aging
	EnableOrganizedReligions bool // Enable organized religion generation

	// In case of disaster, overpopulation, etc. a percentage of the population might migrate to a new location.
	MigrationOverpopulationExcessPopulationFactor float64 // Factor of excess population to migrate in case of overpopulation.
	MigrationOverpopulationMinPopulationFactor    float64 // Minimum factor of total population to migrate in case of overpopulation.
	MigrationToNClosestCities                     int     // Number of the N closest cities to migrate to (in case of disaster)
	MigrationToNewSettlementWithinNRegions        int     // Depth of graph traversal for finding a suitable new settlement location.
	MigrationFatalityChance                       float64 // Chance of death during migration per region traversed.
}

CivConfig is a struct that holds all configuration options for civilization generation.

func NewCivConfig

func NewCivConfig() *CivConfig

NewCivConfig returns a new config for civilization generation.

type CivStats

type CivStats struct {
	Cultures   map[*Culture]int   // Number of regions per culture.
	Religions  map[*Religion]int  // Number of regions per religion.
	CityStates map[*CityState]int // Number of regions per city state.
	Empires    map[*Empire]int    // Number of regions per empire.
}

CivStats contains statistics about civilization related aspects present given a list of regions. This will allow us for example to determine if the primary culture or religion of the empire is different from the capital, which might be destabilizing, etc.

func (*CivStats) Log

func (s *CivStats) Log()

type Config

type Config struct {
	*geo.GeoConfig
	*CivConfig
	*bio.BioConfig
}

Config is a struct that holds all configuration options for the map generation.

func NewConfig

func NewConfig() *Config

NewConfig returns a new Config with default values.

type Culture

type Culture struct {
	ID           int         // Region where the culture originates
	Name         string      // Name of the culture
	Type         CultureType // Type of the culture
	Expansionism float64     // Expansionism of the culture
	Martialism   float64     // Martial skills of the culture
	Spirituality float64     // Spirituality of the culture (religion, superstition, etc.)
	// Sophistication float64
	// Extremism      float64 ?
	// Openness       float64 ?
	// Parent    *Culture
	// Children  []*Culture
	// Extinct   bool
	Language *genlanguage.Language // Language of the culture
	Religion *Religion             // Religion of the culture

	// TODO: DO NOT CACHE THIS!
	Regions []int
	*geo.Stats
}

Culture represents a culture.

Also see: https://ck3.paradoxwikis.com/Culture

TODO:

VALUES

The type of culture will also influence their values. For example, a nomadic or a hunting culture will have higher regart for martial skills and lower regard for sophistication.

I would propose to have a point pool for these attributes and then randomly assign them to the various skills with a certain distribution based on the culture type.

CRAFTS AND SKILLS

The culture will also have a set of crafts, arts, and skills that they are good at. This will be based on their values and the environment they live in.

For example, a nomadic culture will be good at hunting and tracking. They might be exceptional at crafting leather wares (like saddles), and bows.

A river culture will have a ready supply of clay, and will be good at pottery, but not at crafin leather wares like saddles.

A mountain culture will be good at mining, prospecting, and stone carving. If they mine precious metals, they will be good at jewelry making.

A naval culture will be good at ship building, and sailing. Since they might have sea shells as a ready supply, they might be good at jewelry making.

ARTS

Arts will be based on the environment and the values of the culture. For example, a river culture might focus on water and rivers, as well as the flora and fauna related to rivers.

A mountain culture might use iconography to represent the harshness of the mountains, and the gifts of the mines.

func (*Culture) Log

func (c *Culture) Log()

type CultureType

type CultureType int
const (
	CultureTypeWildland CultureType = iota
	CultureTypeGeneric
	CultureTypeRiver
	CultureTypeLake
	CultureTypeNaval
	CultureTypeNomadic
	CultureTypeHunting
	CultureTypeHighland
)

Culture types.

func (CultureType) BiomeCost

func (t CultureType) BiomeCost(biome int) float64

BiomeCost returns the cost for traversion / expanding into a given biome.

func (CultureType) CellTypeCost

func (t CultureType) CellTypeCost(cellType int) float64

CellTypeCost returns the cost of crossing / navigating a given cell type for a given culture.

func (CultureType) Expansionism

func (t CultureType) Expansionism() float64

Expansionism returns the expansionism of a given culture type.

func (CultureType) Martialism

func (t CultureType) Martialism() float64

Martialism returns the martialism of a given culture type.

func (CultureType) Spirituality

func (t CultureType) Spirituality() float64

Spirituality returns the spirituality of a given culture type. TODO: Replace this with a more meaningful value.

func (CultureType) String

func (c CultureType) String() string

String returns the string representation of a given culture type.

type EdgeIndices

type EdgeIndices struct {
	WestVertexCount  uint32
	WestIndices      []uint32 // [westVertexCount]uint32
	SouthVertexCount uint32
	SouthIndices     []uint32 // [southVertexCount]uint32
	EastVertexCount  uint32
	EastIndices      []uint32 // [eastVertexCount]uint32
	NorthVertexCount uint32
	NorthIndices     []uint32 // [northVertexCount]uint32
}

Following the triangle indices is four more lists of indices: Depending on the number of vertices, the tile uses either EdgeIndices16 or EdgeIndices32.

func (*EdgeIndices) Write

func (ei *EdgeIndices) Write(w io.Writer, vertexCount uint32) error

type Empire

type Empire struct {
	ID       int                   // Region where the empire originates (capital)
	Name     string                // Name of the empire
	Emperor  string                // Name of the ruler
	Capital  *City                 // Capital city
	Cities   []*City               // Cities within the territory
	Culture  *Culture              // Primary culture of the empire
	Language *genlanguage.Language // Primary language of the empire

	// TODO: DO NOT CACHE THIS!
	Regions []int // Regions that are part of the empire
	*geo.Stats
}

Empire contains information about a territory with the given ID. TODO: Maybe drop the regions since we can get that info relatively cheaply.

func (*Empire) Log

func (e *Empire) Log()

func (*Empire) String

func (e *Empire) String() string

type Event

type Event struct {
	Year int64           // TODO: Allow different types of time.
	Type string          // Maybe use an enum?
	Msg  string          // Message that describes the event.
	ID   ObjectReference // Reference to the object that the event is about.

}

func (*Event) String

func (e *Event) String() string

type History

type History struct {
	*geo.Calendar
	Events []*Event
}

func NewHistory

func NewHistory(c *geo.Calendar) *History

func (*History) AddEvent

func (h *History) AddEvent(t string, msg string, id ObjectReference) *Event

AddEvent adds an event to the history and returns a pointer to the event.

func (*History) GetEvents

func (h *History) GetEvents(id int, t byte) []*Event

type IndexData

type IndexData struct {
	TriangleCount uint32

	// Either Indices16 or Indices32 is used, depending on the number of vertices.
	// Indices16 []uint16 // [triangleCount * 3]uint16
	Indices []uint32 // [triangleCount * 3]uint32
}

Immediately following the vertex data is the index data. Indices specify how the vertices are linked together into triangles. If tile has more than 65536 vertices, the tile uses the IndexData32 structure to encode indices. Otherwise, it uses the IndexData16 structure.

To enforce proper byte alignment, padding is added before the IndexData to ensure 2 byte alignment for IndexData16 and 4 byte alignment for IndexData32.

Indices are encoded using the high water mark encoding from webgl-loader. Each triplet of indices specifies one triangle to be rendered, in counter-clockwise winding order.

func (*IndexData) Write

func (id *IndexData) Write(w io.Writer, vertexCount uint32) error

type LifeEvent

type LifeEvent struct {
	Year   int
	Day    int
	Region int
}

LifeEvent represents a date and place in the world.

func (LifeEvent) IsSet

func (l LifeEvent) IsSet() bool

IsSet returns true if the life event is set.

type Map

type Map struct {
	*geo.Geo // Geography / geology
	*Civ     // Civilization
	*bio.Bio // Plants / animals / funghi

}

func NewMap

func NewMap(seed int64, numPlates, numPoints, numVolcanoes int, jitter float64) (*Map, error)

func NewMapFromConfig

func NewMapFromConfig(seed int64, cfg *Config) (*Map, error)

func (*Map) ExportOBJ

func (m *Map) ExportOBJ(path string) error

func (*Map) ExportPng

func (m *Map) ExportPng(name string)

func (*Map) ExportSVG

func (m *Map) ExportSVG(path string) error

ExportSVG exports the terrain as SVG to the given path. NOTE: This produces broken somewhat incomplete output due to the wraparound of the mesh.

func (*Map) ExportWebp

func (m *Map) ExportWebp(name string)

func (*Map) Get3DTile

func (m *Map) Get3DTile(x, y, zoom int) *Tile3D

Get3DTile returns the quantized 3D tile for the given x, y, and zoom. WARNING: THIS DOES NOT WORK YET!!!!!

func (*Map) GetGeoJSONBorders

func (m *Map) GetGeoJSONBorders(la1, lo1, la2, lo2 float64, zoom, displayMode int) ([]byte, error)

GetGeoJSONBorders returns all borders as GeoJSON within the given bounds and zoom level.

func (*Map) GetGeoJSONCities

func (m *Map) GetGeoJSONCities(la1, lo1, la2, lo2 float64, zoom int) ([]byte, error)

GetGeoJSONCities returns all cities as GeoJSON within the given bounds and zoom level.

func (*Map) GetHeightMapTile

func (m *Map) GetHeightMapTile(x, y, zoom int) []byte

func (*Map) GetTile

func (m *Map) GetTile(x, y, zoom, displayMode, vectorMode int, drawRivers, drawTradeRoutes, drawLakes, drawShadows, aspectShading bool) image.Image

GetTile returns the image of the tile at the given coordinates and zoom level.

func (*Map) Tick

func (m *Map) Tick()

Tick advances the map by one tick.

type ObjectReference

type ObjectReference struct {
	ID   int  // ID of the object that the event is about.
	Type byte // Type of the object that the event is about.
}

type Person

type Person struct {
	ID      int            // ID of the person
	Region  int            // Location of the person
	Genes   genetics.Genes // Genes.
	City    *City          // City of the person
	Culture *Culture       // Culture of the person

	// Todo: Allow different naming conventions.
	FirstName string
	LastName  string
	NickName  string

	// Birth, death...
	// TODO: Add death cause.
	Age   int // Age of the person.
	Birth LifeEvent
	Death LifeEvent

	// Pregnancy
	PregnancyCounter int     // Days of pregnancy
	Prengancy        *Person // baby (TODO: twins, triplets, etc.)

	// Family (TODO: Distinguish between known and unknown family members.)
	// Maybe use a map of relations to people?
	Mother   *Person
	Father   *Person
	Spouse   *Person   // TODO: keep track of spouses that might have perished?
	Children []*Person // TODO: Split into known and unknown children.
}

Person represents a person in the world. TODO: Improve efficiency of this struct.

  • We could drop age, and use day-ticks for birth and death instead.
  • Also, we can get the gender directly from the genes.
  • We might be able to drop the pregnancy counter and use the birth life event of the child as a counter.
  • We can use use the Region for the location and derive the city from that.
  • A lot of this stuff is identical to simvillage_simple, so we could probably merge the person logic somehow, or move it to a separate package.

func (*Person) Gender

func (p *Person) Gender() geneticshuman.Gender

Gender returns the gender of the person.

func (*Person) Name

func (p *Person) Name() string

Name returns the name of the person.

func (*Person) Ref

func (p *Person) Ref() ObjectReference

Ref returns the object reference of the person.

func (*Person) String

func (p *Person) String() string

String returns the string representation of the person.

type QuantizedMeshHeader

type QuantizedMeshHeader struct {
	// The center of the tile in Earth-centered Fixed coordinates.
	CenterX float64
	CenterY float64
	CenterZ float64

	// The minimum and maximum heights in the area covered by this tile.
	// The minimum may be lower and the maximum may be higher than
	// the height of any vertex in this tile in the case that the min/max vertex
	// was removed during mesh simplification, but these are the appropriate
	// values to use for analysis or visualization.
	MinimumHeight float32
	MaximumHeight float32

	// The tile’s bounding sphere.  The X,Y,Z coordinates are again expressed
	// in Earth-centered Fixed coordinates, and the radius is in meters.
	BoundingSphereCenterX float64
	BoundingSphereCenterY float64
	BoundingSphereCenterZ float64
	BoundingSphereRadius  float64

	// The horizon occlusion point, expressed in the ellipsoid-scaled Earth-centered Fixed frame.
	// If this point is below the horizon, the entire tile is below the horizon.
	// See http://cesiumjs.org/2013/04/25/Horizon-culling/ for more information.
	HorizonOcclusionPointX float64
	HorizonOcclusionPointY float64
	HorizonOcclusionPointZ float64
}

type Religion

type Religion struct {
	ID                          int                 // The region where the religion was founded
	Name                        string              // The name of the religion
	NameGen                     *genstory.Generated // The name generation information
	Culture                     *Culture            // The culture that the religion is based on
	Parent                      *Religion           // The parent religion (if any)
	*genreligion.Classification                     // The religion classification
	Deity                       *genreligion.Deity  // The deity of the religion (if any)
	Expansion                   string              // How the religion wants to expand
	Expansionism                float64             // How much the religion wants to expand
	Founded                     int64               // Year when the religion was founded
}

Religion represents a religion in the world.

TODO: Ensure we can infer symbolisms from events and other things.

For example, if they worship the 99 beer bottles on the wall, we should be able to infer that they highly value beer and the number 99, as well as walls. They might be fearful of the number 100, and might have a taboo against the number 1. They might look kindly on people who can drink 99 beers in a row.

Another example: If they worship the sun, we should be able to infer that they highly value the sun, and that they might be fearful of the moon. They might have a celebration during the summer solstice and consider a total eclipse of the sun to be a bad omen and a moon eclipse to be a good omen.

DEITIES AND SYMBOLS

Folk religions that are purely based on the culture might warship nature itself, such as the sun, summer, the rain, a particular animal, or a particular plant. They might worship one or multiple deities that represent nature, like the sun god, the rain god, the god of the forest.

Organized religions might either worship one or multiple gods, or a single person that is considered to be a god (or chosen).

GRAPH

All these themes and connections could be represented as a graph, which would allow us to infer the relationships between deities and symbols and if mundane events hold any significance for a particular religion.

func (*Religion) String

func (r *Religion) String() string

type Tile3D

type Tile3D struct {
	Header QuantizedMeshHeader
	Vertex VertexData
	Index  IndexData
	Edge   EdgeIndices
}

Each tile is a specially-encoded triangle mesh where vertices overlap their neighbors at tile edges. In other words, at the root, the eastern-most vertices in the western tile have the same longitude as the western-most vertices in the eastern tile.

Terrain tiles are served gzipped. Once extracted, tiles are little-endian, binary data.

func (*Tile3D) Write

func (t *Tile3D) Write(w *bytes.Buffer) error

type TownType

type TownType string

TownType represents the type of a city.

const (
	TownTypeDefault     TownType = "town"
	TownTypeTrading     TownType = "trading"
	TownTypeMining      TownType = "mining"
	TownTypeMiningGems  TownType = "mining (gems)"
	TownTypeQuarry      TownType = "quarry"
	TownTypeFarming     TownType = "agricultural"
	TownTypeDesertOasis TownType = "desert oasis"
)

The different types of cities.

func (TownType) FoundingPopulation

func (t TownType) FoundingPopulation() int

FoundingPopulation returns the starting population of a city type.

func (TownType) GetDistanceSeedFunc

func (t TownType) GetDistanceSeedFunc(m *Civ) func() []int

GetDistanceSeedFunc returns the distance seed function for a city type.

func (TownType) GetFitnessFunction

func (t TownType) GetFitnessFunction(m *Civ) func(int) float64

GetFitnessFunction returns the fitness function for a city type.

type TradeTile

type TradeTile struct {
	// contains filtered or unexported fields
}

func (*TradeTile) PathEstimatedCost

func (n *TradeTile) PathEstimatedCost(to goastar.Pather) float64

PathEstimatedCost is a heuristic method for estimating movement costs between non-adjacent nodes.

func (*TradeTile) PathNeighborCost

func (n *TradeTile) PathNeighborCost(to goastar.Pather) float64

PathNeighborCost calculates the exact movement cost to neighbor nodes.

func (*TradeTile) PathNeighbors

func (n *TradeTile) PathNeighbors() []goastar.Pather

PathNeighbors returns the direct neighboring nodes of this node which can be pathed to.

func (*TradeTile) SetUsed

func (n *TradeTile) SetUsed()

type VertexData

type VertexData struct {
	VertexCount uint32
	// The horizontal coordinate of the vertex in the tile.
	// - When the u value is 0, the vertex is on the Western edge of the tile.
	// - When the value is 32767, the vertex is on the Eastern edge of the tile.
	// - For other values, the vertex's longitude is a linear interpolation between
	// the longitudes of the Western and Eastern edges of the tile.
	U []uint16 // [vertexCount]uint16
	// The vertical coordinate of the vertex in the tile.
	// - When the v value is 0, the vertex is on the Southern edge of the tile.
	// - When the value is 32767, the vertex is on the Northern edge of the tile.
	// - For other values, the vertex's latitude is a linear interpolation between
	// the latitudes of the Southern and Nothern edges of the tile.
	V []uint16 // [vertexCount]uint16
	// The height of the vertex in the tile.
	// - When the height value is 0, the vertex's height is equal to the minimum
	// height within the tile, as specified in the tile's header.
	// - When the value is 32767, the vertex's height is equal to the maximum height
	// within the tile.
	// - For other values, the vertex's height is a linear interpolation between the
	// minimum and maximum heights.
	Height []uint16 // [vertexCount]uint16
}

The vertexCount field indicates the size of the three arrays that follow. The three arrays contain the delta from the previous value that is then zig-zag encoded in order to make small integers, regardless of their sign, use a small number of bits.

func (*VertexData) Write

func (vd *VertexData) Write(w io.Writer) error

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL