Using Lua files as a templete

I never actually used a .lua type file before until recently for saving game data. And I was wondering can I use it as a templete? for example, say a game with many different cars and i want each car to have the basic layout; Speed, Acceleration, Weight, Color, etc. in a Car.lua file.

My real question is, does using the “require “templete.Car”” make a copy of the Car.lua file for the requesting script during run time or is the values in the Car.lua universal across the app? Do they change for everything else that uses it?

I never actually tried it. I’ve only made a save file manager with that doesnt really help in understanding it in that senario.

Requiring a Lua file multiple times always returns the same thing. It is cached by Lua. What you probably want is either a stateless Lua module or more of an OOP style Lua module. The stateless one would look like this:

-- car_stateless.lua
local M = {}

function M.new(speed, acceleration, weight, color)
	return {
		speed = speed,
		acceleration = acceleration,
		weight = weight,
		color = color
	}
end

function M.repaint(car, color)
	car.color = color
end

function M.strip_seats(car)
	car.weight = car.weight - 50
end

function M.upgrade_engine(car)
	car.speed = car.speed + 10
	car.acceleration = car.acceleration + 110
end

return M

And used like this:

local car = require "car"

local volvo = car.new(220, 800, 1500, "blue")
local ferrari = car.new(320, 1800, 1100, "red")

car.repaint(ferrari, "yellow")
car.upgrade_engine(volvo)

Or more of an OOP-style:

-- car_oop.lua
local M = {}

function M.new(speed, acceleration, weight, color)
	local car = {
		speed = speed,
		acceleration = acceleration,
		weight = weight,
		color = color,
	}

	function car.repaint(color)
		car.color = color
	end
	
	function car.strip_seats()
		car.weight = car.weight - 50
	end

	function car.upgrade_engine()
		car.speed = car.speed + 10
		car.acceleration = car.acceleration + 110
	end
	
	return car
end

return M

Used like this:

local car = require "car"

local volvo = car.new(220, 800, 1500, "blue")
local ferrari = car.new(320, 1800, 1100, "red")

ferrari.repaint("yellow")
volvo.upgrade_engine()
2 Likes

That’s pretty great, Thank you. I understand Object Oriented Programming because I’m coming from a Java background but what do you mean by using a stateless lua module?

Sorry if im completely missing the point :rofl:

I actually used that term slightly incorrectly. A stateful Lua module is a module where state is stored inside the module itself where as a stateless Lua module contains no state at all, only logic.

I extrapolated from that definition a bit but the meaning is still almost the same.

In my first example the car.lua module contained only functions that take a car object (Lua table) as it’s first argument. The car contains the state while the Lua module provides stateless functions that operate on the car objects.

In my second example I mixed the two. The functions and the state were both stored in the car object (Lua table). This is more akin to how OOP works. The object is an instance of a class and it contains both the state and functions to manipulate the state.

1 Like

Don’t forget using “:” instead of “.”

ferrari:repaint("yellow")
volvo:upgrade_engine()
1 Like

I was looking over then code sample from the OOP example and realized you were calling the functions from the instances instead of the lua module itself. This as well as Lua Tables could come in handy to make a fun light RPG sometime in the future. Thanks again. :+1:

This is not necessary in my example since I’m using a closure based solution.

Read more about the difference here: http://lua-users.org/wiki/ObjectOrientationClosureApproach

Oops, my mistake.
Btw, interesting article, never heard about closure approach. I am pretty sure “Programming in Lua” mention only oop and metatable approach.

I prefer this. More readable. No semi-colon syntax. Easier to encapsulate data if needed. Faster. Only disadvantage is additional memory consumption, but that is usually not a problem unless you have many instances.

1 Like

I assume it would be possible to pass one of these tables around as a msg too? I Hichnmight be a good way to handle pickups.

Sure, as long as the table contains only valid data types for message passing (ie no functions). And the table must be less than 2kB.

1 Like