Here we use the __call
metamethod to create a definition on what happens when you call the table like it's a function. Player is defined at the top as a table, {}
, but with the __call
metamethod, doing Player(name, health)
is valid. Once the __call
metamethod is invoked, we simply take the arguments passed to it and insert it into a table. After which, we just simply return the table after using setmetatable
to define our object's __index
, which is used whenever we try to access the player object's table. The __index
will hold everything inside of the Player table, but out object only holds name and health. Using __index
, if what we're trying to access doesn't exist in the player object such as doing playerOne.xyz
, it uses the table defined in __index
to look in as well, if xyz
is a key inside of Player, then that is returned.