Compare commits

...

3 Commits

Author SHA1 Message Date
Pascal Abresch 3d6b27ea45 New main loop and protocol version 2022-06-19 12:44:17 +02:00
Pascal Abresch 69b37d85d6 add server image 2022-06-19 12:41:55 +02:00
Pascal Abresch d13fdd5bf4 update readme 2022-06-19 12:41:55 +02:00
10 changed files with 363 additions and 296 deletions

View File

@ -12,17 +12,23 @@ I have not investigated this much yet. Safe to say it is not intended to run so
# Implementation status
## Implemented
* Loading textures (but not hashed for network yet)
* drawing on canvases (locally only)
* Loading textures
* drawing on canvases
* physics calculation for collison and movement
* drawing physics collisions (on the physics layer)
* Basic networking
* Get clientID
* Draw all players
* sync physics state
* Send/Receive drawn stuff
* Send disconnect on client quit
* Add chat support
* Send disconnect on client error
* Chat support
* Drawing
* Draw with custom color
* Re-do base textures as gray scale to color in arbitrarily
## Not implemented (rough goals anyhow)
* UI to connect to specific server
* Reconnect to server
@ -32,19 +38,21 @@ I have not investigated this much yet. Safe to say it is not intended to run so
* Loading the game/map (server stuff?)
* confirmation before clearing canvas (that's quite destructive :D)
* Make a way to add dialogs and stuff
* Drawing
* drawing preview (shows the grid directly, also gives feedback to the user for selected block)
* Draw with colors custom stencils
* Define stencils based on drawn stuff on the canvas
* Re-do base textures as gray scale to color in arbitrarily
* Allow the textures to be scaled up before placing
* Have a preview of where textures will be placed
* Have a way to move the grid by pixel increments
* Advanced physics
* Each pixel gets a physics vector associated, each hit pixel gets the vector added
to a "positon" vector, which can be added as a diff to the player
This can replace the gravity code directly, and allow stuff to push players around
in addition to simply blocking them like the current physics does.
* Programming layer
* Basically: Have a set of colors/programms, each of those has a single code run
Associated with it, the programms/colors can then be drawn on a dedicated canvas
@ -61,9 +69,9 @@ I have not investigated this much yet. Safe to say it is not intended to run so
* Define colors for use in programming layer
* Build a map of all instances and their allowed communication partners.
* figure out if this is supposed to run on the server client or both (probably predicted?)
* Networking support
* Figure out why and how physics is tied to framerate, why does jump height differ?
* Implement receiving/sending drawing commands
* Implement initial state sync (mainly server work)
* Add ack que, resend lost packets (but only for stuff like drawing and such, movement may drop)
* Tell the user if the server doesn't support the networking version requested
@ -84,14 +92,26 @@ I have not investigated this much yet. Safe to say it is not intended to run so
3. Run ```love(_x86) path/to/checkout```
# Packaging the game (On haiku)
# Packaging the game
## Create a .love archive
1. Copy any font you want to bundle to fonts/font.ttf (This cannot be bundled as a symlink)
2. Zip the files
* If you bundle a font:
```zip -r Poppy main.lua conf.lua lua/ textures/ fonts/```
* If you don't bundle a font:
```zip -r Poppy main.lua conf.lua lua/ textures/```
3. ``mv Poppy.zip Poppy``` (I don't know why zip wants to be smart here...)
## Package for windows
4. Download the love2d distribution from http://love2d.org/
(For example https://github.com/love2d/love/releases/download/11.4/love-11.4-win64.zip)
5. unpack the distribution
6. add the Poppy.zip from the previous step to the love2d executable
* copy /b love.exe+Poppy.zip Poppy.exe
7. (add license info for poppy?)
8. Repack the distribution archive
## Package for HaikuHaiku
3. ```mv Poppy.zip Poppy```
4. If you did not change the icon Run ```resattr -O -o Poppy ressources/Poppy.rsrc```
If you changed the Icon:

View File

@ -1,18 +1,4 @@
local path = "textures/blocks/krock/Glass/3.png"
local texture = {data = love.image.newImageData(path),
image = love.graphics.newImage(path)}
drawing = {}
drawing.color = {1, 1, 1, 1}
drawing.cursor = love.data.hash("sha512", texture.data:getString())
textures[drawing.cursor] = texture
texture, path = nil, nil
local clientChannel = love.thread.getChannel ( "clientChannel" );
mouse.lastpos = {}
mouse.lastpos.x = 0
mouse.lastpos.y = 0
function alignToGrid(num, thing)
return num - (num % thing)
@ -197,3 +183,20 @@ function drawing.remove_solid(x, y, width, height)
lastRMP.x, lastRMP.y, lastRMP.width, lastRMP.height = x, y, width, height
end
end
function drawing.init()
local path = "textures/blocks/krock/Glass/3.png"
local texture = {data = love.image.newImageData(path),
image = love.graphics.newImage(path)}
drawing.color = {1, 1, 1, 1}
drawing.cursor = love.data.hash("sha512", texture.data:getString())
textures[drawing.cursor] = texture
texture, path = nil, nil
local clientChannel = love.thread.getChannel ( "clientChannel" );
mouse.lastpos = {}
mouse.lastpos.x = 0
mouse.lastpos.y = 0
end

253
lua/gameloop.lua Normal file
View File

@ -0,0 +1,253 @@
gameloop = {}
local rpc = require("server.rpc")
local function normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
-- Draw background
if drawBackground then
color_push()
love.graphics.setColor(0.05, 0.05, 0.05)
love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, world.x * scale, world.y * scale)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(buffer.pixel.bg, layerTransform)
color_pop()
end
-- draw player
for i, player in pairs(players) do
local playerTransform = love.math.newTransform(
math.floor(player.x) * scale + math.floor(view.x) * scale,
math.floor(player.y) * scale + math.floor(view.y) * scale,
0, scale, scale)
love.graphics.draw(player.avatar, playerTransform)
if player.name then
local labelTransform = love.math.newTransform(
math.floor(player.x - (player.label:getWidth() / 2) +
(player.avatar:getPixelWidth() /2)) * scale + math.floor(view.x) * scale,
math.floor(player.y - (player.label:getHeight())) * scale +
math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(player.label, labelTransform)
end
end
color_push()
local mousex, mousey = love.mouse.getPosition( )
local previewTransform = love.math.newTransform(
alignToGrid(mousex, 16) * scale, alignToGrid(mousey, 16) * scale)
love.graphics.setColor(1, 1, 1, .8)
love.graphics.draw(textures[drawing.cursor].image, previewTransform)
color_pop()
-- Draw foreground
love.graphics.draw(buffer.pixel.fg, layerTransform)
-- Draw UI
love.graphics.draw(ui.buffer)
end
local function debugDraw()
normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(buffer.pixel.dbg, layerTransform)
love.graphics.draw(buffer.pixel.dbg2, layerTransform)
love.graphics.setCanvas(buffer.pixel.dbg2)
love.graphics.clear()
love.graphics.setCanvas()
end
local function normalNetworkSend(args)
if clientID == "0" then print("Invalid clientID?") end
local request = "poppyV002" ..US.. clientID ..US.. args
gameloop.client:send(request)
end
local function debugNetworkSend(args)
assert(clientID ~= 0)
local request = "poppyV002" ..US.. clientID ..US.. args
print("=>", request)
gameloop.client:send(request)
end
function normalNetworkSync()
local message, errorString = nil, false
while not errorString do
local message, errorString = gameloop.client:receive()
if not message then
if errorString == "timeout" then return else
error(errorString)
end
end
local response = rpc.validate(message)
if not response.errorMsg then
rpc.execute(v2_message, response.clientID, response.record)
message = nil
else
error(errorMsg)
end
end
end
function debugNetworkSync()
local message, errorString = nil, false
while not errorString do
local message, errorString = gameloop.client:receive()
print("=> " .. message)
print(type(message))
print(errorString)
if not message then
if errorString == "timeout" then return else
error(errorString)
end
end
local response = rpc.validate(message)
if not response.errorMsg then
rpc.execute(v2_message, response.clientID, response.record)
message = nil
else
error(errorMsg)
end
end
end
function gameloop.init(server, nickname)
local socket = require "socket"
local v2_message = require("lua.network")
assert(server, "Gameloop called without server to connect to?")
assert(nickname, "Gameloop called without nickname?")
gameloop.server = server
scale = 1
love.graphics.setDefaultFilter("nearest", "nearest", 0)
layer = true
grid = 16
color = {}
mouse = {}
window = {}
window.x, window.y = love.graphics.getDimensions()
players = {}
textures = {}
view = {}
view.x = 0
view.y = 0
clientID = "0"
gameloop.client = socket.udp()
--gameloop.client:setpeername(server.adress, server.port)
gameloop.client:settimeout(0)
print(gameloop.client:getsockname())
print("Connecting to [" .. server.adress .."]:" .. server.port)
local request = "poppyV002" ..US.. "0" ..US.. unit("init", nickname)
gameloop.client:sendto(request, server.adress, server.port)
if NETWORK_DEBUG then print("<=", request) end
if not NETWORK_DEBUG then
gameloop.networkSend = normalNetworkSend
gameloop.networkSync = normalNetworkSync
else
gameloop.networkSend = debugNetworkSend
gameloop.networkSync = debugNetworkSync
end
love.update = function(dt)
gameloop.networkSync(dt)
love.timer.sleep((1/60) -dt)
end
love.draw = function(dt)
love.graphics.present()
end
love.quit = function()
gameloop.networkSend(unit("player", "leave"))
end
end
function gameloop.loadworld(world)
local buffer = {}
buffer.pixel = {}
buffer.pixel.fg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.bg = love.graphics.newCanvas(world.x, world.y)
if PHYSICS_DEBUG then
buffer.pixel.dbg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.dbg2 = love.graphics.newCanvas(world.x, world.y)
end
buffer.physics = {}
gameloop.buffer = buffer
love.visible = function(visible)
if visible then
love.update = function(dt)
gameloop.networkSync(dt)
camera.input(dt)
physics.input(dt)
drawing.input(dt)
physics.update(dt)
camera.update(dt)
love.timer.sleep((1/60) -dt)
end
else
love.update = function(dt)
gameloop.networkSync(dt)
physics.update(dt)
love.timer.sleep((1/60) -dt)
end
end
end
drawBackground = true
love.keyreleased = function(key, _)
if PHYSICS_DEBUG then
physics.keyreleased_debug(key, _)
end
if key == "r" then
drawBackground = not drawBackground
end
ui.keyreleased(key, _)
camera.keyreleased(key, _)
drawing.keyreleased(key, _)
end
if not PHYSICS_DEBUG then
love.draw = normalDraw
else
love.draw = debugDraw
end
local fullscreen = false
love.keypressed = function(key, _)
physics.keypressed(key, _)
camera.keypressed(key, _)
end
love.resize = function()
ui.resize()
camera.resize()
end
ui.init()
drawing.init()
end

View File

@ -1,11 +1,3 @@
world = {}
world.x = 1024
world.y = 1024
--world.x = 6144
--world.y = 6144
myClientID = "0"
setmetatable(_G, {
__index = function(self, idx)
if rawget(self, idx) == nil then
@ -14,107 +6,15 @@ setmetatable(_G, {
end
})
COLLISION_PRINT = false
PHYSICS_DEBUG = true
DEBUGPRINT = false
drawBackground = true
scale = 1
local constants = require("server.constants")
local US = string.char(31)
love.graphics.setDefaultFilter("nearest", "nearest", 0)
local v1_message = require("lua.network")
local rpc = require("server.rpc")
buffer = {}
buffer.pixel = {}
buffer.pixel.fg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.bg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.dbg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.dbg2 = love.graphics.newCanvas(world.x, world.y)
buffer.physics = {}
layer = true
grid = 16
color = {}
mouse = {}
view = {}
view.x = 0
view.y = 0
window = {}
window.x, window.y = love.graphics.getDimensions()
players = {}
textures = {}
clientID = "0"
local socket = require "socket"
local address = "127.0.0.1"
local port = 11150
local myname = "John Sheridan"
local client = socket.udp()
client:setpeername(address, port)
client:settimeout(0)
NETWORK_DEBUG = true
constants = require("server.constants")
US = string.char(31)
function love.load()
print(client:getsockname())
local request = "poppyV001" ..US.. "0" ..US.. unit("rq", "cid", myname)
client:send(request)
ui.init()
end
function networkSend(args)
assert(clientID ~= "0")
local request = "poppyV001" ..US.. myClientID ..US.. args
client:send(request)
end
function networkSendLog(args)
assert(clientID ~= "0")
local request = "poppyV001" ..US.. myClientID ..US.. args
print("=>", request)
client:send(request)
end
function love.resize()
ui.resize()
camera.resize()
end
function love.keyreleased(key, _)
if PHYSICS_DEBUG then
physics.keyreleased_debug(key, _)
end
if key == "r" then
drawBackground = not drawBackground
end
ui.keyreleased(key, _)
camera.keyreleased(key, _)
drawing.keyreleased(key, _)
end
local fullscreen = false
function love.keypressed(key, _)
physics.keypressed(key, _)
camera.keypressed(key, _)
local server = { adress = "127.0.0.1", port = 11150 }
gameloop.init(server, "Username")
end
@ -149,119 +49,3 @@ function love.errorhandler(msg)
love.timer.sleep(0.1)
end
end
function networkSync()
local message, errorString = nil, false
while not errorString do
local message, errorString = client:receive()
if not message then
if errorString == "timeout" then return else
error(errorString)
end
end
local response = rpc.validate(message)
if not response.errorMsg then
rpc.execute(v1_message, response.clientID, response.record)
else
error(errorMsg)
end
end
end
function love.visible(visible)
if visible then
love.update = function(dt)
networkSync(dt)
camera.input(dt)
physics.input(dt)
drawing.input(dt)
physics.update(dt)
camera.update(dt)
love.timer.sleep((1/60) -dt)
end
else
love.update = function(dt)
networkSync(dt)
physics.update(dt)
love.timer.sleep((1/60) -dt)
end
end
end
function normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
--draw specific world bg
-- Draw background
if drawBackground then
color_push()
love.graphics.setColor(0.05, 0.05, 0.05)
love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, world.x * scale, world.y * scale)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(buffer.pixel.bg, layerTransform)
color_pop()
end
-- draw player
for i, player in pairs(players) do
--print("drawing player " .. i)
local playerTransform = love.math.newTransform(
math.floor(player.x) * scale + math.floor(view.x) * scale,
math.floor(player.y) * scale + math.floor(view.y) * scale,
0, scale, scale)
love.graphics.draw(player.avatar, playerTransform)
if player.name then
local labelTransform = love.math.newTransform(
math.floor(player.x - (player.label:getWidth() / 2) +
(player.avatar:getPixelWidth() /2)) * scale + math.floor(view.x) * scale,
math.floor(player.y - (player.label:getHeight())) * scale +
math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(player.label, labelTransform)
end
end
color_push()
local mousex, mousey = love.mouse.getPosition( )
local previewTransform = love.math.newTransform(
alignToGrid(mousex, 16) * scale, alignToGrid(mousey, 16) * scale)
love.graphics.setColor(1, 1, 1, .8)
love.graphics.draw(textures[drawing.cursor].image, previewTransform)
color_pop()
-- Draw foreground
love.graphics.draw(buffer.pixel.fg, layerTransform)
--love.graphics.draw(buffer.pixel.dbg, layerTransform)
--love.graphics.draw(buffer.pixel.dbg2, layerTransform)
--buffer.pixel.dbg2:renderTo(function() love.graphics.clear() end)
-- Draw UI
love.graphics.draw(ui.buffer)
end
function debugDraw()
normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(buffer.pixel.dbg, layerTransform)
love.graphics.draw(buffer.pixel.dbg2, layerTransform)
love.graphics.setCanvas(buffer.pixel.dbg2)
love.graphics.clear()
love.graphics.setCanvas()
end
if not DEBUGPRINT then love.draw = normalDraw else
love.draw = debugDraw
end
function love.quit()
networkSendLog(unit("player", "leave"))
end

View File

@ -1,26 +1,33 @@
local player = require("lua.player")
local util = require("server.utils");
local v1_message = {}
local v2_message = {}
v1_message.rq = {}
v1_message.rq.cid = function(_, args) -- _ is serverID (0)
local clientID, name = util.nextStringRecord(args)
print("Connected as " .. clientID)
v2_message.init = function(clientID, args)
local newClientID, args = util.nextStringRecord(args)
local nickname, args = util.nextStringRecord(args)
local worldID, args = util.nextStringRecord(args)
local x, y = util.nextIntRecord(args)
y = tonumber(y)
print("Connected as " .. newClientID .. " with name " .. nickname)
print("New worls is " .. worldID .. "Size is [" .. x .. "|" .. y "]")
players[clientID] = player.newPlayer()
camera.target = clientID
myClientID = clientID
if name then print("getting name " .. name) else error("no name :(") end
players[clientID].label = love.graphics.newText(ui.smallFont, name)
players[clientID].name = name
end
camera.target = newClientID
_G.clientID = newClientID
v1_message.rq.ping = function(clientID)
networkSend(unit("rq", "pong"))
players[newClientID].label = love.graphics.newText(ui.smallFont, name)
players[newClientID].name = nickname
local world = { id = worldID, x = x, y = y }
gameloop.loadworld(world)
end
v1_message.player = {}
v1_message.player.join = function(clientID, name)
v2_message.ping = function(clientID)
gameloop.networkSend("pong")
end
v2_message.playerJoin = function(clientID, name)
ui.addChatEntry("", name .. " Joined the game")
players[clientID] = player.newPlayer()
players[clientID].label = love.graphics.newText(ui.smallFont, name)
@ -28,7 +35,7 @@ v1_message.player.join = function(clientID, name)
end
v1_message.player.leave = function(clientID)
v2_message.playerLeave = function(clientID)
if players[clientID] then
local name = players[clientID].name
ui.addChatEntry("", name .. " Left the game")
@ -36,8 +43,8 @@ v1_message.player.leave = function(clientID)
end
end
v1_message.move = {}
v1_message.move.update = function(clientID, args)
v2_message.moveUpdate = function(clientID, args)
if not players[clientID] then return end
local x, args = util.nextIntRecord(args)
local y, args = util.nextIntRecord(args)
@ -51,29 +58,27 @@ v1_message.move.update = function(clientID, args)
end
v1_message.move.flying = function(clientID, args)
v2_message.moveFlying = function(clientID, args)
if not players[clientID] then return end
players[clientID].flying = (args == "true")
end
v1_message.drawing = {}
v1_message.drawing.physics = {}
v1_message.drawing.physics.delete = function(clientID, args)
v2_message.deletePhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.remove_solid(util.getIntRecords(4, args))
end
v1_message.drawing.physics.draw = function(clientID, args)
v2_message.drawPhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.draw_solid(util.getIntRecords(4, args))
end
v1_message.drawing.texture = {}
v1_message.drawing.texture.draw = function(clientID, args)
v2_message.drawTexture = function(clientID, args)
if clientID == camera.target then return end
local x, args = util.nextIntRecord(args)
local y, args = util.nextIntRecord(args)
@ -107,7 +112,7 @@ v1_message.drawing.texture.draw = function(clientID, args)
end
v1_message.drawing.texture.delete = function(clientID, args)
v2_message.deleteTexture = function(clientID, args)
if clientID == camera.target then return end
local x, args = util.nextIntRecord(args)
local y, args = util.nextIntRecord(args)
@ -128,8 +133,7 @@ v1_message.drawing.texture.delete = function(clientID, args)
end
v1_message.chat = {}
v1_message.chat.send = function(clientID, args)
v2_message.chatMessage = function(clientID, args)
local name
if clientID == "0" then
name = ""
@ -139,4 +143,4 @@ v1_message.chat.send = function(clientID, args)
ui.addChatEntry(players[clientID].name, args)
end
return v1_message
return v2_message

View File

@ -92,9 +92,9 @@ function physics.keypressed( key, code, isrepeat)
player.flying = not player.flying
if player.flying then
player.speed.y = 0
networkSend(unit("move", "flying", "true"))
gameloop.networkSend(unit("moveFlying", "true"))
else
networkSend(unit("move", "flying", "false"))
gameloop.networkSend(unit("moveFlying", "false"))
end
end
end
@ -281,7 +281,7 @@ last.packet, last.x, last.y, last.speedx, last.speedy = 0, 0, 0, 0, 0
function physics.send_update(player, dt)
if last.packet > 0.03 then
if last.x ~= player.x or last.y ~= player.y then
networkSend(unit("move", "update", player.x, player.y, player.speed.x, player.speed.y))
gameloop.networkSend(unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y))
last.packet = 0
last.x, last.y = player.x, player.y
last.speedx, last.speedy = player.speedx, player.speedy

View File

@ -1,24 +1,4 @@
ui = {}
ui.smallFont, ui.font, ui.bigFont = nil
local w, h = love.window.getMode()
ui.buffer = love.graphics.newCanvas(w, h)
ui.space = 300
if love.filesystem.getInfo("fonts/font.ttf") then
ui.smallFont = love.graphics.newFont("fonts/font.ttf", 14)
ui.font = love.graphics.newFont("fonts/font.ttf", 20)
ui.bigFont = love.graphics.newFont("fonts/font.ttf", 45)
else
ui.smallFont = love.graphics.getFont(14)
ui.font = love.graphics.getFont(20)
ui.bigFont = love.graphics.getFont(45)
print("Falling back to love2d default font")
end
framenum = 0
ui.scale = love.graphics.newText(ui.bigFont, "scale: " .. scale)
ui.framenum = love.graphics.newText(ui.font, "framenum: " .. framenum)
love.keyboard.setTextInput( false )
function ui.update_framenum(p_framenum)
ui.framenum = nil
@ -89,7 +69,7 @@ function ui.keyreleased(key, _)
if key == "return" and not love.keyboard.isDown("lalt") then
textEnabled = false
if textEntry ~= "" then
networkSend(unit("chat", "send", textEntry))
gameloop.networkSend(unit("chatMessage", textEntry))
textEntry = ""
end
ui.draw(window.x, window.y)
@ -337,7 +317,6 @@ function ui.tabDrawer(textureTree, w, h)
end
local textureTree = ui.loadTextures("textures/blocks")
function ui.draw(w, h)
window.x, window.y = w, h
color_push()
@ -387,6 +366,29 @@ end
ui.init = function()
ui.smallFont, ui.font, ui.bigFont = nil
local w, h = love.window.getMode()
ui.buffer = love.graphics.newCanvas(w, h)
ui.space = 300
if love.filesystem.getInfo("fonts/font.ttf") then
ui.smallFont = love.graphics.newFont("fonts/font.ttf", 14)
ui.font = love.graphics.newFont("fonts/font.ttf", 20)
ui.bigFont = love.graphics.newFont("fonts/font.ttf", 45)
else
ui.smallFont = love.graphics.getFont(14)
ui.font = love.graphics.getFont(20)
ui.bigFont = love.graphics.getFont(45)
print("Falling back to love2d default font")
end
framenum = 0
ui.scale = love.graphics.newText(ui.bigFont, "scale: " .. scale)
ui.framenum = love.graphics.newText(ui.font, "framenum: " .. framenum)
local textureTree = ui.loadTextures("textures/blocks")
love.keyboard.setTextInput( false )
local w,h = love.window.getMode()
ui.draw(w, h)
ui.resize = function()

View File

@ -2,6 +2,7 @@ function dofile(fileString)
local chunk = love.filesystem.load(fileString)
chunk()
end
dofile "lua/gameloop.lua"
dofile "lua/utils.lua"
dofile "lua/layout.lua"
dofile "lua/init.lua"

BIN
ressources/Poppy-server.iom Normal file

Binary file not shown.

BIN
ressources/Poppy-server.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB