blob: 0e3683b0e53a50af9426d83ed49409caceb97ff7 (
plain)
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
|
namespace LivingVillage.Kernel
module Sim =
[<Struct>]
type Vec2 =
{ X: float32
Y: float32 }
[<Struct>]
type Avatar =
{ Pos: Vec2 }
type Input =
{ MoveX: float32
MoveY: float32 }
type TimeStep =
{ Input: Input }
[<Struct>]
type NoHost =
{ Reserved: uint64 }
[<Struct>]
type World =
{ Tick: int64
Time: float
Rng: RngState
Avatar: Avatar
NoHost: NoHost }
let ticksPerSecond = 60L
let secondsPerDay = 86400L
let ticksPerDay = secondsPerDay * ticksPerSecond
let dtSeconds = 1.0 / float ticksPerSecond
let dtSecondsF = 1.0f / float32 ticksPerSecond
let mapWidthTiles = 64
let mapHeightTiles = 48
let tilePixels = 32
let avatarSpeed = 160.0f
let initialWorld (seed: uint64) : World =
let centerX = float32 (mapWidthTiles * tilePixels / 2 - tilePixels / 2)
let centerY = float32 (mapHeightTiles * tilePixels / 2 - tilePixels / 2)
{ Tick = 0L
Time = 0.0
Rng = Rng.ofSeed seed
Avatar = { Pos = { X = centerX; Y = centerY } }
NoHost = { Reserved = 0UL } }
let clamp v lo hi = if v < lo then lo elif v > hi then hi else v
let step (ts: TimeStep) (world: World) : World =
let tick = world.Tick + 1L
let maxX = float32 (mapWidthTiles * tilePixels - tilePixels)
let maxY = float32 (mapHeightTiles * tilePixels - tilePixels)
let dx = ts.Input.MoveX * avatarSpeed * dtSecondsF
let dy = ts.Input.MoveY * avatarSpeed * dtSecondsF
{ Tick = tick
Time = float tick * dtSeconds
Rng = world.Rng
Avatar =
{ Pos =
{ X = clamp (world.Avatar.Pos.X + dx) 0.0f maxX
Y = clamp (world.Avatar.Pos.Y + dy) 0.0f maxY } }
NoHost = world.NoHost }
|