Io.write() crashes the player

When I build the game the player opens and before it renders it becomes unresponsive. I’ve narrowed the issue down to the io.open() function. Which was hard because it crashed before I got any console output. I’m using the 2.0 editor.

Please share the entire piece of code where io.open() is called.

Update: no it doesnt. I’m back to the original error and it’s actually io.write that’s the issue. Also it manages to write but the player window freezes. Here’s the code:

function init(self)
	print(grid.table)
	local x, y, w, h = tilemap.get_bounds("#map")
	local data = update_grid_data(self, w, h)
	local toWrite = "test"
	print(toWrite)
	local f, error = io.open("C:\\Users\\laser\\game\\assets\\objects\\map\\grid_data.lua", "w")
	print(error)
	f:write(toWrite)
	f:close()
	grid.build(w, h)
	grid.build_data(w, h)
	print("success")
	for i=0, w do
		for j=0, h do
			local c = factory.create("#cell_factory", nil, nil, {x=i, y=j})
			grid.table[i][j] = c
		end
	end
end

Are you 100% sure it’s writing the file that’s causing problems? The same code works just fine for me. What happens if you remove everything else except the file writing part?

@ross.grams So here’s the thing. For a while it was just that. Then it was the whole open statement. then later after I added a json module and it worked a few times. Now it won’t work at all. I’ve restarted defold, I’ve restarted my computer, and I’ve reinstalled defold. Still no dice. Something’s really wrong.

Zip the project and share it with me (bjorn.ritzl@king.com).

Do you have any errors in the console? Does it really lock up the engine. Add a print in update() to verify.

Thanks, got the project. I saw a number of things to note:

  1. You’re using (loadfile "C:\\Users\\laser\\game\\assets\\modules\\JSON.lua")() to load a JSON module. For the sake of portability and conforming with how Defold does things I would recommend that you use require "assets.modules.JSON" instead.
  2. You use global functions, for example update_grid_data() in map_script.script. It’s a good practice to avoid this. Prefix with a local keyword and move it to the top of the file (you need to declare it before you use it).
  3. You use table.getn() which is a Lua 5.3 function. Defold uses Lua 5.1/LuaJIT
  4. You should try to stay away from absolute path names to make your game portable. Change from io.open("C:\\Users\\laser\\game\\assets\\objects\\map\\grid_data.lua", "w") to io.open(sys.get_save_file("laser", "grid_data"), "w") to get a portable and writable path on all platforms.

EDIT: I’m surprised that you didn’t get any errors in the console. Are you sure about that?

3 Likes

I implemented your suggestions and now I’m getting this error in a popup:

java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: Could not initialize class com.defold.libs.TexcLibrary
java.lang.NoClassDefFoundError: Could not initialize class com.defold.libs.TexcLibrary

Hmm, which version of the editor are you using? Sounds like this issue:

@Erik_Angelin might have additional input.

I’m using version 1.2.142 on windows. I read over the fixes and looks like the best available fix for me is to change versions but correct me if I’m wrong. Maybe java is out of date? It just started working randomly. As a side note. Are there any specific json modules you recomend? All the one I can find require being built, load file, or say I’m trying to pass a sparse table and I don’t know how to fix that.

This often happens when you run several editor instances simultaneously.

I usually use this one for encoding: https://github.com/rxi/json.lua

For decoding I use the built in json.decode() function.

I implemented all of your fixes and it’s still crashing with the original symptoms.
code:

local grid = require("assets.objects.map.grid")
local listUtils = require("assets.modules.list_utils")

local function update_grid_data(self, w, h)
	local x = io.open(sys.get_save_file("laser", "grid_data.lua"), "w")
	x:close()
	local f, error = io.open(sys.get_save_file("laser", "grid_data.lua"), "r")
	print(f, error)
	local dataOldS = f:read("*a")
	print(dataOldS)
	local dataOld = {}
	local exists = false
	if string.len(dataOldS) > 0 then
		exists = true
		dataOld = json.decode(dataOldS)
	end
	f:close()
	local dataNew = {}
	for i=0, w, 1 do
		table.insert(dataNew, i, {})
		for j=0, h, 1 do
			local iOld = #dataOld
			if i < iOld then
				local jOld = #dataOld[i]
				if exists and j < jOld then
					table.insert(dataNew[i], j, dataOld[i][j])
				else
					table.insert(dataNew[i], j, "")
				end
			else
				table.insert(dataNew[i], "")
			end
		end
	end
	return dataNew
end

function init(self)
	print(grid.table)
	local x, y, w, h = tilemap.get_bounds("#map")
	local data = update_grid_data(self, w, h)
	local toWrite = listUtils.encode(data)
	print(toWrite)
	local f, error = io.open(sys.get_save_file("laser", "grid_data"), "w")
	print(error)
	f:write(toWrite)
	f:close()
	grid.build(w, h)
	grid.build_data(w, h)
	print("success")
	for i=0, w do
		for j=0, h do
			local c = factory.create("#cell_factory", nil, nil, {x=i, y=j})
			grid.table[i][j] = c
		end
	end
end

function final(self)
	-- Add finalization code here
	-- Remove this function if not needed
end

function update(self, dt)
	-- Add update code here
	-- Remove this function if not needed
end

function on_message(self, message_id, message, sender)
	-- Add message-handling code here
	-- Remove this function if not needed
end

function on_input(self, action_id, action)
	-- Add input-handling code here
	-- Remove this function if not needed
end

function on_reload(self)
	-- Add reload-handling code here
	-- Remove this function if not needed
end

Can you please set a breakpoint or add print() calls before and after io.open() to confirm that execution doesn’t go beyond that line of code? Which system are you testing this on? Windows? Which version?

Im testing on windows 10 with an amd processor. I loaded it on a second computer also windows 10 with an Intel i5 processor and got the result. I have print statements in and out of the io statements. Specifically where should i add them? Because i get zero console read out. Not even any build errors or the default console startup read out, it’s completely blank.

E.g. start early in your code, to see that you get output at all in the Editor.
Then, start adding prints further down in your code, to pinpoint your issue.

1 Like

@britzl @Mathias_Westerdahl I don’t get any debug readouts:

1 Like

Ok, that’s weird. None at all? And you are using “Build and Run” (Ctrl+B)?
Add a script to your top collection, and add a “print()” inside that init function. It should come out to the Console log view in the editor.

It also gave me a similar crash when I initialized a 2D array with an initializer list. I added a script with a print call in init and added on the top level of the main object with the main script and I still have no console output. I did the same with the init on the main script and got the same result.

Can you please start with a new completely blank project?