Can a variable in a function be changed when it is called again?

I’m making a gun and each time the mouse clicks, it calls a function. Let’s say I make a bullet using Instance.new(). If the bullet function was called again, would I never be able to change anything about the old bullet?

You can just return the old bullet in the function

local function createBullet()
local bullet = Instance.new()
return bullet
end

local newBullet = createBullet() --this is the bullet that was created
1 Like

For scenarios like these, you generally have two options, one of which is easier but (typically) less performant.

For the easier and less performant option, you can perform all of your calculations/logic for each individual bullet in a new thread (thus performing calculations separate from the main thread that instantiated the bullet). This can be done in a variety of ways, but this is what I generally do:

local runSvc = game:GetService'RunService';

local function fireBullet()
	local bullet_id: string; --generate a bullet id. the id itself does not matter so long as it differs from all other bullets
	--create a bullet
	runSvc:BindToRenderStep(bullet_id, 0, function() --consider changing renderpriority for a real game scenario, 0 is just a placeholder
		local hit: boolean;
		--move the bullet and determine whether the bullet hit something from a raycast performed each frame
		
		if hit then
			runSvc:UnbindFromRenderStep(bullet_id);
			--deal damage or something and destroy the bullet
		end
	end);
end

The more conservative option involves combining all these separate threads into one central calculative thread for all bullets. This is generally more performant because we aren’t creating remotely as many threads in most cases, but may introduce some complications to more complex logistics systems:

local runSvc = game:GetService'RunService';

local bullets = {}; --store bullets and all their metadata (lifetime, current distance travelled, damage, or whatever you deem necessary)

runSvc:BindToRenderStep('bullet_handler', 0, function()
	for bullet, metadata in bullets do
		local hit: boolean;
		--perform calculations/logistics for each bullet in the bullets array
		
		if hit then
			bullets[bullet] = nil; --remove the bullet that made contact from the array so the handler no longer performs calculations for it
			--deal damage or something and destroy the bullet
		end
	end
end);

local function fireBullet()
	local bullet: Instance; --create a bullet
	
	bullets[bullet] = {}; --array here represents the new bullet's metadata
end