FastCast2
Unofficial continuation of FastCast for Roblox
An improved version of FastCast with Parallel scripting, more extensions, and statically typed.
A powerful modern projectile library
FastCast2 It's a Roblox projectile library powered by VMsDispatcher designed to simulate thousands of projectiles without relying on physics replication.
Because FastCast is no longer actively maintained by EtiTheSpirit, this repository continues the project with updates and adaptations.
Benefits of using FastCast2
- Highly customizable
- Versatile projectile library
- Parallel scripting support
- Easy to use and integrate
- Raycast and Blockcast support
- BulkMoveTo support
- Built-in ObjectCache
- Flexible and extensible design
- Improves development productivity
- High Performance
- Completely free
FastCast2 is an open-source project, and contributions from the community are welcome.
Read more on FastCast2 devforum
Installation guide
- Go to Releases and install the
.rbxmfile from the latest release. - Open Roblox Studio and open any project.
- Go to File → Import Roblox Model and import the
.rbxmfile. - After importing, FastCast2 will appear in your Workspace.
- Drag FastCast2 into ReplicatedStorage.
- Create a Part and set:
- Size to
1, 1, 1 CanTouch= falseCanCollide= falseCanQuery= false
- Size to
- Done — you’re ready to use FastCast2.
Code example
Shooting projectiles from your head
-- Services
local Rep = game:GetService("ReplicatedStorage")
local RepFirst = game:GetService("ReplicatedFirst")
local Players = game:GetService("Players")
local UIS = game:GetService("UserInputService")
-- Modules
local FastCast2 = Rep:WaitForChild("FastCast2")
-- Requires
local FastCastTypes = require(FastCast2:WaitForChild("TypeDefinitions"))
local FastCastEnums = require(FastCast2:WaitForChild("FastCastEnums"))
local FastCastM = require(FastCast2)
-- CONSTANTS
local SPEED = 500
-- Variables
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local Head = character:WaitForChild("Head")
local Mouse = player:GetMouse()
local ProjectileContainer = workspace:WaitForChild("Projectiles")
local ProjectileTemplate = Rep:WaitForChild("Projectile")
local debounce = false
local debounce_time = 0.05
-- CastParams
local CastParams = RaycastParams.new()
CastParams.FilterDescendantsInstances = {character}
CastParams.FilterType = Enum.RaycastFilterType.Exclude
CastParams.IgnoreWater = true
-- Behavior
local castBehavior: FastCastTypes = FastCastM.newBehavior()
castBehavior.MaxDistance = 1000
castBehavior.RaycastParams = CastParams
castBehavior.HighFidelityBehavior = FastCastEnums.HighFidelityBehavior.Default
castBehavior.HighFidelitySegmentSize = 1
castBehavior.Acceleration = Vector3.new(0, -workspace.Gravity/2.3, 0)
castBehavior.AutoIgnoreContainer = true
castBehavior.CosmeticBulletContainer = ProjectileContainer
castBehavior.CosmeticBulletTemplate = ProjectileTemplate
castBehavior.UserData = {} -- Initial UserData when ActiveCast created
castBehavior.FastCastEventsConfig = {
UseHit = true,
UseLengthChanged = false, -- Warning: Setting this to true will make your FPS tank when there are 100-200+ projectiles
UseCastTerminating = true,
UseCastFire = true,
UsePierced = false
}
-- Caster
local Caster = FastCastM.new()
Caster:Init(
4, -- Roblox limits at 4 :(
RepFirst,
"CastVMs",
RepFirst,
"CastVMContainer",
"CastVM",
true
)
-- Functions
local function OnCastTerminating(cast: FastCastTypes.ActiveCastCompement)
local obj = cast.RayInfo.CosmeticBulletObject
if obj then
obj:Destroy()
end
end
local function OnHit()
print("Hit!")
end
local function OnCastFire()
print("CastFire!")
end
-- Connections
Caster.CastTerminating:Connect(OnCastTerminating)
Caster.Hit:Connect(OnHit)
Caster.CastFire:Connect(OnCastFire)
UIS.InputBegan:Connect(function(Input: InputObject, gp: boolean)
if gp then return end
if debounce then return end
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
debounce = true
local Origin = Head.Position
local Direction = (Mouse.Hit.Position - Origin).Unit
Caster:RaycastFire(Origin, Direction, SPEED, castBehavior)
task.wait(debounce_time)
debounce = false
end
end)
How to set up FastCastEventsModule
-- Services
local Rep = game:GetService("ReplicatedStorage")
-- Modules
local FastCast2 = Rep:WaitForChild("FastCast2")
-- Requires
local TypeDef = require(FastCast2:WaitForChild("TypeDefinitions"))
-- Module
local module: TypeDef.FastCastEvents = {}
local debounce = false
local debounce_time = 0.2
module.LengthChanged = function(cast : TypeDef.ActiveCast)
if not debounce then
debounce = true
print("OnLengthChanged Test")
task.delay(debounce_time, function()
debounce = false
end)
end
end
module.CastFire = function()
print("CastFire!")
end
module.CastTerminating = function()
print("CastTerminating!")
end
module.RayHit = function()
print("Hit!")
end
module.CanPierce = function(cast, resultOfCast : RaycastResult, segmentVelocity, CosmeticBulletObject)
local CanPierce = false
if resultOfCast.Instance:GetAttribute("CanPierce") == true then
CanPierce = true
end
print(CanPierce)
return CanPierce
end
module.Pierced = function()
print("Pierced!")
end
return module
(FastCastEventsModule can be used to optimize some FastCastEvents, like LengthChanged)
-> Get started with the FastCast2 documentation
People behind FastCast2
- Mawin CK: Main developer, Maintainer, Graphic designer
- Naymmmm: Help with proper docs, CI, Rojo supports, wally supports, Github pages(Moonwave)
- EtiTheSpirit: Original developer
SPECIAL THANKS TO
- @avibah On Discord: For helping me make VMDispatcher
- @ace9b472eeec4f53ba9e8d91bo87c636 On Discord: For advice/ideas