Proyectos Informacion Contacto
Project Documentation

Catalog —
avatar editor & catalog.

Roblox · Luau · Client + Server

An in-game avatar editor and catalog system for Roblox. Architecture and behavior reference — it describes structure, data flows, services and design decisions. No source code, no sensitive identifiers.

~/catalog · knowledge-graph SNAPSHOT
catalog --info
projectCatalog
typeAvatar editor + catalog
languageLuau
syncRojo → Roblox Studio
branchrefactor/estructura
archCore + Features (hybrid)
cycles● none detected
→ graph: 1082 nodes · 1602 rels · 136 communities
1082Graph nodes
1602Relationships
136Communities
4Runtime roots
← Volver a proyectos
DOC-001 · Panda15Fps · CATALOG · ARCHITECTURE REFERENCE
Model snapshot: branch refactor/estructura (hybrid Core + Features architecture). Generated from the project knowledge graph — structural extraction only, no model-token cost.

01 Overview

Catalog is a Roblox experience whose core is an in-game avatar editor: the player browses Roblox's official catalog, tries on clothing and accessories over a live 3D preview, adjusts body colors and proportions, saves outfits, shares them with the community via codes, and buys items directly.

The project is split into two halves that talk to each other through a typed Remotes layer:

  • Client — all UI, the 3D preview, reactivity, and presentation logic. Replicated to players.
  • Server — the authority: DataStore persistence, validation, catalog queries, purchases, moderation, and everything that must not be trusted to the client.

Main features it delivers

  • Paginated catalog browsing and search, with categories, subcategories, and filters.
  • 3D preview with an orbit camera, clothing try-on, body color editing, and proportion scaling.
  • Accessory refinement (move, rotate, scale).
  • Undo / redo of avatar changes.
  • Player inventory and favorites.
  • Saving personal outfits and publishing outfits to the community via shareable codes.
  • Community outfit browser with sorting, gender filters, and creator filters.
  • Emotes played on the real character.
  • Single and bulk purchases, plus Robux gifting between players.
  • A style-preference onboarding that feeds physical outfit stands in the world.
  • Chat tags by group role, a player-to-player likes system, leaderboards.
  • An admin command system (kick, ban, outfit deletion) based on group rank.
  • A loading / intro screen shown before the main UI.

02 Tech stack & tooling

ItemUse in the project
LuauThe single language for all code (client and server). Extension .luau; only entry points use the init.* names Rojo requires.
RojoSyncs the repository code into Roblox Studio. The folder→location mapping is in the runtime section.
CharmReactive state library (signals and derived values). The foundation of UI reactivity.
CharmSyncReplicates reactive server state to the client over a Remote.
ProfileStoreThird-party DataStore wrapper for persistent player data with safe sessions.
SprSpring-based animation library for smooth UI transitions.
Trove / Signal / ObserversLifecycle utilities: resource cleanup, custom events, and instance observation.
TypedRemoteWrapper that creates and types the RemoteEvent/RemoteFunction objects centrally.

Third-party libraries are vendored (copied into the repo) under their original names, kept separate from in-house code.

03 Roblox services used

The following Roblox engine services are used across the codebase. The "scope" column notes whether the usage is mainly client, server, or both.

ServiceScopeWhat it is used for
ReplicatedStorageBothRoot container for the shared AvatarCreator tree and the runtime Remotes folder; every module resolves dependencies from here.
PlayersBothLocal player access, player added/removing lifecycle, friend checks, rank-in-group queries, and the official ban/unban API.
MarketplaceServiceBothPrompting purchases, processing developer-product receipts, querying product info, and prompting subscription/Robux flows.
AvatarEditorServiceServerSearching the official catalog, resolving item/bundle descriptions, and inferring bundles by name.
DataStoreServiceServerBacking store for persistent data (player profiles via ProfileStore, the community outfit index, and the deletion blocklist).
RunServiceBothFrame and physics step hooks for the preview camera, animations, and Studio-vs-runtime checks.
TweenServiceClientUI tweening alongside the spring library for transitions and effects.
UserInputServiceClientMouse, touch, and keyboard input for preview rotation/pan/zoom and shortcuts.
ContextActionServiceClientBound action shortcuts (e.g. free camera).
CollectionServiceClientTag-based UI effects (hover/click effects, animated textures) applied across many elements.
HttpServiceServerJSON encode/decode and outbound requests for the asset→bundle reverse lookup via a proxy host.
TextChatServiceClientInjecting chat tags and gradients into chat messages.
ChatBothLegacy chat surface support where needed.
SocialServiceClientFriend-related social surfaces (e.g. gifting to friends).
TeleportServiceServerTeleport flow used by an admin command.
MessagingServiceServerCross-server messaging where needed.
GroupServiceServerResolving creator-group information.
InsertServiceServerLoading assets on demand.
SoundServiceClientSound playback configuration (respects filtering).
LightingBothScene/lighting setup for environments and preview.
GuiServiceClientGUI insets and screen metrics.
StarterGuiClientToggling default Roblox UI elements.
ContentProviderClientPreloading assets during the intro.
PhysicsServiceServerCollision-group setup (e.g. disabling player-player collisions).
ServerScriptServiceServerRoot container for the AvatarCreatorServer tree.
workspaceBothWorld objects: outfit stands, leaderboards, trampolines, and the baseplate.

Engine objects also used through Roblox APIs include HumanoidDescription (full avatar appearance), Animation/AnimationTrack (emotes and leaderboard models), and Camera (scriptable preview camera).

04 Runtime architecture — the 4 roots

At runtime the project lives under four roots inside Roblox's DataModel. These names are stable: they never change even when the interior is reorganized.

Repository folderRoblox locationNature
src/avatarCreatorReplicatedStorage.AvatarCreatorClient code + shared modules. Replicated to all players.
src/avatarCreatorServerServerScriptService.AvatarCreatorServerServer code. Never replicated to the client.
src/clientStarterPlayer.StarterPlayerScripts.ClientPlayer LocalScript entry points.
src/replicatedFirstReplicatedFirst.IntroClientIntro / loading screen, loaded before everything else.

Additionally, the server creates a Remotes folder (AvatarCreatorEvents) in ReplicatedStorage at runtime, where the RemoteEvent and RemoteFunction objects both halves use live.

Single-root principle: all client code hangs off AvatarCreator and all server code off AvatarCreatorServer. There are no loose "Shared" or "Server" folders outside these roots.

05 Hybrid architecture — Core + Features

Each root's interior follows a hybrid layout: a cross-cutting base (Core, Config, Domain) plus vertical per-feature folders (Features). The rule is simple: cross-cutting, reusable things go in the base; things that belong to one feature go in that feature's folder.

Cross-cutting layers (client)

LayerWhat it holds
Core/PackagesVendored third-party libraries (reactive state, springs, signals, cleanup, sync, etc.).
Core/LibIn-house generic utilities: number formatting, table tools, logger, rich-text escaping, UI helpers, item-info cache.
Core/NetRemote definitions, serialization, and shared cache-key generation.
Core/TypesShared types, interfaces, and "tuning" constants.
ConfigStatic configuration data: limits, images, purchase tiers, themes, group roles, chat tags, etc.
DomainPure business logic with no UI or state: item adaptation, detail lookup, product parsing, chat name color.

Features (client)

Each feature groups its controllers, panels, views, and state in its own folder:

Avatar
Catalog
Outfits
Community
Emotes
Purchase
Gifting
Settings
Chat
StylePreference
Interface
UIKit

The same principle applies on the server, with Core, Data, Admin, Runtime, and a set of Features that mirror the client's.

06 Security model — client vs server

In Roblox, anything living in ReplicatedStorage is replicated to players and can be inspected. The guiding principle is therefore:

The client is never the source of truth. The server validates and decides everything that matters.

  • Server authority: purchases, data writes, admin permissions, accessory/makeup limits, and applying the avatar description are resolved and validated on the server.
  • Sensitive data off the client: the full catalog schema, server-only identifiers, and server-side serialization live in the server root, where they are not replicated.
  • The client sends intent, not decisions: e.g. "I want to buy this item" or "I want to equip this"; the server checks and executes.

As part of hardening, modules only the server needs (catalog schema, leaderboard animation identifiers, and description serialization) live in the server root instead of ReplicatedStorage, reducing the exposed code surface without affecting behavior: the client still receives categories through a RemoteFunction rather than reading the schema directly.

Reality to keep in mind: UI code that runs on the client is always readable by the client; it cannot be fully hidden. The strategy is not to hide the UI but to ensure that copying the code cannot exploit the game, because all authority lives on the server.

07 Client structure

Entry points (src/client)

These are LocalScripts. The main one acts as a pure orchestrator: it holds no business logic. Its job is to require modules, resolve all UI references once, inject explicit dependencies into each module, and start the boot sequence. There are also auxiliary entries for the donation board and the world trampolines.

The boot sequence, at a high level:

  1. Parallel boot of chat and purchases.
  2. Initialization of stateful services (favorites, catalog, inventory, outfits).
  3. Single resolution of every UI reference into one table.
  4. Dependency injection into each module (order matters).
  5. Wiring of emote playback and the HUD buttons.
  6. Start: categories, tabs, and the catalog grid.

Client module families

FamilyResponsibility
Controllers (Controller suffix)Orchestrate open/close and wiring of a feature (catalog, emotes, outfits, community, gifting, settings, onboarding, HUD).
Panels and menus (Panel / Menu)The concrete UI of each feature.
Cards and views (Card / View)Presentation of a single item or outfit.
Stores (Store)Shared reactive state built on signals.
UIKitReusable components: widgets (switches, sliders, color pickers, dropdowns), visual effects, the 3D preview, the panel manager, and the responsive grid.

Canonical systems (single source of truth)

To avoid duplication, certain responsibilities have a single owner:

  • Favorites — one service holds the favorites set; everything else consumes it.
  • UI references — one module resolves all UI-tree references; reference-lookup chains are never duplicated at boot.
  • Avatar state — one central module holds the client avatar state (critical; it follows a strict order: state is declared before functions).
  • Emote state — one controller centralizes which emote is currently playing.
  • HUD buttons — one controller wires all HUD buttons; it is the most connected node on the client (acting as a bridge across many features).
  • Item-info cache — one module caches product info and resolves lookups in parallel, avoiding serial calls.

08 Server structure

The server has its own thin orchestrator that initializes services and registers each feature's handlers.

FolderContents
DataPersistence wrapper (ProfileStore), the public player-data API, and a "guard" that validates and cleans the avatar description before persisting it.
CoreServer utilities (e.g. safe description application, formatting, fetching player data).
ConfigStatic data only the server needs (catalog schema, leaderboard animation identifiers).
AdminModular command system: command router, group-rank permission manager, ban service, and a per-category commands folder.
RuntimeScripts that auto-run at server start (player collisions, leaderboard animations, leaderboards, etc.).
FeaturesOne folder per feature, each with its services and a handlers subfolder.

Handler pattern

Handlers take two shapes depending on their nature:

  • Query (search, pagination, groups, categories): expose a function bound to a RemoteFunction.
  • Effect / subscription (avatar, outfits, codes, bundles, favorites, emotes, settings, style preference): initialize with side effects and create their own Remotes.

Common dependencies (schema, cache keys, catalog services, player data, constants) are injected into handlers rather than each one resolving them on its own.

Catalog services (server)

They live within the catalog feature: a layer that queries Roblox's official catalog, a per-player paginated cache, active pagination sessions, and creator-group resolution.

09 Configurable files (Config)

The files under ReplicatedStorage.AvatarCreator/Config are the project's tuning knobs: static data meant to be edited to customize the game without touching logic. The most important ones:

FileWhat it configuresEdit when you want to…
AvatarConstantsCentral constants: asset-type display names, default clothing references, avatar-description field maps (numeric, string, color, scale), core cached bundles, default mood, and the group id used across the game.Change defaults, the target group, or how avatar fields are mapped. Most depended-on Config file — handle with care.
AccessoryLimitsMaximum rigid and layered accessories the player may wear (counting logic included).Adjust how many accessories of each kind are allowed.
MakeupLimitsMaximum number of makeup layers.Allow more or fewer makeup layers.
PurchaseTiersCosmetic purchase tiers selected by price: celebration color, confetti amount, and effect duration per price bracket.Re-tune the post-purchase celebration by price.
FeaturedItemsManually curated list of catalog item ids shown first in the "Featured" tab; list order = display order.Change which items are featured. Edit only this list.
ImagesCentral registry of UI image asset references (label icons, item banners, gender icons, arrows, and more).Swap any UI icon/image in one place.
MusicIdsList of audio asset ids for the background music shuffle.Add or change background music tracks.
EnvironmentThemesSelectable environment/scene themes (id, name, preview image, scene name).Add or rename preview environments.
GroupRolesGroup rank → role mapping with display name, color, icon, and chat-tag identifier; includes which roles are active.Define group roles, their chat tags, and colors. (Cosmetic; visible to clients by design.)
ChatTagsChat-tag definitions (name, color, gradient) consumed by the chat client.Customize chat-tag appearance.
DonationProductIdsDeveloper-product ids used as donation buttons on the donation board, one per Robux price.Wire the donation board to your own developer products.
TextGlyphsSpecial glyph characters (Robux, Premium, Verified) used inside rich text.Change which font glyphs render for these symbols.
Note: the catalog category schema and the leaderboard animation ids were moved out of this client Config into the server Config for security; they are no longer client-editable from ReplicatedStorage. Categories now reach the client through a RemoteFunction.

10 State management (Charm / CharmSync)

The UI is reactive. State lives in "stores" as Charm signals; UI modules subscribe to those signals and redraw when they change. This avoids manually wiring updates throughout the UI.

Key concepts:

  • Signal: a reactive value with read, write, and subscribe.
  • Derived value: recomputed from other signals.
  • Peek: read a signal without creating a reactive dependency. Used carefully to avoid stale caches in queries.
  • Subscribe vs listen: subscribe skips the initial call; listen fires at setup too. Choosing wrong here caused boot-time "auto-save" bugs that were fixed with explicit guards.

CharmSync replicates server state to the client over a dedicated Remote (for example, players' chat tags).

11 Data persistence

Player data (favorites, purchase history, settings, likes, style preference, saved outfits, published codes, stats) is persisted with ProfileStore, which provides safe per-player sessions.

Notable persistence patterns:

  • "Push + pull" loading: on profile load the server pushes settings to the client; the client also has a fallback that requests them if they did not arrive in time. A "settings ready" guard prevents the client from overwriting data with defaults during boot.
  • Forced writes after changes: in-memory changes are explicitly committed to DataStore when they must persist.
  • Deferred flush (anti rate-limit): community outfits live in an in-memory index that is the source of truth; changes mark the index "dirty" and a background loop flushes it periodically in a single operation, with a guaranteed flush on server close. Individual keys that need an immediate lookup are written right away. This pattern avoids saturating the DataStore queue when publishing/deleting in bursts.
  • Persistent blocklist: outfits deleted by admins are recorded in a blocklist so they do not reappear when their owner reloads their profile. This list uses the same deferred flush.

12 Client-server communication (Remotes)

The boundary between client and server is the Remotes layer. They are described by purpose (without detailing their payloads).

Catalog and avatar

  • Search items, request the next page, get creator groups, and get the catalog categories.
  • Save the avatar state, clear it to the original avatar, get the saved description.
  • Resolve bundle descriptions and infer bundles from items.
  • Toggle and get favorites.
  • Play, stop, and resolve emotes (the server returns the animation id to the client).

Purchases and economy

  • Single-purchase request and purchase notifications (local and global).
  • Bulk purchase and completion notification.
  • Bulk item-ownership verification.
  • Robux gifting between players (request, confirmation to sender, notice to receiver).
  • Price binding for presentation.

Outfits and community

  • Generate and look up outfit codes, record wears, toggle a code favorite, list a creator's outfits.
  • Paginated queries of community outfits and favorites, with keyword, sort, gender, and creator.
  • CRUD operations on personal outfits (save, rename, delete, update, favorite, set gender).

Social and settings

  • Verify permission to view another player's outfit; like a player and broadcast the notice.
  • Chat tags and system messages.
  • Update a setting, receive settings on load (push), and request them (pull).
  • Style preference: set, log funnel steps, receive and request the preference.
Remotes are created centrally through a typed wrapper; names must be unique within their folder.

13 Main data flows

Conceptual descriptions of how information travels in the most important operations.

Catalog search

The UI requests a search → the server queries Roblox's official catalog → it returns paginated results that the catalog grid renders.

Equipping an item

The client avatar state records the change, applies it to the preview, and sends it to the server → the server validates and cleans the description, merges it with the saved one, and applies it to the character queued per player (to avoid race conditions when equipping fast).

Body proportion adjustment

The slider computes scale values that are applied to the preview with throttling, translating scale names into the format the avatar description expects.

Purchase

The UI requests a purchase → the server launches the official Marketplace flow → on completion, the client fires celebration effects (flash, confetti, sounds).

Robux gift

A subscriber requests to gift another player enough for a product → the server uses the official Robux transfer, accounting for the fact that the receiver gets a fraction of the sent amount and that per-transfer minimum and maximum caps exist. Effects and notices fire on confirmation.

Emote

The UI requests an emote → the server resolves the animation id and returns it → the client loads the animation onto the character. Requesting the same emote again stops it.

Undo / redo

The avatar-state history moves a pointer over saved snapshots and notifies change listeners to refresh the view.

Accessory refinement

Selecting an accessory initializes the sliders; dragging previews on the rig; releasing commits the change and persists it.

Save to Roblox (HUD)

The save button resolves item info across several parallel phases (individual products, direct bundles and cache, and name inference) and opens the outfit purchase modal. The reverse bundle lookup, being the slowest phase and dependent on a network proxy, runs in the background with progressive rendering and a server-side time budget.

Community outfits

At startup the server loads the full index of published outfits (from all users, online or not). Publishing adds an entry to the index and writes the lookup key immediately, deferring the index flush. Queries iterate the in-memory index, filter and sort, and paginate.

Chat tags

The server syncs tags to the client (via CharmSync) and the client applies them to messages through the text chat service.

Loading and intro

The intro builds its own screen and, when finished, marks loading as done. The main UI (HUD, style onboarding) waits for that signal before showing.

Hidden players

Depending on the privacy setting, the client makes other players transparent (a local, non-replicated effect) and blocks their selection in popups.

14 Subsystems by feature

Avatar

Central client avatar state, validation rules, character loading, equipped list, body-color panel, scaling panel, accessory refinement, undo/redo, and reset to the default avatar. The actual application of the description to the character happens on the server, queued per player.

Catalog

Open/close controller, client catalog API, paginator, category and subcategory tabs, search bar and filters, query builder, item cards and detail view, inventory, favorites, and featured items.

Outfits

Outfit API, "my outfits" controller and menu, outfit viewer, outfit purchase modal, save-to-Roblox and update menus. Outfits are identified by name; an outfit's "style" is, by convention, a keyword over its name rather than a separate field.

Community

Community outfit browser with sorting (relevance, favorites, popularity, trending, oldest, newest), per-tab gender filters and a creator filter; player popup (view, wear, like); publish-outfit and "match" menus; shareable-code controller. There are also physical stands in the world that display outfits by style preference, with a fallback so they never end up empty.

Emotes

An emotes menu with search and favorites, and a controller that maintains the playback state on the real character.

Purchase

Purchase client (flow, prompts, window state, and post-purchase effects) and bulk purchase. Validation and receipt processing happen on the server.

Gifting

Lets a subscriber gift another player the Robux needed for a product, via the official Robux transfer, with its limits and split. It accounts for the cross-server gift case (the receiver's notice may be generic).

Settings

Settings panel and store with "push + pull" persistence and guards that prevent boot-time overwrites. Covers, among others, outfit visibility, hidden players, and purchase notifications.

Style preference

A one-time onboarding to pick style and gender; gender is stored in one format and translated to another for server queries. It feeds the world outfit stands. It appears after the intro, thanks to the loading-done signal.

Chat and social

Chat tags by group role (synced server→client), per-username name color, system messages, and a player-to-player likes system with persistence and a chat notice.

Interface and intro

The HUD and its buttons, the panel manager (blur, overlay, sounds), the frame router, music, free camera, subscription banner, toasts, and the top bar. The intro lives in the first-loaded root and controls when the interface is revealed.

Administration

A modular command system based on group rank (not gamepass): a router with aliases, a permission manager with per-session rank caching, and a ban service over the official API (cross-server, permanent or temporary). It includes moderation commands (kick, ban, unban) and outfit commands (delete by code or by user), with the persistent blocklist described above. Adding a new command is declarative: create the command file, register it in the module list, and define its minimum rank.

15 Core nodes of the project

The knowledge-graph analysis identifies the most connected abstractions (the "god nodes") — the pieces the rest depends on most. They are the best starting points for understanding the system and the ones that need the most care when changing.

PieceWhy it is central
HUD wiringMost connected node on the client; bridges catalog, refinements, community, gifting, panels, and more. The effective orchestrator of interaction.
Player-data fetch (server)Entry point to everything persisted; many systems depend on it.
Avatar viewport creationFoundation of every 3D preview (preview, stands, outfit cards).
Button-hover helperReused by nearly all UI; connects very different features.
Preview rig buildCore of the avatar's representation in the preview.
List population (menus and items)Common rendering of outfits and items across several menus.

The graph detects no import cycles, indicating a clean dependency hierarchy. Extraction was purely structural (no model-token cost).

The navigable interactive graph is available at graphify-out/graph.html and the full report at graphify-out/GRAPH_REPORT.md.

16 Coding conventions

  • One require convention, absolute: from the client, reference through the AvatarCreator root; on the server, server-local modules are referenced through the server root. No cross-package relative paths and no old-structure names. Exception: siblings within the same package may use relative references.
  • Suffixes by role: Controller (flow), Panel/Menu (UI), Card/View (presentation), Store (reactive state), Net (Remote definition), Handler (server handler); no suffix for utilities, data, or pure libraries.
  • Where each new file goes: third-party library → Packages; in-house utility → Lib; Remote definition → Net/Remotes; static data → Config; pure logic → Domain; any feature module → its Feature; shared UI → UIKit.
  • Explicit dependency injection: modules receive their dependencies on initialization rather than resolving them globally.
  • State-before-functions order in the critical avatar-state module.
  • Subscription cleanup: subscriptions always return their cancel function to avoid leaks.
  • Extension .luau except the entry points Rojo requires as init.*.

17 Studio-only dependencies

Some assets are not in the repository because they live in Studio: the assets inside the client root, the world objects (stands, leaderboards, trampolines), and the UI elements inside the player's UI tree. The code references them by path and leaves them intact.

Historical note: a top-bar icon library and its icon system were removed entirely; there are no top-bar icons anymore. Music, free camera (via shortcut), and hide-UI still work without them.

18 Glossary

Rojo
Tool that syncs repository code into Roblox Studio.
ReplicatedStorage
Roblox container whose contents are replicated to all clients.
ServerScriptService
Roblox container whose contents exist only on the server.
Remote (RemoteEvent / RemoteFunction)
Roblox's official mechanism for client-server communication.
Charm
Reactive state library based on signals.
Signal
A reactive value that notifies its observers when it changes.
ProfileStore
DataStore wrapper with safe per-player sessions.
HumanoidDescription
Roblox object describing an avatar's full appearance.
Bundle
A set of catalog items sold together.
Outfit
A saved set of an avatar's clothing and configuration.
God node
In the knowledge graph, a highly connected piece much of the system depends on.
Community (of the graph)
A group of strongly related pieces, detected automatically.

A Appendix — Catalog category schema

Interactive map of the 14 active categories and their subcategories in the Avatar Creator, mirroring Schema/init.lua. Each entry documents the corresponding AvatarEditorService enum / filter and the kind of implementation it requires. This is the concrete schema behind the catalog search flow described above.

Schema state: the Creators category is removed, and Inventory / Favorites currently expose only their All tab (per-type subcategories are commented out in the source pending FavoritesService). The tree below reflects only what is active.
API AvatarEditorService call local client-side / inventory filter future needs FavoritesService
14 categorias · 0 abiertas
Descriptive document of the Catalog project. It includes no source code, no asset/product/group identifiers, no storage keys, and no reproducible logic. Its goal is to explain structure, responsibilities, and flows.