API
Accessory
Functions
.isAssetTypeAccessory
DubitUtils.Accessory.isAssetTypeAccessory(assetType: Enum.AssetType): boolean
Checks if the given asset type is an accessory.
Example Usage
print(DubitUtils.Accessory.isAssetTypeAccessory(Enum.AssetType.ShortsAccessory)) --> true
print(DubitUtils.Accessory.isAssetTypeAccessory(Enum.AssetType.Animation)) --> false
.matchAssetTypeToAccessoryType
DubitUtils.Accessory.matchAssetTypeToAccessoryType(assetType: Enum.AssetType): Enum.AccessoryType
Matches the given asset type to its corresponding accessory type.
Example Usage
print(DubitUtils.Accessory.matchAssetTypeToAccessoryType(Enum.AssetType.Hat)) --> Enum.AccessoryType.Hat
Camera
Functions
.zoomToExtents
DubitUtils.Camera.zoomToExtents(camera: Camera, extentsInstance: BasePart | Model): ()
Zooms the provided Camera instance to the extents of the provided BasePart or Model instance.
Character
Functions
.cloneCharacter
DubitUtils.Character.cloneCharacter(character: Model, isAnchored: boolean?): Model?
Creates a clone of the provided character, without overhead display of display name & health.
.resetCharacterTransparency
DubitUtils.Character.resetCharacterTransparency(character: Model, tweenInfo: TweenInfo?): ()
Resets the transparency of all parts within the provided character to the original value, if it was made invisible via Character.setCharacterTransparency.
Notice
This function must be used in conjunction with setCharacterTransparency, which stores the original transparency values of each part. If the character did not have its transparency modified via that function, this function will fail.
.setCharacterFrozen
DubitUtils.Character.setCharacterFrozen(character: Model, frozen: boolean?): ()
Set a provided character to be frozen or unfrozen.
.setCharacterTransparency
DubitUtils.Character.setCharacterTransparency(character: Model, targetTransparency: number, tweenInfo: TweenInfo?): ()
Sets the transparency of all valid parts within the provided character to the provided value. This will also apply to any valid parts which become a descendant of the character before transparency values are reset.
Notice
This function is usually intended to be used in conjunction with resetCharacterTransparency, as it will restore the original transparency values of each part, which are stored through this function.
Instance
Functions
.findAncestorWithTag
DubitUtils.InstanceUtility.findAncestorWithTag(instance: Instance, tag: string): Instance?
Finds & returns the first ancestor of the given instance with the provided tag, if there is one.
Notice
This function will ignore the provided instance, and only check its ancestors.
.findDescendantsWithTag
DubitUtils.InstanceUtility.findDescendantsWithTag(instance: Instance, tag: string): { Instance }
Danger
It is advised to use QueryDescendants instead.
Finds & returns a table of descendants of the given instance which have the provided tag.
Notice
This function will ignore the provided instance, and only check its descendants.
.setDescendantTransparency
DubitUtils.InstanceUtility.setDescendantTransparency(instance: Instance, transparency: number): ()
Sets the transparency of a given instance and all of its descendants to a provided value. The transprency to set may be any number, however only values between 0 and 1 are supported (e.g. providing a value above 1 will be equivalent to providing 1).
Notice
This function will dynamically set either the LocalTransparencyModifier (client, will not replicate) or the Transparency of the instance (server, will replicate), depending on whether the function is called from the client or the server.
.verifyInstance
DubitUtils.InstanceUtility.verifyInstance(instanceName: string, instanceType: string, instanceParent: Instance?, timeout: number?): Instance?
Danger
This function yields.
Ensure that an Instance exists within the given parent Instance, and create it if it does not exist.
Danger
Developers should ensure that the provided 'instanceType' equates to a valid Instance subclass. This is something that as of current can not be natively checked in Lua/Luau, so will cause an error if it is not valid.
.waitForChildren
DubitUtils.InstanceUtility.waitForChildren(instance: Instance, query: string, timeout: number?): Instance?
Danger
This function yields.
Wait for a series of children to appear in an instance.
Warning
Will return nil if any of the children do not appear within the provided timeout.
.findInstance
DubitUtils.InstanceUtility.findInstance(parent: Instance, path: string): Instance?
Find instance within a parent, this function removes a need for chaining FindFirstChild calls.
The path string must follow the format: instance_name.instance_name.instance_name...
Number
Functions
.abbreviate
DubitUtils.Number.abbreviate(numberToAbbreviate: number, includePlusSymbol: boolean?, decimals: number?): string
Abbreviates the given number with a large number notation, depending on the nearest power of one thousand lower than it, up to 10 ^ 30 ("N").
Example Usage
print(DubitUtils.Number.abbreviate(372)) --> 372
print(DubitUtils.Number.abbreviate(59678)) --> 59K+
print(DubitUtils.Number.abbreviate(59678, false)) --> 59K
print(DubitUtils.Number.abbreviate(1000000000)) --> 1B
print(DubitUtils.Number.abbreviate(4967827362967902)) --> 4Qd+
print(DubitUtils.Number.abbreviate(4967827362967902, true, 2)) --> 4.96Qd+
.roundToNearest
DubitUtils.Number.roundToNearest(numberToRound: number, roundTo: number): number
Rounds a given number to the nearest multiple of the given 'roundTo' number.
Example Usage
print(DubitUtils.Number.roundToNearest(37, 5)) --> 35
.commaSeparate
DubitUtils.Number.commaSeparate(numberToSeparate: number): string
Separate the given number with commas every three digits to make the number more human-readable.
Example Usage
DubitUtils.Number.commaSeparate(528) --> 528
DubitUtils.Number.commaSeparate(59678) --> 59,678
DubitUtils.Number.commaSeparate(1000000000) --> 1,000,000,000
RobloxGroup
Functions
.getMemberRank
DubitUtils.RobloxGroup.getMemberRank(player: Player, groupId: number?, retries: number?): number?
Get the rank of the given player in the group with the ID provided.
Warning
If groupId is not provided and the creator ID of the current experience is not that of a group, this function will fail and return nil.
.isPlayerAboveGroupRank
DubitUtils.RobloxGroup.isPlayerAboveGroupRank(player: Player, minimumGroupRank: number, whitelist: {[number]: any}?, retries: number?, creatorIdOverride: number?): boolean
Check if the specified player is at or above the provided group rank, or otherwise succeeds the permissions of that rank. Returns true if any of the following conditions have been met: - The group rank of the player in the specified group matches or exceeds the minimum group rank - The player is the owner of the game - The player is whitelisted - The game is running in Studio
Example Usage
DubitUtils.RobloxGroup.isPlayerAboveGroupRank(playerWhoJustJoined, 250, { [aSpecificExternalPlayer.UserId] = true }, 3, 0)
Stack
Properties
first
DubitUtils.Stack.first: number
last
DubitUtils.Stack.last: number
size
DubitUtils.Stack.size: number
Functions
.new
DubitUtils.Stack.new<T>(): Stack<T>
:push
DubitUtils.Stack:push<T>(value: T): ()
:pushFirst
DubitUtils.Stack:pushFirst<T>(value: T): ()
:pushLast
DubitUtils.Stack:pushFirst<T>(value: T): ()
:pop
DubitUtils.Stack:pop<T>(): T?
:popFirst
DubitUtils.Stack:popFirst<T>(): T?
:popLast
DubitUtils.Stack:popLast<T>(): T?
:peek
DubitUtils.Stack:peek<T>(): T?
:peekFirst
DubitUtils.Stack:peekFirst<T>(): T?
:peekLast
DubitUtils.Stack:peekLast<T>(): T?
Table
Functions
.construct
DubitUtils.Table.construct<T>(constructingFunction: () -> T): T
Construct a table from a given function.
The only reason it exists so the code looks "cleaner" (very subjective).
Example Usage
local COLOR_PALETTE = DubitUtils.Table.construct(function()
local hexColors = { "#FF0000", "#00FF00", "#0000FF" }
local colors = {}
for i, hex in hexColors do
colors[i] = Color3.fromHex(hex)
end
return colors
end)
.compare
DubitUtils.Table.compare(source: {[any]: any}, other: {[any]: any}): boolean
This function roughly (It won't traverse other tables) compares two tables, both arrays and dictionaries are supported.
Cyclical References not supported.
Example Usage
local tbl_one = { test = true }
local tbl_two = { test = true, hello = "world" }
print(DubitUtils.Table.compare(tbl)) --> false
local tbl_one = { test = true }
local tbl_two = { test = true }
print(DubitUtils.Table.compare(tbl)) --> true
local tbl_one = { test = true, nested = { foo = "bar" } }
local tbl_two = { test = true, nested = { foo = "bar" } }
print(DubitUtils.Table.compare(tbl)) --> false, the table entries are roughly compared, both values of nested fields point to different tables
.compareDeep
DubitUtils.Table.compareDeep<A, B>(source: A, other: B): boolean
This function deeply compares two tables, both arrays and dictionaries are supported.
Cyclical References not supported.
Example Usage
local tbl_one = { test = true }
local tbl_two = { test = true, hello = "world" }
print(DubitUtils.Table.compareDeep(tbl)) --> false
local tbl_one = { test = true }
local tbl_two = { test = true }
print(DubitUtils.Table.compareDeep(tbl)) --> true
local tbl_one = { test = true, nested = { foo = "bar" } }
local tbl_two = { test = true, nested = { foo = "bar" } }
print(DubitUtils.Table.compareDeep(tbl)) --> true
.deepClone
DubitUtils.Table.deepClone<T>(tbl: T): T
This function creates a deep copy of given table.
Cyclical References not supported.
Example Usage
local tbl = { test = true }
local tblClone = DubitUtils.Table.deepClone(tbl)
tblClone.test = false -- will only modify the table contents of the tblClone
print(tbl.test, tblClone.test) --> true, false
.deepFreeze
DubitUtils.Table.deepFreeze<T>(tbl: T): T
This function deep freezes the table making it read only.
Cyclical References not supported.
Example Usage
local tbl = { test = true }
DubitUtils.Table.deepFreeze(tbl)
tbl.test = false --> attempt to modify a readonly table
.merge
DubitUtils.Table.merge(source: {[any]: any}, other: {[any]: any})
Merges two given tables together, if source table has a property that other table has - it will be overwritten with the value of other table.
Cyclical References not supported.
Example Usage
local tbl = { test = true, foo = 8 }
local tblOther = { test = false, bar = 16 }
print(DubitUtils.Table.merge(tbl, tblOther)) --> { test = false, foo = 8, bar = 16 }
.getRandomDictionaryEntry
DubitUtils.Table.merge(source: {[string]: any}, other: {[string]: any})
Gets a random entry (key-value pair) from a given dictionary.
.stringify
DubitUtils.Table.stringify(tableBase: {[any]: any}), options: { spaces: number?, usesemicolon: boolean?, depth: number? }): string
'Stringifies' a table, recursively converting it to a string representation of its contents.
Options: spaces - The number of spaces to use for indentation usesemicolon - Whether to use a semicolon instead of a comma for separating table entries depth - The depth of the table in the recursion to stringify up to
Example Usage
local tbl = { test = true, foo = 8 }
local stringifiedTable = DubitUtils.Table.stringify(tbl)
print(stringifiedTable)
--> {
--> ["test"] = true;
--> ["foo"] = 8
--> }
Time
Functions
.formatToCountdownTimer
DubitUtils.Time.formatToCountdownTimer(seconds: number): string
Formats seconds to countdown timer format (hr:mm:ss).
Example Usage
print(DubitUtils.Time.formatToCountdownTimer(59)) --> 00:00:59
print(DubitUtils.Time.formatToCountdownTimer(127)) --> 00:02:07
print(DubitUtils.Time.formatToCountdownTimer(86399)) --> 23:59:59
.formatToRaceTimer
DubitUtils.Time.formatToRaceTimer(seconds: number): string
Formats seconds to race like timer format (mm:ss:msms). This differs from Time.formatToRaceTimer as this one gives a lot more precise time back. (Useful for racing games)
Example Usage
print(DubitUtils.Time.formatToRaceTimer(59.99)) --> 00:59.990
print(DubitUtils.Time.formatToRaceTimer(127.138)) --> 02:07.138
print(DubitUtils.Time.formatToRaceTimer(16.552)) --> 00:16.552
print(DubitUtils.Time.formatToRaceTimer(6)) --> 00:06.000
.formatToRaceTimerDetailed
DubitUtils.Time.formatToRaceTimerDetailed(seconds: number): string
Formats seconds to race like timer format (mm:ss:msms). This differs from Time.formatToRaceTimer as this one gives a lot more precise time back. (Useful for racing games)
Example Usage
print(DubitUtils.Time.formatToRaceTimer(59.99)) --> 00:59.9900
print(DubitUtils.Time.formatToRaceTimer(127.138)) --> 02:07.1380
print(DubitUtils.Time.formatToRaceTimer(16.552)) --> 00:16.5520
print(DubitUtils.Time.formatToRaceTimer(6)) --> 00:06.0000
.formatSecondsToMinutesAndSeconds
DubitUtils.Time.formatSecondsToMinutesAndSeconds(seconds: number, useNotations: boolean?): string
Formats the given time in seconds to minutes and seconds, in the format of minutes:seconds or [minutes]m[seconds]s
Example Usage
print(DubitUtils.Time.formatSecondsToMinutesAndSeconds(1235)) --> 20:35
print(DubitUtils.Time.formatSecondsToMinutesAndSeconds(12)) --> 00:12
print(DubitUtils.Time.formatSecondsToMinutesAndSeconds(1235, true)) --> 20m35s
print(DubitUtils.Time.formatSecondsToMinutesAndSeconds(12, true)) --> 12s
.getFormattedTimeOfDay
DubitUtils.Time.getFormattedTimeOfDay(unixTimestamp: number?): string
Formats the given time of day provided as a timestamp in the format of hours:minutes:seconds, formatting the current time of day if no timestamp is provided.
Example Usage
print(DubitUtils.Time.getFormattedTimeOfDay()) -- will print current time in the 00:00:00 format
print(DubitUtils.Time.getFormattedTimeOfDay(1702723900)) --> 10:51:40
Vector
Functions
.findNearestGroundAroundPoint
DubitUtils.Vector.findNearestGroundAroundPoint(origin: Vector3, radius: number, params: RaycastParams?): Vector3
Returns the nearest ground point within a sphere radius around origin, if it doesn't find any ground point it returns the origin.
.findRandomGroundAroundPoint
DubitUtils.Vector.findRandomGroundAroundPoint(origin: Vector3, radius: number, params: RaycastParams?): Vector3
Returns a random point on the ground within a sphere radius around origin, if it doesn't find any ground point it returns the origin.
.getRandomPointInPart
DubitUtils.Vector.getRandomPointInPart(part: BasePart, randomiseYPosition: boolean?): Vector3
Gets and returns a random position within a given part, with the option to only randomise along the X & Z axes and optionally Y axis.
.quadraticBezier
DubitUtils.Vector.quadraticBezier(time: number, p0, p1, p2)
fzy
Functions
.filter
DubitUtils.fzy.filter(needle: string, haystack: string, caseSensitive: boolean?): { {number, { number }, number } }
.hasMatch
DubitUtils.fzy.hasMatch(needle: string, haystack: string, caseSensitive: boolean?): boolean
Check if needle is a subsequence of the haystack.
Usually called before score or positions.
.positions
DubitUtils.fzy.positions(needle: string, haystack: string, caseSensitive: boolean?): { [number]: number }
Compute the locations where fzy matches a string.
Determine where each character of the needle is matched to the haystack in the optimal match.
.score
DubitUtils.fzy.score(needle: string, haystack: string, caseSensitive: boolean?): number
Compute a matching score.