Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skipped on_item_eats functions #2615

Closed
Lymkwi opened this issue Apr 9, 2015 · 5 comments
Closed

Skipped on_item_eats functions #2615

Lymkwi opened this issue Apr 9, 2015 · 5 comments
Labels
Bug Issues that were confirmed to be a bug Low priority @ Script API

Comments

@Lymkwi
Copy link
Contributor

Lymkwi commented Apr 9, 2015

Hello,
I recently found something very strange while working on the new hunger mod. Here is the explaination : the new hunger mod by @BlockMen is using a new way to know when players eat some food without changing the function in the on_use fields of their definition : it registers a function in the core.on_item_eats table, which (is supposed to) launch this function whenever a player eats something, an item with on_use = minetest.item_eat(foo,bar) . However, while using the mod, I noticed that the function was never launched. After a complete day of removing mod per mod, using another game, and even read some of the builtin registration function, I discovered something : the game we were using (@Ombridride 's one ) contained another call to minetest.register_on_item_eat with a function returning true to cancel the engine's answer to eat, and to stop its job. But when I removed it, hunger's function started to run, and could make the hunger system work. So why?
In a nutshell, when the engine is parsing the core.on_item_eats table, whenever one of the functions returns the itemstack or true (to abort its job, or to cancel the engine answer), the following functions (registered after) are skipped, because the engine stops parsing when a functions cancels the engine answer by returning the itemstack.
It means that something like :

minetest.register_on_item_eat(function()
    print("foo")
end)

minetest.register_on_item_eat(function()
    print("bar")
end)

minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing)
    print("done")
    return itemstack
end)

launches the three functions while this :

minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing)
    print("done")
    return itemstack
end)

minetest.register_on_item_eat(function()
    print("foo")
end)

minetest.register_on_item_eat(function()
    print("bar")
end)

only sends "done" (and both of these pieces of code break hunger's system because the mod is loaded after). (tested on minetest_game at minetest/minetest_game@fe7a982 with engine at 0a41326 )
This can be a big problem whenever a mod is loaded before another one and contains a on_item_eat function canceling the engine answer while the other one, for example, only send a debug print, or plays a sound at the player.

@BetterToAutomateTheWorld

+1,
I confirmed and aprouved we need an update/upgrade/improve of this function...

@BlockMen BlockMen added Bug Issues that were confirmed to be a bug @ Script API Low priority labels Apr 10, 2015
@rubenwardy
Copy link
Member

This is expected behaviour. The other callbacks, eg: on formspec fields receive, do this. You can run the other callbacks and still modify the itemstack by not returning an itemstack or true, as it's pass by value. However, the default action will run.

I am the author of minetest.register_on_item_eat.

It would be useful to be able to override default behaviour without stopping the other callbacks from running. The point of cancelling is so that the other functions don't process the event twice, but I guess it is realistic that there is only one hunger mod installed at a time.

@rubenwardy
Copy link
Member

I suggest either separating effects (sounds, etc) from mechanics (hunger) or making it so callbacks can signal if they want following callbacks to run, but it needs to be done in a backwards compatible way.

Why do the call backs in the subgame return non nil? They shouldn't if they don't modify it.

@rubenwardy
Copy link
Member

This is the code in question: https://github.com/Ombridride/minetest-minetestforfun-server/blob/a1dfa30979a782e3ec0213df05ac53f25b1833d8/minetestforfun_game/mods/default/init.lua#L93
It doesn't seem compatible with HUD/hunger, anyway, it relies on the default processing of food. A register_on_hp_change callback might be better for it.

@Lymkwi
Copy link
Contributor Author

Lymkwi commented Apr 13, 2015

This piece of code was suppressed, but anyway, if it's an expected behavior, there is no reason I keep this issue open. It will be closed in 2 days , so if anyone wants to let an opinion or propose something else, they are free to do so.
And hud_change callback could be a good idea, but must start after the on_item_eat process is finished (if the hud_change is from some food) and the engine did its work (increasing hp, or nothing).
Thanks for responding @rubenwardy .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Issues that were confirmed to be a bug Low priority @ Script API
Projects
None yet
Development

No branches or pull requests

4 participants