{"id":"breezy1214/ezutil","name":"ezutil","scope":"breezy1214","platform":"roblox","description":"Reusable, game-agnostic Roblox utilities: tables, math, dates, instances, players, layout, projectiles, particles and more.","version":"0.1.0","latest":"0.1.0","versions":["0.1.0"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{"howmanysmall/janitor":{"version":"^1.18.3","alias":"Janitor"},"evaera/promise":{"version":"^4.0.0","alias":"Promise"}},"integrity":"27d36f4ebbc7b58b19e54b40a1348f18c4845689e472452bfb3d5ec14be6af2c","likes":0,"downloads":0,"install":"forest install breezy1214/ezutil","url":"https://forest.dev/p/roblox/breezy1214/ezutil","files":"https://api.forest.dev/ai/package/roblox/breezy1214/ezutil/files","readme":"# EZUtil\n\n[Documentation](https://breezy1214.github.io/EZUtil/)\n\nEZUtil is a collection of small, game-agnostic Roblox utilities: tables, math, dates, instances, players, UI layout, projectiles, particles and VFX. It has no game config, Knit services or hardcoded game paths, so you can drop it into any project.\n\n## Installation\n\nAdd the package to your [Wally](https://wally.run) manifest:\n\n```toml\n[dependencies]\nEZUtil = \"breezy1214/ezutil@0.1.0\"\n```\n\nEZUtil depends on [Janitor](https://github.com/howmanysmall/Janitor) and [Promise](https://github.com/evaera/roblox-lua-promise); Wally installs both for you.\n\n## Usage\n\n```lua\nlocal EZUtil = require(ReplicatedStorage.Packages.EZUtil)\n\nprint(EZUtil.MathUtil.shortenNumber(1200)) -- 1.2K\nprint(EZUtil.DateUtil.formatDuration(3725)) -- 1h 2m 5s\n\n-- Or require a single module directly\nlocal TableUtil = require(ReplicatedStorage.Packages.EZUtil.TableUtil)\n```\n\nEach module is required lazily, the first time its field is read, so a client-only module never runs on the server (and the reverse). The package root is fully typed, so `EZUtil.` autocompletes every module and its functions.\n\n## Modules\n\n### AimIndicator\n\nA single neon disc that marks where an ability will land.\n\n- `create(size, color?, parent?)`: replaces any existing indicator with a new disc, parented to `parent` (defaults to `workspace`).\n- `update(position)`: moves the indicator onto a ground position.\n- `destroy()`: removes the indicator.\n\n### CharacterRigUtil\n\nHelpers for character rigs, humanoids and skinned meshes.\n\n- `waitForHumanoid(character, timeout)`: returns the character's Humanoid, waiting up to `timeout` seconds.\n- `waitForAnimator(humanoid, timeout)`: returns the humanoid's Animator, waiting up to `timeout` seconds.\n- `findBodyPart(character, name)`: finds a body part by name, resolving accessory handles to their MeshPart.\n- `waitForBodyPart(character, name, timeout)`: polls `findBodyPart` until it succeeds, times out, or the character is removed.\n- `getFeetY(rootPart, humanoid)`: the world Y of the character's feet.\n- `standRootOn(character, rootPart, humanoid, groundCFrame)`: pivots the character so its feet rest on `groundCFrame`.\n- `isGroundedState(state)`: whether a HumanoidStateType counts as grounded.\n- `findSkinnedMesh(character)`: the MeshPart whose Bones pose a skinned character, or nil for a jointed rig.\n- `collectCharacterBones(character)`: every Bone under the character, parents before children.\n\n### DateUtil\n\nTimestamps, periods and human-readable durations.\n\n- `SECONDS_PER_DAY`, `SECONDS_PER_WEEK`: constants.\n- `dateTimeComponentsToTimestamp(components)`: converts UTC date components to a unix timestamp in seconds.\n- `unix()`: the current UTC unix timestamp in seconds.\n- `getPeriod(timestamp, duration, offset?)`: the index of the fixed-length period containing `timestamp`.\n- `getPeriodEnd(period, duration, offset?)`: the timestamp at which a period ends.\n- `formatDuration(seconds)`: formats seconds as `1h 2m 5s`.\n- `timeAgoUnix(timestamp, endTimestamp?)`: seconds elapsed since `timestamp`.\n- `formatUnix(timestamp, format, locale?)`: formats a timestamp with a DateTime format string.\n- `unixToClockFormat(timestamp, format?, locale?)`: formats a timestamp as `mm:ss` by default.\n- `timeAgo(timestamp, endTimestamp?)`: a readable \"time ago\" string, such as `1 minute 20 seconds ago`.\n- `totalTime(timestamp, endTimestamp?, separator?, depth?)`: a readable total duration with an optional unit limit.\n\n### FixedRewardSequence\n\n- `build(weights)`: builds a deterministic, evenly spread reward sequence whose frequencies match `weights`, starting at the rarest reward.\n\n### GroundUtil\n\n- `projectDown(position, depth, raycastParams, resultOffset?)`: raycasts straight down and returns the hit position plus an optional offset.\n- `raycast(origin, direction, filterList?, filterType?, collisionGroup?)`: a one-call raycast that builds its RaycastParams for you.\n\n### InstanceUtil\n\n- `FindFirstAncestorWithTag(instance, tag)`: the nearest ancestor with a CollectionService tag.\n- `GetDescendantsWithTag(instance, tag)`: every descendant with a tag.\n- `ExpectChild(parent, name)`: returns a child, or errors with its full path if it is missing.\n- `findFirstChildWithTag(instance, tagName)`: the first direct child with a tag.\n- `weldParts(part0, part1)`: welds two parts with a WeldConstraint.\n- `weldAttachments(attach1, attach2)`: joins two attachments with a RigidConstraint.\n- `lookAt(object, target, rotateOnYAxis?)`: tweens a part to face a target and returns a Promise that resolves when the tween ends.\n\n### JanitorUtil\n\n- `safeDestroy(janitor?)`: destroys a Janitor unless it is nil or already cleaning, and warns instead of throwing on failure.\n\n### LayoutUtil\n\nKeeps ScrollingFrame canvases and items sized correctly.\n\n- `resolveUDim(size, referenceSize)`: converts a UDim to pixels against a reference size.\n- `FixScrollingCanvas(layout, scrollingFrame, padding?)`: keeps CanvasSize fitted to the layout's content and padding. Returns a cleanup function.\n- `FixAuthoredListHeights(scrollingFrame, layout, items)`: locks list items and padding to their authored heights relative to the viewport. Returns a cleanup function.\n- `FixLayout(layout, scrollingFrame, itemAspectRatio?, padding?)`: applies aspect-ratio constraints to items and keeps the vertical canvas fitted. Returns a cleanup function.\n\n### MathUtil\n\n- `lerp(start, stop, alpha)`: linear interpolation.\n- `round(number)`: rounds to the nearest integer.\n- `roundNumber(num, numPlaces)`: rounds to the nearest value with a number of decimal places.\n- `formatInt(number, decimals?)`: adds thousands separators, such as `1,000.01`.\n- `shortenNumber(number, minimumTiers?)`: abbreviates large numbers, such as `1.2K` or `3M`.\n- `random(min, max?, float?)`: a random integer or float. `min` defaults to 1 when only one number is given.\n- `randomRange(min, max)`: a random float in a range.\n- `randomString(length?)`: a random alphanumeric string, 18 characters by default.\n- `randomObj(tableOrInstance)`: a random array element or child.\n- `randomInDisc(radius)`: a uniformly random flat offset inside a disc.\n- `getRandomInPart(part)`: a random CFrame on a part's XZ plane.\n- `getVector3(object)`: extracts a position from a Vector3, CFrame, Attachment, BasePart, value object or Camera.\n- `getDistance(origin, target)`: the distance between any two values `getVector3` supports.\n- `getPartBottomSurface(part)`: the CFrame at the centre of a part's bottom face.\n- `isNumberSecure(value)`: true only for non-negative numbers.\n\n### ParticleUtil\n\n- `waitForTemplate(name, folder)`, `waitForPart(name, folder)`, `waitForModel(name, folder)`: wait up to 5 seconds for a typed asset in `folder`, and warn if it is missing or the wrong class.\n- `burst(template, cframe)`: clones an attachment, emits each emitter's `EmitCount` attribute after its optional `EmitDelay`, then cleans up.\n- `setEnabled(root, enabled)`: toggles every ParticleEmitter under `root`.\n- `release(root)`: stops emitters and lights, then destroys `root` after its particles finish.\n\n### PlayerUtil\n\n- `ensureAnimator(character)`: returns the character's Animator, creating one if needed.\n- `loadAnimation(janitor, character, animationId)`: loads an Action4 track that the Janitor stops and destroys.\n- `getHumanoid(object)`: the Humanoid of a Player, character Model or Humanoid.\n- `isAlive(object)`, `hasHumanoid(object)`: humanoid health and presence checks.\n- `getCharacterHeight(character)`: the character's bounding-box height.\n- `getPositiontAtFeet(character)`: the world position at the character's feet.\n- `getCharacterInformation(player)`: returns the character, Humanoid and HumanoidRootPart.\n- `getPlayerFromInstance(part)` (alias `getPlayerFromPart`): the Player whose character contains a part.\n- `getGroupRank(player, groupId)`: a cached group rank lookup.\n- `isCreator(player)`, `getUserLevel(player)`, `userLevel`: checks for the game creator, group staff and Premium.\n- `disableOtherUi(value, exception?)`: client only. Hides or restores every ScreenGui except `exception` and Topbar GUIs.\n\n### ProfileUtil\n\n- `scope(label, callback)`: runs a non-yielding callback inside a named MicroProfiler scope and returns its results.\n\n### ProjectileUtil\n\nBallistic projectiles and aim previews.\n\n- `calculateLaunchVelocity(origin, target, duration, gravity?)`: the launch velocity needed to hit `target` in `duration` seconds.\n- `getPositionAtTime(origin, velocity, time, gravity?)`, `getVelocityAtTime(velocity, time, gravity?)`: the arc's position and velocity at a time.\n- `launch(config)`: animates an anchored part along the arc, with optional raycast hits and bounces. Returns a controller with `Cancel` and `IsActive`.\n- `createAimBeam(config)`: draws the arc with a single curved Beam. Returns an object with `Update` and `Destroy`.\n\n### SearchUtil\n\n- `getPartCount(instance)`, `getDescendantParts(instance)`: count or collect descendant BaseParts.\n- `getFirstPart(instance)`: the first BasePart child.\n- `getAncestor(child, nameOrPredicate)`: the first ancestor, or the instance itself, that matches.\n- `find(node, keyOrPredicate, maxDepth?)`: a breadth-limited search through Instance children or nested tables.\n- `exists(node, names)`: whether every named child or key exists.\n\n### SystemUtil\n\n- `timeout(delay, callback)`: runs `callback` after `delay` seconds.\n- `interval(interval, callback)`: runs `callback(elapsed, dt)` every `interval` seconds until it returns `false`. Returns the connection.\n- `inTable(table, value)`: whether a value is in a table.\n- `disconnect(connectionOrList)`: disconnects one connection or a list of them.\n- `getProductInfo(productId, infoType?)`: a cached, pcall-wrapped `MarketplaceService:GetProductInfo`.\n- `isMobile()`, `isConsole()`: input-based platform checks.\n\n### TableDiffUtil\n\n- `shallowEqual(left, right)`: whether two tables have the same keys and values.\n\n### TableUtil\n\n- `flip`, `map`, `filter`, `mapIndex`: transform tables, or an Instance's children.\n- `extend`, `assign`: merge tables, with an optional deep merge.\n- `split`, `join`, `trimWhitespace`, `trimLeadingWhitespace`, `trimTrailingWhitespace`: string helpers.\n- `treePath(tree, path, delimiter?)`: reads a dotted path through a table or Instance tree.\n- `insertIf(target, value, condition)`: appends a value only if the condition passes.\n- `instanceChildrenToTable(instance)`: maps child names to children.\n- `makeConfigFromValues(folder)`: converts a Folder or Configuration of value objects into a nested table.\n- `tableLength`, `indexOf`, `tableRandom`, `tableRandomIndex`, `tableRemove`: counting, lookup, random picks and in-place removal.\n\n### VfxUtil\n\nPlays VFX templates whose emitters are configured with `EmitCount`, `EmitDelay` and `EmitDuration` attributes.\n\n- `uprightAt(template, position)`: a CFrame at `position` that keeps the template's rotation.\n- `play(template, cframe, parent?)`: plays a one-shot clone, parented to `parent` (defaults to `workspace`), and cleans it up when finished.\n- `attach(template, part)`: welds a continuously emitting clone to `part` and returns a stop function.\n\n## License\n\nMIT\n","readmeTruncated":false}