Making a combat game with ranged weapons? FastCast may be the module for you!

Is there any way to prevent shooting through walls?

Hey, I’ve been using your module and its fantastic. However I have little criticism on the documentation. I was curious is Caster:Fire() returned the activeCast however your docs don’t go over if it does. I had to read the module’s code instead. It would be fantastic if you made this small adjustment to the documentation so people don’t have to go through the confusion I had to. Aside from that your documentation is fantastic I really appreciate the effort put into this module :slight_smile:

Sorry I am late. Of the replies I have read that pose new questions, here’s some answers:

The method given on that thread seems like it would work. You basically just need to do a raycast in your pierce callback. The origin of the ray should be exactly how the thread describes it: some distance in the same direction of the incoming ray, and then the direction of the new ray is the opposite of the bullet’s direction.

This will have issues if you have a very large part and bullet drop, because this method can’t figure out where a curve will start and end within a part, doing that will be quite complicated…

The error message says exactly what you need to do:

local cache =
local part = cache:GetPart()


local part = PartCache:GetPart()

A static invocation means that you called the method on the actual module itself rather than one of the module’s custom objects that is, again, created via

That’s in the method signature.


The format all methods follow is ReturnType Name(parameters...) - if a function returns nothing, its return type is void in lieu of typical programming terms. In this case, it means the method’s name is Fire, and it returns an ActiveCast instance.

1 Like

hello, I was reviewing the module and found a programming error. Basically maximum distance doesn’t work on rays that don’t have physics, since they only produce raycast per update.

Don’t you understand me?, I’ll explain: the distance is checked when the trajectory is updated, which means that you will have to wait for the trajectory to update to check the distance.

This would not be affected on ranged weapons, but on handheld weapons; you have to wait for the raycast to update and the distance would never be correct.

I suggest checking the distance in one heartbeat from the last point - the origin.

This module is amazing but I have one issue.
How can I get the player thats firing the caster?

Unlike the example code I dont use a script / remote event inside of the tool.
I have one remote event that every player uses that connects to a script inside of serverscriptservice so multiple people use the same caster.

How do I get the player that fired the caster? For my OnHit event I need to get the player dealing damage before dealing damage to another player so I can do some checks.

You can get the active cast object and stuff it in the UserData folder like so, from the active cast documentation.

	local activeCast = currentEntityFastCastHandler:Fire(origin, direction)
	local bulletOwner = world.Get(entity, PlayerComponent)
	activeCast.UserData.Owner = bulletOwner
	activeCast.UserData.BulletID = bulletID --bulletID system
	ProjectileService.ReplicateProjectileClientToServer:Fire(origin, direction, attachment, bulletID)

to identify the owner

		local function rayHit(activeCast, result: RaycastResult, segmentVelocity, bullet)
			local instanceHit: BasePart = result.Instance
			local owner = activeCast.UserData.Owner
--do stuff
		local castComponent = entityFastCastHandler.fastcast

		local replicationRayHitSignal = castComponent.RayHit:Connect(rayHit)

Thank you for the help! Greatly appreciated.

Is there a way to get the cosmetic part? I want to do something with the cosmetic bullet.

1 Like

In what situations could RayHit not fire, but LengthChanged and CastTerminated do? I am having a problem with this. It could be an issue on my end but I can’t find any cases in the docs where this could happen. I don’t manually terminate the cast.

guns[player] = {
		caster = caster,
		behavior = behavior,
		connections = {
			caster.RayHit:Connect(function(_, result: RaycastResult)

				_, origin: Vector3, direction: Vector3, length: number, _, bullet: BasePart


I can send a place file, but that is what I have.

RayHit will not fire if the ray is terminated due to exceeding its maximum distance, hence why the docs say to handle bullet disposal in CastTerminating, not RayHit. RayHit is not guaranteed to fire (if it terminates due to exceeding maximum distance, it didn’t hit anything, so it would break the contract of the hit never being nil in RayHit if it did fire that event). CastTerminating, on the other hand, is guaranteed to always fire for any given cast.

1 Like

Great Modulescript. One Problem tho: It completely breaks Projectiles that use Trails (The first 2 ones are with the Module, the last one is without the modulescript)

PartCache placest a part far away after returning it, just disable the trail before returning

1 Like

@Xan_TheDragon Question,

There is a delay from when the player fires the caster and the ray actually gets created on the client, causing projectiles to “lag” behind the gun when the player is walking.

As you can see it’s extremely noticeable in game especially for weapons with slower bullet speeds.

I’m assuming it has to do with the replication. Is there anyway you can fix this? Or what can I do to fix this?

This problem is preventing me from using this module in any published worked.

I have multiple players that will fire a remote event so that the server can use fastcast to cast a projectile, but in my case, i have different types of weapons, HitScan and Projectile and a serverscript that’s using 2 modules for the casting of both types. Do i make one caster object per module? To fire and not create a caster object every time the main script requests to fire of course.

Yeah that’s the way you do it. Effectively assign guns a lookup from gun → caster.

Just remember to not send the gun type over the event, as that is a gaping security hole. The server should know what gun someone is using already.

1 Like

Not sure if its a problem with FastCast or my use of it, but AutoIgnoreContainer will add the CosmeticBulletContainer to the RaycastParam table, even if its set to whitelist.

Here in the API it states it will not work if its using a whitelist. This caused my bullets to hit each other, and setting AutoIgnoreContainer to false fixed it for me.

This is the way I was using it.

	local RaycastParam =
	RaycastParam.FilterType = Enum.RaycastFilterType.Whitelist
	RaycastParam.FilterDescendantsInstances = {workspace.CurrentMap.Decor, workspace.CurrentMap.ObstacleHolder}
	FastCastBehavior.RaycastParams = RaycastParam

	FastCastBehavior.CanPierceFunction = CanPierce
	FastCastBehavior.CosmeticBulletContainer = workspace.fastCast

It shouldn’t, as the API member states. Though technically, “will not function” does imply that it just won’t work as you expect in general.

How can I access a bullet that has been released? For example, to change the color of the bullet at the time of flight.

Does this work if i use models as bullets?

I’m using fast cast for my mech game and I’m having a few problems I just want to know if it’s me or just limitations of the module.

My mech character can wield up to 4 guns simultaneously and fire simultaneously. In studio this is not an issue but in live servers even having only two players with the same loadout makes ping start to skyrocket.

Do we have any stress test references to see if it’s just me or limitations of the module?

Probably worth noting that the weapons have a pretty high fire rate of around 1 shot every 1/100 of a second.

I find it hard to believe that fast cast would have trouble with 8 high fire rate guns so I’m hoping it’s just me and my terrible code…

1 Like