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

I’m getting an error which says that the “LengthChanged” signal is nil, But everything looked fine after I looked at the variable that stored the caster. Does anyone know why this would be happening?

im curious, can a non_client like a NPC can use FastCast?

Haven’t used FastCast in a while, but when you’re tyring to do a Server Side Cast, are you creating a FastCast instance for every player on the server, or every gun type the client sends?

Or Just one Server FastCast instance that is constantly updated with new gun data every request?

[Feel free for anyone to answer]

Should I be creating a new caster every time a bullet is fired?

No, you should only create a caster once

1 Like

Does anyone know how to make the bullets despawn after some time after firing them?

The newBehavior has a property for that called max distance.

local CastBehavior = FastCast.newBehavior()
CastBehavior.MaxDistance = 100

1 Like

At some point in the game I need to remove the gun from players and I’m simply finding the gun on the players’ characters or in their backpacks and doing:

tool:Destroy()

This seems to work perfectly aside from one issue: In case the player was shooting as the gun was destroyed the CosmeticBullet-s stop and remain stuck in air forever.

Is there a proper solution for destroying guns properly to avoid such issues?

I could stop it shooting by destroying the client script but then still need to somehow clean up the CosmeticBullet-s already flying in the air, before destroying the gun. How?

Edit: Solution: Before destroying the tool I send it an event and use a function to 1st set it to being destroyed = true, so it can not shoot anymore and a second later, right before destroying the tool I use CastBehavior.CosmeticBulletProvider:Dispose() to properly get rid of the whole PartCache.

While in theory this is a great approach, however, doing hit reg on the server invites client-server delay issues to bullet trajectory in FastCast from what I’ve discovered. I had to do hit reg on the client because I noticed I would have to predict movement and fire ahead of the moving target when hit reg was done on the server. If you’ve found solutions to mitigate the delay, I would love to know. I’ve already tried lag compensation methods like the one CS:GO uses to no effect.

This is a more custom solution as I don’t really think modules like this one or raycast hitbox are necessary unless you’re an absolute beginner/non scripter. On the server, save every character’s position every heartbeat inside a world model as shown here. When you launch a projectile, again every heartbeat, find the worldmodel corresponding/closest to the server’s current time - player ping, and use something like workspace:GetPartBoundsInBox on it (if you want to use the part one, you may have to clone/move the part to that world model temporarily.)
Edit: This would also entail making a separate projectile that has the actual visuals on the caster’s client only, and also replicating to other clients separetely.

This method is essentially what CS:GO does and I’ve tried it. I’ll try it again but there’s quite a lot going on the server and a system like this looks like it demands quite a bit.

I’m also using the BulletCache module, so how would I return the bullet to the cache after it reaches its distance?

I saved every player’s position on a dictionary along with timestamps down to the ms and the characters were just blocks so I made a custom raycaster that determined whether the bullet hit a player or not without having to create unnecessary debris in the workspace. Once a player fired I’d subtract the player’s ping to the current time and I would do table check thru the raycaster. I’d cast the ray 20 times from timestamp-10ms to timestamp+10ms and if at least 50% of the casts hit I’d deal damage. This turned out to be much faster than raycasting.

2 Likes

Interesting approach. How’s the performance with 20+ players on the server? My game demands a high player count, roughly around 32-50 range.

It was just a fun project not something designed to actually run, ideally there’s no need for such impractical complexity assuming your player characters aren’t blocks and that there are obstacles between them. It ran extremely smoothly I couldn’t really tell a difference even on 100-180 ping. You can try my method of approach using Roblox’s raycasts and without casting a ray 20 times per invoke although raycasts are extremely lightweight so you could give that a shot as well.

Hey, I’ve got a really weird bug with this. So for my bullet piercing, every time a bullet gets fired I put the cast as a key into a table with the number of times it can pierce enemies as the value, which I use for the CanPierceFunction. However, I noticed that after the bullet pierces an enemy, and then the enemy dies by any means, even if the gun gets unequipped, the CanPierceFunction is inexplicably broken for the rest of the session. Instead of passing the actual cast that hit something, it seems to pass a cast that doesn’t actually exist, as it can’t be found in the cast pierces table. And this only happens for the CanPierceFunction, the RayHit function is still able to get the number of pierces just fine. I have absolutely no idea why the enemy dying would trigger this to happen. Can anyone help with this?

I would not use this as a serious scripter.

The example gun code is extremly messy and the whole module written as an attempt to confuse other readers.

It works, it use good logic, but for a serious project it’s better to write your own than debugging someone elses entanglement.

Good comments though! Just wish the structure of the code was more userfriendly.

2 Likes

When using Fast Cast I’ve never understood how to utilize FastCast.new() and Behaviors.

Like for Client Visuals, I usually make one new Caster and one Behavior once on the client, and every different gun used throughout the servertime, just has the Behavior be adjusted before firing from the one Caster.

And this always worked okay, I just don’t know if there’s a better practice.

What I do is fire the projectile first on the client for both hitreg and visualization, then fire an event to a server handler, where it fires it’s own hitreg bullet, then fires all of the other clients to visualize the bullet. once the projectile hits something on the clients simulation, i then subtract the distance between the impact points and if it’s beyond a certain threshold, i void the shot presuming it’s an exploiter, but if it’s less, we use the clients hitreg for the actual data.

if the server doesn’t hit anything, we go with the clients hitreg for the data.

if the client doesn’t hit anything, we void the shot to make the client’s experience more realistic.

excuse my grammar.

6 Likes

That’s a pretty nice way of going about it! How’s the feel of hitreg? Any complaints from your players whatsoever?