Skip to content

1.16.1#15

Merged
Raild3x merged 7 commits intomainfrom
auto_deploy_test
Jan 7, 2026
Merged

1.16.1#15
Raild3x merged 7 commits intomainfrom
auto_deploy_test

Conversation

@Raild3x
Copy link
Owner

@Raild3x Raild3x commented Jan 7, 2026

No description provided.

Raild3x added 7 commits August 7, 2025 16:19
Adds new methods to FusionUtil for binding and observing instance properties and attributes, including two-way binding support. Introduces mapValuesToStates for mapping dictionary values to state objects, with mutator support. Improves array and table utility functions with better error handling and documentation. Updates type annotations and internal structure for clarity and maintainability. Minor refactoring and docstring updates in init.luau for version management.
Updated FusionUtil to reference 'plainsour/lemon@0.4.0-dev.1.4' as Fusion_v0_3_0 in wally.toml and incremented the package version to 1.15.0. Adjusted documentation and removed outdated class order for FusionUtil in moonwave.toml. Minor docstring and formatting improvements in FusionUtil_v0_3_0 and init.luau.
Renamed various script files to the scripts/ directory for better organization and project structure.
Introduces debug part grouping in DrawUtil, allowing creation, clearing, and management of debug parts by group and id. Refactors DrawUtil API to support optional naming for vectors, points, and lines, and adds error handling for property assignment. InstanceUtil.emitParticles now supports delayed emission and cancellation, and minor doc and assertion fixes are made in MathUtil and TblUtil. Bumps wally.toml version to 1.16.0.
Bump package version to 1.16.1 and switch Fusion_v0_3_0 dependency from plainsour/lemon to elttob/fusion. Commented out the previous lemon dependency.
Copilot AI review requested due to automatic review settings January 7, 2026 17:11
@Raild3x Raild3x merged commit 856c622 into main Jan 7, 2026
1 of 2 checks passed
@Raild3x Raild3x deleted the auto_deploy_test branch January 7, 2026 17:11
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR bumps the version from 1.14.0 to 1.16.1 and includes significant enhancements to utility modules, particularly FusionUtil with new state binding functions, DebugUtil with breakpoint capabilities, DrawUtil with improved part management, and InstanceUtil with a refactored particle emission system. The PR also introduces development tooling scripts and updates dependencies.

Key Changes:

  • Added comprehensive state observation and binding utilities to FusionUtil (outAttribute, outProperty, bindAttributeToState, bindPropertyToState, mapValuesToStates)
  • Introduced breakpoint debugging functionality in DebugUtil with step/pause/resume controls
  • Enhanced DrawUtil with group-based part management and a new part() function
  • Refactored InstanceUtil's emitParticles to support delayed emissions with cancellation

Reviewed changes

Copilot reviewed 12 out of 17 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/RailUtil/wally.toml Version bump to 1.16.1 and commented out older Fusion dependencies
src/RailUtil/TblUtil/init.luau Fixed typo in documentation (@wihin → @Within) and improved BinarySearch documentation
src/RailUtil/MathUtil.luau Removed type assertions from isBetween for performance
src/RailUtil/InstanceUtil/init.luau Fixed indentation and refactored emitParticles to use QueryDescendants and support cancellation
src/RailUtil/FusionUtil/init.luau Cleaned up code formatting and improved type annotations
src/RailUtil/FusionUtil/FusionUtil_v0_3_0.luau Added extensive new utilities including state observers, property binders, mapValuesToStates, and table manipulation functions
src/RailUtil/FusionUtil/FusionUtil_v0_2_5.luau Marked as deprecated and ignored
src/RailUtil/FusionUtil/FusionUtil_v0_2_0.luau Marked as deprecated and ignored
src/RailUtil/DrawUtil.luau Added part() function with group management, clearGroup, and clearPart utilities
src/RailUtil/DebugUtil.luau Implemented breakpoint system with TestService attributes for pause/step/resume control
sourcemap.json Updated with new package structure and file mappings
scripts/setup.sh New shell script for environment setup and package management
scripts/runTests.story.luau New test runner story file
scripts/runTests.sh New shell script for initializing test environment
scripts/runTests.server.luau New server-side test runner
scripts/publish.sh New shell script for publishing to Wally
moonwave.toml Removed FusionUtil class ordering section

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1186 to +1201
local innerScope = innerScope(scope)

-- Create a Value state to hold this specific value
-- Cast to Value<any> to work around type system limitations
local valueState = Fusion.Value(innerScope, refValue) :: Value<any>

-- Store the scope for cleanup and value state for future updates
internalMap[key] = {
Scope = innerScope,
Value = valueState
}

-- Create the output state for this key
-- If a mutator is provided, wrap in a Computed to apply transformation
-- Otherwise, just use the raw value state
outputMapRaw[key] = Fusion.Computed(innerScope, function(use, cScope)
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable shadowing issue: The local variable innerScope on line 1186 shadows the imported innerScope function from line 37. This creates ambiguity and makes the code harder to understand. Consider renaming the local variable to something like keyScope or itemScope to avoid confusion.

Suggested change
local innerScope = innerScope(scope)
-- Create a Value state to hold this specific value
-- Cast to Value<any> to work around type system limitations
local valueState = Fusion.Value(innerScope, refValue) :: Value<any>
-- Store the scope for cleanup and value state for future updates
internalMap[key] = {
Scope = innerScope,
Value = valueState
}
-- Create the output state for this key
-- If a mutator is provided, wrap in a Computed to apply transformation
-- Otherwise, just use the raw value state
outputMapRaw[key] = Fusion.Computed(innerScope, function(use, cScope)
local keyScope = innerScope(scope)
-- Create a Value state to hold this specific value
-- Cast to Value<any> to work around type system limitations
local valueState = Fusion.Value(keyScope, refValue) :: Value<any>
-- Store the scope for cleanup and value state for future updates
internalMap[key] = {
Scope = keyScope,
Value = valueState
}
-- Create the output state for this key
-- If a mutator is provided, wrap in a Computed to apply transformation
-- Otherwise, just use the raw value state
outputMapRaw[key] = Fusion.Computed(keyScope, function(use, cScope)

Copilot uses AI. Check for mistakes.

Calls the provided callback immediately with the initial state and then again anytime the state updates.
Just a simpler version of `scope:Observer(state):onBind(fn)`.
Kept for backwards compatability.
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error in documentation: "compatability" should be "compatibility".

Suggested change
Kept for backwards compatability.
Kept for backwards compatibility.

Copilot uses AI. Check for mistakes.
Comment on lines +664 to +671
local emitCount: number? = emitCount or emitter:GetAttribute("EmitCount") :: number? or emitter.Rate
if emitDelay and typeof(emitDelay) == "number" then
local delayedThread = task.delay(emitDelay, function()
emitter:Emit(emitCount)
end)
table.insert(delayedThreads, delayedThread)
else
emitter:Emit(emitCount)
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable shadowing issue: The parameter emitCount is shadowed by a local variable with the same name on line 664. This makes the function parameter inaccessible within the Emit function. Consider renaming either the parameter or the local variable to avoid confusion and ensure proper scoping.

Suggested change
local emitCount: number? = emitCount or emitter:GetAttribute("EmitCount") :: number? or emitter.Rate
if emitDelay and typeof(emitDelay) == "number" then
local delayedThread = task.delay(emitDelay, function()
emitter:Emit(emitCount)
end)
table.insert(delayedThreads, delayedThread)
else
emitter:Emit(emitCount)
local resolvedEmitCount: number? = emitCount or emitter:GetAttribute("EmitCount") :: number? or emitter.Rate
if emitDelay and typeof(emitDelay) == "number" then
local delayedThread = task.delay(emitDelay, function()
emitter:Emit(resolvedEmitCount)
end)
table.insert(delayedThreads, delayedThread)
else
emitter:Emit(resolvedEmitCount)

Copilot uses AI. Check for mistakes.
Comment on lines +1476 to +1477
currentValue:set(newValue)
return currentValue
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect return value type in updateInsteadOfReplace mode: When updateInsteadOfReplace is true and the value is successfully updated, the function returns currentValue (line 1433 and 1477) which is the Value state object itself, not the previous value of type V. This is inconsistent with the documented return type V? and the behavior when updateInsteadOfReplace is false (which returns the actual previous value). The function should return the previous value before the update, not the Value state object.

Suggested change
currentValue:set(newValue)
return currentValue
local previous = peek(currentValue)
currentValue:set(newValue)
return previous

Copilot uses AI. Check for mistakes.
Comment on lines +1432 to +1433
currentValue:set(newValue)
return currentValue
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect return value type in updateInsteadOfReplace mode: When updateInsteadOfReplace is true and the value is successfully updated, the function returns currentValue (the Value state object itself) instead of the previous value of type V. This is inconsistent with the documented return type V? and the behavior when updateInsteadOfReplace is false. The function should return the previous value before the update, not the Value state object.

Suggested change
currentValue:set(newValue)
return currentValue
local previousValue = peek(currentValue)
currentValue:set(newValue)
return previousValue

Copilot uses AI. Check for mistakes.
# Fusion_v0_2_0 = "elttob/fusion@0.2.0"
# Fusion_v0_2_5 = "raild3x/fusion@0.2.5"
Fusion_v0_3_0 = "elttob/fusion@0.3.0"
# Fusion_v0_3_0 = "plainsour/lemon@0.4.0-dev.1.4"
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate dependency key: Line 16 defines a commented-out dependency with the key Fusion_v0_3_0, but this key is already used on line 15 for an active dependency. While commented out, this creates confusion and could cause issues if uncommented accidentally. The comment should either use a different key name or be removed entirely.

Suggested change
# Fusion_v0_3_0 = "plainsour/lemon@0.4.0-dev.1.4"
# Lemon_v0_4_0_dev_1_4 = "plainsour/lemon@0.4.0-dev.1.4"

Copilot uses AI. Check for mistakes.

Observes a raw property of an instance and returns a state that is updated with the property's value.

:::caution Does not memoize the state
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation incomplete: The caution tag states "Does not memoize the state" but doesn't complete the thought. It should explain the implications or consequences of not memoizing, such as "Does not memoize the state, so calling this function multiple times will create separate Value states for the same property" or similar clarification.

Copilot uses AI. Check for mistakes.
function InstanceUtil.getAttachmentsAlignedCFrame(partAttachment: Attachment, targetAttachment: Attachment): CFrame
assert(partAttachment:IsA("Attachment") or not targetAttachment:IsA("Attachment"), "Both inputs must be attachments")
return targetAttachment.WorldCFrame * partAttachment.CFrame:Inverse()
assert(partAttachment:IsA("Attachment") or not targetAttachment:IsA("Attachment"), "Both inputs must be attachments")
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic error in assertion: The condition uses or when it should use and. Currently, it checks if partAttachment is an Attachment OR targetAttachment is NOT an Attachment, which is incorrect. The assertion should verify that BOTH inputs are Attachments. Change or to and to correctly validate both parameters.

Suggested change
assert(partAttachment:IsA("Attachment") or not targetAttachment:IsA("Attachment"), "Both inputs must be attachments")
assert(partAttachment:IsA("Attachment") and targetAttachment:IsA("Attachment"), "Both inputs must be attachments")

Copilot uses AI. Check for mistakes.
local id = props.Id or HttpService:GenerateGUID(false)
props.Id = nil

local group = upsertGroup(props.GroupName or "Default")
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property mismatch: The function parameter is documented as 'Group' (line 78), but the code checks for 'GroupName' (line 88). This inconsistency means users passing 'Group' won't have their property read correctly. Either update the documentation to match the implementation or change the code to use 'Group' instead of 'GroupName'.

Copilot uses AI. Check for mistakes.
end

--[=[
Clears all debug parts a group.
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete documentation: The documentation mentions "Clears all debug parts a group" but is missing the word "from" or "in". It should read "Clears all debug parts from a group" or "Clears all debug parts in a group".

Suggested change
Clears all debug parts a group.
Clears all debug parts from a group.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants