Custom renderer | by frodev

features of my game are those RPG elements of power progression, equipment collecting monster fighting, resource collecting, socializing with players and AI and doing procedurally generated quests in an open world in short. Currently looking at the lua heap and doing some nice optimizations trying to get the ping stable.
I noticed the camera it glitched out when geting close to an npc possibly due to camera trying to move around a type of wall.
MY advice for your game would be to make a bunch of spells and sword skills and start out with player versus player while also designing the abilities to be used by NPCs. I had this great thing happen in my development where I was able to convert most of my player systems to be used by NPCs and it saved a lot of work and ends up being very neat in coding and gameplay.
I never played Eve Online! But secretly this game is like a mix of Kingdom Hearts, Runescape and Breath of Fire Dragon Quarter and a little bit of Yugioh inspiration.

I just enjoy making my dream game :slight_smile:

WOW! I love your gameā€™s inspirations. I was a big fan of yugioh and kingdom hearts when I
was a kid.

Currently Its Becoming a more daunting task to work on my game as I know what the next step is, However.
(I have no idea how to get there)

This is what I wish to achieve:

This is what I have:
Nothing cant figure out how to use WCS and RefX unfortunately
Besides that I already have the VFX and SFX ready for the abilities but Iā€™ve been stuck on figuring out how to use this framework for almost a weekā€¦ I know using this one will save me tons of time from bartokens personal experience he shared with meā€¦
Might Hire a scripter honestly :pensive:

I have a useful function I use for VFX.
This is a multiply number sequence function that can change the size of Particle Emitters in code.

local function multnumseq(sequence,Scale)
	local numberKeypoints2 = {}
	for i = 1, #sequence.Keypoints do
		local currKeypoint = sequence.Keypoints[i]
		table.insert(numberKeypoints2, NumberSequenceKeypoint.new(currKeypoint.Time,currKeypoint.Value*Scale))	
	end
	return NumberSequence.new(numberKeypoints2)
end

In my game one thing I did was create like 30 different ball style attacks.


Then wrote one function that handles all of them.

function dfg.Energyball(Subject,Target,Type,Damage,Scale)
	local charging
	local Subject=Subject
	local Target=Target
	local Type=Type
	local Damage=Damage
	local Scale=Scale
	local Human=nil
	if Scale==nil then Scale=1 end
	local Player,Player2=nil
	if Target~=nil  and Subject~=nil then
		Human=Subject.Parent:FindFirstChildOfClass("Humanoid")
		if Human==nil then
			Human=Subject.Parent.Parent:FindFirstChildOfClass("Humanoid")
		end
			local Angular
			Player=game.Players:GetPlayerFromCharacter(Human.Parent)
			local Rotate=false 	
		if Player==nil and Target then
			if Human.Parent:FindFirstChild("HumanoidRootPart"):FindFirstChildOfClass("BodyGyro")==nil then
				Angular=Instance.new("BodyGyro")
				Angular.CFrame=CFrame.new(Human.Parent:FindFirstChild("HumanoidRootPart").Position,Target.Position)
				Angular.Parent=Human.Parent:FindFirstChild("HumanoidRootPart")
				Debris:AddItem(Angular,.6)		
			if Human.AutoRotate==true then
					Rotate=true
					Human.AutoRotate=false		
					spawn(function() task.wait(.6) Human.AutoRotate=true end)
				else Human.AutoRotate=false	end	
				end
		end
	local Comp=false
	local Core=Type.Parent.Core:Clone()
	local EFX=Type:Clone()
	--local simmodel=Instance.new("Model")
	--Core.Parent=simmodel
	
--	Core.Parent
	local w
	local Speed=Type.MagicID:GetAttribute("Speed")
	local DamageScript=repspell.Damage.DmgRoll:Clone()
	DamageScript.Value=Damage
	DamageScript.Parent=Core
	local Obj=Instance.new("ObjectValue")
	Obj.Value=Subject
	Obj.Name="Owner"
	Obj.Parent=Core
	EFX.Parent=Core	
	Core.Size=Type.MagicID:GetAttribute("Size")
	Core.CFrame=Subject.CFrame:ToWorldSpace(CFrame.new(0, 0,(-1*(Core.Size.Z/2+Subject.Size.Z/2))))
	Core.Massless=true
	Core.Anchored=false			
	Core.Parent=Subject.Parent
	--simmodel:Destroy()
		if Human~=nil then
			if Human.Parent:FindFirstChild("UpperTorso") then		
				local AR=mathrandom(1,7)
				local Anim=Human:LoadAnimation(script.Animations:FindFirstChild("Energyball"..AR))
				Anim:Play()
				task.delay(Anim.Length,function() Anim:Stop() end)
			end
		end
		if Player then
			Core:SetNetworkOwner(Player)
		elseif Target then
			Player2=game.Players:GetPlayerFromCharacter(Target.Parent)
			if Player2 then
				Core:SetNetworkOwner(Player2)
			end
		end
		--task.delay(1.2,function() dfg.Deflect(Core) end)
	---local Core2=Core:Clone()	
		local DamageCharacter=Core
		--Core2.CanCollide=false
		--Core2.CanQuery=false
		--Core2.CanTouch=false
		--.Anchored=true
		
		local hittable={}
		local function checktable(hit)
			for i,v in pairs(hittable) do
				if v==hit.Parent then
					return true
				end
			end
			return false
		end
		local Hits = 0
local tcon=nil 		tcon=Core.Touched:Connect(function(hit)
				
			dfg.ExplosionConditions(hit,Core,Type.MagicID)
			if hit.Parent~=Subject and tostring(hit.Parent)~=tostring(Subject) and hit.Parent~=Human.Parent and hit.Parent~=Core.Parent then Core.CanTouch=false		
				local arrow = Core
				local Owner
				local Character=nil
				local damage
				if arrow:FindFirstChild("Owner")==nil then
					Owner=Instance.new("ObjectValue")
					Owner.Value=arrow.Parent
				end
				Owner = arrow.Owner
				local DMG =repspell.DMG:clone()
                   Debris:AddItem(DMG,7)
				local humanoid = hit.Parent:findFirstChild("Humanoid")
				local Protect=hit.Parent:findFirstChild("Protect")
				if (humanoid~=nil and Protect~=nil) and humanoid.Parent~=Subject then
					if humanoid.Parent ~= Obj.Value then			
						if checktable(hit)==false then 
							Comp=true
							arrow.CanTouch=false	
								if game.Players:FindFirstChild(Owner.Value.Name)~=nil then
									Character = game.Players:FindFirstChild(Owner.Value.Name).Character
									Core.DmgRoll.Value= game.Players:FindFirstChild(Owner.Value.Name).PlayerGui.Bonus.MAG.Value
							else 
								pcall(function() Core.DmgRoll.Value = Damage end)
								
							end
								if hit.Parent.Protect.Value ~= 2 then
									if Core.DmgRoll.Value>=80 then
										damage = (mathrandom(0,Core.DmgRoll.Value/1.1)) 
										Core.DmgRoll.Value= damage
									elseif	 Core.DmgRoll.Value<=80 then
										damage = (mathrandom(0,Core.DmgRoll.Value))
										Core.DmgRoll.Value= damage
									end
								elseif hit.Parent.Protect.Value == 2 then		
									if Core.DmgRoll.Value>=80 then
										damage = (mathrandom(0,Core.DmgRoll.Value/3)) 
									elseif Core.DmgRoll.Value<=80 then
										damage = (mathrandom(0,Core.DmgRoll.Value/2)) 
									end	
								end
								if Character~=nil then
									if Character:FindFirstChild("Staff") ~= nil  or Character:FindFirstChild("Scythe") ~= nil or Character:FindFirstChild("ScytheX") ~= nil then
										Core.DmgRoll.Value= damage+ damage*.15
										damage=Core.DmgRoll.Value
									end
							end
							damage =math.floor(damage)
								dfg.DealDamage(humanoid,damage,2,hit,Type.MagicID:GetAttribute("Element"),Subject)
								table.insert(hittable,hit.Parent)
								--humanoid.Health = humanoid.Health - damage
								--Hits = Hits + 1
								--DMG.HitSplat.Hit.Text = ""..(damage)..""
						--	if humanoid.Parent:FindFirstChild("Head")~=nil then
							--DMG.Parent = humanoid.Parent.Head
						--	else humanoid.Parent:FindFirstChild("HumanoidRootPart")	
						--	end
							
							--	DMG.HitSplat.Hit.Server.Disabled = false

							else 
							arrow.CanTouch=false	
							end	
							--		explosion = game.Lighting.Bewm:clone()
							--		explosion.Position = hit.Position
							--		explosion.Mesh.Scale = Vector3.new(0.25, 0.25, 0.25)
							--		explosion.Parent = workspace
							task.wait()
			
				
						end
					end		
				end		
				if Hits<1 then
					Core.CanTouch=true
				else tcon:Disconnect()
				tcon=nil	
				end	
				
		end)
	if (Subject) then
		w = Instance.new("Weld")
		w.Part0,w.Part1 = Subject,Core
		w.C0 = Core.CFrame:toObjectSpace(Subject.CFrame):inverse()
		w.Parent = Subject
	end
	for _,v in pairs(EFX:GetDescendants()) do		
local v=v	
	if v:IsA("Sound") then
			TweenSound(v)
			if v.Looped==true then
				spawn(function()
					v.RollOffMaxDistance*=Scale	
					repeat task.wait(.05) until Comp==true					
					local goal = {}
					goal.Volume =  0
					local tweenInfo = TweenInfo.new(.5)
					local tween = TweenService:Create(v, tweenInfo, goal)
					tween:Play() 
				end)
			end
		end	
		
		if v:IsA("PointLight") then
			spawn(function()
				local v=v
				local goal = {}
				goal.Brightness = v.Brightness
				goal.Range= v.Range*Scale
				local tweenInfo = TweenInfo.new(2)
				local tween = TweenService:Create(v, tweenInfo, goal)	
				v.Brightness=0
				v.Range=0
				tween:Play()
			end)
		end	
		if v:IsA("ParticleEmitter") then
			spawn(function()
				local Bubbleb=v				
						local PrevTrans=Bubbleb.Transparency
						local Prevsize=dfg.multnumseq(Bubbleb.Size,Scale)
				local Steps=15
				local CSteps=0
				local fram=.0333
				local deftimes=Bubbleb.TimeScale
				Bubbleb.TimeScale=Bubbleb.TimeScale/3
				repeat 
					
						v.TimeScale=deftimes*(CSteps/5)							
						CSteps=CSteps+1	
						--local Ratio=CSteps/Steps
						--local numberKeypoints2 = {
						--	NumberSequenceKeypoint.new(0, 1-Ratio), -- At t=0, size of 0
						--	NumberSequenceKeypoint.new(1, 1), -- At t=1, size of 10
						--}
									
									Bubbleb.Size = dfg.multnumseq(Prevsize,CSteps/15)
									Bubbleb.TimeScale=deftimes*(CSteps/15)
									Bubbleb.Transparency = dfg.multnumseq(PrevTrans,17/CSteps+2)
									task.wait(fram)	
					
						until CSteps+2>=Steps	
				Bubbleb.TimeScale=deftimes		
				Bubbleb.Transparency=PrevTrans
				Bubbleb.Size=Prevsize		
				local Steps=60
				local CSteps=0
				local fram=3/30
				--local c	
			repeat 
					CSteps=CSteps+1
					if Comp==true and CSteps<30 then
						CSteps=30
								
							else CSteps=CSteps+1	
							end
						if CSteps>=45 or Comp==true then
								if CSteps<45 then
									CSteps=45
								end
								task.wait(fram)	
								local Ratio=CSteps/Steps
								local numberKeypoints2 = {
									NumberSequenceKeypoint.new(0, Ratio), -- At t=0, size of 0
									NumberSequenceKeypoint.new(1, 1), -- At t=1, size of 10
								}
								Bubbleb.Transparency = dfg.multnumseq(PrevTrans,(CSteps-44)*1)
							end
					task.wait(fram)	
					until CSteps>=Steps	
					Bubbleb.Enabled=false 
			end)
		end
	end
	if Target~=nil then					
			local goal = {}
			
			local tweenInfo
			local Tick
			local tween
			task.wait(.75)
			local Vectir=nil
			if Target then
				Vectir=(Target.Position-Subject.Position).Magnitude
			else 
				Vectir=80
			end	
			local B=Instance.new("BodyPosition")
			B.Position=Core.Position	
			w:Destroy()
			Core.Anchored=true
			if Vectir<40 and Vectir>12.5 then
		tweenInfo = TweenInfo.new(Vectir/10,Enum.EasingStyle.Linear)
		Tick=Vectir/10
		elseif Vectir>=40 then
			tweenInfo = TweenInfo.new(4,Enum.EasingStyle.Linear)
			Tick=4
		elseif Vectir<=12.5 then
			Tick=1.25
			tweenInfo = TweenInfo.new(1,Enum.EasingStyle.Linear)
		end	
			if Vectir>8 and Target then -- follow the target
			goal.Position = Target.Position
			tween = TweenService:Create(B, tweenInfo, goal)
			tween:Play()
			spawn(function()
			local Cero=0
			repeat		
					Cero=Cero+.25
						
					
					if (Target.Position-Core.Position).Magnitude<2 then
						Comp=true	
					end
					local tweenInfo
					if Tick-Cero>0 then
						tweenInfo=TweenInfo.new(Tick-Cero,Enum.EasingStyle.Linear)	
					else	
						tweenInfo=TweenInfo.new(.4,Enum.EasingStyle.Linear)	
					end
				goal.Position = Target.Position
				local tween2 = TweenService:Create(Core, tweenInfo, goal)
				tween:Pause()
				tween=tween2
							tween:Play()	
							task.wait(.25/Speed)
							
				until Cero>=Tick	or Comp==true
						Comp=true
						
						task.wait(.6)
						Core.CanTouch=false
						task.wait(1.5)
					if Player and Core.Parent~=nil then
						Core.Anchored=false
						Core:SetNetworkOwner(nil)
					end
					Core:Destroy()
					 tcon:Disconnect() 
						
			end)	
		else
			tweenInfo = TweenInfo.new(1/Speed,Enum.EasingStyle.Linear)
			goal.Position = Target.Position	
			local tween = TweenService:Create(B, tweenInfo, goal)
			tween:Play()
			tween.Completed:Wait()			
			Comp=true
					task.wait(.6)
					Core.CanTouch=false
					task.wait(1.5)
				if Player then
					Core:SetNetworkOwner(nil)
				end
				Core:Destroy()
				 tcon:Disconnect() 
					--if Core2~=nil then
					--	Core2:Destroy()
					--end	
		end	
				
			end	
	end		
end	

This is definitely the way to go about creating simple and effective systems. So donā€™t worry! Less is more!
They also utilize this neat object that determines their behavior.

Thank you for providing this but Iā€™m probably gonna use refx because itā€™s documented and doesnā€™t need presintalled assets

Hey! I just started UI Design!
Wondering if this is a good Fps Reader or if it can be optimized lol

local RunService = game:GetService("RunService")
local FpsLabel = script.Parent

local TimeFunction = RunService:IsRunning() and time or os.clock

local LastIteration, Start
local FrameUpdateTable = {}

local function HeartbeatUpdate()
	LastIteration = TimeFunction()
	
	for Index = #FrameUpdateTable, 1, -1 do
		FrameUpdateTable[Index + 1] = FrameUpdateTable[Index] >= LastIteration - 1 and FrameUpdateTable[Index] or nil
	end
	
	FrameUpdateTable[1] = LastIteration
	FpsLabel.Text = "FPS: " .. tostring(math.floor(TimeFunction() - Start >= 1 and #FrameUpdateTable or #FrameUpdateTable / (TimeFunction() - Start)))
end

Start = TimeFunction()
RunService.Heartbeat:Connect(HeartbeatUpdate)

Yes itā€™s optimized if you run it only once and use the reading of the FPS for all your FPS needs. I use the FPS value FPS timing value for things that require being done once per frame and it is completely seamless, no issues with the calculations on my end.
At some point i had to go through and make sure all my scripts were not calculating 1/FPS in exchange for the FPS timing object which is much more important.

FPSTiming.Value=1/FPS.Value--equivalent to .0333 at 30 FPS and .01666 at 60fps

The code was more of a demonstration on how to go about it of course you can use whatever youā€™d like. Itā€™s really not that hard and can be a fun project to write them yourself. Generally VFX requires that you have a library of configured assets in my example it goes through the children of an attachment and does tweening of sound, particle emitter size, light and tweening of the CFrame. Thatā€™s pretty much all it takes for VFX. Another popular library for VFX is [UPDATE 0.1.0] Lumina - A custom particle system - Resources / Community Resources - Developer Forum | Roblox

Yea was thinking about using lumina but wcs isnā€™t that compatible with it unfortunately