You could use a bindable function to get an incremented value to set the seed.
Something like:
--npc script
local ranSeed = bindFunc:Invoke()
math.randomSeed(ranSeed)
local skin = {Color3.fromRGB(255, 204, 153),Color3.fromRGB(90, 76, 66),Color3.fromRGB(143, 76, 42),Color3.fromRGB(204, 142, 105),Color3.fromRGB(160, 95, 53),Color3.fromRGB(234, 184, 146),Color3.fromRGB(124, 92, 70),Color3.fromRGB(108, 88, 75),Color3.fromRGB(170, 85, 0)}
local skincolor = skin[math.random(1, #skin)]
--othr script
local Inc = 1
bindFunc.OnInvoke = function()
Inc *= 2
return Inc + os.time()
end
Not sure why I wrote it that way, this could be more straightforward:
--npc script
local skin = {Color3.fromRGB(255, 204, 153),Color3.fromRGB(90, 76, 66),Color3.fromRGB(143, 76, 42),Color3.fromRGB(204, 142, 105),Color3.fromRGB(160, 95, 53),Color3.fromRGB(234, 184, 146),Color3.fromRGB(124, 92, 70),Color3.fromRGB(108, 88, 75),Color3.fromRGB(170, 85, 0)}
local ranNum = bindFunc:Invoke(1, #skin)
local skincolor = skin[ranNum]
--othr script
bindFunc.OnInvoke = function(low, high)
return math.random(low, high)
end
From my understanding this should work because when the seed is set at the start of the game it creates a sequence of pseudo random numbers, calls to math.random access the next in the sequence and as calls to this are now in the same scope they should access it sequentially despite the tick being the same. Whereas, previously each thread was accessing the first in the sequence because the seeds were identical in each thread.