tesseract

package module
v0.0.0-...-d34077f Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2021 License: AGPL-3.0 Imports: 17 Imported by: 0

README

tesseract

Discord

Deterministic physics engine in golang. Designed for the Argo Navis game. Contains the Space Stone.

License

See COPYING file

tesseract opens wormhole

Documentation

Overview

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright 2019 The tesseract Authors

This file is part of tesseract.

tesseract is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

tesseract is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

Index

Constants

View Source
const (
	Sphere = iota
	Box
)
View Source
const (
	DBL_EPSILON = 2.2204460492503131E-16

	GravitationalConstant = 6.674e-11
)
View Source
const (
	Terra = iota
	Gas
)

Variables

View Source
var (
	//
	// Math
	//
	KHat = &V3{0, 0, 1}
)

Functions

func DebugSectors

func DebugSectors(onlyMapped bool)

func DegToRad

func DegToRad(degrees float64) float64

func DevShipOrbit

func DevShipOrbit()

func DevWorld

func DevWorld(testSeed uint64)

func DevWorldStars

func DevWorldStars()

func HandleAction

func HandleAction(j map[string]interface{}) error

The input to this function is raw bytes from other layers, e.g. the binary payload of a WebSocket message. As such these bytes have not yet been validated, and may be malicious. TODO: refactor and document security assumptions and input validation in diff layers. TODO: for dev/test we use a simple JSON schema

func HandleMsg

func HandleMsg(msg []byte) error

func InitWorld

func InitWorld()

func NewEntitySub

func NewEntitySub(e Id) (<-chan []byte, chan<- bool)

func NewGalaxy

func NewGalaxy()

func NewRand

func NewRand(seed uint64) (*xrand.Rand, error)

func NormalizeAngle

func NormalizeAngle(a float64) float64

func RadToDeg

func RadToDeg(radians float64) float64

func ResetState

func ResetState()

func StartEngine

func StartEngine()

func StartWebSocket

func StartWebSocket()

func WriteControlClose

func WriteControlClose(c *websocket.Conn, closeCode int, str string) error

Types

type Action

type Action interface {
	Execute() error
}

Actions are authenticated requests to modify the game state. Most actions originate from users, where we consider them authenticated post user account signature verification. Actions can also originate from the game engine itself; such actions are always considered authenticated.

type ActionEngineThrust

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

func (*ActionEngineThrust) Execute

func (a *ActionEngineThrust) Execute() error

type ActionRotate

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

func (*ActionRotate) Execute

func (a *ActionRotate) Execute() error

type Atmosphere

type Atmosphere struct {
	Height, ScaleHeight float64
	PressureSeaLevel    float64
}

func (*Atmosphere) PressureAtAltitude

func (a *Atmosphere) PressureAtAltitude(alt float64) float64

https://en.wikipedia.org/wiki/Scale_height

type BVHNode

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

Bounding Volume Hierarchy Tree. Each non-leaf holds a bounding volume encompassing all its child nodes. Each leaf holds a bounding volume of a single entity.

func (*BVHNode) Delete

func (n *BVHNode) Delete()

func (*BVHNode) Insert

func (n *BVHNode) Insert(e Id, v BoundingVolume)

func (*BVHNode) IsLeaf

func (n *BVHNode) IsLeaf() bool

func (*BVHNode) PotentialContacts

func (n *BVHNode) PotentialContacts() [][2]Id

func (*BVHNode) UpdateBoundingVolume

func (n *BVHNode) UpdateBoundingVolume()

type Body

type Body struct {
	Name string

	Mass   float64
	Radius float64

	Orbit    *OE
	Rotation *V3

	Atmosphere *Atmosphere

	MagField float64
}

type BoundingShape

type BoundingShape uint8

Collision Detection

type BoundingSphere

type BoundingSphere struct {
	P *V3
	R float64
}

func (*BoundingSphere) CalcGrowth

func (s *BoundingSphere) CalcGrowth(bv BoundingVolume) float64

func (*BoundingSphere) NewBoundingVolume

func (s *BoundingSphere) NewBoundingVolume(bv BoundingVolume) BoundingVolume

func (*BoundingSphere) Overlaps

func (s *BoundingSphere) Overlaps(bv BoundingVolume) bool

func (*BoundingSphere) Shape

func (s *BoundingSphere) Shape() BoundingShape

BoundingVolume interface

func (*BoundingSphere) SurfaceArea

func (s *BoundingSphere) SurfaceArea() float64

func (*BoundingSphere) Volume

func (s *BoundingSphere) Volume() float64

type BoundingVolume

type BoundingVolume interface {
	// Returns the shape type of the bounding volume.
	Shape() BoundingShape

	// Returns whether this volume overlaps with the passed volume.
	Overlaps(BoundingVolume) bool

	// Returns a bounding volume that fully bounds this volume
	// and the passed volume.
	NewBoundingVolume(BoundingVolume) BoundingVolume

	// Returns how much this bounding volume would have to grow in order to
	// bound the passed bounding volume.
	// This value can be derived from the NewBoundingVolume method and is
	// provided a separate method for optimization purposes.
	// The returned value is dimensionless and not a volume unit.
	CalcGrowth(BoundingVolume) float64

	// Returns the volume in cubic meters (m^3)
	Volume() float64

	// Returns the surface area in square meters (m^2)
	SurfaceArea() float64
}

The BoundingVolume interface enables any 3D volume that fully bounds one or more 3D volumes to be used with the Bounding Volume Hierarchy Tree and other constructs used in collision detection.

type Component

type Component interface {
}

Components are data containers for entities. They contain no game logic.

type DragForceGen

type DragForceGen struct {
	DragCoef1, DragCoef2 float64
}

TODO: apply same drag function on rotation

func (*DragForceGen) IsExpired

func (d *DragForceGen) IsExpired() bool

func (*DragForceGen) UpdateForce

func (d *DragForceGen) UpdateForce(e Id, duration float64) (*V3, *V3)

type Engine

type Engine interface {
	MaxThrust() float64
	SetThrust(float64) error
}

type EntJSON

type EntJSON struct {
	Id  Id       `json: "id"`
	Mas *float64 `json: "mass"`
	Pos *V3      `json: "pos"`
	Vel *V3      `json: "vel"`
	Ori *Q       `json: "ori"`
	Rot *V3      `json: "rot"`
}

JSON Encoding

type EntitySub

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

func (*EntitySub) Update

func (es *EntitySub) Update()

type EntitySubData

type EntitySubData struct {
	OE            *OE
	OrbitalPoints []V3

	Pos *V3
	Vel *V3

	Ori *Q
	Rot *V3
}

type ForceGen

type ForceGen interface {
	// UpdateForce returns linear force and torque.
	// Zero force/torque should be returned as nil.
	// UpdateForce is called by the physics system once per game frame.
	UpdateForce(e Id, duration float64) (*V3, *V3)

	// IsExpired returns whether the force generator is expired.
	// IsExpired is called by the physics system once per game frame update.
	IsExpired() bool
}

ForceGen interface is implemented by force generators that generate linear force and angular torque (the rotational equivalent of linear force) onto moveable entities with mass.

Force generators implementing the ForceGen interface are called by the physics system once per game frame.

Force generators must keep track of when they are expired.

type GameEngine

type GameEngine struct {
	// contains filtered or unexported fields
}
var GE *GameEngine

func (*GameEngine) Loop

func (ge *GameEngine) Loop() error

type Hyperdrive

type Hyperdrive struct {
}

The hyperdrive system implements travel through hyperspace.

func (*Hyperdrive) Init

func (hd *Hyperdrive) Init() error

System interface

func (*Hyperdrive) IsHotPostUpdate

func (hd *Hyperdrive) IsHotPostUpdate(e Id) bool

func (*Hyperdrive) Update

func (hd *Hyperdrive) Update(wTime, elapsed float64, rf *RefFrame) error

type Hyperspace

type Hyperspace struct {
	// Start position in galactic grid units (see galaxy.go)
	Start *V3

	// Target the hyperdrive is locked onto
	// TODO: support non-star targets
	// TODO: support hyperdrive in arbitrary directions without target lock
	Target *Star

	// Time when reaching target
	TargetTime float64

	// Multiple of speed of light in vacuum
	Speed float64

	// If exited by user action
	Exited bool
}

Data for an instance of one ship in hyperdrive

func NewHyperspace

func NewHyperspace(start *V3, target *Star, wTime, tTime float64) *Hyperspace

type Id

type Id uint64

Entities are ids.

func DevNewShip

func DevNewShip() Id

type M3

type M3 [9]float64

3x3 Matrix

func InertiaTensorCuboid

func InertiaTensorCuboid(m, w, h, d float64) *M3

https://en.wikipedia.org/wiki/List_of_moments_of_inertia

mass, width, height, depth

func (*M3) Inverse

func (m *M3) Inverse()

func (*M3) Mul

func (m *M3) Mul(a *M3) *M3

func (*M3) Transform

func (m *M3) Transform(v *V3) *V3

func (*M3) TransformTranspose

func (m *M3) TransformTranspose(v *V3) *V3

type M4

type M4 [12]float64

3x4 Matrix

func (*M4) Transform

func (m *M4) Transform(v *V3) *V3

type MassHistogram

type MassHistogram struct {
	Ranges     []MassRange
	AvgMass    float64
	TotalStars int
}
var (
	Rand     *xrand.Rand
	MassHist *MassHistogram
)

type MassRange

type MassRange struct {
	Start     float64
	Range     float64
	StarCount int
}

Mass Histogram / Initial Stellar Mass Function (IMF)

[1] https://en.wikipedia.org/wiki/Initial_mass_function [2] https://github.com/Azeret/galIMF

type MessageBus

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

MessageBus is a channel-based message / event bus where systems post messages delivered to all subscribers.

func (*MessageBus) Post

func (mb *MessageBus) Post(msg []byte)

func (*MessageBus) Subscribe

func (mb *MessageBus) Subscribe() <-chan []byte

type Moon

type Moon struct {
}

MOONS

type OE

type OE struct {
	Ω float64
	// contains filtered or unexported fields
}

OE holds orbital elements [2] and related variables to uniquely represent a specific orbit in the simplified two-body model. The orbiter is assumed to have neglible mass compared to the primary (host) body and the primary is stationary in the applicable reference frame.

Elements/Fields:

h: Specific angular momentum (m^2·s^-1) (See [3] and chapter 2.4 in [1]) i: Inclination (degrees) Ω: Longitude of the ascending node (degrees) e: Eccentricity (0 <= e <= inf) ω: Argument of Periapsis (degrees) θ: True Anomaly (degrees) μ: Standard gravitational parameter of the primary (m^3·s^-2)

func StateVectorToOrbital

func StateVectorToOrbital(r, v *V3, μ float64) *OE

StateVectorToOrbital returns the orbital elements converted from the orbital state vector and standard gravitational parameter of the primary. See Algorithm 4.2 and https://en.wikipedia.org/wiki/Orbital_state_vectors

func (*OE) Altitude

func (o *OE) Altitude() float64

Altitude returns the distance between the orbiter and the primary. Altitude works for parabolic and hyperbolic orbits, but returns positive infinity if 1 + e*math.Cos(θ) <= 0.

func (*OE) Apoapsis

func (o *OE) Apoapsis() float64

Apoapsis returns the farthest point of the orbit. Positive infinity is returned if the orbit is parabolic or hyperbolic.

func (*OE) Debug

func (o *OE) Debug()

func (*OE) Fmt

func (o *OE) Fmt() string

func (*OE) OrbitalToStateVector

func (o *OE) OrbitalToStateVector() (*V3, *V3)

OrbitalToStateVector returns the orbital state vector of the orbit. Perifocal coordinates are used in an intermediate step. See Algorithm 4.5 and https://en.wikipedia.org/wiki/Perifocal_coordinate_system

func (*OE) Periapsis

func (o *OE) Periapsis() float64

Periapsis returns the nearest point of the orbit.

func (*OE) Period

func (o *OE) Period() float64

Period returns the orbital period. Positive infinity is returned if the orbit is parabolic or hyperbolic. https://en.wikipedia.org/wiki/Orbital_period#Small_body_orbiting_a_central_body

func (*OE) PointsApprox

func (o *OE) PointsApprox(n uint) []V3

PointsApprox returns n points approximating the orbit. The points are ordered by orbital direction and evenly spaced in orbital time but not in distance (unless the orbit is circular).

func (*OE) SemimajorAxis

func (o *OE) SemimajorAxis() float64

SemimajorAxis returns the semimajor axis of the orbit.

func (*OE) SemiminorAxis

func (o *OE) SemiminorAxis() float64

SemiminorAxis returns the semiminor axis of the orbit. TODO: generalize to all orbit types, see table 3.1

func (*OE) Speed

func (o *OE) Speed() float64

Speed returns the orbital speed of the orbiter relative to the primary. https://en.wikipedia.org/wiki/Vis-viva_equation

func (*OE) TimeFromTrueAnomaly

func (o *OE) TimeFromTrueAnomaly(θ float64) float64

TimeFromTrueAnomaly returns the time for a given true anomaly.

func (*OE) TrueAnomalyFromTime

func (o *OE) TrueAnomalyFromTime(t float64) float64

TrueAnomalyFromTime returns the orbit's true anomaly in radians at time t.

type Physics

type Physics struct{}

The Physics system simulates classical mechanics.

func (*Physics) Init

func (p *Physics) Init() error

System interface

func (*Physics) IsHotPostUpdate

func (p *Physics) IsHotPostUpdate(e Id) bool

func (*Physics) Update

func (p *Physics) Update(worldTime, elapsed float64, rf *RefFrame) error

type Planet

type Planet struct {
	Entity Id
	Mass   float64
	Radius float64

	AxialTilt      float64
	RotationPeriod float64

	SurfaceGravity float64
	Atmosphere     *Atmosphere
}

func (*Planet) DefaultOrbit

func (p *Planet) DefaultOrbit() *OE

DefaultOrbit returns a circular, prograde orbit 100km above a planet's surface or above its atmosphere (if it has one).

func (*Planet) GeodeticToCartesian

func (p *Planet) GeodeticToCartesian(lat, lon float64) float64

Where we lock X,Y,Z coords does not matter, as we do not yet have surface features. Simply select a orientation derived from the planet's orientation 3D vector.

func (*Planet) GravityAtAltitude

func (p *Planet) GravityAtAltitude(alt float64) float64

https://en.wikipedia.org/wiki/Gravity_of_Earth#Altitude p.surface_gravity has been pre-calculated by world building scripts

type PlanetBase

type PlanetBase uint8

PLANETS

type ProcGen

type ProcGen struct{}

The ProcGen system procedurally generates the game world. The ProcGen system is activated when players traverse new space/terrain.

func (*ProcGen) Init

func (pg *ProcGen) Init() error

System interface

func (*ProcGen) IsHotPostUpdate

func (pg *ProcGen) IsHotPostUpdate(e Id) bool

func (*ProcGen) Update

func (pg *ProcGen) Update(worldTime, elapsed float64, rf *RefFrame) error

type Q

type Q struct {
	R, I, J, K float64
}

Quaternion

func (*Q) AddScaledVector

func (q *Q) AddScaledVector(v *V3, s float64) *Q

func (*Q) ForwardVector

func (q *Q) ForwardVector() *V3

func (*Q) Mul

func (q *Q) Mul(a *Q) *Q

func (*Q) Normalise

func (q *Q) Normalise()

type RefFrame

type RefFrame struct {
	// The top-level reference frame (the Milky Way galaxy) has Parent,
	// Position, Orbit and Orientation all set to nil.
	Parent *RefFrame

	Pos   *V3
	Orbit *OE

	// Except for the top-level frame, Orientation is always non-nil;
	// it's required to translate local coordinates to outer frame(s).
	// A zero orientation equals inheriting the parent's frame orientation
	Orientation *Q

	Radius float64
}

See https://en.wikipedia.org/wiki/Frame_of_reference

and https://en.wikipedia.org/wiki/Celestial_coordinate_system

The game world is a hiearchical tree of reference frames.
Each reference frame except the root has one parent reference frame.
Child frames are "dragged along" their parent frames.

Most gameplay logic only knows about the local frame, but some gameplay
involves multiple frames.  For example, warp drive involves leaving one
ref frame, spending some time in a noninteractive / locked frame and
then arriving in a destination frame.

The top-level or root reference frame is the Milky Way galaxy.
It has no parent or surrounding context and can be thought of as a
static/stationary 3D grid.

2nd level reference frames are generally star systems, centered on the
system's approximate barycenter.  In a single-star system the reference
frame center is the center of the star.

3rd level frames can be planets orbiting stars, 4th level moons of planets.

The location of a reference frame relative its parent is encoded
as either a 3D X,Y,Z position or as orbital elements, with the other
set to nil.

If the frame is stationary relative its parent - for example the inside
of a building on a planet surface - then it has a 3D position (X,Y,Z)
but no orbital elements.

func (*RefFrame) IsRoot

func (rf *RefFrame) IsRoot() bool

type RefFrameJSON

type RefFrameJSON struct {
	Ents []EntJSON `json: "ents"`
}

type Rotational

type Rotational struct {
	R    *V3 // Rotation X,Y,Z 3D vector
	IITB *M3 // Inverse Inertia Tensor Body space/coordinates
	IITW *M3 // Inverse Inertia Tensor World space/coordinates
	T    *M4 // 3x4 matrix transforming body space/coordinates to world
}

If an object can rotate it has an inertia tensor

type Script

type Script struct {
	Name         string
	UnicodeStart int
	CharCount    int
	Weight       int
}

TODO: check if we can use package unicode for more of this

type Sector

type Sector struct {
	// Galactic X,Y,Z in gridUnit
	Corner *V3

	// Value between 0.0 and 1.0 denoting how much the sector has been
	// explored by players == procedurally generated
	Mapped float64

	// Star positions are in gridUnit
	Stars []*Star
}

Sector is a galactic 3D cube volume used by the procedural generation of stars and other galactic-level features.

func GetSector

func GetSector(pos *V3) *Sector

func (*Sector) Debug

func (s *Sector) Debug()

Debug

func (*Sector) Key

func (s *Sector) Key() string

func (*Sector) Traverse

func (s *Sector) Traverse()

Traverse enacts partial procedural generation of a sector. Traverse is generally called by the TODO system when a player is traversing the sector (having spent X time and/or moved Y distance in the sector).

type ShipClass

type ShipClass interface {
	// The mass in kilograms (kg) of the ship when no modules are attached
	// and nothing is in the cargo bay.
	MassBase() float64

	// The radius in meters (m) of the ship's bounding sphere.
	BoundingSphereRadius() float64

	// The ship volume in cubic meters (m^3) excluding any external modules.
	VolumeBase() float64
	// The ship volume when packed inside a cargo bay or other storage.
	PackedVolumeBase() float64

	// Control Moment Gyroscope (CMG) Max Torque in newtons (N).
	//
	// This is a built-in, non-modular engine situated at the ship's
	// center of mass.  The CMG has a single function: generate torque around
	// the ship's center of mass.  This rotates the ship in any direction
	// without changing velocity.
	//
	// This is a simple mechanism to enable the physics engine to simulate
	// "turning inertia" realistically; players will notice their ships
	// turn slower when storing heavy cargo or fielding heavy modules
	// like armor plates.
	//
	// By using a 3D vector we can configure ships that turn faster "up"/"down"
	// (pitch) than "left"/"right" (yaw), making banked turns useful
	// even in zero-g/vacuum (https://en.wikipedia.org/wiki/Banked_turn).
	CMGTorqueCap() V3

	// Hull/Armor/Shield Capacity in hit points.
	HullHPCap() float64

	// Cargo bay capacity in cubic meters (m^3).
	CargoBayCap() float64

	// Hull Aerodynamic Lift and Drag Coefficients (dimensionless quantities).
	// This is the base lift/drag of the ship hull before taking into account
	// modules that affect lift/drag and aerodynamic player skills.
	// TODO: split into subsonic, supersonic, hypersonic
	AeroLiftBase() float64
	AeroDragBase() float64

	// Hard Point integer count.
	// Each Hard Point can attach one external module such as a weapon module.
	HardPoints() uint8

	// High Power Slot integer count.
	// Each internal high power slot can fit one high-powered module.
	HighPowerSlots() uint8

	// Low Power Slot integer count.
	// Each internal low power slot can fit one low-powered module.
	LowPowerSlots() uint8
}

Ship classes are analogous to classical navy ship classes. See https://en.wikipedia.org/wiki/Ship_class.

Each class is uniquely identified by a set of constants defining physical and gameplay parameters.

Ship classes are not OOP classes and there is no inheritance or instancing. Rather, each ship class is encoded as a set of constants and an empty struct implements the ShipClass interface.

This enables other packages to read immutable ship parameters while game state components store dynamic parameters like ship mass and hull/armor/shield hit points.

Naming convention: "Base" and "Cap" denotes a value intrinsic to the ship class before effects are applied from any attached modules or player character skills. "Base" and "Cap" are always suffixes.

A parameter's real-time value can be lower than its base value. An example of this is a ship without any modules or cargo flown by a player with trained aerodynamic skills - the ship's effective drag would be lower than the hull's base value.

type Star

type Star struct {
	Entity Id
	Body

	SpectralType rune
	Luminosity   float64
	SurfaceTemp  float64
}

Star is a unique star.

func NewStar

func NewStar(mass float64) *Star

NewStar returns a procedurally generated star. Many of the stars attributes are derived from the mass.

func (*Star) Debug

func (s *Star) Debug()

func (*Star) DefaultOrbit

func (s *Star) DefaultOrbit() *OE

DefaultOrbit returns an orbit suitable as destination for FTL drives.

func (*Star) HabitableZone

func (s *Star) HabitableZone() (float64, float64)

https://www.planetarybiology.com/calculating_habitable_zone.html TODO: update to latest research

type StarSystem

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

Star system barycenters are fixed points in the galactic reference frame. In single-star systems, the barycenter equals the center of the star.

type State

type State struct {
	MsgBus    *MessageBus
	ActionBus *MessageBus

	EntCount  uint64
	EntFrames map[Id]*RefFrame

	HotEnts  map[*RefFrame]map[Id]bool
	IdleEnts map[*RefFrame]map[Id]bool

	IdleSince map[Id]float64

	EntitySubs          map[*EntitySub]bool
	EntitySubsCloseChan chan *EntitySub

	// Hyperspace component holds data used by the Hyperdrive System
	Hyperspace map[Id]*Hyperspace

	StarsById   map[Id]*Star
	StarsByName map[string]*Star

	Sectors map[string]*Sector

	//
	// Physics Components
	//
	// Mass component holds float64 values
	Mass map[Id]*float64

	// Position and Velocity components holds 3x1 vectors
	Pos map[Id]*V3
	Vel map[Id]*V3

	// Orbit Component holds Keplerian Orbital Elements
	Orb map[Id]*OE

	// Orientation Component holds quaternions
	Ori map[Id]*Q

	// Holds force/torque generators for movable entities
	ForceGens map[Id][]ForceGen

	// Holds rotational data for entities that can rotate
	Rot map[Id]*Rotational

	// Holds ship class data
	ShipClass map[Id]ShipClass
}
var S *State

func (*State) AddEntitySub

func (s *State) AddEntitySub(e Id)

func (*State) AddForceGen

func (s *State) AddForceGen(e Id, fg ForceGen)

func (*State) AddStar

func (s *State) AddStar(star *Star, pos *V3)

func (*State) MarshalJSON

func (s *State) MarshalJSON() ([]byte, error)

Encode state as an array of reference frames, each having an array of entities where each entity has mass, position, etc. TODO: for now, we assume all entities have all components

func (*State) NewEntity

func (s *State) NewEntity() Id

func (*State) SetHot

func (s *State) SetHot(e Id, rf *RefFrame)

func (*State) SetIdle

func (s *State) SetIdle(e Id, rf *RefFrame, since float64)

type System

type System interface {
	// Init is called by the game engine once before the game loop begins.
	// It should perform any initialization needed by the system.
	Init() error

	// Update is called by the game engine once for each hot ref frame
	// every game frame.  Update is not called if there are no hot ref frames
	// (all game entities idle) in a given game frame.
	// The system must perform any state updates for all hot entities in the
	// hot ref frame.  Depending on the system, it may also update state for
	// idle entities in the hot ref frame (e.g. if an area of effect weapon
	// hits idle entities).
	Update(worldTime, elapsed float64, rf *RefFrame) error

	// IsHotPostUpdate is called by the game engine once for each hot entity
	// every game frame.  IsHotPostUpdate is not called if there are no hot
	// entities in the given game frame (all entities idle).
	// The system must return if the given entity remains hot after the last
	// update.
	//
	// Example: the classical mechanics system returns true for any entity
	//          that has active force generators and false otherwise.
	IsHotPostUpdate(Id) bool
}

Systems contain and execute game logic. Systems operate on and manipulate component data (game state).

Each system handles a subset of components, which may overlap with other component subsets handled by other systems.

Examples of systems include physics, combat and player trading exchanges.

While components hold the game state data, systems track some data such as which entities "are in the system" (have data in all related components)

type ThrustForceGen

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

For e.g. center-of-mass-aligned engines

func (*ThrustForceGen) IsExpired

func (t *ThrustForceGen) IsExpired() bool

func (*ThrustForceGen) UpdateForce

func (t *ThrustForceGen) UpdateForce(e Id, elapsed float64) (*V3, *V3)

type Timer

type Timer struct {
	Id     Id
	MS     time.Time
	Action *Action
}

The timer component is attachable to any entity and used for things like delayed-effect weapons, manufacturing processes and skill training.

type TimerComponent

type TimerComponent struct {
	Timers map[Id]*Timer
	Sorted TimerList
}

func (*TimerComponent) AddEntityData

func (tc *TimerComponent) AddEntityData(id Id, t *Timer)

func (*TimerComponent) GetEntityData

func (tc *TimerComponent) GetEntityData(id Id) *Timer

func (*TimerComponent) Init

func (tc *TimerComponent) Init() error

func (*TimerComponent) RemoveEntity

func (tc *TimerComponent) RemoveEntity(id Id)

type TimerList

type TimerList []*Timer

Alongside the map of entity ids to Timers, we also maintain this list (slice) of Timers Sorted in chronological order. The engine loop uses this to only traverse expired Timers.

func (TimerList) Len

func (tl TimerList) Len() int

sort.Interface

func (TimerList) Less

func (tl TimerList) Less(i, j int) bool

func (TimerList) Swap

func (tl TimerList) Swap(i, j int)

type TurnForceGen

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

For Ship turning

func (*TurnForceGen) IsExpired

func (t *TurnForceGen) IsExpired() bool

func (*TurnForceGen) UpdateForce

func (t *TurnForceGen) UpdateForce(e Id, elapsed float64) (*V3, *V3)

type V3

type V3 struct {
	X, Y, Z float64
}

Types and functions for 3D game math, including vectors, matrices, quaternions and trigonometry.

Based primarily on chapters 2 and 9 in [1].

func (*V3) Add

func (v *V3) Add(a, b *V3) *V3

func (*V3) AddScaledVector

func (v *V3) AddScaledVector(a *V3, s float64) *V3

func (*V3) ComponentProduct

func (v *V3) ComponentProduct(a, b *V3) *V3

func (*V3) Fmt

func (v *V3) Fmt() string

func (*V3) Invert

func (v *V3) Invert()

func (*V3) IsZero

func (v *V3) IsZero() bool

func (*V3) Magnitude

func (v *V3) Magnitude() float64

func (*V3) MulScalar

func (v *V3) MulScalar(a *V3, s float64) *V3

func (*V3) Normalise

func (v *V3) Normalise()

func (*V3) ScalarProduct

func (v *V3) ScalarProduct(a *V3) float64

func (*V3) Set

func (v *V3) Set(a *V3) *V3

func (*V3) SquareMagnitude

func (v *V3) SquareMagnitude() float64

func (*V3) Sub

func (v *V3) Sub(a, b *V3) *V3

func (*V3) VectorProduct

func (v *V3) VectorProduct(a, b *V3) *V3

type WarmJet

type WarmJet struct{}

func (*WarmJet) AeroDragBase

func (s *WarmJet) AeroDragBase() float64

func (*WarmJet) AeroLiftBase

func (s *WarmJet) AeroLiftBase() float64

func (*WarmJet) BoundingSphereRadius

func (s *WarmJet) BoundingSphereRadius() float64

func (*WarmJet) CMGTorqueCap

func (s *WarmJet) CMGTorqueCap() V3

func (*WarmJet) CargoBayCap

func (s *WarmJet) CargoBayCap() float64

func (*WarmJet) HardPoints

func (s *WarmJet) HardPoints() uint8

func (*WarmJet) HighPowerSlots

func (s *WarmJet) HighPowerSlots() uint8

func (*WarmJet) HullHPCap

func (s *WarmJet) HullHPCap() float64

func (*WarmJet) LowPowerSlots

func (s *WarmJet) LowPowerSlots() uint8

func (*WarmJet) MassBase

func (s *WarmJet) MassBase() float64

func (*WarmJet) PackedVolumeBase

func (s *WarmJet) PackedVolumeBase() float64

func (*WarmJet) VolumeBase

func (s *WarmJet) VolumeBase() float64

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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