Hello everyone,
I am pleased to share my first open-source resource with the Roblox developer community: Chirp (v0.4.0), a lightweight, high-performance RichText typewriter and dialogue engine built for modern Roblox experiences.
Many existing dialogue modules suffer from runtime performance stutters caused by frequent string allocations, broken XML tags mid-reveal, or rigid animation framework constraints. Chirp solves these challenges using a zero-GC table buffer architecture, frame-perfect grapheme rendering, and an extensible inline tag system.
Key Features
- 60 FPS Grapheme Rendering: Leverages
MaxVisibleGraphemesandRenderStepped. Unclosed RichText tags are safely handled during character reveals without exposing raw XML markup on screen. - Stacked Mathematical Effects: Allows developers to stack dynamic inline animation tags simultaneously (e.g.,
<shake><wave>text</wave></shake>) with smooth optical subpixel wave calculations. - Zero-GC Table Buffer Allocation: Employs pre-allocated memory buffers during render loops to eliminate Lua garbage collection frame hitches during long dialogue sequences.
- Custom Effect API (
Chirp.RegisterEffect): Enables dynamic registration of custom inline text animation tags at runtime without modifying core module files. - Inline Dialogue Commands: Provides control over dialogue flow mid-sentence using
<pause=X>,<speed=X>, and<event=X>tags. - Multiplayer Synchronization: Accepts
workspace:GetServerTimeNow()in the:Type()method to synchronize typewriter cutscenes across multiple client screens down to the millisecond. - UGC Security Sanitization: Includes a built-in
Chirp.Sanitize()helper function to safeguard against RichText XML injection attacks when displaying player usernames or chat input.
Quick Setup & Code Example
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Chirp = require(ReplicatedStorage.Chirp)
-- 1. Register a custom inline effect tag
Chirp.RegisterEffect("pulse", function(index, time)
local sizeOffset = math.sin(time * 8) * 3
return sizeOffset, 0
end)
-- 2. Initialize a Chirp instance
local dialogue = Chirp.new(script.Parent.TextLabel, {
Speed = 0.04,
Preset = "Pop",
ShowPrompt = true,
})
-- 3. Listen for inline cutscene events
dialogue.OnEventTriggered:Connect(function(eventName)
print("Cutscene event triggered:", eventName)
end)
-- 4. Type line with stacked tags & commands
dialogue:Type("Welcome to <wave><pulse>Chirp Engine</pulse></wave>.<pause=0.5><event=camera_zoom>")
Links & Documentation
- GitHub Repository: github.com/7frostt/chirp
- Live Documentation & API Reference: 7frostt.github.io/chirp
- Download
.rbxm(Latest Release): github.com/7frostt/chirp/releases
Feedback
As this is my first open-source release, I would greatly appreciate any feedback, suggestions, or bug reports in the replies below or directly on the GitHub repository.
