How to move a bullet smoothly and in a way that is not expensive on the server

i wanna make some war game i want to apply some stuff like gravity and bullets speed decreasing by time and also be able to go through objects if the bullet is hard enough

what method of moving the bullets should i use?

1 Like

Do all vfx on client, never in server, to make it smooth. Client fires the shoot remote, and server replicates a bullet vfx remote to all clients with the position and direction dafa.
Vfx on server will always be laggy because of its constant replciation. For examppe tweens on server arent tweens on client, they’re many positional changes om the client which looks choppy and increases recv.

For bullets you should use fast cast. Its highly configurable, has bullet speed, lets you detect when a bullet hit, etc. Do it on client only tho

i understand but what i meant is like

while true do 
local db = heartbeat:Wait()
bullet.Position +=Direction*db
end

doesnt sound cheap on the performance

i dont think fastcast will help with what im trying to do

In general you never want to use something like.
First thing first, you need to calculate how fast your bullet is going. I am not going to give ALL the answers but you need to get it to a number that is viable for you to multiply by delta time.

Hint: If you do this right, the amount of time you pass through the equation shouldn’t matter. Aka time1 + time20 + time40 = time61 would be equal to passing through time61 the distance result will be the same.

Once you have that all sorted, this makes your bullet movement deterministic. And it gives you the tools to abstract the positions of the bullet to a data form and not need an instance at all for the server only side bullet.

You are then going to multiply delta time by this value.

--Note This is intentionally high concept code
local RunService = game:GetService("RunService")

--[[ PERF
If you want to cut down performance costs you will need to remove your dependance on instances for detections 
as much as you can.  It's far cheaper to update a table then it is to update the position of an instance.
--]]

-- List of Currently Active Bullets 
local ActiveBullets = {}

--[[
We do whatever process for the bullet to calculate if we hit and fire off whatever we need to or
result from it
]]
local function checkBulletDetections(bulletObj)
	--[[ your bullet detection logic]]
end

--[[
Calculating where the bullet should be and storing the Value
-- Not direction needs to be unitized =)
]]
local function processBulletSimulation(bulletObj, deltaTime)
	bulletObj.CurrentPosition += ((bulletObj.Speed * deltaTime)  * bulletObj.Direction)
	
	--[[NOTES
	So hypothetically you now hwave where teh bullet should be at this part in the frame.  
	Now there are different approaches to all of this past here for performance reasons start simple
	only do the super performant stuff you "HAVE to"
	]]	
end

--[[
On heart beat at this part in the frame we will calculate where the bullet should be now
for the love of all thats holy don't 
]]
RunService.HeartBeat:Connect(function(deltaTime)
	for i = 1, #ActiveBullets do 
		processBulletSimulation(ActiveBullets[i], deltaTime)
	end
end)
3 Likes

You should always be leery of while true dos. While is powerful but if your doing while, and you have any sort of wait roll over on built into it, you may as well directly hook it to the event your waiting with. It’s not only more concise but cuts down on weird logic concerns.

If you are concerned what happens if I have too many bullets and its slowing the frame, then figure out a way of governing how many are processed per a frame, and push the remainder to the next, and don’t calculate till you process all standing bullets.

OR you can get really fancy and use a queue for it. But that’s a whole explanation. =)

1 Like

So, if this is your first time, I highly suggest avoiding gravity bullets. Only use gravity and do true projectile calculations for grenades and rockets. Things that move perceptually slower than near instant.

Why? I promise you will hurt yourself doing this. Unless you are extremely experienced with this kind of thing, which by you asking the question we can assume you aren’t (“That’s not a diss this is me just stating the present facts”) then use HITSCAN for all your guns.

And real projectile math only for grenades, rockets, and slower projectiles. You should really ask yourself how effective or how often is the player going to experience the actual effects of bullet drag/gravity.

Which let me clarify this for you, if you are not sniping from perceptivally really far away, the player is never going to feel it. Because bullets at mid and close range move near instantly. Gravity and bullet drag are only really REALLY felt at longer ranges.

So ask yourself, are you making a game where you want every gun to be able to shoot from any perceivable distance and the bullet will simulate it’s fully true flight path till it inevitably bites dirt? If that answer is no, which likely is, then don’t worry about.

Pro Tip: If it feels like it works that way to the player, then it doesn’t matter how you do it. Think about why you want this implementation and how the player actually can perceive that experience. If you can achieve that same feeling with a simpler more reliable method. Use that instead, cuz at the end of the day unless you are making a true simulation game, we are magicians not scientist.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.