Log In  

hello world.
I think I'm missing something in the custom function realm when it comes to using variables as arguments. I'm trying to pass in a variable that defines one of 6 beams to a function so I can use it for all of the beams but it does not seem to be working and I think I'm trying to do something that might not be allowed in Pico-8. For example I have a custom function to light up this beam and it works great:

..but I need to reuse this to do something similar for 5 more of these beams. I'd like to create a reusable function around the following as I am repeating code:

function beam_2()
if mg(35) and p.x<500
then
pal(5,7)
spr(35,384,328) sfx(0)
b2_charge=true
else b2_charge=false pal()
end
if b2_go==true then
pal(5,7)
spr(35,384,328)
pal()
end
end

I thought I could get away with using something like the below bm_chg function in place of the beam_2 function but it does not seem to be passing the b2_charge variable when I input it for chg_var.

function bm_chg(sp,sx,sy,sc,chg_var,go_var)

if mg(sp) and p.x<96 then

   pal(sc,7)  
   spr(sp,sx,sy) sfx(0)
   chg_var=true   

else chg_var=false pal()

end

if go_var==true then
pal(sc,7)
spr(sp,sx,sy)
pal()
end

end

I was unable to find any documentation of exactly how this works in the manual and any help would be greatly appreciated.

P#141240 2024-02-07 03:49

I would be adding some values and variables as arguments to this.
function bm_chg(35,384,328,5,b2_charge,b2_go)

P#141241 2024-02-07 03:53
3

"I think I'm trying to do something that might not be allowed in Pico-8."

Sort of, though pretty much all programming languages do this so it's not a problem specific to Pico-8 or lua in particular.

I'm not entirely sure—I'm making some assumptions about how the rest of your code works so if those are wrong let me know—but I think the problem you're having is with passing variables by value versus passing by reference. In particular, in your bm_ch function when you try to change the value of chg_var.

I'm assuming that you have one variable for each beam to indicate whether it's on or off? So like b1_charge, b2_charge, etc. which are initially false and you change them to true as the beams are activated?

The problem here is passing variables by value versus passing by reference. In lua "simple" variable types—numbers, strings and booleans—are passed by value. Which means when you pass these kinds of values to a function the function makes a new copy of the value and assigns it to the function parameter. The value outside the function and the one inside the function are two completely different variables and making changes to one won't affect the other. Here's an example:

  outside_var = false

  function f(inside_var)
     -- before changing iside_var both variables have the same value.
     print('before changing')
     print('outside:'..tostr(outside_var))
     print('inside:'..tostr(inside_var))

     -- but if i change inside_var then the two are different
     inside_var = true
     print('after changing')
     print('outside:'..tostr(outside_var))
     print('inside:'..tostr(inside_var))
  end

  f(outside_var)

  -- after the function completes inside_var no longer exists and
  -- outside_var remains unchanged

  print('after f')
  print('outside:'..tostr(outside_var))
  print('inside:'..tostr(inside_var))

So I think that's why it seems like b2_charge isn't being passed to chg_var. It is being passed but you're modifying a copy not the original.

In contrast, tables/arrays in lua can be quite large so making a copy every time you pass it to a function would be very costly so they're passed by reference. Basically instead of passing the table itself lua passes a pointer that says, "the table's over there." In this case the variable inside the function and the one outside are referring to the same table so making changes to one changes both.

  outside_var = {false} -- a table/array this time

  function f(inside_var)
     -- before changing iside_var both variables have the same value.
     print('before changing')
     print('outside:'..tostr(outside_var[1]))
     print('inside:'..tostr(inside_var[1]))

     -- this time if i change inside_var i also change outside_var
     inside_var[1] = true
     print('after changing')
     print('outside:'..tostr(outside_var[1]))
     print('inside:'..tostr(inside_var[1]))
  end

  f(outside_var)

  -- after the function completes inside_var no longer exists but
  -- outside_var does and has been altered

  print('after f')
  print('outside:'..tostr(outside_var[1]))
  print('inside:'..tostr(inside_var))

If I'm right that you're using separate variables for each beam then my suggestion would be to put all of those together into a global array. Then instead of passing that array itself to bm_ch just pass in the number of which beam you want to change and modify the array. Something like this:

  function _init()
     -- whatever other stuff you already doing here if anything
     beam_charges = {false, false, false, false, false}
  end

  -- changed the parameter from chg_var to chg_num
  function bm_chg(sp,sx,sy,sc,chg_num,go_var)

     if mg(sp) and p.x<96 then

        pal(sc,7)  
        spr(sp,sx,sy) sfx(0)

        -- modify the table at the given chg_num
        beam_charges[chg_num] = true

     else
        -- modify the table at the given chg_num
        beam_charges[chg_num] = false
        pal()
     end

     if go_var==true then
        pal(sc,7)
        spr(sp,sx,sy)
        pal()
     end

  end

And then you'd have to change any other code that uses the old variables to use the array instead.

P#141250 2024-02-07 10:50
1

"I think I'm trying to do something that might not be allowed in Pico-8." - This is me not understanding how coding works at all :P but thanks to your detailed explanation of how you can use arrays like this I am now re-writing this section of my game to be so much more scalable and compact. I love this community. Thanks for the wisdom jasondelaat! This worked very well.

P#141300 2024-02-08 20:18

[Please log in to post a comment]