Simple Tiled Implementation - STI v1.2.3.0

Showcase your libraries, tools and other projects that help your fellow love users.
ikarius
Prole
Posts: 3
Joined: Fri Feb 21, 2020 12:08 pm

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by ikarius »

ikarius wrote: Fri Feb 21, 2020 2:39 pm Thanks for your quick reply.

I succeeded adding static components by creating custom layers and adding manually all needed physics, so I think I am on the good path.

But I'm creating a lot of custom layers (one per static object). Is it OK to create a layer for every object in the game ?

Plus, I don't know how to change the tile in a given layer: I can replace any tile with an ID=0 and it removes it correctly.
But adding another tile ID is a no go (crash).

I tried with one single layer and multiple objects / sprites attached and it works well!
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by Karai17 »

Yeah, custom layers are just layers that you dump your own data into. You can use one layer for tonnes of objects, it just allows you to order the draws so that your objects draw over and under other layers correctly.

As for the crash, I am uncertain about that. Can you share a .love example I can tinker with?
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
JuanjoSalvador
Prole
Posts: 26
Joined: Wed Nov 27, 2019 9:19 pm
Location: Almeria, ES
Contact:

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by JuanjoSalvador »

Question about STI, sorry if already answered, I didn't found anything...

I'm trying to write a lazy-loader for different maps into a platformer game. Maps are made with Tiled and loaded into Love2D with STI (btw, thanks for this module @Karai17!), at this point I realized that everytime I switch to another map, the old map seems still loaded. Example, I've got the following code to get the graphic stats, because I noticed an increment of memory everytime I get into a new level/map:

Code: Select all

	local stats = love.graphics.getStats()
	print("Canvases: " .. stats["canvases"]
	print("Texture Memory: " .. stats["texturememory"] / 1024 / 1024
Each map has 2 layers, tiles and objects. For the first map, the Canvases value is 2, OK. Second map, 4. Third map, 6... And the texture memory, increases by 12-13 MB each time.

My lazy loader has the following code:

Code: Select all

local levelList = {
    'level01',
    'level02',
    'level03'
}

function Level:load(level)
    map = sti("assets/maps/" .. levelList[level] .. ".lua", { "box2d" })
    return map
end
Actually is just an "array of levels" and loader by selector. There is no function to unload the level. Everytime I call Level:load(), also sets the variable to nil and load it again. But I think there should be any way to unload/release the old unneeded canvases, isn't it? Maybe I just forgot something...
itch.io profile - When I'm uploading my works and devblogs
GitHub - All my code is here!
Horchata - A set of Lua modules I wrote to make some task easier
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by Karai17 »

Hm. It would seem that luajit isn't properly removing canvases when they are dereferenced. I'll have to look into this. I can call :release() on canvases when they are knowingly being tossed, such as when resizing the window, but I may need to add some sort of destroy function to a map to properly clear canvases when you are overwriting a variable in your own code.

Also worth noting in the code you show in your post, your "map" variable is global and so returning it isn't particularly useful. What I would recommend instead would simply be

Code: Select all

function Level:load(level)
    return sti(string.format("assets/maps/%s.lua", levelList[level]), { "box2d" })
end
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
JuanjoSalvador
Prole
Posts: 26
Joined: Wed Nov 27, 2019 9:19 pm
Location: Almeria, ES
Contact:

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by JuanjoSalvador »

pgimeno wrote: Thu Apr 23, 2020 10:24 pm Related: https://love2d.org/forums/viewtopic.php ... 60#p231860
That was I thought. But the canvases are created by STI, so... I can hack the library to add my own release() function into the old canvas. In fact, I added my own function, but only can release one of the two created canvas. I'm holding this line, thanks again!
Karai17 wrote: Thu Apr 23, 2020 10:49 pm Also worth noting in the code you show in your post, your "map" variable is global and so returning it isn't particularly useful. What I would recommend instead would simply be

Code: Select all

function Level:load(level)
    return sti(string.format("assets/maps/%s.lua", levelList[level]), { "box2d" })
end
Yeah, I need to rewrite a lot, and also I need to improve my Lua skills... Thanks for the suggestion :) I'm going to check the lib and if ) I'm able to add a properly :release() function for the canvases, maybe I can send you a PR.
itch.io profile - When I'm uploading my works and devblogs
GitHub - All my code is here!
Horchata - A set of Lua modules I wrote to make some task easier
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by pgimeno »

Karai17 wrote: Thu Apr 23, 2020 10:49 pm Hm. It would seem that luajit isn't properly removing canvases when they are dereferenced.
It's working as designed. The problem is that there aren't enough objects to trigger a GC; LuaJIT doesn't know (or care about, not sure) the underlying size of the objects so it treats all the same way regardless of size. If you just keep generating objects, eventually the GC will trigger and the canvases will be released, but that delay may not be affordable for some use cases. If you call collectgarbage() manually, the canvases are removed immediately.
User avatar
JuanjoSalvador
Prole
Posts: 26
Joined: Wed Nov 27, 2019 9:19 pm
Location: Almeria, ES
Contact:

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by JuanjoSalvador »

pgimeno wrote: Thu Apr 23, 2020 11:46 pm If you call collectgarbage() manually, the canvases are removed immediately.
This works too. No need to call my custom :release() for canvas everytime I load a new map, just collectgarbage() and go.
itch.io profile - When I'm uploading my works and devblogs
GitHub - All my code is here!
Horchata - A set of Lua modules I wrote to make some task easier
dashbandith
Prole
Posts: 2
Joined: Tue May 26, 2020 5:21 am

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by dashbandith »

Greetings, I am new to Löve2d and I want to use it in my STI project. Sorry if my question is very basic I copy and paste the example from the tutorial (https://github.com/karai17/Simple-Tiled ... -to-sti.md)

Code: Select all

-- Include Simple Tiled Implementation into project
local sti = require "sti"

function love.load()
	-- Load map file
	map = sti("map.lua")

	-- Create new dynamic data layer called "Sprites" as the 8th layer
	local layer = map:addCustomLayer("Sprites", 8)

	-- Get player spawn object
	local player
	for k, object in pairs(map.objects) do
		if object.name == "Player" then
			player = object
			break
		end
	end

	-- Create player object
	local sprite = love.graphics.newImage("sprite.png")
	layer.player = {
		sprite = sprite,
		x      = player.x,
		y      = player.y,
		ox     = sprite:getWidth() / 2,
		oy     = sprite:getHeight() / 1.35
	}

	-- Add controls to player
	layer.update = function(self, dt)
		-- 96 pixels per second
		local speed = 96 * dt

		-- Move player up
		if love.keyboard.isDown("w", "up") then
			self.player.y = self.player.y - speed
		end

		-- Move player down
		if love.keyboard.isDown("s", "down") then
			self.player.y = self.player.y + speed
		end

		-- Move player left
		if love.keyboard.isDown("a", "left") then
			self.player.x = self.player.x - speed
		end

		-- Move player right
		if love.keyboard.isDown("d", "right") then
			self.player.x = self.player.x + speed
		end
	end

	-- Draw player
	layer.draw = function(self)
		love.graphics.draw(
			self.player.sprite,
			math.floor(self.player.x),
			math.floor(self.player.y),
			0,
			1,
			1,
			self.player.ox,
			self.player.oy
		)

		-- Temporarily draw a point at our location so we know
		-- that our sprite is offset properly
		love.graphics.setPointSize(5)
		love.graphics.points(math.floor(self.player.x), math.floor(self.player.y))
	end

	-- Remove unneeded object layer
	map:removeLayer("Spawn Point")
end

function love.update(dt)
	-- Update world
	map:update(dt)
end

function love.draw()
	-- Scale world
	local scale = 2
	local screen_width  = love.graphics.getWidth()  / scale
	local screen_height = love.graphics.getHeight() / scale

	-- Translate world so that player is always centred
	local player = map.layers["Sprites"].player
	local tx = math.floor(player.x - screen_width  / 2)
	local ty = math.floor(player.y - screen_height / 2)

	-- Transform world
	love.graphics.scale(scale)
	love.graphics.translate(-tx, -ty)

	-- Draw world
	map:draw()
end
and when running it shows me the following error message .

Code: Select all

Error

sti/init.lua:729: Layer not found: Spawn Point


Traceback

[C]: in function 'assert'
sti/init.lua:729: in function 'removeLayer'
main.lua:76: in function 'load'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
What am I doing wrong?
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v1.2.3.0

Post by Karai17 »

you don't have a layer in your map named Spawn Point so trying to remove it is throwing an error.
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests