Set value from another script (SOLVED)


#1

Hi,

I would like to know if it will be bad to set a local value = a value from another .lua script in the update() block.

My constants.lua

local M = {}

M.asteroid_speed = 15
M.asteroid_create_timer = 5

return M

My factory.script

local asteroid_speed = constants.asteroid_speed
local asteroid_create_timer = constants.asteroid_create_timer

function update(self, dt)
   asteroid_create_timer = asteroid_create_timer - dt
   if asteroid_create_timer < 0 then
	   create_factory(self)
	   asteroid_create_timer = constants.asteroid_create_timer
	   print("Set!")
   end
end

For example:

asteroid_create_timer = constants.asteroid_create_timer

Is this bad in update() block?


#2

Something like this doesn’t look that bad. But it is totally dependent on what create_factory(self) does.

As I understand it asteroid_create_timer = constants.asteroid_create_timer would just be a simple table look up which are fairly cheap.

You could also do it in the init of the script by using the builtins timer function.

timer.delay(asteroid_create_timer, true, function() create_factory(self) end)


#3

This is what the create_factory(self) looks like:

local function create_factory(self)
   math.randomseed(socket.gettime()) math.random()math.random()

   local start_x_axis = math.random(0, constants.window_width)
   local start_y_axis = constants.window_height + 80

   local end_x_axis = math.random(0, constants.window_width)
   local end_y_axis = -80

   self.start_position = vmath.vector3(start_x_axis, start_y_axis , 0)
   self.end_position = vmath.vector3(end_x_axis, end_y_axis, 0)

   local asteroid_id = factory.create(hashes.MESSAGE_FACTORY_ASTEROID_PATH, self.start_position)
   go.animate(asteroid_id, "position", go.PLAYBACK_ONCE_FORWARD, self.end_position, go.EASING_LINEAR, 15)
end

#4

Yeah this is fine. It won’t be a problem for Defold if you don’t do it hundreds of times per frame.

That said there are few things you could improve on, but remember that they are quite small and you would only see an improvement in performance if you actually called it hundreds of times per frame.

math.randomseed(socket.gettime()) math.random()math.random()
-- You should only do math.randomseed once, do it when you initialize
-- the app, maybe in your main.script. This isn't a performance gain but
-- done so math.random() behaves as you would expect.
self.start_position = vmath.vector3(start_x_axis, start_y_axis , 0)
self.end_position = vmath.vector3(end_x_axis, end_y_axis, 0)
-- Table/user data creation is not free so you could reuse the old self.start_position vector
-- self.start_position.x = start_x_axis
-- self.start_position.y = start_y_axis
-- self.end_position .x = end_x_axis
-- self.end_position .y = end_y_axis
-- This way we don't call vmath.vector3

#5

I have updated the code:

From > To:

-- FROM
self.start_position = vmath.vector3(start_x_axis, start_y_axis , 0)
self.end_position = vmath.vector3(end_x_axis, end_y_axis, 0)

--TO
self.start_position.x = start_x_axis
self.start_position.y = start_y_axis
self.end_position .x = end_x_axis
self.end_position .y = end_y_axis

I’m receiving the following error:

ERROR:SCRIPT: /states/go/asteroid/factory.script:16: attempt to index field ‘start_position’ (a nil value)


#6

It is saying that self doesn’t have a field start_position. So add it! :grin:

In your init you should initialize them.

function init(self)
    self.start_position = vmath.vector3()
    self.end_position = vmath.vector3()
end 

#7

Perfect! Thank you.

It is actually good because it does not call vmath.vector3() everytime.

Let me quickly try the builtin timer function.


#8

Will it be a problem is I change all my locals in my factory_create() to self?

I don’t really understand the difference between local and self in a block function.


#9

It is all about scope. local variables will be just that - local. That means that you can’t reference to them from a different function (or even outside a if statement etc.). They will be collected by the garbage collector when running outside of the scope.

How and when you use self or local or any of the other ways of putting variables/functions in different scopes are a matter of preference and style. That said, if many parts of the script will be referencing a variable and/or mutating it then I would put it in self. For instance, one thing that I tend to put in self a lot personally is gui nodes. So instead of calling gui.get_node("txt_name") all over the code I do it once and put it into self. While a variable used more as a “constant” I would put at the top of the script in local (outside of all your functions), an example of such a variable could be a color value you keep referencing.

In short. local is for defining in which scope the variable will be created in (all variables are by default created in the global scope). Therefore if your variable is only important in one scope, put it as local in that scope. If you will reference the variable a lot all over the script put it in self, if a variable is created in one function and the next function will need it then simply pass it as an argument.