Compare commits

...

6 Commits

11 changed files with 63 additions and 157 deletions
+10
View File
@@ -0,0 +1,10 @@
# Godot editor cache / generated files
.godot/
# Godot export artifacts
export/
*.tmp
# OS
.DS_Store
Thumbs.db
-1
View File
@@ -1 +0,0 @@
-22
View File
@@ -1,22 +0,0 @@
63f7b34db8d8cdea90c76aacccf841ec
::res://::1787012074
README.md::TextFile::-1::1787011777::0::1::::<><><>0<>0<><>::
::res://docs/::1787011777
::res://docs/architecture/::1787011795
avatar.md::TextFile::-1::1787011777::0::1::::<><><>0<>0<><>::
content_moderation.md::TextFile::-1::1787011777::0::1::::<><><>0<>0<><>::
networking.md::TextFile::-1::1787011777::0::1::::<><><>0<>0<><>::
world.md::TextFile::-1::1787011777::0::1::::<><><>0<>0<><>::
::res://scenes/::1787011795
main.tscn::PackedScene::-1::1787011795::0::1::::<><><>0<>0<><>::res://scripts/chunk_stream_manager.gd
::res://scripts/::1787012062
chunk.gd::GDScript::7364239597441807588::1787011795::0::1::::Chunk<>Node3D<><>0<>0<><>::
chunk_data_decoder.gd::GDScript::3922068956043581888::1787012104::0::1::::ChunkDataDecoder<>RefCounted<><>0<>0<><>::
chunk_scene.gd::GDScript::9207602004456600331::1787011795::0::1::::ChunkScene<>Node3D<><>0<>0<><>::
chunk_stream_manager.gd::GDScript::2366645676568508746::1787011963::0::1::::ChunkStreamManager<>Node<><>0<>0<><>::
dynamic_object_node.gd::GDScript::8863349716576659118::1787011795::0::1::::DynamicObjectNode<>Node3D<><>0<>0<><>::
static_object_node.gd::GDScript::5276389741929225897::1787011795::0::1::::StaticObjectNode<>Node3D<><>0<>0<><>::
tile_def.gd::GDScript::2430528079284085109::1787011795::0::1::::TileDef<>RefCounted<><>0<>0<><>::
tile_layer.gd::GDScript::4797906255131447844::1787011795::0::1::::TileLayer<>RefCounted<><>0<>0<><>::
tile_layer_node.gd::GDScript::9033225196818247616::1787011795::0::1::::TileLayerNode<>Node3D<><>0<>0<><>::
world_object.gd::GDScript::6429674491464200335::1787011795::0::1::::WorldObject<>RefCounted<><>0<>0<><>::
@@ -1,5 +0,0 @@
[folding]
node_unfolds=[NodePath("."), PackedStringArray("Visibility")]
resource_unfolds=[]
nodes_folded=[]
-11
View File
@@ -1,11 +0,0 @@
[game_view]
select_mode=0
[editor_metadata]
executable_path="/home/daddy/godot/godot"
[recent_files]
scenes=["res://scenes/main.tscn"]
-81
View File
@@ -1,81 +0,0 @@
list=[{
"base": &"Node3D",
"class": &"Chunk",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/chunk.gd"
}, {
"base": &"RefCounted",
"class": &"ChunkDataDecoder",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/chunk_data_decoder.gd"
}, {
"base": &"Node3D",
"class": &"ChunkScene",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/chunk_scene.gd"
}, {
"base": &"Node",
"class": &"ChunkStreamManager",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/chunk_stream_manager.gd"
}, {
"base": &"Node3D",
"class": &"DynamicObjectNode",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/dynamic_object_node.gd"
}, {
"base": &"Node3D",
"class": &"StaticObjectNode",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/static_object_node.gd"
}, {
"base": &"RefCounted",
"class": &"TileDef",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/tile_def.gd"
}, {
"base": &"RefCounted",
"class": &"TileLayer",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/tile_layer.gd"
}, {
"base": &"Node3D",
"class": &"TileLayerNode",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/tile_layer_node.gd"
}, {
"base": &"RefCounted",
"class": &"WorldObject",
"icon": "",
"is_abstract": false,
"is_tool": false,
"language": &"GDScript",
"path": "res://scripts/world_object.gd"
}]
Binary file not shown.
+11 -32
View File
@@ -107,27 +107,6 @@ class TileLayerData:
return null
## A single tile definition (palette entry).
class TileDef:
var id: int = 0
var asset_id: String = ""
var solid: bool = false
var flags: int = 0
var variants: int = 1
func is_solid() -> bool:
return solid
func is_walkable() -> bool:
return (flags & 0x01) != 0
func is_climbable() -> bool:
return (flags & 0x02) != 0
func is_liquid() -> bool:
return (flags & 0x04) != 0
## A world object parsed from chunk data.
class WorldObjectData:
var id: String = ""
@@ -159,9 +138,9 @@ class ChunkPayload:
var checksum: String = ""
# ─── Binary Decoding ────────────────────────────────────────────────────────
# ───────────────── Binary Decoding ─────────────────
const MAGIC: PackedByteArray = PackedByteArray([0x41, 0x47, 0x50, 0x43]) # "AGPC"
static var MAGIC := PackedByteArray([0x41, 0x47, 0x50, 0x43]) # "AGPC"
const HEADER_SIZE: int = 48
const SECTION_META: int = 0x01
const SECTION_TILE: int = 0x02
@@ -274,7 +253,7 @@ static func encode_binary(payload: ChunkPayload) -> PackedByteArray:
return header + payload_bytes
# ─── Section Parsers ────────────────────────────────────────────────────────
# ───────────────── Section Parsers ─────────────────
static func _parse_metadata_section(data: PackedByteArray, result: ChunkPayload) -> void:
var offset := 0
@@ -496,7 +475,7 @@ static func _parse_revision_meta_section(data: PackedByteArray, result: ChunkPay
result.author = data.slice(offset, offset + author_len).get_string_from_utf8()
# ─── Section Builders ───────────────────────────────────────────────────────
# ───────────────── Section Builders ─────────────────
static func _build_metadata_section(payload: ChunkPayload) -> PackedByteArray:
var data := PackedByteArray()
@@ -607,7 +586,7 @@ static func _wrap_section(data: PackedByteArray, section_id: int) -> PackedByteA
return wrapped
# ─── Binary Helpers ─────────────────────────────────────────────────────────
# ───────────────── Binary Helpers ─────────────────
static func _read_uint16(data: PackedByteArray, offset: int) -> int:
return data[offset] | (data[offset + 1] << 8)
@@ -668,18 +647,18 @@ static func _write_string(s: String) -> PackedByteArray:
static func _hex_to_bytes(hex_str: String) -> PackedByteArray:
var result := PackedByteArray()
for i in range(0, hex_str.length(), 2):
var byte_val := int("0x" + hex_str.substr(i, 2), 16)
var byte_val := ("0x" + hex_str.substr(i, 2)).hex_to_int()
result.append(byte_val)
return result
# ─── SHA-256 ────────────────────────────────────────────────────────────────
# ───────────────── SHA-256 ─────────────────
static func _sha256_hex(data: PackedByteArray) -> String:
var sha256 := SHA256Hash.new()
sha256.start()
sha256.update(data)
var hash := sha256.finish()
var ctx := HashingContext.new()
ctx.start(HashingContext.HASH_SHA256)
ctx.update(data)
var hash := ctx.finish()
var hex_chars := "0123456789abcdef"
var result := ""
for byte_val in hash:
+5 -5
View File
@@ -92,7 +92,7 @@ func _add_static_object(obj: WorldObject) -> void:
var static_obj := StaticObjectNode.new()
static_obj.world_object = obj
static_obj.position = obj.position
static_obj.rotation = obj.rotation
static_obj.quaternion = Quaternion(obj.rotation.x, obj.rotation.y, obj.rotation.z, obj.rotation.w)
static_obj.scale = obj.scale
static_obj.name = "static_%s" % obj.id
add_child(static_obj)
@@ -102,7 +102,7 @@ func _add_dynamic_object(obj: WorldObject) -> void:
var dynamic_obj := DynamicObjectNode.new()
dynamic_obj.world_object = obj
dynamic_obj.position = obj.position
dynamic_obj.rotation = obj.rotation
dynamic_obj.quaternion = Quaternion(obj.rotation.x, obj.rotation.y, obj.rotation.z, obj.rotation.w)
dynamic_obj.scale = obj.scale
dynamic_obj.name = "dynamic_%s" % obj.id
add_child(dynamic_obj)
@@ -164,7 +164,7 @@ func contains_position(pos: Vector3) -> bool:
## Check if a chunk coordinate is adjacent to this chunk.
func is_adjacent(other_coord: Vector3i) -> bool:
var dx := abs(coord.x - other_coord.x)
var dy := abs(coord.y - other_coord.y)
var dz := abs(coord.z - other_coord.z)
var dx: int = abs(coord.x - other_coord.x)
var dy: int = abs(coord.y - other_coord.y)
var dz: int = abs(coord.z - other_coord.z)
return dx <= 1 and dy <= 1 and dz <= 1 and (dx + dy + dz) > 0
+15
View File
@@ -0,0 +1,15 @@
Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org
roundtrip bounds.position = (0.0, 0.0, 0.0) (expected (0.5, 1.5, 2.5))
roundtrip coord = (0, 0, 0) (expected (1, 2, 3))
format_version present? -> <null>
version field -> 1
SCRIPT ERROR: Invalid assignment of property or key 'properties' with value of type 'bool' on a base object of type 'RefCounted (WorldObjectData)'.
at: _parse_object_section (res://scripts/chunk_data_decoder.gd:407)
GDScript backtrace (most recent call first):
[0] _parse_object_section (res://scripts/chunk_data_decoder.gd:407)
[1] _init (res://test_review.gd:25)
SCRIPT ERROR: Out of bounds get index '0' (on base: 'Array[WorldObjectData]')
at: _init (res://test_review.gd:26)
GDScript backtrace (most recent call first):
[0] _init (res://test_review.gd:26)
+22
View File
@@ -0,0 +1,22 @@
extends SceneTree
func _init() -> void:
# 1. float32 encode/decode
var b: PackedByteArray = ChunkDataDecoder._write_float32(0.5)
print("float32(0.5) bytes = ", b, " (expected 00 00 00 3f)")
var decoded_f: float = ChunkDataDecoder._read_float32(PackedByteArray([0x00, 0x00, 0x00, 0x3f]), 0)
print("read_float32 of 0x3f000000 = ", decoded_f, " (expected 0.5)")
# 2. metadata section wrapping: inspect first bytes of encoded payload
var payload: ChunkDataDecoder.ChunkPayload = ChunkDataDecoder.ChunkPayload.new()
payload.world_id = "w"
payload.room_id = "r"
payload.coord = Vector3i(1, 2, 3)
var meta: PackedByteArray = ChunkDataDecoder._build_metadata_section(payload)
print("metadata section first 12 bytes = ", meta.slice(0, 12))
# 3. properties parse with empty-ish string
var props_str := "{}"
var val = JSON.parse_string(props_str) or {}
print("'JSON.parse_string(props_str) or {{}}' type = ", typeof(val), " value = ", val)
quit()