#function somehow returning nil

1 messages · Page 1 of 1 (latest)

red wigeon
#

can someone help me out rq

                hex.BrickColor = BrickColor.Green()
                hexMaisPerto = hex    
            end
        end
    end
    print(hexMaisPerto)
    return hexMaisPerto
end
--this is just a snippet

youd think that when a hex gets turned green that it would be able to return it, but ocasionally dosent

minor surgeBOT
#

studio** You are now Level 1! **studio

pearl frost
red wigeon
pearl frost
red wigeon
pearl frost
#

Mind showing the line where this function is called?

red wigeon
#

"encontratProximo" is the function where the code snippet is contained

pearl frost
#

And "encotrarproximo" is the function that you've just showed a snipped of, right?.. nevermind

#

Does that print statement above the print actually print?

red wigeon
#

not when it fails

#

but the hex still turns green

#

thats whats bugging me

pearl frost
#

When it fails, is there an error inside the output, or does it just return nil?

red wigeon
#

return nil

#

which is weird since hex does exist

pearl frost
#

Then I'll just assume that you've some lines with "if XXX then return end" in the script, I would add prints onto all of these, and see which checks are failing

pearl frost
red wigeon
#

if you want i can send the full function, its quite small

red wigeon
pearl frost
#

e.g.:

call 1 -> everything goes fine and it turns green
call 2 -> something goes wrong and it errors, but call 1 still turned it green

red wigeon
# pearl frost Sure
function encontrarProximo(hexselecionado, hexobjetivo, chave, anterior)
    hexobjetivo.BrickColor = BrickColor.Gray()
    local hexMaisPerto = nil
    local hex = nil
    local maisCurto = math.huge
    for i, hex in workspace.Mapa:GetChildren() do
        if hex ~= hexselecionado and --nao é o do meio 
            hex ~= anterior and
            hex.Position.Y > -4.871 and --nao tem agua 
            not ColService:HasTag(hex, chave) and --nao fooi eleminado
            math.abs(hexselecionado.Position.Y - hex.Position.Y) < 1.8 and --altura
            (hex.Position - hexselecionado.Position).Magnitude <= 5.7 then    --6 mais perto
                local distanciaAoObjetivo = (hex.Position - hexobjetivo.Position).Magnitude
                if distanciaAoObjetivo < maisCurto then
                    maisCurto = distanciaAoObjetivo
                    hex.BrickColor = BrickColor.Green()
                    hexMaisPerto = hex
                    else
                    hex.BrickColor = BrickColor.Black()    
                end
        end
    end
    task.wait(0.2)
    print(hexMaisPerto)
    return hexMaisPerto
end
#

basically it checks for an elegible hex to return of the 6 around it

#

elinates ones that are too far, the middle one, ones that are "underwater", and chave is a tag on hexes i dont want to be selected

#

and the past selected

#

so it wont go back

pearl frost
#

Oh god, that's one of the longest if statements I've seen in a while and I cannot read any of the vars 😆

red wigeon
#

on 9 seconds this happens. the blue square under the black is the current selected, it checks all around it, the other blue is the past selected so it cant be returned, the black got declared "too far" to be returne, however, the green ones are eligible to be returned

minor surgeBOT
#

studio** You are now Level 2! **studio

red wigeon
#

but then this happens, meaning that it returned nil and got marked as a dead end

#

when it shouldnt have

pearl frost
#

(So not inside the function, but what it returns)

#

As I highly doubt that this is the case

#

It more so appears that some check later down in the stack is falsely calling a dead end

red wigeon
#

even if hex does exist

#

and just got colored green

pearl frost
#

(e.g. if one says "failure", then I've no clue that it does)

red wigeon
#

passo means step

#

bosta means crap

#

so it didnt return a hex, even though one just got coloured green

#

maybe put if HexMaisPerto then return HexMaisPerto else return hex?

#

this wouldnt be optimal but im running out of ideas

pearl frost
red wigeon
#

then why isnt the function returning anything

pearl frost
#

I mean, I cannot see any condition where the function would not print anything

#

Or well, it would print "nil , so technically it wouldn't print anything, but those still show up in the output (as a while line)

red wigeon
#

thats the thing, its weird

#

-> hex.BrickColor = BrickColor.Green() | this happens since i see a hex turning green
-> hexMaisPerto = hex | setting hexMaisPerto to the hex that just turned green
-> return hexMaisPerto | should return the green hex, returns nil for no aparent reason

pearl frost
#

you've 2 if statements, both when false simply continue the stack, so it should always end up at that print statement at the bottom, no matter if they end up as true or false (either of them to be frank)

red wigeon
pearl frost
#

Well they're not even getting run. As that print statement should print something every time the function gets called

#

be it nil or an instance, it should still be printing

#

"Bosta" gets printed when the function doesn't get called to be frank

red wigeon
#

if you want i can send the code calling it

red wigeon
pearl frost
red wigeon
pearl frost
pearl frost
red wigeon
#

how could that be

#

this is in a for loop

pearl frost
#

this is even weirder. As this tells me that passo always fires

#

meaning that proximo did exist

#

Perhaps it's the second condition that fails

red wigeon
#

cuz print("hexMaisPerto") dosent even fire

pearl frost
#

which is the pattern we saw in the output

red wigeon
#

maybe it didnt fire?

#

still makes no sence

pearl frost
#

It's most likely the "table.find() " that fails

red wigeon
pearl frost
#

you can test this by replacing "bosta" with "basta", proximo.Name

pearl frost
red wigeon
#

now these two include the hex they were hoping to return/get

minor surgeBOT
#

studio** You are now Level 3! **studio

pearl frost
red wigeon
#

even weirder

#

oh nvm

#

function didnt fire

#

so it has the old hexagono1

#

and the table.find detects that its the old and stops it

#

i think

pearl frost
red wigeon
#

not after last passo

pearl frost
#

"function fired hexagono" is the same step

pearl frost
red wigeon
#

oh right

pearl frost
#

table.find(caminho, proximo) returned nil (so false), what is this piece attempting to do?

#

(other than finding the current hex in a table)

red wigeon
#

detecting if there is no more path

pearl frost
#

when does something get added/removed from caminho?

red wigeon
#

atp let me just send the full thing

pearl frost
#

👍

red wigeon
#
function calcularCaminho(hexInicial, hexObjetivo, maxPassos)
    a = true
    while a == true do
        local caminho = {}
        local atual = hexInicial
        local chave = math.random(1, 1)

        for i = 1, maxPassos do -- prevent infinite loop with a max step limit

            if atual == hexObjetivo then
                print("chegou")
                break -- reached the goal
            end

            local proximo = encontrarProximo(atual, hexObjetivo, chave, caminho[#caminho])
                print("passo")
            if not proximo or table.find(caminho, proximo) then
                print("bosta", proximo) -- no path forward or loop detected
                ColService:AddTag(atual, chave)
                atual.BrickColor = BrickColor.Red()
                atual = hexInicial
                caminho = {}
            else
                atual.BrickColor = BrickColor.Yellow()
                if caminho[#caminho] then
                    caminho[#caminho].BrickColor = BrickColor.Yellow()
                end
                atual = proximo
                table.insert(caminho, atual)
            end
        end
        print("for loop acabou")

        return caminho
    end
end
pearl frost
#

so caminho means road (guessing this is refering to the path it tries to pathfind), so basically what I think is happening is that it will try to run twice for a single hex

#

first time it passes correctly, second time it sees that it's already in the road and fails

#

It does appear that this script is based off of "Dijksta's pathfinding"

red wigeon
#

i made it from scrath with a bit of help from chatgpt because i dont know the lua syntax or whatever its called

pearl frost
#

Basically, the problem is that it seemingly selects a "random hex", and then tries to see if it already visited it

#

So I'm guessing that it selects the same hex twice, first time is fine. But the second time it's already on the path, and thus returns

red wigeon
#

what if i just tell it to ignore any hex already in the path?

#

how can i do "if hex ~= (any from caminho table)

pearl frost
#

Well, then it may backtrack. How a normal pathfinding system works (explaining both dijkstra's and A*, I would recommend using A*)

So, dijkstras: split the map into grips, then slowly keep trying new neighbours (unvisited) and see what route is cheaper. Doesn't take into consideration if it's closer to the goal or not

A*: split the map up in grids, check how expensive it is to go to all neighbouring grid spaces. Determine the cost as: movement costs (e.g., in this case it can all be 1), then determine the beeline to the goal, and add some heuristics costs based off of this (e.g. 1/stud, depending on how large your tiles are. H-costs should be a half decent estimate of the realistic costs to get to a location). Keep on checking points, saving paths to those points until you've met your goal

A* is faster as the H-cost prefer grids closer to the goal, so it will start pointing to the target faster

#

The main problem is that you only assume for 1 path, which is the end goal. But if you back up then you full start over, instead of just trying new neighbours

#

It will stand back as I don't really see code to tell the script what next step is the best

red wigeon
#

it cant backtrack since it gets fed the last hex in the list

pearl frost
#

If it's not backtracking then the table.find should never return true

red wigeon
pearl frost
red wigeon
#

i asked chatgpt to generate an A* script and it seemed too complicated

#

and this is so close to working anyway

pearl frost
red wigeon
pearl frost
# red wigeon and this is so close to working anyway

Well yes and no to be frank. You've no real way of telling it where to go. So it will try everything. Just like dijkstra's, yet you'll have to add proper open/close lists. Which would then also require sorting

pearl frost
red wigeon
#

i mean when it goes straight without stopping

#

but how can i tell it to ignore any hex that is on a list?

pearl frost
red wigeon
pearl frost
#

If you don't feel like integrating a*, then you can still learn from how it manages it

red wigeon
#

and i just found this gif

#

the a* representation is EXACTLY what mine does

pearl frost
#

At least from the video you've shown

#

The only reason it explores that much there is because the beeline points into a wall

red wigeon
#

the video i shown is of it trying to reach an impossible path

#

one sec lemme show one of it trying an actual possible path

red wigeon
pearl frost
pearl frost
#

Hm, welp, time to check your math again I guess

#

Ah I see, so you do seem to be checking some distance with "distanciaAoObjective", but you change it to green before the others have a chance to even check. So the "closest distance" can be multiple ones. So you visualisation will already be off. Now, as for the rest. You don't really keep track of what squares you've already tried to visit before. So the second it encounters a roadblock it will dump the entire path. Instead of back tracking. The main problem (and you can see this with the a* visualization), is that the "shortest path" isn't always just running directly at the goal

red wigeon
pearl frost
#

Basically, how algos like a* and dijkstras work is just by saving a shit ton of paths, and if the one it assumed to be the best is blocked, it will try the second best option, and so forth

pearl frost
red wigeon
minor surgeBOT
#

studio** You are now Level 4! **studio

pearl frost
#

A* uses open/closed lists for this. The open list is just a sorted list for "next best options", so it doesn't have to start from the start again

pearl frost
red wigeon
#

green means it checked and said "this one is closer, so closesthex is now this one" and black means "this one isnt closer, just ignore"

pearl frost
#

so when you're unlucky, then it will turn every neighbour green (if it goes from furthest away to closest)

red wigeon
#

not really unlucky, just means it checked all and found the best, black means it wasnt better

pearl frost
#

Anyways, that doesn't matter. The main thing that does matter is just the fact you fully reset every time you encounter a roadblock. So basically what you do. is then re-calculate everything. Even though you can just caghe formerly given pathfinding information and go off of that

red wigeon
#

but eats easy to fix

#

just have it go back a number of steps

#

and i dont need this to be optimized

pearl frost
#

I mean, that's the only real thing you've to fix

#

That other issue will then resolve itself. As fixing that does involve caghing stuff you already visited, meaning you can just only check shit you haven't visited yet

pearl frost
#

Then you don't have any issue anymore. As just only checking tiles you've not yet visited will make it turning back on itself impossible

#

(unless you open up former tiles again, which you should just simply not do)

#

Anyways, I do have to go now. But I strongly advice you to read into the aforementioned algorithms. A lot of folks have written a lot of papers regarding them, and there's a reason why such algorithms are still being recommended after all these years

red wigeon
red wigeon
pearl frost
red wigeon
#

and like A* it can eliminate excess path

pearl frost
#

Also, next time; don’t be ashamed of looking how others have solved certain issues. There have been certain “issues” that we’ve been solving for decades now (hell, I believe a* is already 60+ years old), plenty of these methods have been refined to hell and back, so you can always find stuff to use for your own systems

red wigeon
pearl frost
pearl frost
#

So 8, plus another 3 ish after I linked the resources

red wigeon
#

but the problem was that i barely knew lua, so i had a friend help me

pearl frost
#

Next time you could just look for stuff, then try to implement a custom version of their algorithms. Then it will be 3 instead of 11

red wigeon
pearl frost
pearl frost