Page 1 of 1

love.graphics.newImage() returns userdata instead of Image

Posted: Tue Oct 31, 2023 1:36 am
by rimann
It may be obvious by the question, but I am new to the lua language. I am not new to programming, however I am far more familiar with traditional OOP as opposed to procedural coding. I am assuming this is just a misunderstanding of the lua language but I don't know.

According to the documentation love.graphics.newImage should return an 'Image' type. However it appears to be returning type of 'userdata' and I can not call the image methods on it. here is a minimal example from my attempt to learn love by making a simple breakout game.

Code: Select all

Rect = require'rect'

function love.load()
  love.window.setMode(400,500)

  -- make block grid
  Blocks = {}
  local pinkBlock = love.graphics.newImage('assets/block.png') -- output is 'userdata'
  print(type(pinkBlock));
  for i=0, 20 do
    local nextRow = {}
    for c=0, 10 do
      table.insert(nextRow, {Rect.createRect(pinkBlock)})
    end
    table.insert(Blocks, nextRow)
  end

  --set Window Size
  love.window.setMode(CalculateGridWidth(Blocks[1]), CalculateGridHeight(Blocks)+200)
end

Re: love.graphics.newImage() returns userdata instead of Image

Posted: Tue Oct 31, 2023 10:20 am
by Hugues Ross
You've misunderstood the language. I started writing an explanation , but honestly just read section 2.2 of the lua reference manual. It's relatively short and will probably resolve things better than I could!

But the TL;DR is: Lua does not allow you to define types (ish) and 'userdata' is a catch-all that you could sort of compare to C/C++'s void*. If you create an object from Love's API, the reported type will be userdata unless it's listed as one of Lua's built-in types.

As for why you're unable to call Image's methods, we'd have to know what the content of rect.lua is--you haven't directly called any methods on Image in that example.

Re: love.graphics.newImage() returns userdata instead of Image

Posted: Tue Oct 31, 2023 7:12 pm
by zorg
A bit of a different explanation, lua's type function does not know of any types that aren't part of the language itself; any and all types löve gives you are of type userdata, so the type function is not the tool you want to use to check that.

Object is the supertype of all löve types, as the wiki helpfully tells you, and those have a type method to use on them, as well as a typeOf method where you give it a string to check if it's the correct type or not (which can return true for even multiple different strings, due to inheritance (e.g. a FileData is also a Data and an Object, so all 3 of those strings given to typeOf on a FileData would return true)

As an aside, there is one case where something returned by a löve constructor won't function with methods, but that only happens in Threads if you send over something that you didn't require in the module for in that Thread.

Apart from that, don't call setMode multiple times like that for no reason, since it'll recreate the window and that causes flicker, annoying users, and do show the rect.lua you're requiring in, because as it was said before, you are probably doing something wrong, but we can't see what due to no image methods are shown in the file you did provide.