summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-02-04 23:28:08 +0000
committerubq323 <ubq323@ubq323.website>2023-02-04 23:28:08 +0000
commit9339e47c79f40fe9c4541e638d7fd67ab634c600 (patch)
treead1efddc3608ca506534d3e7ab7b2ae4a35a0476
parent0dc1276df57aa16b4f0eaecf54fb5cd8f00115c6 (diff)
improve tracking of loading chunks, and increase load dist around player
-rw-r--r--client/main.lua20
-rw-r--r--common/map.lua27
-rw-r--r--server/server.lua2
3 files changed, 33 insertions, 16 deletions
diff --git a/client/main.lua b/client/main.lua
index da1b91d..769fccf 100644
--- a/client/main.lua
+++ b/client/main.lua
@@ -83,10 +83,7 @@ local function send_settile(hpos,tile)
end
--- hack
-local time_since_last_chunkreq = 100
function love.update(dt)
- time_since_last_chunkreq = time_since_last_chunkreq + dt
if local_player then
update_local_player(local_player,dt)
if love.keyboard.isScancodeDown"q" then camera.zoom = camera.zoom*1.05 end
@@ -107,11 +104,18 @@ function love.update(dt)
send_settile(mh,false)
end
+ -- load chunks near player
if local_player then
local player_cp = local_player.pos:to_hex():containing_chunk()
- if map:chunk(player_cp) == nil and time_since_last_chunkreq > 1 then
- time_since_last_chunkreq = 0
- peer:send(json.encode{t="reqchunk",u=player_cp.u,v=player_cp.v})
+ for du = -1,1 do
+ for dv = -1,1 do
+ local cp = player_cp+coords.ChunkPos:make(du,dv)
+ if map:chunk(cp) == nil then
+ print("sending chunk request",cp)
+ map:mark_chunk_loading(cp)
+ peer:send(json.encode{t="reqchunk",u=cp.u,v=cp.v})
+ end
+ end
end
end
@@ -119,7 +123,7 @@ function love.update(dt)
repeat
local ev = host:service()
if ev and ev.type == "receive" then
- print(ev.data)
+ -- print(ev.data)
local j = json.decode(ev.data)
local op = j.t
if op == "join" then
@@ -138,7 +142,7 @@ function love.update(dt)
local_player = {pos=coords.Pos:make(pl.x,pl.y),color=pl.color,id=pl.id}
elseif op == "chunk" then
local ch = Chunk.from_packet_data(j)
- map:add_chunk(ch.cp,ch)
+ map:add_chunk(ch)
elseif op == "settile" then
local h = coords.Hex:make(j.q,j.r)
map:set_at(h,j.tile)
diff --git a/common/map.lua b/common/map.lua
index 5bcd09e..d32cbf3 100644
--- a/common/map.lua
+++ b/common/map.lua
@@ -1,6 +1,11 @@
-- a Map is a 2d array of chunks
-- it handles loading and unloading of chunks
--- the specifics of which are then implemented separately for client and server
+-- each slot in the Map is either a Chunk object (if that chunk is loaded),
+-- nil (if not loaded), or false (if 'loading'). on the client 'loading' means
+-- the request for the chunk is currently in flight. on the server it might one day
+-- mean that terrain generation for that chunk is currently in progress.
+-- to test whether a chunk is loaded you can do if map:chunk(cp) then ... end
+-- to test whether a chunk needs to be loaded you do if map:chunk(cp) == nil then ... end.
-- it will probably also do things relating to entities and multiblock things
local class = require"common.class"
@@ -11,13 +16,21 @@ local Map = class()
function Map.make(cls)
return setmetatable({chunks={}},cls)
end
-function Map.add_chunk(self,cp,the_chunk)
- print("adding chunk",cp)
- assert(the_chunk.cp == cp,"attempting to add chunk with the wrong cp")
+function Map._set_chunk(self,cp,value)
if not self.chunks[cp.u] then self.chunks[cp.u] = {} end
- self.chunks[cp.u][cp.v] = the_chunk
+ self.chunks[cp.u][cp.v] = value
+end
+function Map.add_chunk(self,the_chunk)
+ local cp = the_chunk.cp
+ print("adding chunk",cp)
+ self:_set_chunk(cp,the_chunk)
+end
+function Map.mark_chunk_loading(self,cp)
+ print("marking chunk as loading",cp)
+ self:_set_chunk(cp,false)
end
function Map.unload_chunk(self,cp)
+ print("unloading chunk",cp)
if not self.chunks[cp.u] then return end
self.chunks[cp.u][cp.v] = nil
-- remove list if empty
@@ -42,7 +55,7 @@ function Map.at(self,hpos)
local cpu,cpv = math.floor(hpos.q/CHUNK_SIZE),math.floor(hpos.r/CHUNK_SIZE)
local hoffq,hoffr = hpos.q-(cpu*CHUNK_SIZE), hpos.r-(cpv*CHUNK_SIZE)
local ch = self:_chunkuv(cpu,cpv)
- if ch == nil then return nil end
+ if not ch then return nil end
return ch:_atqr(hoffq,hoffr)
end
function Map.set_at(self,hpos,tile)
@@ -50,7 +63,7 @@ function Map.set_at(self,hpos,tile)
local ch = self:chunk(cp)
-- setting a tile in an unloaded chunk is silently ignored
-- this might change one day
- if ch == nil then return nil end
+ if not ch then return nil end
ch:set_at(hoffs,tile)
end
diff --git a/server/server.lua b/server/server.lua
index a7ee04b..f11b805 100644
--- a/server/server.lua
+++ b/server/server.lua
@@ -67,7 +67,7 @@ local function get_or_gen_chunk(cp)
local ch = map:chunk(cp)
if not ch then
ch = worldgen.gen_chunk(cp)
- map:add_chunk(cp,ch)
+ map:add_chunk(ch)
end
return ch
end