From ec6a391cb9cf0c0feac0fe3615a59cc7cb6db2d5 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Fri, 3 Feb 2023 01:32:09 +0000 Subject: drawing changes, world generation, perlin noise --- server/noise.lua | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ server/server.lua | 17 ++++++++-- 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 server/noise.lua (limited to 'server') diff --git a/server/noise.lua b/server/noise.lua new file mode 100644 index 0000000..1480448 --- /dev/null +++ b/server/noise.lua @@ -0,0 +1,96 @@ +local Pos = require"common.coords".Pos +local tau = 2*math.pi + +math.randomseed(os.time()) + +local function random_unit_vec() + local theta = math.random()*tau + return Pos.make(math.cos(theta),math.sin(theta)) +end +local function lerp(a,b,t) return (1-t)*a + t*b end +local function smoothstep(x) + if x<0 then return 0 end + if x>1 then return 1 end + return x*x*(3 - 2*x) +end +local function slerp(a,b,t) return lerp(a,b,smoothstep(t)) end + +local NoiseGen = {} +NoiseGen.__index = NoiseGen +function NoiseGen.make() + local grid = {} + setmetatable(grid,{__index=function(t,k) t[k] = {} return t[k] end}) + return setmetatable({grid=grid},NoiseGen) +end +function NoiseGen.vertex(self,ix,iy) + local v = self.grid[ix][iy] + if v then return v end + vv = random_unit_vec() + self.grid[ix][iy] = vv + return vv +end + +function NoiseGen.at(self,x,y) + local x0 = math.floor(x) + local y0 = math.floor(y) + local x1 = x0 + 1 + local y1 = y0 + 1 + + local v00 = self:vertex(x0,y0) + local v01 = self:vertex(x0,y1) + local v10 = self:vertex(x1,y0) + local v11 = self:vertex(x1,y1) + + local p = Pos.make + local d00 = v00:dot(p(x-x0,y-y0)) + local d01 = v01:dot(p(x-x0,y-y1)) + local d10 = v10:dot(p(x-x1,y-y0)) + local d11 = v11:dot(p(x-x1,y-y1)) + + local q0 = slerp(d00,d01,y-y0) + local q1 = slerp(d10,d11,y-y0) + local z = slerp(q0,q1,x-x0) + return z +end + +local NoiseAgg = {} +NoiseAgg.__index = NoiseAgg +function NoiseAgg.make(things) + return setmetatable({things=things or {}},NoiseAgg) +end +function NoiseAgg.make_perlin_octaves(nocts) + local things = {} + for i=1,nocts do + table.insert(things,{amp=2^i,scale=2^(nocts-i),gen=NoiseGen.make()}) + end + return NoiseAgg.make(things) +end +function NoiseAgg.at(self,x,y) + local n = 0 + local t = 0 + assert(#self.things>0,"can't generate noise with no noise things") + for _,thing in ipairs(self.things) do + local gen,scale,amp = thing.gen,thing.scale,thing.amp + n = n + amp + t = t + gen:at(x*scale,y*scale)*amp + end + return t/n +end + +-- local chars = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. " + +-- local scale = 3 + +-- for x=1,10-10/40,10/40 do +-- for y = 1,10-10/60,10/60 do + +-- local n = at(1+(x-1)/scale,1+(y-1)/scale) +-- local nn = (n +1)/2 +-- local nnn = 1+nn*#chars +-- local c = chars:sub(nnn,nnn) +-- io.write(c) +-- end +-- io.write("\n") +-- end + +return {NoiseGen=NoiseGen,NoiseAgg=NoiseAgg} diff --git a/server/server.lua b/server/server.lua index ff3c3eb..67860ea 100644 --- a/server/server.lua +++ b/server/server.lua @@ -1,6 +1,8 @@ local enet = require"enet" local json = require"common.dkjson" +local chunk = require"common.chunk" local Chunk = require"common.chunk".Chunk +local noise = require"noise" local unpack = unpack or table.unpack local coords = require"common.coords" @@ -58,7 +60,18 @@ local function player_move_packet(player,x,y) return json.encode{t="move",id=player.id,x=x,y=y} end -local the_chunk = Chunk.gen() +local the_tiles = {} +local ng = noise.NoiseAgg.make_perlin_octaves(4) +for q = 1,chunk.SIZE-1 do + for r = 1,chunk.SIZE-1 do + local p = coords.Hex.make(q,r):to_pos() + local nv = ng:at(p.x/20,p.y/20) + assert(nv ~= 1,"oopsy") + the_tiles[chunk.index(q,r)] = nv > 0 and 1+math.floor(math.sqrt(nv)*8) or false + end +end +local the_chunk = Chunk.make(the_tiles) +print"generated chunk" while true do local ev = host:service(100) @@ -104,7 +117,7 @@ while true do elseif op == "settile" then local h = coords.Hex.make(j.q,j.r) the_chunk:set_at(h,j.tile) - print(player.id,"settile",h,j.tile) + -- print(player.id,"settile",h,j.tile) for i,otherplayer in ipairs(playerlist) do if otherplayer ~= player then -- same packet structure s2c as c2s -- cgit v1.2.3