Skip to content

Commit 7462e80

Browse files
committed
docs: document player-point-change bootstrap slice
1 parent bd08a24 commit 7462e80

7 files changed

Lines changed: 168 additions & 4 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Current scope of the project:
1717
- A deterministic selected-character `SYNC_POSITION` reconciliation path wired through the current bootstrap runtime.
1818
- A first visible-world bootstrap that inserts the selected character into the game world after `ENTERGAME`.
1919
- A first self-only `CHARACTER_UPDATE` refresh emitted immediately after the visible-world insert.
20+
- A first self-only `PLAYER_POINT_CHANGE` refresh emitted immediately after the selected-character update.
2021
- Multi-stage Docker build with a lightweight runtime image that keeps Go debug information intact by avoiding stripped builds.
2122

2223
## Near-term goal
@@ -114,6 +115,7 @@ Legend:
114115
- `spec/protocol/select-world-entry.md`
115116
- `spec/protocol/visible-world-bootstrap.md`
116117
- `spec/protocol/character-update-bootstrap.md`
118+
- `spec/protocol/player-point-change-bootstrap.md`
117119
- `spec/protocol/sync-position-bootstrap.md`
118120
- `spec/protocol/boot-path.md`
119121
- `spec/protocol/packet-matrix.md`
@@ -188,7 +190,7 @@ Current stub bootstrap credentials:
188190

189191
Current minimal runtime path exposed by the shipped binaries:
190192
- `authd`: `HANDSHAKE -> AUTH -> LOGIN3 -> AUTH_SUCCESS`
191-
- `gamed`: `HANDSHAKE -> LOGIN -> SELECT -> EMPIRE_SELECT? -> CHARACTER_CREATE? -> CHARACTER_SELECT -> LOADING -> GAME -> CHARACTER_ADD -> CHAR_ADDITIONAL_INFO -> CHARACTER_UPDATE -> MOVE/SYNC_POSITION`
193+
- `gamed`: `HANDSHAKE -> LOGIN -> SELECT -> EMPIRE_SELECT? -> CHARACTER_CREATE? -> CHARACTER_SELECT -> LOADING -> GAME -> CHARACTER_ADD -> CHAR_ADDITIONAL_INFO -> CHARACTER_UPDATE -> PLAYER_POINT_CHANGE -> MOVE/SYNC_POSITION`
192194

193195
This is still a bootstrap runtime, not full gameplay.
194196
What exists today:
@@ -199,7 +201,7 @@ What exists today:
199201
- deterministic selected-character `SYNC_POSITION` reconciliation in `GAME`
200202
- bootstrap movement updates character coordinates and persists them across fresh auth/game sessions
201203
- empty-account bootstrap flow can select empire before first character creation, and that choice persists across fresh auth/game sessions
202-
- the selected character is inserted into the visible world after `ENTERGAME` via minimal `CHARACTER_ADD` + `CHAR_ADDITIONAL_INFO` + `CHARACTER_UPDATE`
204+
- the selected character is inserted into the visible world after `ENTERGAME` via minimal `CHARACTER_ADD` + `CHAR_ADDITIONAL_INFO` + `CHARACTER_UPDATE` + `PLAYER_POINT_CHANGE`
203205

204206
What still does not exist yet:
205207
- compatibility-grade persistence matching the legacy target
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Player-Point-Change Bootstrap Implementation Plan
2+
3+
> For Hermes: use test-driven-development. Keep slices tiny and push one commit at a time.
4+
5+
Goal: add the first minimal `PLAYER_POINT_CHANGE` emission after `ENTERGAME` so the selected character gets a deterministic self-only point refresh during the bootstrap transition into `GAME`.
6+
7+
Architecture: freeze a project-owned codec for `PLAYER_POINT_CHANGE`, extend visible-world bootstrap tests to expect the extra frame, then wire the minimal runtime to emit one deterministic self-only point refresh for the selected character.
8+
9+
Tech stack: Go 1.26, existing frame/session/world packages, current authd/gamed bootstrap runtime.
10+
11+
---
12+
13+
## Task 1: Freeze player-point-change packet codec
14+
Objective: define the server-side `PLAYER_POINT_CHANGE` packet shape.
15+
16+
Files:
17+
- Modify: `internal/proto/world/world.go`
18+
- Modify: `internal/proto/world/world_test.go`
19+
20+
Steps:
21+
1. Write failing tests for:
22+
- `PLAYER_POINT_CHANGE` encode/decode
23+
- invalid header rejection
24+
2. Run: `go test ./internal/proto/world`
25+
3. Implement the smallest codec set to pass.
26+
4. Re-run: `go test ./internal/proto/world`
27+
5. Commit: `feat: add player-point-change packet codec`
28+
29+
## Task 2: Extend visible-world bootstrap in the runtime
30+
Objective: emit `PLAYER_POINT_CHANGE` after the selected-character visible bootstrap.
31+
32+
Files:
33+
- Modify: `internal/minimal/factory.go`
34+
- Modify: `internal/minimal/factory_test.go`
35+
36+
Steps:
37+
1. Write failing tests for:
38+
- existing selected character gets the extra point-change frame
39+
- newly created selected character gets the same sequence
40+
2. Run: `go test ./internal/minimal`
41+
3. Implement the smallest selected-character packet builder.
42+
4. Re-run: `go test ./internal/minimal`
43+
5. Commit: `feat: add player-point-change bootstrap`
44+
45+
## Task 3: Cover boot composition
46+
Objective: verify the composed boot flow and TCP harness can emit the extra point-change frame.
47+
48+
Files:
49+
- Modify: `internal/boot/flow_test.go`
50+
- Modify: `internal/boot/flow_socket_test.go`
51+
52+
Steps:
53+
1. Extend visible-world bootstrap tests to expect `PLAYER_POINT_CHANGE`.
54+
2. Run: `go test ./internal/boot`
55+
3. Re-run after wiring the test config.
56+
4. Commit: `test: cover player-point-change bootstrap`
57+
58+
## Task 4: Update docs
59+
Objective: document the first `PLAYER_POINT_CHANGE` slice.
60+
61+
Files:
62+
- Modify: `README.md`
63+
- Modify: `spec/protocol/README.md`
64+
- Modify: `spec/protocol/visible-world-bootstrap.md`
65+
- Modify: `spec/protocol/boot-path.md`
66+
- Modify: `spec/protocol/packet-matrix.md`
67+
- Create: `spec/protocol/player-point-change-bootstrap.md`
68+
69+
Steps:
70+
1. Document packet layout and bootstrap order.
71+
2. Run: `go test ./... && go vet ./...`
72+
3. Commit: `docs: document player-point-change bootstrap slice`
73+
74+
## Verification
75+
- `go test ./internal/proto/world`
76+
- `go test ./internal/minimal`
77+
- `go test ./internal/boot`
78+
- `go test ./...`
79+
- `go vet ./...`
80+
81+
## Scope guardrails
82+
- Do not add repeated point-change streams yet
83+
- Do not add other entities yet
84+
- Do not add combat/inventory-driven point changes yet
85+
- Keep the slice deterministic and selected-character only

spec/protocol/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The repository targets TMP4-era client compatibility, but the protocol contract
1111
- `login-selection.md` — minimal login-by-key and selection-surface packet layouts
1212
- `select-world-entry.md` — minimal selection, loading, and enter-game packet choreography
1313
- `character-update-bootstrap.md` — first self-only state refresh after entering `GAME`
14+
- `player-point-change-bootstrap.md` — first self-only point refresh after entering `GAME`
1415
- `sync-position-bootstrap.md` — first self-only sync-position reconciliation after entering `GAME`
1516
- `boot-path.md` — first milestone from connect to basic movement
1617
- `packet-matrix.md` — working inventory for the first protocol slice

spec/protocol/boot-path.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Expected outcomes:
103103
- the server keeps the session stable after the transition
104104
- the selected character is inserted into the visible world with deterministic bootstrap packets
105105
- the selected character receives a first deterministic `CHARACTER_UPDATE` refresh after the visible insert
106+
- the selected character receives a first deterministic `PLAYER_POINT_CHANGE` refresh during the same bootstrap burst
106107

107108
## 9. Basic movement works
108109
The client sends a movement packet and the server processes it in the live game phase.
@@ -137,5 +138,6 @@ This document depends on:
137138
- `spec/protocol/frame-layout.md`
138139
- `spec/protocol/packet-matrix.md`
139140
- `spec/protocol/character-update-bootstrap.md`
141+
- `spec/protocol/player-point-change-bootstrap.md`
140142
- `spec/protocol/sync-position-bootstrap.md`
141143
- `docs/testing-strategy.md`

spec/protocol/packet-matrix.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Status values:
5151
| `PLAYER_DELETE_SUCCESS` | server -> client | `0x020E` | select | planned | later milestone |
5252
| `MAIN_CHARACTER` | server -> client | `0x0210` | loading | documented | main actor bootstrap |
5353
| `PLAYER_POINTS` | server -> client | `0x0214` | loading/game bootstrap | documented | initial stat payload |
54-
| `PLAYER_POINT_CHANGE` | server -> client | `0x0215` | game | planned | likely needed shortly after bootstrap |
54+
| `PLAYER_POINT_CHANGE` | server -> client | `0x0215` | game bootstrap | documented | first self-only point refresh after the selected-character bootstrap |
5555

5656
## Movement
5757

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Player-point-change bootstrap
2+
3+
This document freezes the first minimal `PLAYER_POINT_CHANGE` behavior used by the bootstrap runtime after `ENTERGAME`.
4+
5+
The goal of this slice is narrow:
6+
- emit a deterministic self-only point refresh after the selected character enters `GAME`
7+
- keep the bootstrap limited to one selected character
8+
- avoid adding a broader stat system too early
9+
10+
It does not yet define general-purpose point updates during gameplay.
11+
12+
## Covered packet
13+
14+
- `PLAYER_POINT_CHANGE` server -> client (`0x0215`)
15+
16+
## Working flow
17+
18+
The current project-owned bootstrap behavior after `ENTERGAME` is:
19+
20+
1. the session transitions to `GAME`
21+
2. the server emits:
22+
- `PHASE(GAME)`
23+
- `CHARACTER_ADD`
24+
- `CHAR_ADDITIONAL_INFO`
25+
- `CHARACTER_UPDATE`
26+
- `PLAYER_POINT_CHANGE`
27+
3. the `PLAYER_POINT_CHANGE` frame refreshes one deterministic point for the selected character only
28+
29+
This slice is intentionally narrow:
30+
- only the selected character receives the point refresh
31+
- only one deterministic point-change frame is emitted during bootstrap
32+
- no fanout to other sessions is required yet
33+
- no general-purpose stat recalculation engine is required yet
34+
35+
## Packet layout
36+
37+
Direction:
38+
- server -> client
39+
40+
Header:
41+
- `0x0215`
42+
43+
Payload layout:
44+
- `vid``uint32`
45+
- `type``uint8`
46+
- `amount``int32`
47+
- `value``int32`
48+
49+
Frame length:
50+
- `17` bytes total (`4 + 13`)
51+
52+
## Current bootstrap behavior
53+
54+
The bootstrap runtime currently emits one deterministic self-only point refresh:
55+
- `type = 1`
56+
- `amount` mirrors the selected character bootstrap point value at index `1`
57+
- `value` mirrors the same selected character bootstrap point value
58+
59+
For the current stub/bootstrap characters this means:
60+
- existing selected character refresh uses its persisted point value
61+
- newly created selected character refresh uses its initial point value
62+
63+
This is good enough for the first `PLAYER_POINT_CHANGE` slice, but not yet the final compatibility target.
64+
65+
## Out of scope
66+
67+
This slice does not yet freeze:
68+
- repeated point-change streams during gameplay
69+
- point-change updates for other entities
70+
- derived stat recalculation rules
71+
- inventory, buffs, or combat-driven point updates

spec/protocol/visible-world-bootstrap.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ It does not yet freeze the broader entity stream for NPCs, mobs, items, or other
1515
- `CHARACTER_ADD`
1616
- `CHAR_ADDITIONAL_INFO`
1717
- `CHARACTER_UPDATE`
18+
- `PLAYER_POINT_CHANGE`
1819

1920
## Working flow
2021

@@ -28,10 +29,12 @@ The current project-owned world bootstrap after `ENTERGAME` is:
2829
- `CHARACTER_ADD`
2930
- `CHAR_ADDITIONAL_INFO`
3031
- `CHARACTER_UPDATE`
32+
- `PLAYER_POINT_CHANGE`
3133

3234
This slice is intentionally narrow:
3335
- only the selected character is announced
3436
- only the selected character gets a deterministic self-update refresh
37+
- only the selected character gets a deterministic self-only point refresh
3538
- no item/NPC/mob bursts are required yet
3639
- no fanout to other sessions is required yet
3740

@@ -91,7 +94,7 @@ The bootstrap runtime currently uses deterministic values for the visible insert
9194
- a fixed self-insert type for player characters
9295
- deterministic movement/attack speed values
9396
- deterministic state bootstrap
94-
- selected character coordinates, race, empire, level, visible parts, and self-update state
97+
- selected character coordinates, race, empire, level, visible parts, self-update state, and one self-only point refresh
9598

9699
This is good enough for the first visible-world slice, but not yet the final compatibility target.
97100

0 commit comments

Comments
 (0)