Flashcast - a fine-grained alternative to FastCast

Flashcast is a raycasting library built for projectiles.

I made this because I was fed up of FastCast’s abstractions. Flashcast lets you have more fine-grained control over your bullets so you can implement your own systems (ex: gravity, reflection, physical bullets) without any hassle.
You can find some examples on the repository README linked below.

Basic Usage

local SPEED = 25
local MAX_DISTANCE = 1000
local GRAVITY = Vector3.new(0, -workspace.Gravity, 0)

local function gravity(bullet: Flashcast.Bullet, deltaTime: number)
    local parallelComponent = bullet.direction:Dot(GRAVITY.Unit) * GRAVITY.Unit
    local perpendicularComponent = bullet.direction - parallelComponent
    local newDirection = perpendicularComponent + (parallelComponent + GRAVITY * deltaTime)

    bullet.direction = newDirection.Unit * bullet.direction.Magnitude
end

local function maxDistance(bullet: Flashcast.Bullet)
    if bullet.distanceTraveled > MAX_DISTANCE then
        bullet:stop()
    end
end

local flashcast = Flashcast.new()
local behavior = Flashcast.createBehavior()
    :setDesiredFramerate(10) -- the bullet will move every 1 / 10 seconds
    :beforeStep(maxDistance) -- applies a max distance check before moving the bullet
    :afterStep(gravity) -- applies gravity after moving the bullet

local direction = Random.new():NextUnitVector()
local bullet = flashcast:spawnBullet(
    behavior,
    Vector3.new(0, 10, 0),
    direction * SPEED
)

Links

23 Likes

Flashcast had an issue with its signal class which entirely broke stopping. This is now fixed with 2.4.1.

3 Likes

will you include a video showing the module in action?

2 Likes

I don’t believe that’d be necessary, you can implement the systems you want.

1 Like

3.0.0

I rewrote Flashcast to work with a behavior pattern, framerates instead of ticks, and more.

You cannot pass a function to define the tick anymore, instead you have to connect a callback to flashcast.event and iterate through the bullets with :getBullets (yes, raycasts were renamed to bullets).
Flashcast.Result does not exist anymore, you should just call bullet:stop() instead.
No more :onStop, there’s :isStopped, to use in an :afterStep callback.
No more state, you’ve got data to work with and Flashcast-made fields were moved to the bullet instance.

local flashcast = Flashcast.new()
local behavior = Flashcast.createBehavior()
    :setDesiredFramerate(10)
    :afterStep(function(bullet)
        print(`bullet traveled {bullet.distanceTraveled} studs`)
    end)

flashcast.event:Connect(function()
    for _, bullet in flashcast:getBullets() do
        bullet.desiredFramerate = os.clock()
    end
end)

local bullet = flashcast:spawnBullet(behavior, Vector3.yAxis * 25, Vector3.xAxis * 25)

Learn more about 3.0.0 in the documentation
ps: I haven’t updated the examples yet

2 Likes

Do you think that you can benchmark the performance of the new update? I’m very interested in using this library!

2 Likes

For sure, I could try benchmarking it. I have benchmarked earlier versions but haven’t gotten to it for this one yet.

1 Like

I like the expandability & being able to create your own behavior with ease. Good work

1 Like

I set up a quick test environment with 100 parts and 500 concurrent bullets spawning every half a second. They’re going 1000 studs a second. I’m also moving attachments for each bullet on :beforeStep. Flashcast:step took around 4-5 milliseconds per frame. Keep in mind the performance of a raycast can vary from different factors such as part count and length.
image

1 Like

*if i spawn the 500 bullets once, these are the results I get.
image

1 Like

HI, this is sweet, thanks for sharing!

Do the Flashcast Rockets do damage?

I go knocked through the floor, and I am hurt bad!

Can this also be used for Grenades or throwable weapons?

Also why do the rockets go through the walls and floor, but bounce of some things?

Thanks!

2 Likes

Hi, it can be used for anything, all it does is raycast in a direction and let you customize some behavior. It doesn’t move models or anything like that.
I’ve never seen the rockets go through walls and floors.
And also, the example places still use the old Flashcast so be wary of that. I’m working on making new ones.

1 Like

Does this have incorporated replication? Just curious. Anyways cool module I’ll probably use it. I made my own projectiles before because I was fed up with how complicated fast cast was for making a bullet, but that system became hard to maintain and it felt wonky. I will be trying this out, I’ll try to remember to give some feedback.

1 Like

I believe it’s just a raycast, which can be easily replicated as a projectile if that’s what you’re implying I presume

1 Like

nah, replication refers to the visualization of projectiles on clientside.

for example when using fast cast, the visual object representing the projectile is purely cosmetic. when visualized on the server, sure it’s easier, but when the client is moving the bullets on the server seem to lag behind. not only this, but doing purely cosmetic things, especially with base parts, can be laggy on its own. because of this we network through the server, and spawn separate projectile instances to follow a predetermined path, so that they are visually aligned for everyone. however if the projectiles are hit detection wise managed on the server it may appear to be off from where the projectile “actually hit”.

kinda a mouthful, but i hope you understand.

2 Likes

Hi, unfortunately it doesn’t offer any type of replication, all it does is raycast and let you customize some behavior, nothing else.

2 Likes

Added 2 examples.

1 Like

3.0.3

You can now advance bullets yourself with Flashcast:stepBullet(bullet, deltaTime), for syncing bullets or… anything really.

1 Like

image
it says the file is corrupted

1 Like

I just fixed this issue, thanks.

1 Like