I have enemies in my game that have behaviours - 1 behaviour function per enemy. Instead of defining the behaviour within the enemy class definition (waste of memory as the function will be created for each enemy of the same type) I want to define each behaviour once (outside the enemy class) and have each enemy instance hold a reference to its single behaviour. The enemy object needs to be able to send a reference of itself to the single behaviour function. I tried this:
function setup() enemy_group1={} for i=1,max_group_enemies do enemy={ e.alive=false, behav=en_visit(self) } add(enemy_group1,enemy) end add(enemies,enemy_group1) end function en_visit(e) e.x+=1 end function spawn(x,y,etype,edir,vel) for _,e in pairs(enemies[etype]) do if not e.alive then e.alive=true return end end end function update() for _,egroup in pairs(enemies) do for _,e in pairs(egroup) do if e.alive then e:behav() end end end end |
The en_visit function is correctly being called, but it isn't receiving a value for its parameter (e). The error reported is: attempt to index local 'e' (a nil value). Can anyone spot where I'm going wrong?



You need to pass the function object, not call the function:
behav=en_visit, |



https://www.lua.org/pil/16.html
Short answer: "self" doesn't have any particular meaning except as a variable name (which is currently nil), unless you're naming functions like "function enemy:behav(...)" (which get an implied "self" variable passed, as if you wrote "function behav(enemy,...)" instead). You also can't put {a=self} or enemy={a=enemy} inside a table declaration and expect Lua to know you're referring to a table that hasn't been created yet, because both "self" and "enemy" would just be nil variables here.
In Pico-8, I'd probably recommend not using these self functions, since it's messy and can cost tokens. Instead, just do this:
local enemy={alive=false, --e doesn't exist! the false value is now at enemy.alive / enemy["alive"] behav=en_visit} --assigns a function normally, even if it needs enemy as a parameter enemy.gun = new_gun(enemy) --tables can be updated dynamically, for anything that *needs* self enemy:behav() --the function is defined the same, but its 1st argument when called is enemy |
[Please log in to post a comment]