Ok, so your question is actually independent from metatables or Solarus, it is about the passing a value of type function vs calling a function.
function metatable:example()
--some code
end
This defines a field "example" (of type function) on the object "metatable", and not an "example" global value.
Which means that you can call it like this, assuming you have an entity called my_entity:
my_entity:example()
and not like this
example() -- Does not work: example is nil
If you want to make a value of type function instead of doing the call entity:example(), just wrap the call it in a function:
local function f()
my_entity:example()
end
Then it is a value of type function (and not a function call anymore, this is the trick!) so you can pass it to anything that wants a value of type function, like pcall, sol.timer.start, etc.
local success = pcall(f)
if success then
...
else
...
end
You can even keep it anonymous if you prefer:
local success = pcall(function()
entity:example()
end)
if success then
...
else
...
end