This commit is contained in:
Vicente Ferrari Smith 2026-02-08 15:22:38 +01:00
parent 5a79ae71c0
commit 35bbc5cbfd
2 changed files with 231 additions and 0 deletions

73
src/client/chunk.zig Normal file
View File

@ -0,0 +1,73 @@
const std = @import("std");
const shared = @import("shared");
const enet = @import("c.zig").enet;
pub fn spawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, comptime T: type, value: T) !shared.entity.id {
std.debug.assert(value.id != shared.entity.INVALID_ID);
const ptr = try allocator.create(T);
errdefer allocator.destroy(ptr);
ptr.* = value;
const ref = shared.entity.makeRef(T, ptr);
try self.entities.append(allocator, ref);
return ptr.id;
}
pub fn find(self: *shared.chunk.Chunk, id: shared.entity.id) ?shared.entity.Ref {
for (self.entities.items) |ref| {
switch (ref) {
inline else => |ptr| {
if (ptr.id == id) {
return ref;
}
}
}
}
return null;
}
pub fn findT(self: *shared.chunk.Chunk, comptime T: type, id: shared.entity.id) ?*T {
for (self.entities.items) |ref| {
switch (ref) {
inline else => |ptr| {
if (ptr.id == id and @TypeOf(ptr) == *T) {
return ptr;
}
}
}
}
return null;
}
pub fn despawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, id: shared.entity.id) bool {
var i: usize = 0;
while (i < self.entities.items.len) {
const ref = self.entities.items[i];
var found = false;
switch (ref) {
inline else => |ptr| {
if (ptr.id == id) {
allocator.destroy(ptr);
found = true;
}
},
}
if (found) {
_ = self.entities.swapRemove(i);
return true;
}
i += 1;
}
return false;
}

158
src/shared/protocol_v1.zig Normal file
View File

@ -0,0 +1,158 @@
const std = @import("std");
const zm = @import("zmath");
// const bufzilla = @import("bufzilla");
const entity = @import("entity.zig");
const bits = @import("bits.zig");
pub const SERVER_PORT: u16 = 1337;
const MessageKind = enum(c_char) {
spawn_entity,
update_entity,
despawn_entity,
};
pub const Message = union(MessageKind) {
spawn_entity: SpawnEntity,
update_entity: UpdateEntity,
despawn_entity: DespawnEntity,
};
const EntityKind = enum(c_char) {
soldier,
alien,
};
pub const SpawnEntity = union(EntityKind) {
soldier: Soldier,
alien: Alien,
};
pub const UpdateEntity = union(EntityKind) {
soldier: Soldier,
alien: Alien,
};
pub const DespawnEntity = union(EntityKind) {
soldier: Soldier,
alien: Alien,
};
pub fn makeSpawnMessage(e: entity.Ref) Message {
switch (e) {
.Soldier => |s| { return Soldier.makeSpawn(s.*); },
.Alien => |a| { return Alien.makeSpawn(a.*); },
}
}
pub fn makeUpdateMessage(e: entity.Ref) Message {
switch (e) {
.Soldier => |s| { return Soldier.makeUpdate(s.*); },
.Alien => |a| { return Alien.makeUpdate(a.*); },
}
}
pub fn makeDespawnMessage(e: entity.Ref) Message {
switch (e) {
.Soldier => |s| { return Soldier.makeDespawn(s.*); },
.Alien => |a| { return Alien.makeDespawn(a.*); },
}
}
pub const Soldier = struct {
id: entity.id = entity.INVALID_ID,
hp: i32,
pos: zm.Vec,
vel: zm.Vec,
pub fn init(soldier: entity.Soldier) Soldier {
return .{
.id = soldier.id,
.hp = soldier.hp,
.pos = soldier.pos,
.vel = soldier.vel,
};
}
pub fn makeSpawn(soldier: entity.Soldier) Message {
return .{
.spawn_entity = .{ .soldier = init(soldier) }
};
}
pub fn makeUpdate(soldier: entity.Soldier) Message {
return .{
.update_entity = .{ .soldier = init(soldier) }
};
}
pub fn makeDespawn(soldier: entity.Soldier) Message {
return .{
.despawn_entity = .{ .soldier = init(soldier) }
};
}
};
pub const Alien = struct {
id: entity.id = entity.INVALID_ID,
hp: i32,
pos: zm.Vec,
pub fn init(alien: entity.Alien) Alien {
return .{
.id = alien.id,
.pos = alien.pos,
.hp = alien.hp,
};
}
pub fn makeSpawn(alien: entity.Alien) Message {
return .{
.spawn_entity = .{ .alien = init(alien) }
};
}
pub fn makeUpdate(alien: entity.Alien) Message {
return .{
.update_entity = .{ .alien = init(alien) }
};
}
pub fn makeDespawn(alien: entity.Alien) Message {
return .{
.despawn_entity = .{ .alien = init(alien) }
};
}
};
test "Protocol" {
std.debug.print("Protocol\n", .{});
const s = entity.Soldier{
.hp = 66,
.pos = .{1, 2, 3, 4},
.vel = .{5, 6, 7, 8},
};
const msg = makeSpawnMessage(s);
const allocator = std.testing.allocator;
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
defer aw.deinit(allocator);
var writer = bits.BitWriter.init(&aw);
try writer.serialize(allocator, msg);
var reader = bits.BitReader.init(writer.written());
const recv = try reader.deserialize(allocator, Message);
std.debug.print("msg: {}\n", .{msg});
std.debug.print("recv: {}\n", .{recv});
try std.testing.expectEqual(msg, recv);
}