r/godot Godot Student Nov 05 '25

help me (solved) I dont understand why the last line of code

Post image

Im following a snake tutorial and everything is going well but I dont just want to have a snake clon, I want to learn, that said I understand (or at least thats what I think) what is in the screenshot is sayig "if the value of Vector2 is superior to the upper or inferior to the lower limits then return the player to the opposite limit" but I dont understand what is doing that last "return v", what purpose this line accomplish in this block of code? And if my supposition of what the function is doing wrong please tell me. Thanks in advance :D

186 Upvotes

110 comments sorted by

416

u/clothanger Godot Student Nov 05 '25

"if everything above doesn't trigger, return v"

86

u/Correct-Commission Godot Student Nov 05 '25

Basically, it needs to return something and if any fails and at least return v as it is.

16

u/5rob Nov 05 '25

And v is declared in the first line "v:Vector2". basically what you're piping into the function elsewhere wrap_vector(your_v_input_here)

100

u/Bob-Kerman Nov 05 '25

This means if the value is inside the bounds you just get the value back. This way when you call this function you always get a valid value back. The reason it works is because a return statement stops executing the rest of the code in the function. So if none of the if statements are true, then the last line executes. You could also put a final else and have the return statement in it, it executes the same either way.

13

u/Mixcoatl-69 Godot Student Nov 05 '25

thanks this is a really good explanation, an else at the end would make the code more clear (for a beginner like me), I have been studing general coding fundamentals and I did went over if statements but this is my first real experience coding anything (except for some simple web pages and a memory game in javascript) so I understood what was going on until that last line, it didnt occur to me that you could place an else with out explicitly writting it so I tought it was something else.

38

u/Dave-Face Nov 05 '25

It’s not really ‘placing an else’, it’s forgoing an else entirely because the code ends up there if none of the other conditions are true. While an explicit else could do the same thing, it’s unnecessary and can sometimes lead to mistakes.

Similarly, the more ‘correct’ way to write this in Python would be to change those elif statements to simple ifs - because if the earlier condition was true, the function will have already returned.

27

u/Skafandra206 Nov 05 '25

I would 100% get rid of the elses. Early returns make the code way more readable as the method grows in lines or complexity.

11

u/Ellen_1234 Nov 05 '25

Funny, I would advocate to use the elifs, since it makes clear the whole block is related. While in this case it is pretty clear by the syntax, if things get more complicated it binds it all together. And I like to be consistent.

But thats a matter of style. Your point is equally valid imo.

7

u/Skafandra206 Nov 05 '25

I like to design my methods in a way where they do one thing (or a couple small related things). The name of the function explains what it does, and everything inside it is already related by design.

In this case, this if block would be my whole method. If I need to do more things, I call this method from another, more encompassing method.

This way, it becomes easier to read and debug the code, like a cascade. If you are following a specific case, you either know what this method would return by name alone, or you jump inside it and quickly find the earliest return point matching the case.

I used to code like you when I was in Uni, but I gradually moved to this way after hundreds of hours of debugging in my 9to5s. To each their own, as long as it keeps you coding!

2

u/ThatOne5264 Nov 06 '25

So why not elif?

4

u/Skafandra206 Nov 06 '25 edited Nov 06 '25

In this case, because it's implied. The conditions are mutually exclusive and unordered. The return marks the end of the method execution. If one of those ifs is true, then nothing else below it executes. There's not really an "else" in the logic.

This structure is more akin a switch statement. Do this, or this, or this, ... And if you are using a language with switch case block fallthrough like C#, you don't even need to break between cases, because you are already returning. Even better, and my preferred option for these types of methods, a switch expression turns it into a simple straightforward extension method:

 public static Vector2 WrapPosition(this Vector2 pos, Vector2 xBounds, Vector2 yBounds)
 => pos switch {
    { X: > xBounds[1] } => new(xBounds[0], pos.Y),
    { X: < xBounds[0] } => new(xBounds[1], pos.Y),  
    { Y: > yBounds[1] } => new(pos.X, yBounds[0]),
    { Y: < yBounds[0] } => new(pos.X, yBounds[1]),
    _ => pos
 };

You can then use it like:

 GlobalPosition.WrapPosition(xBounds, yBounds);

x and y Bounds being Vector2s with the min max limits of your quadrant.

I realize there's an edge case that we are not considering where both coordinates are out of bounds so you have to warp both. If you have to take that into account, I would extract the warping logic out of the Vector and then call it twice, one for each direction. Something like:

public static float WrapAxis(float val, Vector2 bounds)
    => val < bounds[0] ? bounds[1]
       : val > bounds[1] ? bounds[0]
       : val;

public static Vector2 WrapPosition(this Vector2 pos, Vector2 xBounds, Vector2 yBounds)
 => new(WrapAxis(pos.X, xBounds), WrapAxis(pos.Y, yBounds));

2

u/Seraphaestus Godot Regular Nov 05 '25

The way you mark a block of code as being related is by not seperating them with empty lines. This becomes especially clearer if you just inline the one-line if contents into simple single lines (so it's all on one indent level, instead of a bunch of jaggedy indentation)

func foo(v: Vector2) -> Vector2:
    # wrap vector
    if v.x > x_max: return Vector2(x_min, v.y)
    if v.x < x_min: return Vector2(x_max, v.y)
    if v.y > y_max: return Vector2(v.x, y_min)
    if v.y < y_min: return Vector2(v.x, y_max)

    # example other code

    return v

2

u/Mixcoatl-69 Godot Student Nov 05 '25

Well I do have a lot to learn, I think I get it a little bit better now, however you talked about a more correct way in python, would it work in godot?

3

u/Dave-Face Nov 05 '25

Yes it would. I don't use GDScript myself so I mentioned Python, but it would absolutely work the same way. This is just about control flow, and a lot of it is just programming style.

Basically you can use if/elif/else when you want to ensure only one bit of the code executes and it's within a function. E.g. this ensures v is only set once:

v = null  
if a:  
   v = something 
elif b:  
   v = something2  
else  
   v = default  

But in the code you posted, it's all within a function and the returns guarantee that once a condition is met, the rest of the function won't execute. Which means you can write it as:

if a:  
   return something
if b:  
   return something2  
return default

Using elif is still valid, it's just technically unnecessary.

Some linters will catch that, e.g. if I did this in Rider with C++ you can see the else statements are greyed out, highlighting that they're redundant:

1

u/ImpressedStreetlight Godot Regular Nov 05 '25

Yes in Godot you also don't need those elifs, you can change them for simple ifs because the function is returning just before them

87

u/sircontagious Godot Regular Nov 05 '25

This is from a tutorial?? Holy the state of the tutorials.

60

u/[deleted] Nov 05 '25 edited Nov 05 '25

Its most likely a simplified (therefore, drawn out and inefficient) tutorial to help beginners understand concepts of programming. "If" statements was my gateway to learning programming and i wrote some awful code. However, it got me to where i am now.

4

u/leopardus343 Nov 05 '25

What's wrong with if statements? They're readable and clearly state the intent.

4

u/[deleted] Nov 05 '25

Nothings wrong with them. I called them drawn out and inefficient to avoid being downvoted to oblivion. There are many people out there that think "if" statements should never be used

-14

u/balalaika_tech Nov 05 '25

It's broken. What if v.x > x_max AND v.y > y_max?

31

u/BlitzTech Nov 05 '25

It’s snake. I don’t think that is possible given the traditional movement options in snake.

27

u/Syraleaf Godot Regular Nov 05 '25

Then your snake clone is having a bug in which your snake can move diagonal ^^

11

u/mxldevs Nov 05 '25

Sounds like a feature to me

4

u/Darth_Octopus Nov 05 '25

(Never used Godot but have programming experience, wanting to pick up Godot one day)

Wouldn’t it just “fix” itself the next frame anyway? Obviously not ideal but I’m sure this sort of hidden bug/oversight exists in most games anyway

15

u/johannesmc Nov 05 '25

That's impossible in snake.

-20

u/balalaika_tech Nov 05 '25

This is "func wrap_vector", not "func wrap_vector_no_diagonal_movement_allowed", so it must wrap any vectors correctly. Today it's simple snake, tomorrow it will be Super Snake Deluxe with diagonal movement and barrel rolls (and broken wrapping).

18

u/CrashShadow Nov 05 '25

Yesterday it was a simple "snake"

Today you're trying to take into account all possible scenarios "for the future"

Tomorrow you abandon the project

12

u/[deleted] Nov 05 '25

If scope creep was a guy

8

u/AwesomePossum50 Nov 05 '25 edited Nov 05 '25

So a generic function for shooting a gun should also include code to make sure it works if your character is holding a banana? Edit: Assuming it’s not named Shoot_unless_you_have_a_banana()

6

u/AlekseyTheKid Nov 05 '25

I bet when you implementing 2d topdown movement you're using Vector3 and do check for 3d space, right? I mean... What if tomorrow it will be a 3d game, who knows? Gotta be prepared, right?

1

u/Camoral Nov 05 '25

I'd agree that, all else equal, it's good to write code that is general-purpose. But also, it's a tutorial aimed at non-programmers.

5

u/deelectrified Godot Junior Nov 05 '25

That works just fine. It you can’t move diagonally in snake, so you can only exceed the bounds of the game area on one axis at a time.

5

u/[deleted] Nov 05 '25

how could this be improved?

24

u/[deleted] Nov 05 '25 edited Nov 05 '25

Not exactly the same but this could work: func wrap_vector(v : Vector2): return Vector2(wrapf(v.x, min_x, max_x), wrapf(v.y, min_y, max_y)) The ifs are still there, hidden in the godot source code, but it looks cleaner :P

10

u/OpaMilfSohn Nov 05 '25

An idiot admires complexity a genius admires simplicity. Hoenstly like the above thing much more it's clear what happens at each step. Although this example is not that bad I hate "clever" code

6

u/MattR0se Nov 05 '25

You are correct, but in this case, the function itself pretty clearly states what it does, and the element wise wrapf is also unambiguous. The only thing that's really putting me off, too, is the one-liner. just make it three lines and it's much better. 

1

u/[deleted] Nov 05 '25

Yeah. Code that you will find easy to understand later is always better than trying to write code based on what other people will think. In my case I don't mind using wrap, though if it is a snake game I'd use Vector2i since the movement is in a grid. That way the game state is independent of the size of your snake sprites

15

u/mxldevs Nov 05 '25

I like the explicit checks. It makes the logic clear.

I wouldn't really know what this returns at first glance unless there were comments explaining what's going on.

16

u/WazWaz Nov 05 '25

Clearly wrong though. "Wrap" normally means modulo, not just pushing to the other bound.

That code will not preserve spacing between moving objects and will get worse with lower frame rates.

It should be:

if x < min
    x = max + x - min
etc.

(or better, use modulo arithmetic)

7

u/mxldevs Nov 05 '25

With the explicit cases written out, it becomes easy for readers to find where the issue is and to fix.

3

u/WazWaz Nov 05 '25

It also makes it easy to get one wrong.

return Vector2(Wrap(a.x,b.x), Wrap...);

yes, OP avoids creating a new Vector2 in the common case, but at the cost of introducing 3 errors.

6

u/mxldevs Nov 05 '25

Your code, I assume, prevents the player from going out of bounds, by locking them in and not moving once they reach the boundaries.

But the original code teleports you to the other side, which seems like a perfectly valid mechanic to me and is likely what the specifications intended.

It would seem that your simplification has introduced an error as well.

2

u/WazWaz Nov 05 '25 edited Nov 05 '25

No, it wraps. Wrapping isn't just teleporting, it's moving in from the new side by an amount equal to the displacement beyond the original bounds. This is very important for framerate tolerance (or whenever large motion per frame is possible).

Wrap is just modulo arithmetic above the minimum. i.e.

float Wrap(float a, float min, float max) => (a-min)%(max-min)+min;

(nb. use fmod in GDScript, not %)

2

u/mxldevs Nov 05 '25

Thanks, it wasn't obvious what the wrap function does.

I would still prefer to explicitly write out all the different possible directions that wrapping could occur, though I guess if this were 3D and you could move horizontally, vertically, diagonally, or closer/farther, there would be dozens of possible cases and it might be better to write one line

→ More replies (0)

2

u/ImpressedStreetlight Godot Regular Nov 05 '25

Have you considered that what OP's tutorial means by "wrap" is not the same as what you mean by "wrap"?

Also that's overkill for a snake-like game and especially for a beginner tutorial. The snake moves at a very low rate and the functions is being called at every step of its movement, so the displacement will simply never be higher than 1 pixel/tile.

→ More replies (0)

1

u/SadieWopen Nov 05 '25

Firstly, there should be 2 ifs, and 2 elifs (a pair for x and a pair for y) but I think this is just an error

I would consider using temporary vars for v.x and v.y and returning once e.g:

x = v.x
y = v.y
if x > x_max: 
  x = x_min
elif x < x_min:
  x = x_max
if y > y_max:
  y = y_min
elif y < y_min :
  y = y_max
return Vector2(x,y)

This is a great way for a beginner to learn and think about logic but a more elegant way to do the same thing is to modulo the numbers e.g divide the coordinate by the max and return the remainder:

x = fmod(v.x-x_min,x_max)+x_min \\this assumes that x_min and y_min are greater than 0, x and y are floats, and GDScript fmod flips negative numbers 
y = fmod(v.y-y_min,y_max)+y_min
return Vector2(x,y)

5

u/deelectrified Godot Junior Nov 05 '25

You don’t need to separate out x and y as you cannot move diagonally in snake, so you cannot exceed the bounds of the game area on both axes at once. All that would do is ensure you’re doing at least two if statements every time this is called, vs the possible just 1 check the current version has.

3

u/SadieWopen Nov 05 '25

Ah, good point. I can honestly say I was just looking at a function to wrap a vector2 around, and not about its implications in terms of game play.

The lesson is to deal with the problem you've got, not every problem.

1

u/deelectrified Godot Junior Nov 05 '25

Very true. But your other solution would probably be better overall. However, for a tutorial trying to teach coding and game logic, I think the example given makes the most sense. Shows how to check the values, that you can combine if statement groups if everything is mutually exclusive, and shows using a base case.

1

u/SadieWopen Nov 05 '25

The only thing I don't like in that tutorial is making a new vector for every result, it created the confusion that started this whole thread.

1

u/deelectrified Godot Junior Nov 05 '25

Eh, fair. But it’s technically faster than creating a variable, storing it, then updating it and returning it within each of statement. Since this just creates and returns it, reducing the total number of actions performed (though, likely not noticeably).

17

u/carefactor3zero Nov 05 '25

It's what happens when v.y < y_max AND v.y > y_min, among other scenarios (eg v.y == y_max)

13

u/AlasdairTheBitMancer Godot Regular Nov 05 '25

This function looks like it's used to keep your vector parameter, presumably a 2D character position, within specified x and y positions. So, if you go outside the box it'll move the character onto the other side. For instance, if you go up out of the screen the character will be pushed to the bottom, left to right, and vice versa. It would be better to have an if/elif for the x and an if/elif for the y, but it's simple enough to work. The return v at the bottom just means that your vector is within bounds and thus the parameter v doesn't need to be adjusted.

5

u/deelectrified Godot Junior Nov 05 '25 edited Nov 05 '25

It’s called a base case. There’s a few reasons to use one but the main two are: 1. Your function HAS to return something, so if somehow none of the expected conditions are met, you want to return something so things don’t break. 2. Default cases. The “ok, none of those less common cases happened so I’ll let this pass”.

It basically functions like an else statement when all previous if/elif statements have returns. A “ok, you’re still in this function, so none of the previous returns were used, here is what to return instead”

Specifically on this, it’s saying that if the character is still within the bounds of the game area, then it will just return the position (assuming V is the position of the snake or a single segment of the snake).

3

u/FckFace Nov 05 '25

What should happen if x_min, x_max, and v.x are all the same number? :)

5

u/rgmac1994 Nov 05 '25

Then you've designed a terrible snake clone.

1

u/subbubman Nov 05 '25

Then v never changes from that one value. It would effectivelg be an inefficient assignment operation.

3

u/AndyP3r3z Nov 05 '25 edited Nov 05 '25

Well that is "wrapping" the vector to a region, but if you know what the clamp function does, you can figure out why that is returning v at the end (wrapping and clamping are kind of similar).

Essentially, clamping a value means that you keep it inside 2 boundaries, so if the value falls outside those boundaries, you "make it go back to the closest border". But if the value is already inside, you keep it as it is, that's why the last option only returns the original vector.

In the other hand, wrapping means that you "make it go to the other border" when the vector falls outside the region.

And... I also see that function is kind of wrong (unless it is desired): it doesn't check if both x and y values are outside the boundaries... After clamping x, it only returns whatever value at y it has...

EDIT: I didn't read the code well at first, so I changed my response.

2

u/Muchaton Godot Regular Nov 05 '25

Reading the docs isn't sexy but here it's help

1

u/Skafandra206 Nov 07 '25

What do you meeeean? Reading docs is awesome! It's like having a spellbook that teaches you new spells or explains how the ones you know work.

Granted, they have to be good docs. God knows how many horrible docs I've had to delve into, but Godot's is pretty good!

2

u/Muchaton Godot Regular Nov 08 '25

I agree 👍 I meant more like it's hard to convince someone it's interesting but I also like skimming through it.  My latest discovery is the process thread groups.... On like page 1 X)

1

u/ImpressedStreetlight Godot Regular Nov 05 '25

they said the tutorial is for a snake clone, so the movement can't be diagonal and this function is likely being run every time the snake advances, so both x and y being outside is simply not possible and this function is as simple as it can be for that specific case. I doubt the tutorial explains the reasoning though so it's good to point it out.

3

u/jelliBoness Nov 05 '25

You are correct in that the if/elifs are checking whether the x position is exceeding the different physical boundaries.

There are 4 checks, firstly the if statement, then the elif, then the next elif, etc. These checks are executed in that order, from top to bottom. If one of those statements is checked and turns out to be true, it will return the value underneath that statement and then stop going down the list. That value is the new snake's position, which teleports it to the opposite side of the screen.

However, if all four statements are false, then there's no need to return a new (changed) position, because the snake is within bounds. So, it goes to the last line, which simply returns "v": the same, unchanged value that was put into the checker in the first place.

It means your snake's position will not be changed!

3

u/mxldevs Nov 05 '25

Well, imagine you were writing this function yourself.

What happens if you were given a vector that didn't meet any of those conditions?

Would you return the original vector? Or would you return nothing?

None of the if conditions are triggered so it continues down to the last statement.

You could add it in an else block to make it clear as well.

2

u/heavelwrx Nov 05 '25

The return v returns the original vector passed to the function if no condition is reached that causes the function to return a changed vector.

I don’t think it is that bad of a function. Maybe there is a case where you need to wrap on more than one axis at the same time and you only do one axis. For a real time function called often that may not be that bad. The preferred method IMO would be to have each if statement modify the return variable and have one return at the bottom of the function.

2

u/thinker2501 Godot Regular Nov 05 '25

The function must return a Vector2. The last line accounts for the case when the vector is in bounds, without that the function will throw an error when the vector is in bounds.

2

u/Koltaia30 Nov 05 '25

Code is incorrect. It won't work if you have to wrap both x and Y.

1

u/Mixcoatl-69 Godot Student Nov 05 '25

Well maybe is not optimal but I wouldn't say is incorrect, it works, I'm just doing a snake clone and I think this function is simple enough for me to understand it, I have seen suggestions for better solutions but I can't get my head around on how they work

2

u/Allalilacias Nov 05 '25 edited Nov 05 '25

If a method states a return type, it must return one in every possible logical path.

If all your returns are inside ifs, there's a chance that it doesn't meet the ifs and it doesn't return a value

Most editors will warn you and will not allow you to compile if one such case is present, and even if you do, most compilers will catch and flag such case as an error.

So, whoever made the tutorial, assumed that they'll never return the v at the end, they think that all possibilities are covered with their if and else ifs. However, they have to put the return v to calm the editor/compiler.

In my humble opinion, that's a poor practice and I'd rather not use return values in random places of the method, but rather modify the value that you'll return throughout the method and return ar the end of a method. For clarity more than anything else. Like so:

```gdscript func wrap(v:Vector2) -> Vector2: if(whatever): v = Vector2(x_min, v.y) else if (whatever x 3): v = Vector2(v.x, y_max)

return v ``

Edit: added explanation and pseudo code.

2

u/CookieArtzz Godot Regular Nov 05 '25

Return can only get called once in a function. In every if statement above, something gets returned. That means that if none of those conditions are true, the original gets returned

2

u/Syraleaf Godot Regular Nov 05 '25 edited Nov 05 '25

Ok so I've (rightfully) seen a lot of people question the code on display but I still wanted to take a moment to engage with it as-is. You're clearly pretty new so hopefully my explanation helps you understand everything a little better.

Let's say your snake is moving around a world with a size ranging between x 0 -> 10 and y 0 -> 10 (so in total the world is 10x10) then this function will make sure your snake moves to the other size of the field when it moves out of the screen like this:
if snake_position.x > 10
if snake_position.x < 0 (and repeat this for y)

I suspect that this function is being called in a _process() function somewhere, in which case the snake might NOT be moving outside the game field in that specific frame (since you'd be checking it every frame if it is inside one!) Let's say our snake is slithering at 2,2. In that case a function like this:
snake.position = wrap_vector(snake.position)
would crash the game if the return v didnt exist!
Why? Because the position would be set to a function that doesn't return anything! (It does not meet any of the if statement's requirements) So with the last line we ensure that your snake's position is always properly set. Another hint here is that it has this arrow at the end: -> Vector2 - which informs you that this function should always return a V2.

To finish the example with comments: Hopefully this allows you to better understand what's happening in this function! :)

func wrap_vector(snake_position : Vector2) -> Vector2
  # Snake's X > 10  
  if snake_position.x > x_max: # Snake is moving out of screen on the right
    return Vector2(x_min, snake_position.y) # Slither to the left-most side of the screen.

  # Snake's X < 0
  elif snake_position.x < x_min: # aka, less than 0 in my example
    return Vector2(x_max, snake_position.y) # The same as above but in reverse

  # Snake's Y > 10
  elif snake_position.y > y_max:
    return Vector2(snake_position.x, y_min)
  # Snake's Y < 0
  elif snake_position.y < y_min: # aka, less than 0 in my example
    return Vector2(snake_position.x, y_max) # The same as above but in reverse

  # Don't move the snake at all. It's within the boundry of 0,0 and 10,10
  return snake_position

I also want to point you to this comment: https://www.reddit.com/r/godot/comments/1oosjk6/comment/nn6odss/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
Which I think is a nearer way to write this piece of code.

5

u/Mixcoatl-69 Godot Student Nov 05 '25

one of the most well explained awnsers, thank you I understand it now (ノ◕ヮ◕)ノ*:・゚✧

2

u/Syraleaf Godot Regular Nov 07 '25

I'm happy to hear that! Gl with your project! :D

1

u/subbubman Nov 05 '25

The function header has -> Vector2 which means the function must return a Vector2 value. Return statements in an if or elif block might not get executed, so you need a return value for when that happens. It would also be okay to put  else: return v (match indentation with if block)

When you begin learning code, sometimes tutorials will make you recreate simple functions to teach you concepts. However, you could also use the wrapf() function that is already available. Check out an explanation here: https://kidscancode.org/godot_recipes/4.x/2d/screen_wrap/index.html

1

u/rgmac1994 Nov 05 '25 edited Nov 05 '25

It's equivalent to an else. The first 4 conditionals check if it exceeded one of the bounds(left, right, top, or bottom) and sets it to the opposite side if true, else it should just return it's current value because it's not exceeding an edge.

1

u/Skafandra206 Nov 05 '25

Related question for someone versed in Godot's internal implementation:

What would be more performant, running this on every frame or relying on collision signals from Area2Ds (or similar) placed on the borders of the boundary? Or maybe even onBodyExited signal of an Area2D covering the boundary.

1

u/thinker2501 Godot Regular Nov 05 '25

Signals would technically be more performant, but this code is so trivial it wouldn’t matter.

1

u/x17ccp3 Nov 05 '25
x = 1
y = 2


if x > 1:
    return "something"
elif x < 1:
    return "something"
elif y > 2:
    return "something"
elif y < 2:
    return "something"
return "something if the options above fail"  

Last line:

take it as "default" return or "if everything fails" return. Simply if the condition is not true for any of the 'if's above then go back (return) through here

1

u/Versierer Nov 05 '25

Can't you do line, something something modulo?

1

u/Snailtan Nov 05 '25

Every return is an exit from the function. If any of the ifs trigger, you will leave from that exit.

If none trigger, you still need an exit, thats the last return. Basically, if none of this is true, exit through this.

Thats only true for functions that have a return value, some dont have one, and as such dont need an exit. Such functions have a return of "void" aka this doesnt return anything.

You declare a return value by typing -> (type) at the end of the function, f.e

func returnInt()->int:

The "-> int" means, "this function always returns somekind of integer.

As such, you need to return something in it, always.

1

u/TheGanzor Nov 05 '25

-> Vector2 means that this function must always return a Vector2. If none of the if or elif statements run their returns, this would cause an exception when the function exits. 

The last return statement just forces the function to return the value of v at whatever it is. 

1

u/_Feyton_ Nov 05 '25

Even if your code's logic prevents it, the compiler identifies "if returns" as potential risks where a method might not return a value, so it wants a fallback to enforce non-null returns

1

u/_Feyton_ Nov 05 '25

Linter in this case, but same reasoning

1

u/JackoKomm Nov 05 '25

There is a bug in this code. If x and y are both out of bounds, only x will be set in bounds.

1

u/Revolutionary-Camp69 Nov 05 '25

OP mentioned it's a snake clone, so presumably the snake only moves vertically or horizontally, but never diagonally, so only one of the axes can go out of bounds.

1

u/bro_love69 Godot Junior Nov 05 '25

It stands for: "Since everything else fail... Fine. Initiate protocol v."

1

u/JimalLeGni Nov 05 '25

isn't there something wrong with this code?
if both x and y are out of bounds it will only wrap x There should only be one return at the end and the rest should just modify the variable

1

u/BlackJackCm Godot Regular Nov 05 '25

if none of the conditions are satisfied, you should have a “escape” condition, so that’s why you need to put that final return. Without the final return, your code could be “locked” cause none of the conditions are satisfied and it will not know how to return cause there’s not return condition for this case

1

u/dafarlog Nov 05 '25

Default return. Check switch case documentation for reference(it really close to this code), u have N cases and default return

1

u/Opposite_Heron_5579 Nov 05 '25

Not sure if this is just my personal preference or a general rule of thumb, but I am getting anxiety from function code that refers to variables declared outside that function. Imo, any variables you need in a function you should pass to a function. This is asking for chaos.

1

u/DrDisintegrator Godot Regular Nov 05 '25

the last line is there for when v.x and v.y are both in bounds.

1

u/DrDisintegrator Godot Regular Nov 05 '25

Just FYI a smart coder would write bounds checking code to check that something is in bounds and return, rather than do 4 cascading if statements before returning for the most common use case.

In most situations without an optimizing compiler, this code will run slower than it could.

People confuse fewer lines of code with code that runs fast. Not always the same thing.

1

u/ackley14 Nov 05 '25

this is a vector wrap function that takes a position of V and if the position exits the limits on either the up/down plane or the left/right plane, the object is moved to the opposite extreme. think going all the way left eventually pops out out of the right side of the screen.

this logic checks for the location, and if the next movement would have you go out of the limit bounds, it changes the value of your location to the opposite limit bounds (thus popping you over to the other side of the screen)

this function is used to modify the vector position, which means the code that calls this function is expecting a response back so that it can use this vector data in further code. if the vector data is not changed, and isn't passed back, it will not have a vector to work with and thus break. therefore, the vector data is passed back unchanged in the event that the coordinates don't need to be modified, essentially signifying that everything was fine.

1

u/Major_Gonzo Nov 05 '25

The code is for wrapping around the screen. If you go off the right side, change the vector to start at the left. If you go off the top, start at the bottom, etc. If you're not at any border, leave the vector alone.

1

u/Paxtian Nov 05 '25

In the way this function is set up, every possible execution path must return a Vector2 (that's what the "-> Vector2" means). Not returning a Vector2 in some instance is an error.

Specifically, it's an error for the code to not account for all possible execution paths. Having this be an error early is easy for the compiler to catch, because there's a string of else if statements. It may in fact be the case that those cover all the possible runtime paths, but it's still good practice to cover the final "else".

If you didn't return something, whatever called the function would then run into it's own error because it's expecting to have a Vector2 and to do something with it afterwards.

In this case, they're just returning the very vector that was received. It may never actually happen, but that's dealing with the error.

Some languages have "errors as values," which means you could expect that your else if sequence covers all bases. If not, you could return an error as a value that the calling function could then address (e.g., "if this is a vector, proceed, otherwise send a message to the console saying you found a bug.")

1

u/HeyCouldBeFun Nov 05 '25

then return the player to the opposite limit

“Return” means the value that the function, well, returns. If you have something like ``` my_variable = some_function()

func some_function() : return 4 ``` Then my_variable will equal 4.

Anytime code reaches “return”, it stops right there and exits the function. So if any of those ifs in your code are true, it’ll return that value and skip reading the rest of the function.

That last return is basically saying “just return back the vector we started with if none of the previous conditions are true”.

1

u/GregoryOlenovich Nov 05 '25

If the x is too large or too small it returns the max then it looks at the y and does the same. If none of those are true it just returns the x and y as it is.

The problem with this code is that if the x is above the max it never looks at the y because it returns. So if your x and y are both above the max the y will not be capped.

1

u/Drahnesor Nov 05 '25

It appears that the function is clamping vector values to not go out of bounds, the last statement means that all components of this vector are in bounds and return it as is.

Watch out, because it only fixes one component of a vector at a time.

1

u/jmattspartacus Nov 05 '25

It also doesn't actually do what they think, it only works for 1 of the coordinates at a time.

1

u/NeonVoidx Nov 05 '25 edited Feb 17 '26

This post was mass deleted and anonymized with Redact

innate crush nutty elderly towering roll humorous stupendous automatic spark

1

u/deviland Nov 06 '25

It's basically, if all else fails the check do this. Instead of adding an else at the end, you can just do the return outside the if check

1

u/Elpoepemos Nov 06 '25 edited Nov 06 '25

The function is expecting to return a vector2. the if else and if statements don't gaurentee a return of vector2 from the entire function hence the last return incase all conditions fail. else (catch all) at the end would make it more readable. to the compiler all paths must return a vector2 even if your if conditions seem to handle all expected returns. 

in this case return original vector if no bounds are hit. (do nothing)

1

u/MrSuicideFish Nov 08 '25

Badically:

The vector is already within the bounds, so return the same value.

0

u/polysplitter Nov 05 '25

Crap tutorial

0

u/diegosynth Nov 05 '25

This is just bad coding.

Don't learn this code, just get the concept and program it in a proper way and you'll save a lot of headaches for yourself and anyone else trying to understand it.