Safe Multicategory Leaderstats for Roblox Luau
Generate a robust leaderstats system for Roblox with multiple stat categories, ideal for RPG, tycoon, simulator, PvP, racing, or economy games. The result organizes player data between visible scoreboard stats and internal categories, without violating the native behavior of the leaderstats folder.
The prompt guides the AI to create a ready-to-use Luau Script for ServerScriptService, with server-authoritative architecture, centralized configuration, respawn duplication prevention, and optional support for RemoteEvents already existing in your project. It includes strict input validation and a testing workflow for Roblox Studio.
Act as a senior Roblox developer, specializing in Luau, client-server architecture, progression systems, and anti-exploit security. Create a complete leaderstats system with multiple categories of player statistics, using a single server Script to be placed in ServerScriptService.
Before writing the code, consider the context of my game below. If any field is empty, use the suggested default values and keep the configuration clearly concentrated at the top of the script for future editing:
- Place/game name and genre: [PASTE HERE]
- Desired visible stats on the scoreboard: [e.g., Coins, Gems, Kills, Level]
- Desired internal categories and their stats: [e.g., Combat: Kills, Deaths, DamageDealt | Economy: CoinsEarned, CoinsSpent | Progress: XP, Level]
- Initial values for each stat: [PASTE HERE]
- Which stats should appear in the default leaderboard: [PASTE HERE]
- Names and paths of objects already existing in Explorer: [PASTE HERE]
- Existing RemoteEvents/RemoteFunctions, their paths, and purpose: [PASTE HERE]
- Systems that may change stats: [e.g., NPCs, tools, rounds, shop, checkpoints]
- Special rules, maximum limits, minimum values, and display format: [PASTE HERE]
Deliver ONLY a complete, functional, ready-to-paste Luau Script, followed by objective installation and testing instructions. Do not create graphical interfaces, DataStore, external modules, new RemoteEvents, LocalScripts, or multiple files, unless I explicitly ask later. The main code must be entirely inside a single markdown block in the format ```lua.
Mandatory technical requirements:
1. Explicitly declare at the beginning, in comments, that the file is a Script and that it must be inserted into ServerScriptService. Use services with game:GetService(), especially Players and ReplicatedStorage only if it is necessary to integrate RemoteEvents informed in the context.
2. When the player joins, create exactly one Folder called leaderstats directly inside the Player, because this is the structure recognized by Roblox's native leaderboard. Understand that subfolders inside leaderstats are not displayed correctly by the default scoreboard: therefore, only stats selected for display should be direct children of leaderstats.
3. Create a separate Folder in the Player, with a configurable name such as PlayerStats or StatsCategories, to organize the internal categories. Inside it, create Folders by category, such as Economy, Combat, and Progress, containing IntValue, NumberValue, BoolValue, or StringValue as needed. For each stat displayed on the scoreboard, keep a clear and synchronized reference with its categorized source. Prefer that the categorized value be the source of truth and that the mirrored leaderstats value be updated by GetPropertyChangedSignal("Value") or an equivalent strategy, avoiding synchronization loops.
4. Centralize the entire definition of categories, stats, ValueBase types, default values, scoreboard visibility, minimum/maximum limits, and logical order in a configuration table at the top. Validate this configuration on the server before creating instances. Handle duplicate names, invalid categories, disallowed types, and non-existent visible stats defensively, with informative warnings without crashing the server.
5. Guarantee idempotency: if structures or values already exist for any reason, reuse only compatible objects or replace them safely and in a documented way. Do not duplicate connections or recreate leaderstats unnecessarily. Perform cleanup of player-associated connections when PlayerRemoving is fired to avoid memory leaks.
6. If I provide existing RemoteEvents that change stats, integrate them only on the server. For each OnServerEvent, rigorously validate the sending Player, argument types, NaN/infinite numbers, acceptable ranges, maximum modification limits, and gameplay conditions described in the context. Never accept final values for currency, damage, XP, kills, inventory, or level from the client. The client may only request an action; the server must decide and calculate the result. If no RemoteEvents are provided, do not invent network integrations.
7. Implement well-named local functions to locate categorized stats, change values with clamp, create structures, and synchronize visible values. All changes must occur on the server. Comment the code in Portuguese in a useful way, explaining architecture decisions and safe integration points with other game systems.
8. Do not use legacy wait(), do not use loadstring, do not use obfuscated code, and do not assume optional objects exist. Use task and defensive checks when necessary. The script must be compatible with current Roblox Studio and Luau with --!strict, as long as the types do not prevent practical execution.
After the code block, write a short section called "Installation and testing" explaining: where to create and paste the Script; how to edit the configuration table; how to test with Start Server and at least two Players; how to check the categories in Explorer; how to confirm that only direct leaderstats values appear on the scoreboard; and how to later integrate reliable reward systems on the server.