Jump to content
Maris

Avoiding Runtime Errors

Recommended Posts

Posted (edited)

Let's say there is a critical game function "render":

function SomeClass:render()
	--Game code (safe)
end

 

And you want to inject into it.

As you know, replacing the whole function is bad practice.

Therefore, the injection in your mod will look something like this:

local old_fn = SomeClass.render
SomeClass.render = function(self, ...)
	--Your code (unsafe)
	return old_fn(self, ...)
end

 

The main difficulty is that your code may contain errors with a high chance. And if something goes wrong, the user will receive a ton of red errors or the game will freeze because the function is critical and is called roughly every tick.

 

So you want at least stop spam of errors if something went wrong.

 

There is a solution!

local in_progress = false
local old_fn = SomeClass.render
SomeClass.render = function(self, ...)
	if in_progress then
		return old_fn(self, ...)
	end
	in_progress = true
	--Your code (unsafe)
	in_progress = false
	return old_fn(self, ...)
end

 

Actually, this code was created in order to avoid recursion. But as a side effect, it allows to bypass the storm of errors. If something breaks the mod, then the mod just stops working, and the game continues without further errors.

 

 

 

Edited by Maris

Share this post


Link to post
Share on other sites
Posted (edited)

Okay, let's say you need DOUBLE INJECTION. :)

 

Why would you need this? For example, you are a very neat modder and do not want to load the user's CPU, overwriting common game functions and making permanent injection. One of these functions is getText(). And you want to make temporary ninja injection.

 

So we have to go a more complex way:

local old_getText = nil
local function new_getText(str,...)
	--You code (unsafe!)
	return old_getText(str,...)
end


local in_progress = false
local old_render = SomeClass.render
function SomeClass:render(...) --permanent injection
	if in_progress then
		if old_getText and getText == new_getText then
			getText = old_getText
			old_getText = nil
		end
		return old_render(self, ...)
	end
	old_getText = getText
	getText = new_getText --tempry second injection
	in_progress = true
	local result = old_render(self, ...)
	in_progress = false
	if old_getText then
		getText = old_getText
	end
	return result
end

 

If something goes wrong, your feature just stop working and that's it. No further game errors.

 

P.S. Specific function render() does not return a result (by meaning), so you may omit it in this case. But it's not a mistake. Usually you have to keep the result.

 

 

 

Edited by Maris

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...