Blood Engine - A droplet emitter system

Im still getting the error… that didnt fix the root cause when i called it using a client script.

Error: ReplicatedStorage.BloodEngine:110: invalid argument #1 to ‘unpack’ (table expected, got nil)

Can you show me the .new() line inside of the module?

function BloodEngine.new(Limit: number, RandomOffset: boolean, Speed: number, DripDelay: number, DripVisible: boolean, FilterInstances: {})
	local self = setmetatable({}, BloodEngine)

	-- Creates a folder for drips if necessary
	local DripsFolder = Terrain:FindFirstChild("DripsFolder") or Instance.new("Folder", Terrain)
	DripsFolder.Name = DripsFolder.Name == "DripsFolder" and DripsFolder.Name or "DripsFolder"

	-- Create and initialize the RaycastParams object outside of the function
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

--This is line 110
	raycastParams.FilterDescendantsInstances = {DripsFolder, Unpack(FilterInstances)}
	raycastParams.IgnoreWater = true

	-- Assign class variables
	self.Settings = {
		DripLimit = Limit or Constants.Limit,
		Speed = Speed or Constants.Speed,
		DripDelay = DripDelay or Constants.DripDelay,
		RandomOffset = RandomOffset or Constants.RandomOffset,
		DripVisible = DripVisible or Constants.DripVisible
	}

	self.Drips = {}
	self.DripsFolder = DripsFolder
	self.RaycastParams = raycastParams

	-- Assign other variables
	local Distance = Constants.Distance
	self._Random = Random.new()

	-- Connect a single function to the Heartbeat event of the RunService
	RunService.Heartbeat:Connect(function()
		-- If no drips exist, stop managing. Saves Performance.
		if (#self.Drips <= 0) then
			return
		end

		-- Iterate over all drips in the drips table
		for Index, DripArray in self.Drips do
			-- Retreive information
			local -- Unpack information
			DripInstance: MeshPart,
			EndSound: Sound,
			BasePart: BasePart,
			IsPool: boolean = Unpack(DripArray)


			-- Perform a raycast from the position of the part in the direction of its velocity and find the closest part to the drip
			local result = workspace:Raycast(DripInstance.Position, Vector3.new(0, -Distance, 0), self.RaycastParams)

			-- Check if the result is not nil and if the hit object is not the basePart
			if DripInstance and result and result.Instance ~= BasePart and not IsPool then
				-- Move the part to the hit position
				DripArray.IsPool = true
				DripInstance.Anchored = true
				DripInstance.CanCollide = false
				DripInstance.Transparency = DripPart.Transparency
				DripInstance.CFrame = CFrame.new(result.Position) * CFrame.Angles(0, 0, 0)

				-- Grow the size of the part over time to create a blood pool
				local Info = TweenInfo.new(0.5, Enum.EasingStyle.Cubic)
				local RandomTweenIncrement = self._Random:NextNumber(3, 5) / 5
				local CurrentSize = DripInstance.Size
				local SizeGoal = Vector3.new(RandomTweenIncrement, self._Random:NextNumber(1, 10) / 100, RandomTweenIncrement)
				local Tween = TweenService:Create(DripInstance, Info, {Size = SizeGoal})

				-- Play size tween and start the ending sound
				EndSound:Play()
				Tween:Play()

				-- Decrease the size and transparency of the part after a few seconds have passed
				-- Then destroy and delete it from the blood parts dataset
				local DefaultTweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quad)
				local DefaultTween = TweenService:Create(DripInstance, DefaultTweenInfo, {Transparency = 1, Size = Vector3.new(0.01, 0.01, 0.01)})

				task.delay(self._Random:NextNumber(10, 15), function()
					DefaultTween:Play()

					DefaultTween.Completed:Connect(function()
						-- Remove the drip instance from existance and from the Drips dataset
						table.remove(self.Drips, Index)
						DripInstance:Destroy()
					end)
				end)
			end
		end

		-- Check if the number of blood parts exceeds the bloodLimit
		if #self.Drips > self.Settings.DripLimit then
			-- Decrease the size and transparency of the part after a few seconds have passed
			-- Then destroy and delete it from the blood parts dataset
			local OldestDrip: MeshPart? = table.remove(self.Drips, #self.Drips)

			local DefaultTweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quad)
			local DefaultTween = TweenService:Create(OldestDrip, DefaultTweenInfo, {Transparency = 1, Size = Vector3.new(0.01, 0.01, 0.01)})

			DefaultTween:Play()

			DefaultTween.Completed:Connect(function()
				OldestDrip:Destroy()
			end)
		end
	end)

	return self
end
1 Like

That’s an outdated version of the module, I assume its from the source code on GitHub since I forgot to update it.

1 Like

So is the github code updated or do I use the RBLX model link instead?

1 Like

Use the Roblox model for now. And may I ask did you use the BloodEngine file provided with the latest release on GitHub?

2 Likes

I would assume so?
I’m on the main branch but I see the BloodModule file in the src folder has not been updated for 3 weeks. Maybe a commit issue?

Edit: I see the new code as a release on the sidebar. Sorry for the inconvenience.

2 Likes

Report back to me if its the same as the src code, just to make sure its not outdated and if you still encounter bugs.

1 Like

Thanks! everything works good now!

2 Likes

Hey, I have a Issue with the Blood Module. Its said attempt to index nil with ‘Emit’

And when i’m trying to do in a LocalScript There is no Blood. How Do i fix that ?

1 Like

i fixed the issue. Its Working now

1 Like

Hi,
What did you do to fix it ?

Thanks

1 Like

Please share your code. It is possible your blood instance has missing information or isn’t fully formed.

We cannot provide assistance without a baseline to see what error you can be having.

1 Like

I’m guessing Emit is nil because you tried to use the module on the server, which doesn’t wont work.

1 Like

Blood Engine • V0.0.5

↳ General Changes

A showcase has been included on the GitHub Repository.
An efficient method, UpdateSettings, has been added for changing settings.
Resolved an issue that prevented the proper removal of excess droplets.

1 Like

Is there a way to do this on the server?

umm, where is the .rbxl showcase place?

thanks

1 Like

There is, but why would you want to do this? Just wondering.

1 Like

It’s on the V0.0.5 release.

2 Likes

I’ll add back the ability to do it on the server but it won’t be as efficient as doing it on the client.
Canceled, as performing the operating on the server would not be as efficient as doing it on the client. If you have any questions on how you would implement it on the client, ask me.

1 Like