• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Try/Catch on lua?

Joined
Mar 14, 2020
Messages
139
Solutions
3
Reaction score
11
There a way to do a Try/Catch in lua like in java?

I need to verify if in X/Y/Z/Q/H SQM's have players, but when i try to:
Lua:
local playerPos1 = Tile(Position(32340, 32454, 6)):getTopCreature()

And the SQM have no player the function:
Lua:
Tile(Position(32340, 32454, 6)):getTopCreature()
will return nil and will stop the script, i need something to catch that nil and ignore him, even if this SQM have no player.
 
You could always do some error handling.
Your problem with your error is probably that you are trying to get a creature ontop of a void tile. A tile that does not exist.

Since I don't know what version you're using, I tested this in TFS 1.3

Lua:
-- First we get the tile
    local playerPos1 = Tile(Position(1400, 1187, 9))

    -- Then we check if the tile actually exists and is not void
    if playerPos1 ~= nil then
        -- Now that we know there's a tile at this position and not void, we can check for creatures.
        -- Get creature on this tile. If there is none, it returns nil
        local player = playerPos1:getTopCreature()
        -- Check if there is a creature
        if player ~= nil then
            -- Now we know there's a creature ontop of this tile
        end
    end

    return true
 
I'm not a Lua coder, but it's an interesting question, and may be relevant for me later so I did a quick search. These are interesting:


I can see the "pcall" technique being useful, and will try it out with OT at some point. It doesn't seem to implement "finally" properly (if at all) which would be a problem in some development situations, but IMO rarely, if ever, in normal OT use.

FWIW a Lua/C++ trick comes up too:

I would never ask the OT C++developers to prioritize it, but if they implemented some form of Try/Catch in OT Lua for their their own reasons I'd use it :)
 
Last edited:
In Lua it would be assert, but it isn't as powerful as conditionally checking (IFs).
pcall is rarely a good technique to be choosen, there are some folks that "accidentally" learn about the assert(pcall) combination and starts using this everywhere. It's definetely not a technique that can't be used commonly, it runs in a separate environment your code and takes resources that will be more consuming than just checking your code properly through conditions.

assert can be useful to reduce code as it is less verbose than if x then y else z end
Here you can find a good example of assert: andersonfaaria/otclient (https://github.com/andersonfaaria/otclient/blob/f1b46b6b31f081346e3a2e5df4fba3c34bbe9cc3/modules/game_battle/battle.lua#L502)
On line 505 you have a good example of a case where if is preferred because you wouldn't be able to achieve the same using assert.

Now back to the OP original question, in this case you could use pcall but that wouldn't solve your problem, instead you would be just sending the error message to a environment that would be created and destroyed afterwards. You need to check each phase, this is often called 'secure programming'

ex:
Lua:
local tilePos = Tile(Position(32340, 32454, 6))
if tilePos then
    local creature = tilePos:getTopCreature()
    if creature then
        -- do what you need with the creature
    end
end
 
In Lua it would be assert, but it isn't as powerful as conditionally checking (IFs).
pcall is rarely a good technique to be choosen, there are some folks that "accidentally" learn about the assert(pcall) combination and starts using this everywhere. It's definetely not a technique that can't be used commonly, it runs in a separate environment your code and takes resources that will be more consuming than just checking your code properly through conditions.

assert can be useful to reduce code as it is less verbose than if x then y else z end
Here you can find a good example of assert: andersonfaaria/otclient (https://github.com/andersonfaaria/otclient/blob/f1b46b6b31f081346e3a2e5df4fba3c34bbe9cc3/modules/game_battle/battle.lua#L502)
On line 505 you have a good example of a case where if is preferred because you wouldn't be able to achieve the same using assert.

Now back to the OP original question, in this case you could use pcall but that wouldn't solve your problem, instead you would be just sending the error message to a environment that would be created and destroyed afterwards. You need to check each phase, this is often called 'secure programming'

ex:
Lua:
local tilePos = Tile(Position(32340, 32454, 6))
if tilePos then
    local creature = tilePos:getTopCreature()
    if creature then
        -- do what you need with the creature
    end
end
Worked but with this method we have a lot of issues like:
Hardcode (each if statment must be made by hand), variables inside the IF's cannot be used in future without more hardcode/global vars.

Assert is good but like u said, this method spend a lot of resources and for what i'm doing is not a option rn.
Post automatically merged:

I'm not a Lua coder, but it's an interesting question, and may be relevant for me later so I did a quick search. These are interesting:


I can see the "pcall" technique being useful, and will try it out with OT at some point. It doesn't seem to implement "finally" properly (if at all) which would be a problem in some development situations, but IMO rarely, if ever, in normal OT use.

FWIW a Lua/C++ trick comes up too:

I would never ask them the OT C++developers to prioritize it, but if they implemented some form of Try/Catch in OT Lua for their their own reasons I'd use it :)
Nice research and thanks for sharing, this will be usefull a lot!!
I founded this: https://www.lua.org/wshop06/Belmonte.pdf for me, was very good tutorial, a start point.
Post automatically merged:

You could always do some error handling.
Your problem with your error is probably that you are trying to get a creature ontop of a void tile. A tile that does not exist.

Since I don't know what version you're using, I tested this in TFS 1.3

Lua:
-- First we get the tile
    local playerPos1 = Tile(Position(1400, 1187, 9))

    -- Then we check if the tile actually exists and is not void
    if playerPos1 ~= nil then
        -- Now that we know there's a tile at this position and not void, we can check for creatures.
        -- Get creature on this tile. If there is none, it returns nil
        local player = playerPos1:getTopCreature()
        -- Check if there is a creature
        if player ~= nil then
            -- Now we know there's a creature ontop of this tile
        end
    end

    return true
Yep this will be my solution for now, not the best, but solve the problem rn.
Post automatically merged:

like this one maybe?
Not exactly what i'm looking for, but this is a different way to do the night wolf method, i'm looking more for a way to handle nil-exceptions/errors.
 
Last edited:
Worked but with this method we have a lot of issues like:
Hardcode (each if statment must be made by hand), variables inside the IF's cannot be used in future without more hardcode/global vars.

Assert is good but like u said, this method spend a lot of resources and for what i'm doing is not a option rn.
Post automatically merged:


Nice research and thanks for sharing, this will be usefull a lot!!
I founded this: https://www.lua.org/wshop06/Belmonte.pdf for me, was very good tutorial, a start point.
Post automatically merged:


Yep this will be my solution for now, not the best, but solve the problem rn.
Post automatically merged:


Not exactly what i'm looking for, but this is a different way to do the night wolf method, i'm looking more for a way to handle nil-exceptions/errors.
Just figured I'd point out that you could use the function getSpectators to grab all of the creatures in an area.
Getting only the top creature of a stack can be limiting in certain cases, and getSpectators is vastly superior in speed compared to looping through the tiles.
 
Just figured I'd point out that you could use the function getSpectators to grab all of the creatures in an area.
Getting only the top creature of a stack can be limiting in certain cases, and getSpectators is vastly superior in speed compared to looping through the tiles.
this was the first thing that i tried :p, but in the end will be the same, checking tile by tile any way ;/
 
Back
Top