{"id":"cruzfelipee/guiparticleservice","name":"guiparticleservice","scope":"cruzfelipee","platform":"roblox","description":"UI Particle Library focused on ease of use and similarity to the default 3D Particle Emitter","version":"0.4.0","latest":"0.4.0","versions":["0.1.1","0.1.2","0.1.3","0.1.4","0.2.0","0.3.0","0.4.0"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"1b21a511401163009dc6ae70d21295f4406a17005d59f0c3888f4c32a881271b","likes":0,"downloads":0,"install":"forest install cruzfelipee/guiparticleservice","url":"https://forest.dev/p/roblox/cruzfelipee/guiparticleservice","files":"https://api.forest.dev/ai/package/roblox/cruzfelipee/guiparticleservice/files","readme":"# GuiParticleService\n\nGuiParticleService is a client-side Luau library for rendering animated particles inside Roblox UI. It aims to make GUI particles feel familiar to developers who use Roblox's built-in `ParticleEmitter`, while providing a small API for UI objects such as `Frame`, `ImageLabel`, and `ScreenGui` descendants.\n\n## Features\n\n- Emits reusable `ImageLabel` particles into any `GuiBase2d` parent.\n- Continuous, rate-based emission and one-shot bursts with `:Emit()`.\n- Particle motion with speed, spread, acceleration, and drag.\n- `ColorSequence`, `NumberSequence`, and `NumberRange` support for gradual visual changes and randomized values.\n- Configurable lifetime, rotation, rotation speed, transparency, size, texture, and Z offset.\n- Choose whether particles move with their parent UI object (`LockedToPart`).\n- Create an emitter from a Roblox `ParticleEmitter` with `fromEmitter`, optionally keeping compatible properties synchronized.\n- Pools finished particle instances to reduce allocations during repeated emission.\n\n## Requirements\n\n- Roblox Studio\n- A client-side `LocalScript` or UI controller. GuiParticleService updates particles through `RunService:BindToRenderStep`.\n- [Wally](https://wally.run/) is recommended for package installation.\n\n## Installation\n\n### Wally\n\nAdd the package to your project's `wally.toml`:\n\n```toml\n[dependencies]\ngui-particle-service = \"cruzfelipee/gui-particle-service@0.1.0\"\n```\n\nInstall dependencies:\n\n```sh\nwally install\n```\n\nThen require the installed package from the location used by your project. A typical Rojo setup looks like this:\n\n```luau\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal GuiParticleService = require(ReplicatedStorage.Packages.GuiParticleService)\n```\n\n### Manual installation\n\nCopy the contents of `src` into your project and require `init.luau` as a ModuleScript. Keep `Utils.luau` as a child/sibling ModuleScript named `Utils`, since the main module requires `script.Utils`.\n\n## Usage\n\nCreate an emitter by supplying at least a GUI parent. The emitter begins emitting immediately unless `Enabled` is set to `false`.\n\n```luau\nlocal GuiParticleService = require(path.to.GuiParticleService)\n\nlocal emitter = GuiParticleService.start({\n\tParent = script.Parent.ParticleArea,\n\tTexture = \"rbxassetid://1234567890\",\n\tRate = 20,\n\tLifetime = NumberRange.new(0.75, 1.25),\n\tSpeed = NumberRange.new(60, 120),\n\tEmissionDirection = Enum.NormalId.Top,\n\tSpreadAngle = 40,\n\tAcceleration = Vector2.new(0, 80),\n\tDrag = 1,\n\tSize = NumberSequence.new({\n\t\tNumberSequenceKeypoint.new(0, 12),\n\t\tNumberSequenceKeypoint.new(1, 3),\n\t}),\n\tTransparency = NumberSequence.new({\n\t\tNumberSequenceKeypoint.new(0, 0),\n\t\tNumberSequenceKeypoint.new(0.8, 0),\n\t\tNumberSequenceKeypoint.new(1, 1),\n\t}),\n\tColor = ColorSequence.new(Color3.fromRGB(255, 219, 117)),\n})\n\n-- Emit a one-shot burst in addition to the continuous Rate emission.\nemitter:Emit(30)\n\n-- Pause/resume continuous emission.\nemitter.properties.Enabled = false\nemitter.properties.Enabled = true\n\n-- Release pooled and active particle instances when they are no longer needed.\nemitter:Destroy()\n```\n\n### Creating from a `ParticleEmitter`\n\n`fromEmitter` maps the supported settings of an existing `ParticleEmitter` to a GUI emitter. The source `ParticleEmitter` must be parented to a `GuiBase2d`. Pass `true` as the third argument to synchronize compatible property changes and destroy the GUI emitter when the source emitter is destroyed.\n\n```luau\nlocal guiEmitter = GuiParticleService.fromEmitter(\n\tscript.Parent.ParticleEmitter,\n\t{\n\t\tParent = script.Parent.ParticleArea,\n\t\tRate = 35, -- optional override\n\t},\n\ttrue\n)\n```\n\nWhen supplying the overrides table, include `Parent`; otherwise the emitter has no GUI target. If no overrides are needed, `GuiParticleService.fromEmitter(sourceEmitter)` uses the source emitter's GUI parent.\n\n## Emitter API\n\n| Member | Description |\n| --- | --- |\n| `GuiParticleService.start(parameters)` | Creates and registers a GUI emitter. |\n| `GuiParticleService.fromEmitter(particleEmitter, overrides?, bound?)` | Creates an emitter from supported `ParticleEmitter` properties. |\n| `emitter:Emit(count)` | Immediately creates `count` particles. |\n| `emitter:Clear()` | Removes active particles and retains them for reuse. |\n| `emitter:Destroy()` | Clears the emitter, destroys its pooled particles, and unregisters it. |\n| `emitter.properties` | Mutable table containing the emitter configuration. |\n\n## Configuration\n\nAll settings are passed to `start` and can later be changed through `emitter.properties`.\n\n| Property | Type | Default | Notes |\n| --- | --- | --- | --- |\n| `Parent` | `GuiBase2d` | required | UI object that receives the particle `ImageLabel`s. |\n| `Texture` | `string` | `\"\"` | Image asset ID or content URI. |\n| `Enabled` | `boolean` | `true` | Controls continuous rate emission. |\n| `Rate` | `number` | `10` | Positive number of particles emitted per second. |\n| `Lifetime` | `NumberRange` | `NumberRange.new(1, 1)` | Particle lifespan in seconds. |\n| `Speed` | `NumberRange` | `NumberRange.new(10, 10)` | Initial speed in pixels per second. |\n| `EmissionDirection` | `Enum.NormalId` | `Top` | Supports `Top`, `Bottom`, `Left`, and `Right`. |\n| `SpreadAngle` | `number` | `0` | Angular spread around the emission direction, in degrees. |\n| `Acceleration` | `Vector2` | `Vector2.zero` | Acceleration in UI pixels per second squared. |\n| `Drag` | `number` | `0` | Exponential velocity drag. |\n| `Color` | `ColorSequence` | white | Particle colour over its lifetime. |\n| `Transparency` | `NumberSequence` | `NumberSequence.new(0)` | Image transparency over its lifetime. |\n| `Size` | `NumberSequence` | `NumberSequence.new(1)` | Square image size in pixels over its lifetime. |\n| `Rotation` | `NumberRange` | `0-360` | Initial rotation in degrees. |\n| `RotSpeed` | `NumberRange` | `-90-90` | Rotation speed in degrees per second. |\n| `LockedToPart` | `boolean` | `false` | When true, particles move with the UI parent; otherwise they remain in screen space if it moves. |\n| `ZOffset` | `number` | `0` | Z index used for newly created particle images. |\n\n## Current limitations and roadmap\n\nThe following ParticleEmitter-style capabilities are not currently rendered or simulated:\n\n- `Orientation`\n- `Squash`\n- `TimeScale`\n- Flipbook properties\n- Emitter shapes and shape settings\n\n`fromEmitter` with `bound = true` only synchronizes properties whose runtime types match the GUI emitter property. Some native particle settings need conversion, such as 3D acceleration and `Vector2` spread angles, so they are not automatically kept in sync.\n\nThere is also no automated test suite or example place yet.\n\n## Development\n\nThis repository uses [Rokit](https://github.com/rojo-rbx/rokit) to manage its toolchain.\n\n```sh\nrokit install\nselene src\nstylua --check src\n```\n\nTo build a Roblox place from the project tree:\n\n```sh\nrojo build -o \"GuiParticleService.rbxm\"\n```\n\nTo sync the project with Roblox Studio:\n\n```sh\nrojo serve\n```\n\n## Contributing\n\nContributions are welcome. Please open an issue or pull request describing the behaviour you want to add or change. For code contributions:\n\n1. Create a focused branch from the latest default branch.\n2. Keep the public API and `ParticleEmitter` compatibility in mind.\n3. Format and lint your changes with `stylua src` and `selene src`.\n4. Include clear reproduction or validation steps in the pull request.\n\nThe repository runs Selene and StyLua checks on pull requests, which are required for merging.\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n","readmeBorrowedFrom":{"version":"0.2.0","source":"wally"},"readmeTruncated":false}