## Nil value problem

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Sosolol261
Party member
Posts: 125
Joined: Wed Nov 26, 2014 6:43 am

### Nil value problem

This is a code. And it gives me an error. This is the code:

Code: Select all

--main.lua
require("src/player")

end

function love.update(dt)

-- main
mousePosX = love.mouse.getX()
mousePosY = love.mouse.getY()

end

function love.draw()

player_draw()

end

--player.lua
local player = {
posX = mousePosX - 25,
posY = mousePosY - 30
}

function player_draw()
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle('fill', player.posX, player.posY, 50, 60)
end

Is says that mousePosX and Y are nil values, which they aren't.

bdjnk
Citizen
Posts: 81
Joined: Wed Jul 03, 2013 11:44 pm

### Re: Nil value problem

They are rightfully nil at the outset, when you attempt to use them. They're defined in your update function, which hasn't run yet.

An associated problem. Currently player.posX and player.posY will never be updated. You must set those values from within the update function. Updating mousePosX and mousePosY is not sufficient.

Muris
Party member
Posts: 131
Joined: Fri May 23, 2014 9:18 am

### Re: Nil value problem

Basically the problem is, how values are passed and how they react after being passed. For example

Code: Select all

local a = 3
local b = a + 1
a = 5
print(b) -- prints 4

So when you set the players position to mousePos, the mousePos is nil at that moment, because when you require lua-file it does everything that is on the file-scope of stuff, meaning the update hasn't been called even once, and when you try to add value to nil, it doesn't work. Also like bdjnk pointed out, the players position will not be updated automatically, because the value is copied from mousePosX and mousePosY when you use the =.

It is good to know that values aren't like mathematical equal, meaning that when a = b, then a will always be the same value as b (there is something called pass-by-reference in other languages like c++/c# for this kind of thing, but lua doesn't have references up to my knowledge). For example when you assign string to local a, then you assign local b to what local a is assigned to, changing a will not change b. On the otherhand if you assign local a to be a table, and then assign local b to value of a, changing stuff inside table will be seen in both a and b. If you think tables are more like pointers from c/c++ it is a lot easier to understand why this is happening, although lua might not be exactly like this. I think this is one of those reasons why every programmer should know a bit of C/C++ or Assembly to at least have understanding how integers/strings etc. use memory, what are underflow/overflow and why would these happen. Why using <, <=, >=, > is prefered when dealing with floating points, instead of using exact values (such as while a ~= 0.1 vs while a < 0.1).

Sosolol261
Party member
Posts: 125
Joined: Wed Nov 26, 2014 6:43 am

### Re: Nil value problem

Muris wrote: So when you set the players position to mousePos, the mousePos is nil at that moment, because when you require lua-file it does everything that is on the file-scope of stuff, meaning the update hasn't been called even once, and when you try to add value to nil, it doesn't work. Also like bdjnk pointed out, the players position will not be updated automatically, because the value is copied from mousePosX and mousePosY when you use the =.
So should I put the player table into love.update() ?

Muris
Party member
Posts: 131
Joined: Fri May 23, 2014 9:18 am

### Re: Nil value problem

Sosolol261 wrote: So should I put the player table into love.update() ?
Nope, but you need to update player.posX and player.posY inside update method. Also you should take out the mousePosX and mousePosY out from the table definition, because they will just crash the program.

Like this, I didn't try running the code tho, so hopefully I didn't make a typo:

Code: Select all

--main.lua
local player = require("src/player")

end

function love.update(dt)

-- main
mousePosX = love.mouse.getX()
mousePosY = love.mouse.getY()
player.xPos = mousePosX - 25
player.yPos = mousePosY - 30

end

function love.draw()

player.draw()

end

--player.lua
local player = {
posX = 0,
posY = 0
}

function player.draw() -- making draw function part of player-object
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle('fill', player.posX, player.posY, 50, 60)
end

return player


On the above code I also changed the players draw function to be part of the player-object, instead of making more global functions. And the code is now returning the player-object in the end of lua file, then assigning the object into local player in the main.lua.

Somehting to note tho, if you require player.lua multiple times, you always get the same instance, so to get multiple instances, you need to use something that creates new object every time when that function is being called.

### Who is online

Users browsing this forum: actually_reb and 35 guests