-
Notifications
You must be signed in to change notification settings - Fork 1
/
history.go
104 lines (89 loc) · 3.13 KB
/
history.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package genworldvoronoi
import (
"fmt"
"github.com/Flokey82/genworldvoronoi/geo"
)
type History struct {
*geo.Calendar
Events []*Event
}
func NewHistory(c *geo.Calendar) *History {
return &History{
Calendar: c,
}
}
const (
ObjectTypeCity = iota
ObjectTypeCityState
ObjectTypeEmpire
ObjectTypeCulture
ObjectTypeReligion
ObjectTypeRegion
ObjectTypeMountain
ObjectTypeRiver
ObjectTypeLake
ObjectTypeSea
ObjectTypeVolcano
ObjectTypePerson
ObjectTypeTribe
)
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 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.
// TODO: Related event(s), related object(s), etc.?
// For example, the death of a person might be related to the birth of a
// child, or the founding of a city.
// Related object(s) might be the city that a person was born in, or the
// people that were killed in a battle.
}
func (e *Event) String() string {
return fmt.Sprintf("%s: %s", e.Type, e.Msg)
}
func (h *History) GetEvents(id int, t byte) []*Event {
var events []*Event
for _, e := range h.Events {
if e.ID.ID == id && e.ID.Type == t {
events = append(events, e)
}
}
return events
}
// AddEvent adds an event to the history and returns a pointer to the event.
func (h *History) AddEvent(t string, msg string, id ObjectReference) *Event {
event := &Event{
Year: h.GetYear(),
Type: t,
Msg: msg,
ID: id,
}
h.Events = append(h.Events, event)
return event
}
/*
Ok, here are my thoughts on the history system:
Each event is connected to a specific object (e.g. a city, a person, a tribe,
a nation, a regionetc.). The event has a type (e.g. "city founded", "city
destroyed", "city conquered", "city renamed", "city renamed", "volcano erupted",
"earthquake", etc.). Of course, each event might have additional data (e.g.
"city destroyed" might have a reference to what destroyed the city, "city
conquered" might have a reference to who conquered the city, etc.).
When we tick the world, we have in each sub-system (e.g. the geo system, the
city system, the tribe system, the nation system, etc.) a list of events that
happened in the last tick. We then add these events to the history system.
Right now we use a simple slice to store the events, but this might become inefficient
if we have a lot of events. We might want to use a more efficient data structure
that allows us to quickly find events that happened in a specific time range.
There is for example a one dimensional range tree that might be useful, if we
want to find all events that happened in a specific time range.
Cross references might be useful to quickly identify events that are related to
a specific object or to each other.
The downside is, that we need to keep track of those cross references, which takes
additional memory... but once we switch to some form of database, we can probably
just store the cross references there and not in momory.
*/