chunk_key.gno
1.64 Kb · 61 lines
1package personal_world
2
3import (
4 "strconv"
5 "strings"
6)
7
8// formatWorldID converts a world ID to a string key for verifier storage lookups
9func formatWorldID(worldID uint32) string {
10 return strconv.FormatUint(uint64(worldID), 10)
11}
12
13// buildCoordKey builds "x_y" coordinate string
14func buildCoordKey(x, y int) string {
15 return strconv.Itoa(x) + "_" + strconv.Itoa(y)
16}
17
18// parseCoordKey parses "x_y" into (x, y)
19func parseCoordKey(coordKey string) (int, int) {
20 idx := strings.Index(coordKey, "_")
21 if idx == -1 {
22 panic("invalid coordKey: " + coordKey)
23 }
24 x, errX := strconv.Atoi(coordKey[:idx])
25 if errX != nil {
26 panic("invalid x in coordKey: " + coordKey)
27 }
28 y, errY := strconv.Atoi(coordKey[idx+1:])
29 if errY != nil {
30 panic("invalid y in coordKey: " + coordKey)
31 }
32 return x, y
33}
34
35// buildWorldChunkKey builds "worldID:x_y" from world and coord key.
36func buildWorldChunkKey(worldID uint32, coordKey string) string {
37 return formatWorldID(worldID) + ":" + coordKey
38}
39
40// normalizeChunkKey validates and canonicalizes the required world prefix.
41// Accepts only "worldID:x_y", returns canonical "worldID:x_y".
42func normalizeChunkKey(worldID uint32, chunkKey string) string {
43 if chunkKey == "" {
44 panic("empty chunkKey not allowed")
45 }
46
47 colon := strings.Index(chunkKey, ":")
48 if colon == -1 {
49 panic("chunkKey must include worldID prefix: worldID:x_y")
50 }
51
52 keyWorldID := chunkKey[:colon]
53 expected := formatWorldID(worldID)
54 if keyWorldID != expected {
55 panic("chunkKey worldID mismatch: expected " + expected + ", got " + keyWorldID)
56 }
57 coordKey := chunkKey[colon+1:]
58
59 x, y := parseCoordKey(coordKey)
60 return buildWorldChunkKey(worldID, buildCoordKey(x, y))
61}