Blood Engine - A droplet emitter system

Can you use the recent build that I just published out and see if there are any differences?

Blood Engine • v1.1.0

↳ General Changes

Improvements to Emission: You can now emit mixed droplets (decal & default) without making a new emitter instance!
Droplet Color: There’s a new DropletColor setting to change the color of your droplets/pools.

↳ Other Notes

While this was a minor update, what you can do with it is anything but.
Here’s a showcase to show what you can do with this new release:


You can now do a mix of Droplets and Decals. And without creating multiple emitter instances that might eat out your performance.

Here’s the code behind it:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local BloodEngine = require(ReplicatedStorage.BloodEngine)
local Engine = BloodEngine.new({
	Limit = 500,
})

local EMIT_AMOUNT = 50
local EMIT_DELAY = 5

local function Emit()
	-- A random chance of the droplet being a decal
	local IsDecal = math.random(0, 1) == 1
	
	-- Emits a droplet in a random direction relative to a part, and there's a chance that it could be a decal.
	Engine:Emit(script.Parent, nil, {
		Type = IsDecal and "Decal" or "Default",
		DefaultSize = IsDecal and { 1, 1.4 } or { 0.4, 0.7 }
	})
end

-- A custom iteration of the EmitAmount method
while true do
	for Index = 1, EMIT_AMOUNT, 1 do
		local DropletDelay = math.random(0.05, 0.1)

		Emit()
		task.wait(DropletDelay)
	end
	task.wait(EMIT_DELAY)
end
2 Likes

its somewhy not works for me. maybe i need to move this somewhere?

1 Like

You can put it wherever you want, but you have to reference and require the script for it to work. Can you show me your setup?

1 Like

ohh yeah im dum, thanks! its helpful

1 Like

Just tried V1.1.0, i cant use :EmitAmount() or :Emit() without a Data parameter (i dont even know what it is). Please update so its not needed.

1 Like

just do


local BloodEngine = require(Path)

local Engine = BloodEngine.new({
   -- your config.
})

Engine:Emit(Parent, Direction, Engine) 
1 Like

i used that way, but u really cant Emit() without a table as fourth parameter

I second this, some sort of Data parameter in Settings > UpdateSettings is causing errors

The error originates from here:

function Settings:UpdateSettings(Data: {})
	-- Variable definitions
	local Filter = self.Filter
	local Params = self.RaycastParams

	for Setting, Value in Data do
		self[Setting] = Value
	end

	-- Update Param properties
	Params.FilterDescendantsInstances = Filter
end

Update, I have taken it upon myself to fix the problem and have succeeded with a bit of work, here are the steps to fix the nil Data problem:

Inside of the UpdateSettings function in the Settings module, replace Settings:UpdateSettings with:

function Settings:UpdateSettings(Data: {})
	-- Variable definitions
	local Filter = self.Filter
	local Params = self.RaycastParams

	if Data then
		for Setting, Value in Data do
			self[Setting] = Value
		end
	end

	-- Update Param properties
	Params.FilterDescendantsInstances = Filter
end

Inside of the Operator module, replace the local Clone = table.clone(self.Handler) section with:

local Clone = table.clone(self.Handler)
Clone:UpdateSettings(Data or {})
Data = Clone

Inside of the Settings module, replace the Settings.new section with:

local self = setmetatable({
	-- Replace with whatever you have here in the original Settings.new module
}, Settings)

-- Make sure the Data table actually is a table and not nil
Data = Data or {}

for Setting, Value in Data do
	if Setting == "Tweens" then
		for Tween, Info in Value do
			self.Tweens[Tween] = Info
		end
		continue
	end
	self[Setting] = Value
end

return self, self:CreateParams()

Xefpq, I did your job for you lol :smile:

1 Like

That is great!

Can you provide a .rbxl of it working?

Thanks!

I should have further tested this version, sorry for any inconveniences chat.
I’ll be uploading a new bugfix version in a tinyyyyy bit.

It’s actually just this specific line change that was needed.

Clone:UpdateSettings(Data or {})

Blood Engine • v1.1.1

↳ General Changes

Fixes: Fixed an issue where if no Data/Settings table was provided, the module would error. This is in reference to this issue: Blood Engine - A droplet emitter system - #224 by Necro_las

Does this need to be destroyed if a new engine is created everytime the client respawns, or will it garbage collect itself? I don’t see a destroy method anywhere for this.

Oopsies I didn’t think anyone would put it in StarterCharacterScripts. I’ll add a destroy method right away.

Blood Engine • V1.1.2

↳ General Changes

A new Destroy method: Added a Destroy method, that I admit should have been there in the beginning. This is for developers who especially use StarterCharacterScripts. (Reference to issue: Blood Engine - A droplet emitter system - #233 by Lukeskyroblox1)

3 Likes

This gives me an error. I’m trying to use it in my NPC.

local bloodEngine = require(game.ReplicatedStorage:WaitForChild("BloodEngine"))
local Humanoid = script.Parent:WaitForChild("Humanoid")
local OldHealth = Humanoid.Health
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

local Engine = bloodEngine.new({
	Limit = 60, -- Sets the maximum number of droplets that can be created.
	Type = "Decal", -- Defines the droplet type. It can be either "Default" (Sphere) or "Decal",
	RandomOffset = false, -- Determines whether a droplet should spawn at a random offset from a given position.
	OffsetRange = {-20, 10}, -- Specifies the offset range for the position vectors.
	DropletVelocity = {1, 2}, -- Controls the velocity of the emitted droplet.
	DropletDelay = {0.05, 0.1}, -- Sets the delay between emitting droplets in a loop (for the EmitAmount method).
	StartingSize = Vector3.new(0.01, 0.7, 0.01), -- Sets the initial size of the droplets upon landing.
	Expansion = false, -- Determines whether a pool can expand when a droplet lands on it.
	MaximumSize = 1, -- Sets the maximum size a pool can reach.
})

Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	local Instances = Engine.RaycastParams.FilterDescendantsInstances
	Engine.RaycastParams.FilterDescendantsInstances = {Instances and unpack(Instances), char}
	
	if Humanoid.Health < OldHealth then
		Engine:EmitAmount(script.Parent:FindFirstChild("Torso"), nil, 10)
	end

	OldHealth = Humanoid.Health
end)
Workspace.Respawning Dummy.Blood:20: attempt to index nil with 'FilterDescendantsInstances'

You can’t access the internal params, just the filter. Try using this:

Humanoid.HealthChanged:Connect(function()
	Engine:UpdateSettings({
		Filter = {Humanoid.Parent}
	})
	
	if Humanoid.Health < OldHealth then
		Engine:EmitAmount(Humanoid.RootPart, nil, 10)
	end

	OldHealth = Humanoid.Health
end)
2 Likes

guys, is there’s a way to make it not collide to a specific player?

nice blood system, but for some reason sometimes the blood doesn’t become flat as it should.
how i can fix that issue?
Снимок экрана 2024-09-26 184920

1 Like