diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml
new file mode 100644
index 0000000..7432438
--- /dev/null
+++ b/.github/workflows/publish-docs.yml
@@ -0,0 +1,23 @@
+# .github/workflows/publish-docs.yml
+name: publish-docs
+on:
+ push:
+ branches: ["master"]
+jobs:
+ status:
+ runs-on: ubuntu-latest
+ name: Publish docs to GitHub Pages
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: "22"
+ - run: npm i -g moonwave@latest
+ - name: Publish
+ run: |
+ git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
+ git config --global user.email "support+actions@github.com"
+ git config --global user.name "github-actions-bot"
+ moonwave build --publish
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 7a3f61c..475f38a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,8 @@
# Roblox Studio lock files
/*.rbxlx.lock
-/*.rbxl.lock
\ No newline at end of file
+/*.rbxl.lock
+
+# Moonwave related stuff
+/node_modules
+/package-lock.json
\ No newline at end of file
diff --git a/.moonwave/custom.css b/.moonwave/custom.css
new file mode 100644
index 0000000..5d3d0da
--- /dev/null
+++ b/.moonwave/custom.css
@@ -0,0 +1,386 @@
+/**
+ * Modern Moonwave/Docusaurus Theme - shadcn inspired
+ * Clean greyscale, Inter font, professional vibes
+ */
+
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
+@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap');
+
+/* Light theme variables */
+:root {
+ --ifm-color-primary: #171717;
+ --ifm-color-primary-dark: #0a0a0a;
+ --ifm-color-primary-darker: #000000;
+ --ifm-color-primary-darkest: #000000;
+ --ifm-color-primary-light: #262626;
+ --ifm-color-primary-lighter: #404040;
+ --ifm-color-primary-lightest: #525252;
+
+ --ifm-background-color: #ffffff;
+ --ifm-background-surface-color: #fafafa;
+ --ifm-hover-overlay: #f5f5f5;
+
+ --ifm-font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+ --ifm-font-family-monospace: 'JetBrains Mono', 'Fira Code', monospace;
+
+ --ifm-heading-color: #0a0a0a;
+ --ifm-font-color-base: #737373;
+ --ifm-font-color-secondary: #a3a3a3;
+
+ --ifm-code-font-size: 90%;
+ --ifm-global-radius: 0.5rem;
+ --ifm-code-border-radius: 0.5rem;
+
+ --ifm-navbar-background-color: #ffffff;
+ --ifm-navbar-shadow: none;
+
+ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.05);
+
+ --ifm-color-emphasis-0: #fafafa;
+ --ifm-color-emphasis-100: #f5f5f5;
+ --ifm-color-emphasis-200: #e5e5e5;
+ --ifm-color-emphasis-300: #d4d4d4;
+ --ifm-color-emphasis-400: #a3a3a3;
+ --ifm-color-emphasis-600: #525252;
+ --ifm-color-emphasis-700: #404040;
+ --ifm-color-emphasis-800: #262626;
+ --ifm-color-emphasis-900: #171717;
+ --ifm-color-emphasis-1000: #0a0a0a;
+}
+
+/* Dark theme variables */
+[data-theme='dark'] {
+ --ifm-color-primary: #fafafa;
+ --ifm-color-primary-dark: #e5e5e5;
+ --ifm-color-primary-darker: #d4d4d4;
+ --ifm-color-primary-darkest: #a3a3a3;
+ --ifm-color-primary-light: #ffffff;
+ --ifm-color-primary-lighter: #ffffff;
+ --ifm-color-primary-lightest: #ffffff;
+
+ --ifm-background-color: #0a0a0a;
+ --ifm-background-surface-color: #171717;
+ --ifm-hover-overlay: #262626;
+
+ --ifm-heading-color: #fafafa;
+ --ifm-font-color-base: #a3a3a3;
+ --ifm-font-color-secondary: #737373;
+
+ --ifm-navbar-background-color: #0a0a0a;
+
+ --docusaurus-highlighted-code-line-bg: rgba(255, 255, 255, 0.05);
+
+ --ifm-color-emphasis-0: #0a0a0a;
+ --ifm-color-emphasis-100: #171717;
+ --ifm-color-emphasis-200: #262626;
+ --ifm-color-emphasis-300: #404040;
+ --ifm-color-emphasis-400: #737373;
+ --ifm-color-emphasis-600: #a3a3a3;
+ --ifm-color-emphasis-700: #d4d4d4;
+ --ifm-color-emphasis-800: #e5e5e5;
+ --ifm-color-emphasis-900: #fafafa;
+ --ifm-color-emphasis-1000: #ffffff;
+}
+
+/* Global typography */
+body {
+ font-feature-settings: 'cv11', 'ss01';
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 600;
+ letter-spacing: -0.025em;
+}
+
+h1 {
+ font-size: 2.25rem;
+ font-weight: 700;
+}
+
+h2 {
+ font-size: 1.875rem;
+ border-bottom: 1px solid var(--ifm-color-emphasis-200);
+ padding-bottom: 0.5rem;
+ margin-top: 3rem;
+}
+
+/* Navbar styling */
+.navbar {
+ border-bottom: 1px solid var(--ifm-color-emphasis-200);
+ box-shadow: none;
+ padding: 0.75rem 1.5rem;
+}
+
+.navbar__title {
+ font-weight: 700;
+}
+
+.navbar__item {
+ font-weight: 500;
+}
+
+/* Sidebar improvements */
+.theme-doc-sidebar-container {
+ border-right: 1px solid var(--ifm-color-emphasis-200);
+}
+
+.menu__link {
+ border-radius: calc(var(--ifm-global-radius) - 2px);
+ font-size: 0.875rem;
+ font-weight: 500;
+ transition: all 150ms ease;
+}
+
+.menu__link:hover {
+ background: var(--ifm-hover-overlay);
+}
+
+.menu__link--active {
+ background: var(--ifm-color-emphasis-100);
+ font-weight: 600;
+ border-left: none;
+}
+
+.menu__list-item-collapsible:hover {
+ background: transparent;
+}
+
+.menu__caret::before {
+ background: var(--mini-svg) no-repeat;
+}
+
+/* Code blocks */
+div[class^='codeBlockContainer'] {
+ box-shadow: none;
+ border: 1px solid var(--ifm-color-emphasis-200);
+}
+
+.prism-code {
+ background: #0a0a0a !important;
+ font-size: 0.875rem;
+ line-height: 1.7;
+}
+
+[data-theme='dark'] .prism-code {
+ background: #000000 !important;
+}
+
+/* Inline code */
+code {
+ background: var(--ifm-color-emphasis-100);
+ color: var(--ifm-heading-color);
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-radius: calc(var(--ifm-global-radius) - 4px);
+ padding: 0.2em 0.4em;
+ font-size: 0.85em;
+ font-weight: 500;
+}
+
+/* Tables */
+table {
+ border-collapse: collapse;
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-radius: var(--ifm-global-radius);
+ overflow: hidden;
+ font-size: 0.875rem;
+}
+
+thead {
+ background: var(--ifm-color-emphasis-100);
+}
+
+th {
+ font-weight: 600;
+ border-bottom: 1px solid var(--ifm-color-emphasis-200);
+}
+
+td {
+ border-bottom: 1px solid var(--ifm-color-emphasis-200);
+}
+
+tbody tr:last-child td {
+ border-bottom: none;
+}
+
+tbody tr:hover {
+ background: var(--ifm-hover-overlay);
+}
+
+/* Admonitions/Alerts */
+.admonition {
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-left-width: 4px;
+ font-size: 0.875rem;
+}
+
+/* Links */
+.markdown a {
+ text-decoration: underline;
+ text-decoration-color: var(--ifm-color-emphasis-300);
+ text-underline-offset: 3px;
+ font-weight: 500;
+ transition: all 150ms ease;
+}
+
+.markdown a:hover {
+ text-decoration-color: var(--ifm-color-primary);
+}
+
+/* Buttons */
+.button {
+ border-radius: var(--ifm-global-radius);
+ font-weight: 600;
+ font-size: 0.875rem;
+ transition: all 150ms ease;
+ border: 1px solid var(--ifm-color-emphasis-200);
+}
+
+.button--primary {
+ border-color: var(--ifm-color-primary);
+}
+
+.button:hover {
+ opacity: 0.9;
+}
+
+/* Search bar */
+.navbar__search-input {
+ background: var(--ifm-background-surface-color);
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-radius: var(--ifm-global-radius);
+ font-family: 'Inter', sans-serif;
+ font-size: 0.875rem;
+ transition: all 150ms ease;
+}
+
+.navbar__search-input:focus {
+ border-color: var(--ifm-color-primary);
+ box-shadow: 0 0 0 3px rgba(23, 23, 23, 0.1);
+}
+
+[data-theme='dark'] .navbar__search-input:focus {
+ box-shadow: 0 0 0 3px rgba(250, 250, 250, 0.1);
+}
+
+/* Scrollbar */
+::-webkit-scrollbar {
+ width: 10px;
+ height: 10px;
+}
+
+::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--ifm-color-emphasis-200);
+ border-radius: 5px;
+ border: 2px solid var(--ifm-background-color);
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--ifm-color-emphasis-400);
+}
+
+/* TOC (Table of Contents) */
+.table-of-contents {
+ border-left: 1px solid var(--ifm-color-emphasis-200);
+ font-size: 0.875rem;
+}
+
+.table-of-contents__link {
+ color: var(--ifm-font-color-base);
+ transition: all 150ms ease;
+}
+
+.table-of-contents__link--active {
+ color: var(--ifm-heading-color);
+ font-weight: 600;
+}
+
+.table-of-contents__link:hover {
+ color: var(--ifm-heading-color);
+}
+
+/* Footer */
+.footer {
+ background: var(--ifm-background-color);
+ border-top: 1px solid var(--ifm-color-emphasis-200);
+ color: var(--ifm-font-color-secondary);
+ font-size: 0.875rem;
+}
+
+/* Breadcrumbs */
+.breadcrumbs__link {
+ font-size: 0.875rem;
+ font-weight: 500;
+}
+
+/* Tabs */
+.tabs {
+ border-bottom: 1px solid var(--ifm-color-emphasis-200);
+}
+
+.tabs__item {
+ font-weight: 500;
+ border-bottom: 2px solid transparent;
+ transition: all 150ms ease;
+}
+
+.tabs__item--active {
+ border-bottom-color: var(--ifm-color-primary);
+ font-weight: 600;
+}
+
+/* Pagination */
+.pagination-nav__link {
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-radius: var(--ifm-global-radius);
+ transition: all 150ms ease;
+}
+
+.pagination-nav__link:hover {
+ background: var(--ifm-hover-overlay);
+}
+
+/* Card */
+.card {
+ border: 1px solid var(--ifm-color-emphasis-200);
+ box-shadow: none;
+}
+
+/* Theme toggle icon fix */
+html[data-theme='light'] .DocSearch-Button-Placeholder,
+html[data-theme='light'] .clean-btn {
+ color: var(--ifm-font-color-base);
+}
+
+/* Mobile responsiveness */
+@media (max-width: 996px) {
+ h1 {
+ font-size: 1.875rem;
+ }
+
+ h2 {
+ font-size: 1.5rem;
+ }
+}
+
+/* Remove excessive spacing */
+.markdown > h2 {
+ --ifm-h2-vertical-rhythm-top: 2;
+}
+
+/* Clean selection */
+::selection {
+ background: var(--ifm-color-primary);
+ color: var(--ifm-background-color);
+}
+
+/* Focus states for accessibility */
+*:focus-visible {
+ outline: 2px solid var(--ifm-color-primary);
+ outline-offset: 2px;
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 015e174..b7a4cd5 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,13 @@
# FastCast2 (Unofficial)
**An improved version of [FastCast](https://etithespir.it/FastCastAPIDocs/)**
-with **Parallel Luau scripting**, **static typing**, **more extensions**, **built-in object pooling**
+with **Parallel lua scripting**, **static typing**, **more extensions**, **built-in object pooling**
---
**FastCast2** It's a projectiles library powered by [VMsDispatcher](https://github.com/weenachuangkud/VMsDispatcher) meant to **simulate** projectiles without any **physic replication**
-
+
What the benefits of **using** FastCast2 :
@@ -64,7 +64,7 @@ Follow on [FastCast2 devforum](https://devforum.roblox.com/t/fastcast2-an-improv
## Testing
- To test if FastCast2 actually works. Insert a "LocalScript" Inside "StarterCharacterScripts" and paste this code :
-```luau
+```lua
--[[
- Author : Mawin_CK
- Date : 2025
@@ -175,15 +175,15 @@ end)
## Caster Methods
-```luau
+```lua
FastCast.new()
```
Construct a new Caster instance
-
-
+
+
-```luau
+```lua
FastCast:Init(
numWorkers : number,
newParent : Folder,
@@ -204,89 +204,89 @@ Initialize Caster. Allocate the worker amount of `numWorkers`, rename it to `VMn
- useBulkMoveTo: if true, will enable BulkMoveTo to handle CFrame changes for every `ActiveCast.RayInfo.CosmeticBulletObject`. Can be disabled and enabled by `Caster:BindBulkMoveTo(boolean)`
- useObjectCache: if true, will permanently use ObjectCache for Caster
-
-
+
+
-```luau
+```lua
FastCast:SafeCall(f : (...any) -> (...any), ...)
```
Call the passed-in function if it exists
-
-
+
+
-```luau
+```lua
FastCast:BindBulkMoveTo(bool : boolean)
```
Enable or disable `BulkMoveTo` for `Caster`
-
-
+
+
-```luau
+```lua
FastCast:ReturnObject(obj : Instance)
```
Return passed-in `obj` to `ObjectCache`
-
-
+
+
-```luau
+```lua
FastCast:Destroy()
```
Destroy Caster
-
-
+
+
-```luau
+```lua
FastCast:RaycastFire(origin: Vector3, direction: Vector3, velocity: Vector3 | number, BehaviorData: TypeDef.FastCastBehavior?)
```
Create a new `ActiveCast`; it will not work if the `Caster` has not initialized
-
-
+
+
-```luau
+```lua
FastCast:BlockcastFire(origin : Vector3, Size : Vector3, direction : Vector3, velocity : Vector3 | number, BehaviorData: TypeDef.FastCastBehavior?)
```
Create a new `ActiveBlockCast`; it will not work if the `Caster` has not initialized
## Caster Signals
-```luau
+```lua
Caster.RayHit(ActiveCast, RaycastResult, segmentVelocity : Vector3, cosmeticBulletObject : Instance?)
```
Fires every RayHit
-
-
+
+
-```luau
+```lua
Caster.RayPierceFunction(ActiveCast, RaycastResult, segmentVelocity : Vector3, cosmeticBulletObject : Instance?)
```
Fires every RayPierceFunction
-
-
+
+
-```luau
+```lua
Caster.LengthChanged(ActiveCast,lastPoint : Vector3, rayDir : Vector3, rayDisplacement : number, segmentVelocity : Vector3, cosmeticBulletObject : Instance?)
```
Fires every LengthChanged
-
-
+
+
-```luau
+```lua
Caster.CastTerminating(ActiveCast)
```
Fires every CastTerminating
-
-
+
+
-```luau
+```lua
Caster.CastFire(ActiveCast, Origin : Vector3, Direction : Vector3, Velocity : Vector3, behavior : FastCastBehavior)
```
Fires if `ActiveCast` is created successfully before the RunService
diff --git a/docs/intro.md b/docs/intro.md
new file mode 100644
index 0000000..6f375b5
--- /dev/null
+++ b/docs/intro.md
@@ -0,0 +1,17 @@
+---
+sidebar_position: 1
+---
+
+# Introduction
+
+**FastCast2** is a projectile simulation library powered by **VMsDispatcher**, designed to simulate projectiles without relying on physics replication. This approach ensures consistent behavior, improved performance, and reduced network overhead in multiplayer environments.
+
+### Benefits of using FastCast2
+
+* Highly customizable projectile behavior
+* Ability to communicate between the main thread and worker threads, with fine-grained control over execution (at the cost of additional performance overhead when misused)
+* Parallel scripting support for improved scalability
+* Simple and developer-friendly API
+* Support for both raycasting and blockcasting
+* BulkMoveTo integration for efficient cosmetic updates
+* Built-in ObjectCache module to reduce memory allocations
diff --git a/docs/usage.md b/docs/usage.md
new file mode 100644
index 0000000..c2df9ad
--- /dev/null
+++ b/docs/usage.md
@@ -0,0 +1,6 @@
+---
+sidebar_position: 2
+---
+
+# Usage
+For usage, please refer to the [API documentation](/api/FastCast#new)!
\ No newline at end of file
diff --git a/moonwave.toml b/moonwave.toml
new file mode 100644
index 0000000..71a2175
--- /dev/null
+++ b/moonwave.toml
@@ -0,0 +1,20 @@
+title = "FastCast2" # From Git
+gitRepoUrl = "https://github.com/weenachuangkud/FastCast2" # From Git
+
+gitSourceBranch = "main"
+changelog = true
+classOrder = []
+
+[docusaurus]
+onBrokenLinks = "throw"
+onBrokenMarkdownLinks = "warn"
+
+# From git:
+organizationName = "weenachuangkud"
+projectName = "FastCast2"
+url = "https://weenachuangkud.github.io"
+baseUrl = "/FastCast2"
+tagline = "Your project's tagline"
+
+[footer]
+style = "dark"
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..28f127f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,5 @@
+{
+ "dependencies": {
+ "moonwave": "^1.3.0"
+ }
+}
diff --git a/samples/sample1.client.luau b/samples/sample1.client.luau
index c62b3e7..bf1ec3b 100644
--- a/samples/sample1.client.luau
+++ b/samples/sample1.client.luau
@@ -101,7 +101,7 @@ Caster.LengthChanged:Connect(OnLengthChanged)
Caster.CastTerminating:Connect(OnCastTerminating)
Caster.RayHit:Connect(OnRayHit)
---- TEST 1 : Basic Fire
+-- TEST 1 : Basic Fire
--[[UIS.InputBegan:Connect(function(input : InputObject, gp : boolean)
if gp then return end
diff --git a/samples/sample2.client.luau b/samples/sample2.client.luau
index 428ed86..ea5c3ef 100644
--- a/samples/sample2.client.luau
+++ b/samples/sample2.client.luau
@@ -101,7 +101,7 @@ Caster.LengthChanged:Connect(OnLengthChanged)
Caster.CastTerminating:Connect(OnCastTerminating)
Caster.RayHit:Connect(OnRayHit)
---- TEST 1 : Basic Fire
+-- TEST 1 : Basic Fire
UIS.InputBegan:Connect(function(input : InputObject, gp : boolean)
if gp then return end
diff --git a/samples/sample3.client.luau b/samples/sample3.client.luau
index 3c3510b..5549315 100644
--- a/samples/sample3.client.luau
+++ b/samples/sample3.client.luau
@@ -101,7 +101,7 @@ Caster.LengthChanged:Connect(OnLengthChanged)
Caster.CastTerminating:Connect(OnCastTerminating)
Caster.RayHit:Connect(OnRayHit)
---- TEST RESULTS
+-- TEST RESULTS
local targetPos = Vector3.new(0, 5, 0)
diff --git a/samples/sample4.client.luau b/samples/sample4.client.luau
index 9b87526..8887531 100644
--- a/samples/sample4.client.luau
+++ b/samples/sample4.client.luau
@@ -102,7 +102,7 @@ Caster.LengthChanged:Connect(OnLengthChanged)
Caster.CastTerminating:Connect(OnCastTerminating)
Caster.RayHit:Connect(OnRayHit)
---- TEST RESULTS
+-- TEST RESULTS
local targetPos = Vector3.new(0, 5, 0)
diff --git a/samples/sample7.client.luau b/samples/sample7.client.luau
index 5b86447..e4fd11e 100644
--- a/samples/sample7.client.luau
+++ b/samples/sample7.client.luau
@@ -93,7 +93,7 @@ Caster.LengthChanged:Connect(OnLengthChanged)
Caster.CastTerminating:Connect(OnCastTerminating)
Caster.RayHit:Connect(OnRayHit)
---- TEST 1 : Basic Fire
+-- TEST 1 : Basic Fire
UIS.InputBegan:Connect(function(input : InputObject, gp : boolean)
if gp then return end
diff --git a/sourcemap.json b/sourcemap.json
new file mode 100644
index 0000000..6d5e1ca
--- /dev/null
+++ b/sourcemap.json
@@ -0,0 +1 @@
+{"name":"FastCast2","className":"ModuleScript","filePaths":["src/FastCast2/init.luau","default.project.json"],"children":[{"name":"ActiveBlockcast","className":"ModuleScript","filePaths":["src/FastCast2/ActiveBlockcast.luau"]},{"name":"ActiveCast","className":"ModuleScript","filePaths":["src/FastCast2/ActiveCast.luau"]},{"name":"BaseCast","className":"ModuleScript","filePaths":["src/FastCast2/BaseCast.luau"]},{"name":"Configs","className":"ModuleScript","filePaths":["src/FastCast2/Configs.luau"]},{"name":"DefaultConfigs","className":"ModuleScript","filePaths":["src/FastCast2/DefaultConfigs.luau"]},{"name":"FastCastEnums","className":"ModuleScript","filePaths":["src/FastCast2/FastCastEnums.luau"]},{"name":"ObjectCache","className":"ModuleScript","filePaths":["src/FastCast2/ObjectCache.luau"]},{"name":"Signal","className":"ModuleScript","filePaths":["src/FastCast2/Signal.luau"]},{"name":"TypeDefinitions","className":"ModuleScript","filePaths":["src/FastCast2/TypeDefinitions.luau"]},{"name":"FastCastVMs","className":"ModuleScript","filePaths":["src/FastCast2/FastCastVMs/init.luau"],"children":[{"name":"ClientVM","className":"LocalScript","filePaths":["src/FastCast2/FastCastVMs/ClientVM.client.luau","src/FastCast2/FastCastVMs/ClientVM.meta.json"]},{"name":"ServerVM","className":"Script","filePaths":["src/FastCast2/FastCastVMs/ServerVM.server.luau","src/FastCast2/FastCastVMs/ServerVM.meta.json"]}]}]}
\ No newline at end of file
diff --git a/src/FastCast2/ActiveBlockcast.luau b/src/FastCast2/ActiveBlockcast.luau
index 1ebb4aa..7562ed2 100644
--- a/src/FastCast2/ActiveBlockcast.luau
+++ b/src/FastCast2/ActiveBlockcast.luau
@@ -12,17 +12,10 @@ local RS = game:GetService("RunService")
local FastCastModule = script.Parent
-- Requires
---local UtilityModule = FastCastModule:WaitForChild("Utility")
-
-local FastCastEnums = require(FastCastModule:WaitForChild("FastCastEnums"))
---local Utility = require(UtilityModule)
local TypeDef = require(FastCastModule:WaitForChild("TypeDefinitions"))
-local ErrorMsgs = require(script.Parent:WaitForChild("ErrorMessage"))
---local MathUtil = require(UtilityModule.Math)
local Configs = require(FastCastModule:WaitForChild("Configs"))
local DebugLogging = Configs.DebugLogging
local FastCastEnums = require(FastCastModule:WaitForChild("FastCastEnums"))
---local LookUpTables = require(FastCastModule:WaitForChild("LookUpTables"))
-- CONSTs
local MAX_PIERCE_TEST_COUNT = 100
@@ -41,24 +34,22 @@ local DBG_HIT_SUB_COLOR = Color3.new(0.0588235, 0.87451, 1)
local DBG_RAYPIERCE_SUB_COLOR = Color3.new(1, 0.113725, 0.588235)
local DBG_RAYPIERCE_SEGMENT_COLOR = Color3.new(0.305882, 0.243137, 0.329412)
---local DBG_SEGMENT_COLOR = Color3.new(1, 0.666667, 0)
---local DBG_HIT_COLOR = Color3.new(0.2, 1, 0.5)
---local DBG_RAYPIERCE_COLOR = Color3.new(1, 0.2, 0.2)
-
---local DBG_RAY_LIFETIME = 1
---local DBG_HIT_LIFETIME = 1 lmao
-
-- AutomaticPerformance setting
local HIGH_FIDE_INCREASE_SIZE = 0.5
---- ActiveCast
+--[=[
+ @class ActiveBlockCast
+
+ An ActiveBlockCast represents a BlockCast fired by a parent [Caster](Caster). It contains methods of accessing the physics
+ data of this specific BlockCast at any given time, as well as methods to alter its trajectory during runtime.
+]=]
local ActiveCast = {}
ActiveCast.__index = ActiveCast
ActiveCast.__type = "ActiveBlockCast"
------> Local functions
+-- Local Functions
local function DebrisAdd(obj : Instance, Lifetime : number)
if not obj then return end
@@ -104,7 +95,7 @@ local function GetTrajectoryInfo(
cast: TypeDef.ActiveCast | TypeDef.ActiveBlockCast,
index: number
): {[number]: Vector3}
- assert(cast.StateInfo.UpdateConnection ~= nil, ErrorMsgs.ERR_OBJECT_DISPOSED)
+ assert(cast.StateInfo.UpdateConnection ~= nil, "ERR_OBJECT_DISPOSED")
local trajectories = cast.StateInfo.Trajectories
local trajectory = trajectories[index]
local duration = trajectory.EndTime - trajectory.StartTime
@@ -120,13 +111,7 @@ local function GetLatestTrajectoryEndInfo(cast: TypeDef.ActiveCast | TypeDef.Act
return GetTrajectoryInfo(cast, #cast.StateInfo.Trajectories)
end
----> Debugging
-
---[[local function PrintDebug(message : string)
- if Configs.DebugLogging then
- print(message)
- end
-end]]
+-- Debug Functions
local function DbgVisualizeSegment(castStartCFrame: CFrame, size : Vector3, castLength: number, VisualizeCasts : boolean, VisualizeCastSetting : TypeDef.VisualizeCastSettings) : BoxHandleAdornment?
if not VisualizeCasts then return end
@@ -159,7 +144,7 @@ local function DbgVisualizeHit(atCF: CFrame, wasPierce: boolean, VisualizeCasts
return adornment
end
----> Send signals
+-- Send signals
local function SendRayHit(
cast : TypeDef.ActiveBlockCast,
@@ -243,7 +228,7 @@ local function SimulateCast(
delta : number,
expectingShortCall : boolean
)
- assert(cast.StateInfo.UpdateConnection ~= nil, ErrorMsgs.ERR_OBJECT_DISPOSED)
+ assert(cast.StateInfo.UpdateConnection ~= nil, "ERR_OBJECT_DISPOSED")
if DebugLogging.Casting then
print("Casting for frame.")
@@ -494,7 +479,29 @@ local function SimulateCast(
end
end
----> ActiveCast functions
+--[=[
+ @function new
+ @within ActiveBlockCast
+
+ Creates a new ActiveBlockCast instance with the given parameters.
+ This is the fancy part where numbers and vectors start cooperating.
+
+ @param BaseCast TypeDef.BaseCastData -- The base cast data used to initialize the active cast.
+
+ @param activeCastID string -- Unique identifier for this active cast.
+
+ @param origin Vector3 -- The starting position of the cast.
+
+ @param size Vector3 -- The size of the cast volume.
+
+ @param direction Vector3 -- The direction the cast will travel in.
+
+ @param velocity Vector3 | number -- The velocity of the cast (either directional or scalar).
+
+ @param behavior TypeDef.FastCastBehavior -- The FastCast behavior configuration.
+
+ @return TypeDef.ActiveCast -- The newly created ActiveCast instance.
+]=]
function ActiveCast.new(
BaseCast : TypeDef.BaseCastData,
@@ -562,17 +569,13 @@ function ActiveCast.new(
ID = activeCastID
}
- --[[if cast.StateInfo.HighFidelityBehavior == 2 then
- cast.StateInfo.HighFidelityBehavior = 3
- end]]
-
if cast.RayInfo.Parameters ~= nil then
cast.RayInfo.Parameters = CloneCastParams(cast.RayInfo.Parameters)
else
cast.RayInfo.Parameters = RaycastParams.new()
end
- ---> CosmeticBulletObject GET
+ -- CosmeticBulletObject GET
local targetContainer: Instance;
if cast.Caster.ObjectCache then
@@ -580,6 +583,7 @@ function ActiveCast.new(
warn("ObjectCache already handle that for you, Template Dupe")
end
-- 1 kebab please
+ -- i love my kebabs - darwin
cast.RayInfo.CosmeticBulletObject = cast.Caster.ObjectCache:Invoke(CFrame.new(origin, origin + direction))
targetContainer = cast.Caster.CacheHolder
else
@@ -617,7 +621,7 @@ function ActiveCast.new(
end
end
- ---> CosmeticBulletObject Container GET
+ -- CosmeticBulletObject Container GET
local targetContainer: Instance;
local LIB_GETCONTAINER = LookUpTables.Supported_Lib_GETCONTAINER[typeof(behavior.CosmeticBulletProvider)]
@@ -805,146 +809,235 @@ local function ModifyTransformation(cast: TypeDef.ActiveBlockCast, velocity: Vec
end
--- same as ActiveCast:Terminate()
+--[=[
+
+Destroys an ActiveBlockCast, terminating it's simulation, firing the CastTerminating event, and cleaning up resources.
+This is the equivilant of calling `ActiveBlockCast:Terminate()`.
+
+@method Destroy
+@within ActiveBlockCast
+
+]=]
function ActiveCast:Destroy()
ActiveCast:Terminate()
end
-----> SET
+--[=[
+Sets the velocity of an ActiveBlockCast to the specified Vector3.
+
+@method SetVelocity
+@param velocity Vector3 -- The new velocity to set.
+@within ActiveBlockCast
+
+]=]
function ActiveCast:SetVelocity(velocity : Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("SetVelocity", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
ModifyTransformation(self, velocity, nil, nil)
end
+--[=[
+
+Sets the acceleration of an ActiveBlockCast to the specified Vector3.
+
+@method SetAcceleration
+@param acceleration Vector3 -- The new acceleration to set.
+@within ActiveBlockCast
+]=]
function ActiveCast:SetAcceleration(acceleration: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("SetAcceleration", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
ModifyTransformation(self, nil, acceleration, nil)
end
----> GET
+--[=[
+
+Gets the velocity of an ActiveBlockCast.
+@method GetVelocity
+@within ActiveBlockCast
+@return Vector3 -- The current velocity of the ActiveBlockCast.
+]=]
function ActiveCast:GetVelocity() : Vector3
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("GetVelocity", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
local currentTrajectory = self.StateInfo.Trajectories[#self.StateInfo.Trajectories]
return GetVelocityAtTime(self.StateInfo.TotalRuntime - currentTrajectory.StartTime, currentTrajectory.InitialVelocity, currentTrajectory.Acceleration)
end
+--[=[
+
+Gets the acceleration of an ActiveBlockCast.
+
+@method GetAcceleration
+@within ActiveBlockCast
+@return Vector3 -- The current acceleration of the ActiveBlockCast.
+]=]
function ActiveCast:GetAcceleration(): Vector3
assert(getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("GetAcceleration", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
local currentTrajectory = self.StateInfo.Trajectories[#self.StateInfo.Trajectories]
return currentTrajectory.Acceleration
end
+--[=[
+
+Gets the position of an ActiveBlockCast.
+
+@method GetPosition
+@within ActiveBlockCast
+@return Vector3 -- The current position of the ActiveBlockCast.
+]=]
function ActiveCast:GetPosition(): Vector3
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("GetPosition", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
local currentTrajectory = self.StateInfo.Trajectories[#self.StateInfo.Trajectories]
return GetPositionAtTime(self.StateInfo.TotalRuntime - currentTrajectory.StartTime, currentTrajectory.Origin, currentTrajectory.InitialVelocity, currentTrajectory.Acceleration)
end
----> Add
+--[=[
+Add velocity to an ActiveBlockCast with the specified Vector3.
+
+@method AddVelocity
+@param velocity Vector3 -- The new velocity to add.
+@within ActiveBlockCast
+]=]
function ActiveCast:AddVelocity(velocity: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("AddVelocity", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self:SetVelocity(self:GetVelocity() + velocity)
end
+--[=[
+
+Add acceleration to an ActiveBlockCast with the specified Vector3.
+
+@method AddAcceleration
+@param acceleration Vector3 -- The new acceleration to add.
+@within ActiveBlockCast
+]=]
function ActiveCast:AddAcceleration(acceleration: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("AddAcceleration", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self:SetAcceleration(self:GetAcceleration() + acceleration)
end
+--[=[
+
+Add position to an ActiveBlockCast with the specified Vector3.
+
+@method AddPosition
+@param position Vector3 -- The new position to add.
+@within ActiveBlockCast
+]=]
function ActiveCast:AddPosition(position: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("AddPosition", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self:SetPosition(self:GetPosition() + position)
end
----> Others
+--[=[
+
+Pauses simulation for an ActiveBlockCast.
+
+@method Pause
+@within ActiveBlockCast
+]=]
function ActiveCast:Pause()
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("Pause", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self.StateInfo.Paused = true
end
+--[=[
+
+Resumes simulation for an ActiveBlockCast if it was paused previously.
+
+@method Resume
+@within ActiveBlockCast
+
+]=]
function ActiveCast:Resume()
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("Resume", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self.StateInfo.Paused = false
end
+--[=[
+
+Terminates an ActiveBlockCast, firing the CastTerminating event, and cleaning up resources.
+This is the equivilant of calling `Active:Destroy()`.
+
+@method Resume
+@within ActiveBlockCast
+]=]
function ActiveCast:Terminate()
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("Terminate", "ActiveCast.new(...)"))
- assert(self.StateInfo.UpdateConnection ~= nil, ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_NOT_INSTANCE")
+ assert(self.StateInfo.UpdateConnection ~= nil, "ERR_OBJECT_DISPOSED"
)
diff --git a/src/FastCast2/ActiveCast.luau b/src/FastCast2/ActiveCast.luau
index 9f4c0c5..d766b5e 100644
--- a/src/FastCast2/ActiveCast.luau
+++ b/src/FastCast2/ActiveCast.luau
@@ -16,7 +16,6 @@ local FastCastModule = script.Parent
-- Dependencies
local TypeDef = require(FastCastModule:WaitForChild("TypeDefinitions"))
-local ErrorMsgs = require(FastCastModule:WaitForChild("ErrorMessage"))
local Configs = require(FastCastModule:WaitForChild("Configs"))
local DebugLogging = Configs.DebugLogging
local FastCastEnums = require(FastCastModule:WaitForChild("FastCastEnums"))
@@ -40,14 +39,19 @@ local DBG_RAYPIERCE_SUB_COLOR = Color3.new(1, 0.113725, 0.588235)
-- Automatic Performance setting
local HIGH_FIDE_INCREASE_SIZE = 0.5
---- ActiveCast
+--[=[
+ @class ActiveCast
+
+ An ActiveCast represents a bullet fired by a parent [Caster](Caster). It contains methods of accessing the physics
+ data of this specific bullet at any given time, as well as methods to alter its trajectory during runtime.
+]=]
local ActiveCast = {}
ActiveCast.__index = ActiveCast
ActiveCast.__type = "ActiveCast"
------> Local functions
+-- Local functions
local function DebrisAdd(obj : Instance, Lifetime : number)
if not obj then return end
@@ -93,7 +97,7 @@ local function GetTrajectoryInfo(
cast: TypeDef.ActiveCast | TypeDef.ActiveBlockCast,
index: number
): {[number]: Vector3}
- assert(cast.StateInfo.UpdateConnection ~= nil, ErrorMsgs.ERR_OBJECT_DISPOSED)
+ assert(cast.StateInfo.UpdateConnection ~= nil, "ERR_OBJECT_DISPOSED")
local trajectories = cast.StateInfo.Trajectories
local trajectory = trajectories[index]
local duration = trajectory.EndTime - trajectory.StartTime
@@ -109,7 +113,7 @@ local function GetLatestTrajectoryEndInfo(cast: TypeDef.ActiveCast | TypeDef.Act
return GetTrajectoryInfo(cast, #cast.StateInfo.Trajectories)
end
----> Debugging
+-- Debugging
--[[local function PrintDebug(message : string)
if Configs.DebugLogging then
@@ -147,7 +151,7 @@ local function DbgVisualizeHit(atCF: CFrame, wasPierce: boolean, VisualizeCasts
return adornment
end
----> Send signals
+-- Send signals
local function SendRayHit(
cast : TypeDef.ActiveCast,
@@ -231,7 +235,7 @@ local function SimulateCast(
delta : number,
expectingShortCall : boolean
)
- assert(cast.StateInfo.UpdateConnection ~= nil, ErrorMsgs.ERR_OBJECT_DISPOSED)
+ assert(cast.StateInfo.UpdateConnection ~= nil, "ERR_OBJECT_DISPOSED")
--PrintDebug("Casting for frame.")
--print("1C")
@@ -504,7 +508,28 @@ local function SimulateCast(
end
end
----> ActiveCast functions
+--[=[
+ @function new
+ @private
+ @within ActiveCast
+
+ Creates a new ActiveCast instance with the given parameters.
+ Don't use this method! Instead, use [Caster:RaycastFire()](TypeDefinitions#Caster) to create ActiveCasts.
+
+ @param BaseCast TypeDef.BaseCastData -- The base cast data used to initialize the active cast.
+
+ @param activeCastID string -- Unique identifier for this active cast.
+
+ @param origin Vector3 -- The starting position of the cast.
+
+ @param direction Vector3 -- The direction the cast will travel in.
+
+ @param velocity Vector3 | number -- The velocity of the cast (either directional or scalar).
+
+ @param behavior TypeDef.FastCastBehavior -- The FastCast behavior configuration.
+
+ @return ActiveCast -- The newly created ActiveCast instance.
+]=]
function ActiveCast.new(
BaseCast : TypeDef.BaseCastData,
@@ -582,7 +607,7 @@ function ActiveCast.new(
cast.RayInfo.Parameters = RaycastParams.new()
end
- ---> CosmeticBulletObject GET
+ -- CosmeticBulletObject GET
local targetContainer: Instance;
if cast.Caster.ObjectCache then
@@ -627,7 +652,7 @@ function ActiveCast.new(
end
end
- ---> CosmeticBulletObject Container GET
+ -- CosmeticBulletObject Container GET
local targetContainer: Instance;
local LIB_GETCONTAINER = LookUpTables.Supported_Lib_GETCONTAINER[typeof(behavior.CosmeticBulletProvider)] or LookUpTables.Supported_Lib_GETCONTAINER[behavior.CosmeticBulletProvider.Type]
@@ -825,146 +850,241 @@ local function ModifyTransformation(cast: TypeDef.ActiveCast, velocity: Vector3?
end
--- same as ActiveCast:Terminate()
+--[=[
+
+Destroys an ActiveCast, terminating it's simulation, firing the CastTerminating event, and cleaning up resources.
+This is the equivilant of calling `ActiveCast:Terminate()`.
+
+@method Destroy
+@within ActiveCast
+
+]=]
function ActiveCast:Destroy()
ActiveCast:Terminate()
end
-----> SET
+--[=[
+
+Sets the velocity of an ActiveCast to the specified Vector3.
+
+@method SetVelocity
+@param velocity Vector3 -- The new velocity to set.
+@within ActiveCast
+]=]
function ActiveCast:SetVelocity(velocity : Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("SetVelocity", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
ModifyTransformation(self, velocity, nil, nil)
end
+--[=[
+
+Sets the acceleration of an ActiveCast to the specified Vector3.
+
+@method SetAcceleration
+@param acceleration Vector3 -- The new acceleration to set.
+@within ActiveCast
+
+]=]
function ActiveCast:SetAcceleration(acceleration: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("SetAcceleration", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
ModifyTransformation(self, nil, acceleration, nil)
end
----> GET
+--[=[
+Gets the velocity of an ActiveCast.
+
+@method GetVelocity
+@within ActiveCast
+@return Vector3 -- The current velocity of the ActiveCast.
+]=]
function ActiveCast:GetVelocity() : Vector3
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("GetVelocity", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
local currentTrajectory = self.StateInfo.Trajectories[#self.StateInfo.Trajectories]
return GetVelocityAtTime(self.StateInfo.TotalRuntime - currentTrajectory.StartTime, currentTrajectory.InitialVelocity, currentTrajectory.Acceleration)
end
+--[=[
+
+Gets the acceleration of an ActiveCast.
+
+@method GetAcceleration
+@within ActiveCast
+@return Vector3 -- The current acceleration of the ActiveCast.
+
+]=]
function ActiveCast:GetAcceleration(): Vector3
assert(getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("GetAcceleration", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
local currentTrajectory = self.StateInfo.Trajectories[#self.StateInfo.Trajectories]
return currentTrajectory.Acceleration
end
+--[=[
+
+Gets the position of an ActiveCast.
+
+@method GetPosition
+@within ActiveCast
+@return Vector3 -- The current position of the ActiveCast.
+]=]
function ActiveCast:GetPosition(): Vector3
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("GetPosition", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
local currentTrajectory = self.StateInfo.Trajectories[#self.StateInfo.Trajectories]
return GetPositionAtTime(self.StateInfo.TotalRuntime - currentTrajectory.StartTime, currentTrajectory.Origin, currentTrajectory.InitialVelocity, currentTrajectory.Acceleration)
end
----> Add
+--[=[
+
+Add velocity to an ActiveCast with the specified Vector3.
+@method AddVelocity
+@param velocity Vector3 -- The new velocity to add.
+@within ActiveCast
+
+]=]
function ActiveCast:AddVelocity(velocity: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("AddVelocity", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self:SetVelocity(self:GetVelocity() + velocity)
end
+--[=[
+
+Add acceleration to an ActiveCast with the specified Vector3.
+
+@method AddAcceleration
+@param acceleration Vector3 -- The new acceleration to add.
+@within ActiveCast
+
+]=]
function ActiveCast:AddAcceleration(acceleration: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("AddAcceleration", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self:SetAcceleration(self:GetAcceleration() + acceleration)
end
+--[=[
+
+Add position to an ActiveCast with the specified Vector3.
+
+@method AddPosition
+@param position Vector3 -- The new position to add.
+@within ActiveCast
+
+]=]
function ActiveCast:AddPosition(position: Vector3)
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("AddPosition", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self:SetPosition(self:GetPosition() + position)
end
----> Others
+--[=[
+
+Pauses simulation for an ActiveCast.
+@method Pause
+@within ActiveCast
+
+]=]
function ActiveCast:Pause()
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("Pause", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self.StateInfo.Paused = true
end
+--[=[
+
+Resumes simulation for an ActiveCast if it was paused previously.
+
+@method Resume
+@within ActiveCast
+
+]=]
function ActiveCast:Resume()
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("Resume", "ActiveCast.new(...)")
+ "ERR_NOT_INSTANCE"
)
assert(
self.StateInfo.UpdateConnection ~= nil,
- ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_OBJECT_DISPOSED"
)
self.StateInfo.Paused = false
end
+--[=[
+
+Terminates an ActiveCast, firing the CastTerminating event, and cleaning up resources.
+This is the equivilant of calling `Active:Destroy()`.
+
+@method Resume
+@within ActiveCast
+
+]=]
function ActiveCast:Terminate()
assert(
getmetatable(self) == ActiveCast,
- ErrorMsgs.ERR_NOT_INSTANCE:format("Terminate", "ActiveCast.new(...)"))
- assert(self.StateInfo.UpdateConnection ~= nil, ErrorMsgs.ERR_OBJECT_DISPOSED
+ "ERR_NOT_INSTANCE")
+ assert(self.StateInfo.UpdateConnection ~= nil, "ERR_OBJECT_DISPOSED"
)
diff --git a/src/FastCast2/BaseCast.luau b/src/FastCast2/BaseCast.luau
index 0034271..4704735 100644
--- a/src/FastCast2/BaseCast.luau
+++ b/src/FastCast2/BaseCast.luau
@@ -24,7 +24,7 @@ BaseCast.__type = "BaseCast"
-- Connections
local BulkMoveToConnection : RBXScriptConnection = nil
---- Variables
+-- Variables
-- Because each different threads have different BaseCast haha
local Actives = {}
local Actor = nil
@@ -101,12 +101,13 @@ function BaseCast:Raycast(
Origin : Vector3,
Direction : Vector3,
Velocity : Vector3 | number,
- Behavior : TypeDef.FastCastBehavior
+ Behavior : TypeDef.FastCastBehavior,
+ GUID: string
)
--table.insert(self.Actives, ActiveCast.new(self, Origin, Direction, Velocity, Behavior))
Actor:SetAttribute("Tasks", Actor:GetAttribute("Tasks")+1)
- local activeCastID = HTTPS:GenerateGUID(false)
+ local activeCastID = GUID
Actives[activeCastID] = ActiveCast.new({
Output = Output,
ActiveCastCleaner = ActiveCastCleaner,
@@ -119,11 +120,12 @@ function BaseCast:Blockcast(
Size : Vector3,
Direction : Vector3,
Velocity : Vector3 | number,
- Behavior : TypeDef.FastCastBehavior
+ Behavior : TypeDef.FastCastBehavior,
+ GUID : string
)
Actor:SetAttribute("Tasks", Actor:GetAttribute("Tasks")+1)
- local activeCastID = HTTPS:GenerateGUID(false)
+ local activeCastID = GUID
Actives[activeCastID] = ActiveBlockcast.new({
Output = Output,
ActiveCastCleaner = ActiveCastCleaner,
diff --git a/src/FastCast2/DefaultConfigs.luau b/src/FastCast2/DefaultConfigs.luau
index a66883d..f1916cc 100644
--- a/src/FastCast2/DefaultConfigs.luau
+++ b/src/FastCast2/DefaultConfigs.luau
@@ -14,7 +14,7 @@ local FastCastEnums = require(script.Parent:WaitForChild("FastCastEnums"))
local Defaults = {}
----> Configs
+-- Configs
Defaults.VisualizationFolderName = "FastCastVisualizationObjects"
diff --git a/src/FastCast2/FastCastEnums.luau b/src/FastCast2/FastCastEnums.luau
index 9f76d95..c4c6318 100644
--- a/src/FastCast2/FastCastEnums.luau
+++ b/src/FastCast2/FastCastEnums.luau
@@ -6,8 +6,23 @@
--!strict
+--[=[
+
+@class FastCastEnums
+Enums for FastCast2.
+
+]=]
+
local Enums = {}
+
+--[=[
+
+How High-Fidelity the cast simulation should be.
+@type HighFidelityBehavior {Default, Automatic, Always}
+@within FastCastEnums
+
+]=]
Enums.HighFidelityBehavior = {
Default = 1,
Automatic = 2,
diff --git a/src/FastCast2/FastCastVMs/ClientVM.client.luau b/src/FastCast2/FastCastVMs/ClientVM.client.luau
index 3710913..6296fdd 100644
--- a/src/FastCast2/FastCastVMs/ClientVM.client.luau
+++ b/src/FastCast2/FastCastVMs/ClientVM.client.luau
@@ -3,12 +3,10 @@
- Date : 11/03/2025
]]
--- Services
-local Rep = game:GetService("ReplicatedStorage")
-
-- Modules
-- REPLACE WITH ACTUAL PATH
+local Rep = game:GetService("ReplicatedStorage")
local FastCast2Module = Rep:WaitForChild("FastCast2")
-- Requires
@@ -41,13 +39,14 @@ actor:BindToMessage("Raycast", function(
origin : Vector3,
direction : Vector3,
velocity : Vector3 | number,
- behavior : TypeDef.FastCastBehavior
+ behavior : TypeDef.FastCastBehavior,
+ guid : string
)
--print(behavior)
--print(SharedCasters[casterID])
--StoredCasts[casterID][ID] = ActiveCast.new(bindableEvent, origin, direction, velocity, behavior)
- BaseCast:Raycast(origin, direction, velocity, behavior)
+ BaseCast:Raycast(origin, direction, velocity, behavior, guid)
end)
--[[actor:BindToMessage("Blockcast", function(
@@ -68,13 +67,11 @@ actor:BindToMessage("Blockcast", function(
size : Vector3,
direction : Vector3,
velocity : Vector3 | number,
- behavior : TypeDef.FastCastBehavior
+ behavior : TypeDef.FastCastBehavior,
+ GUID : string
)
- --print(behavior)
- --print(SharedCasters[casterID])
- --StoredCasts[casterID][ID] = ActiveCast.new(bindableEvent, origin, direction, velocity, behavior)
- BaseCast:Blockcast(origin, size, direction, velocity, behavior)
+ BaseCast:Blockcast(origin, size, direction, velocity, behavior, GUID)
end)
actor:BindToMessage("BindBulkMoveTo", function(bool : boolean)
diff --git a/src/FastCast2/FastCastVMs/ClientVM.meta.json b/src/FastCast2/FastCastVMs/ClientVM.meta.json
new file mode 100644
index 0000000..54f4692
--- /dev/null
+++ b/src/FastCast2/FastCastVMs/ClientVM.meta.json
@@ -0,0 +1,5 @@
+{
+ "properties": {
+ "Disabled": true
+ }
+}
\ No newline at end of file
diff --git a/src/FastCast2/FastCastVMs/ServerVM.meta.json b/src/FastCast2/FastCastVMs/ServerVM.meta.json
new file mode 100644
index 0000000..54f4692
--- /dev/null
+++ b/src/FastCast2/FastCastVMs/ServerVM.meta.json
@@ -0,0 +1,5 @@
+{
+ "properties": {
+ "Disabled": true
+ }
+}
\ No newline at end of file
diff --git a/src/FastCast2/FastCastVMs/ServerVM.server.luau b/src/FastCast2/FastCastVMs/ServerVM.server.luau
index 725a614..f8c92b4 100644
--- a/src/FastCast2/FastCastVMs/ServerVM.server.luau
+++ b/src/FastCast2/FastCastVMs/ServerVM.server.luau
@@ -3,19 +3,12 @@
- Date : 11/03/2025
]]
--- Services
-local Rep = game:GetService("ReplicatedStorage")
-
-- Modules
-- REPLACE WITH ACTUAL PATH
+local Rep = game:GetService("ReplicatedStorage")
local FastCast2Module = Rep:WaitForChild("FastCast2")
--- Requires
-
-local ActiveCast = require(FastCast2Module:WaitForChild("ActiveCast"))
-local ActiveBlockcast = require(FastCast2Module:WaitForChild("ActiveBlockcast"))
-
local TypeDef = require(FastCast2Module:WaitForChild("TypeDefinitions"))
--local SharedCasters = require(FastCast2Module:WaitForChild("SharedCasters"))
@@ -41,13 +34,14 @@ actor:BindToMessage("Raycast", function(
origin : Vector3,
direction : Vector3,
velocity : Vector3 | number,
- behavior : TypeDef.FastCastBehavior
+ behavior : TypeDef.FastCastBehavior,
+ guid : string
)
--print(behavior)
--print(SharedCasters[casterID])
--StoredCasts[casterID][ID] = ActiveCast.new(bindableEvent, origin, direction, velocity, behavior)
- BaseCast:Raycast(origin, direction, velocity, behavior)
+ BaseCast:Raycast(origin, direction, velocity, behavior, guid)
end)
--[[actor:BindToMessage("Blockcast", function(
diff --git a/src/FastCast2/FastCastVMs/init.luau b/src/FastCast2/FastCastVMs/init.luau
index 2e2d4b6..0037e7c 100644
--- a/src/FastCast2/FastCastVMs/init.luau
+++ b/src/FastCast2/FastCastVMs/init.luau
@@ -7,15 +7,15 @@
-- Modded by Mawin_CK
-- Desc : I make it more customizable and more easy to use :P
----- Services ----
+-- Services --
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")
----- Imports ----
+-- Imports --
----- Settings ----
+-- Settings --
local IS_SERVER = RunService:IsServer()
@@ -57,7 +57,7 @@ local Server = true
local UseBindableEvent = true
----- Constants ----
+-- Constants --
local Dispatcher = {}
Dispatcher.__index = Dispatcher
@@ -70,15 +70,15 @@ local ControllerName = ""
local ContainerName = ""
local ContainerParent = (IS_SERVER and ServerContainerParent or ClientContainerParent)
----- Variables ----
+-- Variables --
local AlreadyInit = false
----- Private Functions ----
+-- Private Functions --
----- Public Functions ----
+-- Public Functions --
--[[
@@ -97,7 +97,7 @@ function Dispatcher.Init(ContainerParent : Instance, VMContainerName : string, V if IS_SERVER and not Server or not Client then return end if AlreadyInit then return end - ---> Init + -- Init local Actor = Instance.new("Actor") Actor:SetAttribute("Tasks", 0) @@ -115,14 +115,14 @@ function Dispatcher.Init(ContainerParent : Instance, VMContainerName : string, V Controller = LocalScript and LocalScript:Clone() end - ---> Setup + -- Setup ControllerName = VMname ContainerName = VMContainerName ContainerParent = ContainerParent - ---> Start + -- Start assert(Controller, "Controller script not found or not valid") diff --git a/src/FastCast2/ObjectCache.luau b/src/FastCast2/ObjectCache.luau index 0fc8275..991fe85 100644 --- a/src/FastCast2/ObjectCache.luau +++ b/src/FastCast2/ObjectCache.luau @@ -2,6 +2,16 @@ - Modded By Mawin_CK Desc : i added __type = "ObjectCache" to letting FastCast Recongize that this is ObjectCache ]] + +--[=[ + +@class ObjectCache +ObjectCache usage should be derived from their DevForum post: + +https://devforum.roblox.com/t/objectcache-a-modern-blazing-fast-model-and-part-cache/3104112 + +]=] + --!strict --!native local HTTPS = game:GetService("HttpService") diff --git a/src/FastCast2/TypeDefinitions.luau b/src/FastCast2/TypeDefinitions.luau index c173eae..bfeff34 100644 --- a/src/FastCast2/TypeDefinitions.luau +++ b/src/FastCast2/TypeDefinitions.luau @@ -1,34 +1,89 @@ +--!strict + --[[ - Author : Mawin CK - Date : 2025 -- Verison : 0.0.4 ]] ---!strict +--[=[ + @class TypeDefinitions + @tag Types + + Type definitions for strict-typing. +]=] --- Requires local Dispatcher = require(script.Parent:WaitForChild("FastCastVMs")) --- Represents the function to determine piercing. +--[=[ + @type CanPierceFunction (ActiveCast, RaycastResult, Vector3) -> boolean + @within TypeDefinitions + + Callback used to decide whether a cast should pierce and continue after a hit. +]=] export type CanPierceFunction = (ActiveCast, RaycastResult, Vector3) -> boolean +--[=[ + @type OnRayHitFunction (ActiveCast, RaycastResult, Vector3, Instance?) -> () + @within TypeDefinitions + + Callback fired when the cast hits something (non-piercing). +]=] export type OnRayHitFunction = (ActiveCast, RaycastResult, segmentVelocity : Vector3, cosmeticBulletObject : Instance?) -> () + +--[=[ + @type OnRayPierceFunction (ActiveCast, RaycastResult, Vector3, Instance?) -> () + @within TypeDefinitions + + Callback fired when the cast pierces something. +]=] export type OnRayPierceFunction = (ActiveCast, RaycastResult, segmentVelocity : Vector3, cosmeticBulletObject : Instance?) -> () + +--[=[ + @type OnLengthChangedFunction (ActiveCast, Vector3, Vector3, number, Vector3, Instance?) -> () + @within TypeDefinitions + + Callback fired when the cast's length changes as it updates. +]=] export type OnLengthChangedFunction = ( - ActiveCast, - lastPoint : Vector3, - rayDir : Vector3, - rayDisplacement : number, - segmentVelocity : Vector3, + ActiveCast, + lastPoint : Vector3, + rayDir : Vector3, + rayDisplacement : number, + segmentVelocity : Vector3, cosmeticBulletObject : Instance? ) -> () + +--[=[ + @type OnCastTerminatingFunction (ActiveCast) -> () + @within TypeDefinitions + + Callback fired right as an ActiveCast is terminating. +]=] export type OnCastTerminatingFunction = (ActiveCast) -> () + +--[=[ + @type OnCastFireFunction (ActiveCast, Vector3, Vector3, Vector3, FastCastBehavior) -> () + @within TypeDefinitions + + Callback fired when a cast is initially fired. +]=] export type OnCastFireFunction = (ActiveCast, Origin : Vector3, Direction : Vector3, Velocity : Vector3, behavior : FastCastBehavior) -> () --- Represents any table. +--[=[ + @type GenericTable {[any]: any} + @within TypeDefinitions + + Represents any table. +]=] export type GenericTable = {[any]: any} --- Represents a Caster :: https://etithespirit.github.io/FastCastAPIDocs/fastcast-objects/caster/ +--[=[ + @type Caster { WorldRoot: WorldRoot, LengthChanged: RBXScriptSignal, RayHit: RBXScriptSignal, RayPierced: RBXScriptSignal, CastTerminating: RBXScriptSignal, CastFire: RBXScriptSignal, Dispatcher: Dispatcher.Dispatcher, AlreadyInit: boolean, Init: (Caster, number, Folder, string, Folder, string, string, boolean, boolean, BasePart | Model, number, Instance) -> (), RaycastFire: (Caster, Vector3, Vector3, Vector3 | number, FastCastBehavior) -> string, BlockcastFire: (Caster, Vector3, Vector3, Vector3, Vector3 | number, FastCastBehavior) -> string, SetBulkMoveEnabled: (boolean) -> (), SetObjectCacheEnabled: (boolean, BasePart | Model, number, Instance) -> (), SetVisualizeCasts: (boolean) -> (), ReturnObject: (Instance) -> (), Destroy: (Caster) -> () } + @within TypeDefinitions + + Represents a Caster. +]=] export type Caster = { WorldRoot: WorldRoot, LengthChanged: RBXScriptSignal, @@ -39,14 +94,14 @@ export type Caster = { Dispatcher : Dispatcher.Dispatcher, AlreadyInit : boolean, --id : string, - + Init : ( - Caster, - numWorkers : number, - newParent : Folder, + Caster, + numWorkers : number, + newParent : Folder, newName : string, ContainerParent : Folder, - VMContainerName : string, + VMContainerName : string, VMname : string, useBulkMoveTo : boolean, useObjectCache : boolean, @@ -54,52 +109,60 @@ export type Caster = { CacheSize : number, CacheHolder : Instance ) -> (), - - -- CastFire - + RaycastFire: (Caster, Origin : Vector3, Direction : Vector3, Velocity : Vector3 | number, Behavior : FastCastBehavior) -> string, BlockcastFire: (Caster, Origin : Vector3, Size : Vector3, Direction : Vector3, Velocity : Vector3 | number, Behavior : FastCastBehavior) -> string, - - -- Utility ig - + SetBulkMoveEnabled : (enabled : boolean) -> (), SetObjectCacheEnabled : (enabled : boolean, Template : BasePart | Model, CacheSize : number, CacheHolder : Instance) -> (), SetVisualizeCasts : (bool : boolean) -> (), - + ReturnObject : (obj : Instance) -> (), - + Destroy : (Caster) -> () } --- Settings +--[=[ + @type VisualizeCastSettings { Debug_SegmentColor: Color3, Debug_SegmentTransparency: number, Debug_SegmentSize: number, Debug_HitColor: Color3, Debug_HitTransparency: number, Debug_HitSize: number, Debug_RayPierceColor: Color3, Debug_RayPierceTransparency: number, Debug_RayPierceSize: number, Debug_RayLifetime: number, Debug_HitLifetime: number } + @within TypeDefinitions + + Debug visualization settings for casts. +]=] export type VisualizeCastSettings = { - -- Segment Debug_SegmentColor: Color3, Debug_SegmentTransparency: number, Debug_SegmentSize: number, - - -- Hit + Debug_HitColor: Color3, Debug_HitTransparency : number, Debug_HitSize : number, - - -- Raypierce + Debug_RayPierceColor: Color3, Debug_RayPierceTransparency : number, Debug_RayPierceSize : number, - - -- Lifetime + Debug_RayLifetime: number, Debug_HitLifetime: number } +--[=[ + @type AdaptivePerformance { HighFidelitySegmentSizeIncrease: number, LowerHighFidelityBehavior: boolean } + @within TypeDefinitions + + Adaptive performance config used when AutomaticPerformance is enabled. +]=] export type AdaptivePerformance = { HighFidelitySegmentSizeIncrease : number, LowerHighFidelityBehavior : boolean } --- Represents a FastCastBehavior :: https://etithespirit.github.io/FastCastAPIDocs/fastcast-objects/fcbehavior/ +--[=[ + @type FastCastBehavior { RaycastParams: RaycastParams?, MaxDistance: number, Acceleration: Vector3, HighFidelityBehavior: number, HighFidelitySegmentSize: number, CosmeticBulletTemplate: Instance?, CosmeticBulletContainer: Instance?, AutoIgnoreContainer: boolean, CanPierceFunction: CanPierceFunction?, UseLengthChanged: boolean, SimulateAfterPhysic: boolean, AutomaticPerformance: boolean, AdaptivePerformance: AdaptivePerformance, VisualizeCasts: boolean, VisualizeCastSettings: VisualizeCastSettings } + @within TypeDefinitions + + Represents a FastCastBehavior configuration. +]=] export type FastCastBehavior = { RaycastParams: RaycastParams?, MaxDistance: number, @@ -107,22 +170,25 @@ export type FastCastBehavior = { HighFidelityBehavior: number, HighFidelitySegmentSize: number, CosmeticBulletTemplate: Instance?, - --CosmeticBulletProvider: any, -- any ObjectPool Library Class(Unused) CosmeticBulletContainer: Instance?, AutoIgnoreContainer: boolean, CanPierceFunction: CanPierceFunction?, UseLengthChanged : boolean, SimulateAfterPhysic : boolean, - - -- Performance + AutomaticPerformance : boolean, AdaptivePerformance : AdaptivePerformance, - + VisualizeCasts : boolean, VisualizeCastSettings : VisualizeCastSettings } --- Represents a CastTrajectory :: https://etithespirit.github.io/FastCastAPIDocs/fastcast-objects/casttrajectory/ +--[=[ + @type CastTrajectory { StartTime: number, EndTime: number, Origin: Vector3, InitialVelocity: Vector3, Acceleration: Vector3 } + @within TypeDefinitions + + Represents a cast trajectory segment. +]=] export type CastTrajectory = { StartTime: number, EndTime: number, @@ -131,7 +197,12 @@ export type CastTrajectory = { Acceleration: Vector3 } --- Represents a CastStateInfo :: https://etithespirit.github.io/FastCastAPIDocs/fastcast-objects/caststateinfo/ +--[=[ + @type CastStateInfo { UpdateConnection: RBXScriptSignal, HighFidelityBehavior: number, HighFidelitySegmentSize: number, Paused: boolean, TotalRuntime: number, DistanceCovered: number, IsActivelySimulatingPierce: boolean, IsActivelyResimulating: boolean, CancelHighResCast: boolean, Trajectories: {[number]: CastTrajectory}, UseLengthChanged: boolean, VisualizeCasts: boolean, VisualizeCastSettings: VisualizeCastSettings } + @within TypeDefinitions + + Represents cast state tracking data. +]=] export type CastStateInfo = { UpdateConnection: RBXScriptSignal, HighFidelityBehavior: number, @@ -148,8 +219,12 @@ export type CastStateInfo = { VisualizeCastSettings : VisualizeCastSettings } +--[=[ + @type CastRayInfo { Parameters: RaycastParams, WorldRoot: WorldRoot, MaxDistance: number, CosmeticBulletObject: Instance?, CanPierceCallback: CanPierceFunction } + @within TypeDefinitions --- Represents a CastRayInfo :: https://etithespirit.github.io/FastCastAPIDocs/fastcast-objects/castrayinfo/ + Represents ray info for an ActiveCast. +]=] export type CastRayInfo = { Parameters: RaycastParams, WorldRoot: WorldRoot, @@ -158,46 +233,47 @@ export type CastRayInfo = { CanPierceCallback: CanPierceFunction } ---[[export type EventDefinition = { - OnLengthChanged : OnLengthChangedFunction, - OnRayHit : OnRayHitFunction, - OnRayPierce : OnRayPierceFunction, - OnCastTerminating : OnCastTerminatingFunction? -}]] +--[=[ + @type ActiveCast { Caster: BaseCastData, StateInfo: CastStateInfo, RayInfo: CastRayInfo, UserData: {[any]: any}, SetVelocity: (ActiveCast, Vector3) -> (), SetAcceleration: (ActiveCast, Vector3) -> (), GetVelocity: (ActiveCast) -> Vector3, GetAcceleration: (ActiveCast) -> Vector3, GetPosition: (ActiveCast) -> Vector3, AddVelocity: (ActiveCast, Vector3) -> (), AddAcceleration: (ActiveCast, Vector3) -> (), AddPosition: (ActiveCast, Vector3) -> (), Pause: (ActiveCast) -> (), Resume: (ActiveCast) -> (), DestroyObject: (ActiveCast, Instance) -> (), Destroy: (ActiveCast) -> (), Terminate: (ActiveCast) -> (), CFrame: CFrame, ID: string } + @within TypeDefinitions --- Represents an ActiveCast :: https://etithespirit.github.io/FastCastAPIDocs/fastcast-objects/activecast/ + Represents an ActiveCast instance. +]=] export type ActiveCast = { - --Definition : {[string] : (...any) -> (...any)}, Caster : BaseCastData, StateInfo: CastStateInfo, RayInfo: CastRayInfo, UserData: {[any]: any}, - - + SetVelocity : (ActiveCast, velocity : Vector3) -> (), SetAcceleration : (ActiveCast, acceleration: Vector3) -> (), - + GetVelocity : (ActiveCast) -> Vector3, GetAcceleration : (ActiveCast) -> Vector3, GetPosition : (ActiveCast) -> Vector3, - + AddVelocity : (ActiveCast, velocity: Vector3) -> (), AddAcceleration : (ActiveCast, acceleration: Vector3) -> (), AddPosition : (ActiveCast, position: Vector3) -> (), - + Pause : (ActiveCast) -> (), Resume : (ActiveCast) -> (), - + DestroyObject : (ActiveCast, obj : Instance) -> (), - + Destroy : (ActiveCast) -> (), Terminate : (ActiveCast) -> (), - + CFrame : CFrame, ID : string } --- BlockCast Mods +--[=[ + @type BlockCastRayInfo { Parameters: RaycastParams, WorldRoot: WorldRoot, MaxDistance: number, CosmeticBulletObject: Instance?, CanPierceCallback: CanPierceFunction, Size: Vector3 } + @within TypeDefinitions + + Ray info for block-cast variants. +]=] export type BlockCastRayInfo = { Parameters : RaycastParams, WorldRoot : WorldRoot, @@ -207,12 +283,18 @@ export type BlockCastRayInfo = { Size : Vector3 } +--[=[ + @type ActiveBlockCast { Caster: BaseCastData, StateInfo: CastStateInfo, RayInfo: BlockCastRayInfo, UserData: {[any]: any}, SetVelocity: (ActiveCast, Vector3) -> (), SetAcceleration: (ActiveCast, Vector3) -> (), GetVelocity: (ActiveCast) -> Vector3, GetAcceleration: (ActiveCast) -> Vector3, GetPosition: (ActiveCast) -> Vector3, AddVelocity: (ActiveCast, Vector3) -> (), AddAcceleration: (ActiveCast, Vector3) -> (), AddPosition: (ActiveCast, Vector3) -> (), Pause: (ActiveCast) -> (), Resume: (ActiveCast) -> (), DestroyObject: (ActiveCast, Instance) -> (), Destroy: (ActiveCast) -> (), Terminate: (ActiveCast) -> (), CFrame: CFrame, ID: string } + @within TypeDefinitions + + Represents an active block-cast instance. +]=] export type ActiveBlockCast = { Caster : BaseCastData, StateInfo : CastStateInfo, RayInfo : BlockCastRayInfo, UserData : {[any] : any}, - + SetVelocity : (ActiveCast, velocity : Vector3) -> (), SetAcceleration : (ActiveCast, acceleration: Vector3) -> (), @@ -226,18 +308,22 @@ export type ActiveBlockCast = { Pause : (ActiveCast) -> (), Resume : (ActiveCast) -> (), - + DestroyObject : (ActiveCast, obj : Instance) -> (), Destroy : (ActiveCast) -> (), Terminate : (ActiveCast) -> (), - + CFrame : CFrame, ID : string } --- BaseCast Mods +--[=[ + @type BaseCast { Actives: { ActiveCast | ActiveBlockCast }, Output: BindableEvent, ActiveCastCleaner: BindableEvent, ObjectCache: BindableFunction?, CacheHolder: any? } + @within TypeDefinitions + Internal base cast object state. +]=] export type BaseCast = { Actives : { ActiveCast | ActiveBlockCast @@ -248,6 +334,12 @@ export type BaseCast = { CacheHolder : any? } +--[=[ + @type BaseCastData { Output: BindableEvent, ActiveCastCleaner: BindableEvent, ObjectCache: BindableFunction?, CacheHolder: any? } + @within TypeDefinitions + + Data stored on the caster that ActiveCasts reference. +]=] export type BaseCastData = { Output : BindableEvent, ActiveCastCleaner : BindableEvent, diff --git a/src/FastCast2/init.luau b/src/FastCast2/init.luau index ed2c8d7..8455641 100644 --- a/src/FastCast2/init.luau +++ b/src/FastCast2/init.luau @@ -48,10 +48,15 @@ -- Verison : 0.0.4 +--[=[ + @class FastCast + + FastCast is the root class of the module and offers the surface level methods required to make it work. This is the object returned from `require(FastCast)`. +]=] + -- Services ---local HTTPS = game:GetService("HttpService") -local RS = game:GetService("RunService") +local HTTPService = game:GetService("HttpService") -- Modules --local BaseCast = script:WaitForChild("BaseCast") @@ -95,37 +100,28 @@ local function DestroySignal(signal : Signal.Signal) end end ---[[ -
- Creates a new FastCastBehavior, which contains information necessary to Fire the cast properly. +--[=[ + Creates a new FastCastBehavior, which contains information necessary to Fire the cast properly. @return FastCastBehavior - - Which Contains : - - Parallel = true, - - RaycastParams = nil, - - Acceleration = Vector3.new(), - - MaxDistance = 1000, - - CanPierceFunction = nil, - - HighFidelityBehavior = TypeDef.HighFidelityBehavior.Default, - - HighFidelitySegmentSize = 0.5, - - CosmeticBulletTemplate = nil, - - CosmeticBulletProvider = nil, - - CosmeticBulletContainer = nil, - - AutoIgnoreContainer = true - -
-]] +]=] function FastCast.newBehavior() : TypeDef.FastCastBehavior return DefaultConfigs.FastCastBehavior :: TypeDef.FastCastBehavior end local DEFAULT_FASTCAST_BEHAVIOR = FastCast.newBehavior() ---[[ +--[=[ + :::warning + + You must [initialize](FastCast#Init) the Caster before using it. Failing to do so will result in nothing happening when attempting to fire! + + ::: Contructs a new Caster object. + @function new + @within FastCast @return Caster -]] +]=] function FastCast.new() : TypeDef.Caster return setmetatable({ LengthChanged = Signal.new(), @@ -136,10 +132,26 @@ function FastCast.new() : TypeDef.Caster WorldRoot = workspace, Dispatcher = nil, AlreadyInit = false - --id = HTTPS:GenerateGUID(false) } :: any, FastCast) :: TypeDef.Caster end +--[=[ + Initializes the Caster with the given parameters. This is required before firing using Raycasts in the Caster or nothing will happen! + @method Init + @within FastCast + + @param numWorkers number -- The number of worker VMs to create for this Caster. Must be greater than 1. + @param newParent Folder -- The Folder in which to place the FastCastVMs Folder + @param newName string -- The name to give the FastCastVMs Folder containing worker scripts. + @param ContainerParent Folder -- The parent Folder in which to place the worker VM Containers. + @param VMContainerName Folder -- The name to give to the Containers housing each worker VM. + @param VMname string -- The name to give each worker VM. + @param useBulkMoveTo boolean -- Whether to enable BulkMoveTo for the [CosmeticBulletObjects](TypeDefinitions#CastRayInfo) + @param useObjectCache boolean -- Whether to use ObjectCache for the [Caster](TypeDefinitions#Caster) + @param Template BasePart | Model -- The template object to use for the ObjectCache (if enabled) + @param CacheSize number -- The size of the ObjectCache (if enabled) + @param CacheHolder Instance -- The Instance in which to place cached objects (if enabled) +]=] function FastCast:Init( numWorkers : number, newParent : Folder, @@ -155,7 +167,10 @@ function FastCast:Init( CacheSize : number, CacheHolder : Instance ) - if self.AlreadyInit then warn("Cannot Init more than 1") return end + if self.AlreadyInit then + warn("Cannot Init more than 1") + return + end assert(numWorkers > 1, "numWorker must be more than 1") local DispatcherClone = DispatcherModule:Clone() @@ -223,27 +238,57 @@ function FastCast:Init( end -- OH YES DADDY end +--[=[ + Raycasts the Caster with the specified parameters. + @method RaycastFire + @within FastCast + + @param origin Vector3 -- The origin of the raycast. + @param direction Vector3 -- The direction of the raycast. + @param velocity Vector3 | number -- The velocity of the raycast. + @param BehaviorData FastCastBehavior? -- The behavior data for the raycast. + @return string -- The ActiveCast ID of the fired raycast. +]=] function FastCast:RaycastFire(origin: Vector3, direction: Vector3, velocity: Vector3 | number, BehaviorData: TypeDef.FastCastBehavior?) if not self.AlreadyInit then error("Please Init caster") end if BehaviorData == nil then BehaviorData = DEFAULT_FASTCAST_BEHAVIOR end - --local ActiveCastID = HTTPS:GenerateGUID(false) - --self.Dispatcher:Dispatch("Raycast", self.id, ActiveCastID, origin, direction, velocity, BehaviorData) - --local newActiveCast : TypeDef.ActiveCast = ActiveCast.new(self, origin, direction, velocity, BehaviorData :: TypeDef.FastCastBehavior) - --return newActiveCast + local ActiveCastID = HTTPService:GenerateGUID(false) -- BABE RAYCAST!!!!! - self.Dispatcher:Dispatch("Raycast", origin, direction, velocity, BehaviorData) - --return ActiveCastID + self.Dispatcher:Dispatch("Raycast", origin, direction, velocity, BehaviorData, ActiveCastID) + return ActiveCastID end +--[=[ + Blockcasts the Caster with the specified parameters. + @method BlockcastFire + @within FastCast + + @param origin Vector3 -- The origin of the blockcast. + @param Size Vector3 -- The size of the blockcast. + @param direction Vector3 -- The direction of the blockcast. + @param velocity Vector3 | number -- The velocity of the raycast. + @param BehaviorData FastCastBehavior? -- The behavior data for the raycast. + @return string -- The ActiveCast ID of the fired raycast. +]=] function FastCast:BlockcastFire(origin : Vector3, Size : Vector3, direction : Vector3, velocity : Vector3 | number, BehaviorData: TypeDef.FastCastBehavior?) if not self.AlreadyInit then error("Please Init caster") end if BehaviorData == nil then BehaviorData = DEFAULT_FASTCAST_BEHAVIOR end + local ActiveCastID = HTTPService:GenerateGUID(false) - - self.Dispatcher:Dispatch("Blockcast", origin, Size, direction, velocity, BehaviorData) + self.Dispatcher:Dispatch("Blockcast", origin, Size, direction, velocity, BehaviorData, ActiveCastID) + return ActiveCastID end +--[=[ + Calls a function safely. + @method SafeCall + @within FastCast + @private + + @param f (any) + @return any -- The result of the function call. +]=] function FastCast:SafeCall(f : (...any) -> (...any), ...) -- am i tripping if f then @@ -251,6 +296,13 @@ function FastCast:SafeCall(f : (...any) -> (...any), ...) end end +--[=[ + Sets whether BulkMoveTo is enabled for this Caster. + @method SetBulkMoveEnabled + @within FastCast + + @param enabled boolean +]=] function FastCast:SetBulkMoveEnabled(enabled : boolean) if not self.AlreadyInit or not self.Dispatcher then warn("Caster not initialized", self) @@ -263,7 +315,14 @@ function FastCast:SetBulkMoveEnabled(enabled : boolean) end]] end +--[=[ + Sets whether ObjectCache is enabled for this Caster. + It is recommended to interface with this via [`FastCast:Init()`](FastCast#Init) instead. + @method SetObjectCacheEnabled + @within FastCast + @param enabled boolean +]=] function FastCast:SetObjectCacheEnabled(enabled : boolean, Template : BasePart | Model, CacheSize : number, CacheHolder : Instance) local Dispatcher = self.Dispatcher @@ -303,10 +362,27 @@ end Configs.VisualizeCasts = bool end]] +--[=[ + :::warning + + Don't call this method if you didn't enable ObjectCache in [FastCast:Init()](FastCast#Init) or via [FastCast:SetObjectCacheEnabled()](FastCast#SetObjectCacheEnabled). Doing so will result in an error. + + ::: + Returns a part to the `ObjectCache` for reuse. + @method ReturnObject + @within FastCast + + @param obj Instance -- The object to return to the cache. +]=] function FastCast:ReturnObject(obj : Instance) self.ObjectCache:ReturnPart(obj) end +--[=[ + Destroy's a Caster, cleaning up all resources used by it. + @method Destroy + @within FastCast +]=] function FastCast:Destroy() if self.ObjectCache then self.ObjectCache:Destroy()