Dynamic Obby: Platforms, Traps, and Obstacles in Luau
Generate a robust controller for obby obstacles in Roblox, including platforms that move between points, disappearing platforms, spikes, lasers, rotating parts, pushers, and damage zones. The system is folder-based and driven by Attributes and Tags, making it possible to configure maps without editing the code for every new obstacle.
Ideal for developers who want a professional, safe, and scalable foundation for obbies, towers, and parkour maps. The prompt requests the specific project Explorer context and forces the AI to deliver a commented server Luau Script, ready to paste, along with clear setup and testing instructions in Roblox Studio.
Act as a senior Roblox developer, specialized in Luau, Roblox Studio, server-authoritative multiplayer systems, character physics, and scalable architecture for obbies. Generate a single complete, robust, commented Luau Script ready to be pasted into Roblox Studio. The script must be a **Script** and must be placed in **ServerScriptService**, with the suggested name `ObbyObstacleController`. It will be the central controller for moving platforms, traps, and dynamic obstacles. Do not create a LocalScript as a required dependency, and do not delegate important decisions to the client. If my context mentions RemoteEvents or RemoteFunctions, use them only if they are truly necessary and fully validate any data received on the server; never trust the client for damage, checkpoints, rewards, inventory, coins, teleportation, or completion state. Before generating the code, consider and incorporate the context below. If any field is empty, assume a sensible default structure and clearly document that assumption after the code: - Main map/obby folder in Workspace: `[COLE_AQUI]` - Moving platforms folder: `[COLE_AQUI]` - Traps folder: `[COLE_AQUI]` - Rotating/dynamic obstacles folder: `[COLE_AQUI]` - Relevant Models/Parts names or paths in the Explorer: `[COLE_AQUI]` - Existing RemoteEvents/RemoteFunctions and purpose: `[COLE_AQUI]` - Existing damage/health system (if any): `[COLE_AQUI]` - Checkpoints, spawn, and respawn rules: `[COLE_AQUI]` - CollectionService Tag conventions already in use: `[COLE_AQUI]` - Attribute conventions already in use: `[COLE_AQUI]` - Performance constraints, estimated player count, and target devices: `[COLE_AQUI]` Design the system to be configurable through **Attributes** on Models or BaseParts, avoiding hardcoded paths in the code whenever possible. Use `CollectionService` to detect objects by Tags and support, at minimum, the following tags and settings. If names conflict with my conventions, prioritize the context I provided: 1. Tag `MovingPlatform`: moves a Part or Model between `PointA` and `PointB` (child BaseParts or references via ObjectValue), with Attributes `Speed`, `WaitTime`, `LoopMode` (`PingPong` or `Loop`) and `EasingStyle` when applicable. 2. Tag `DisappearPlatform`: platform that detects character touch, waits `DisappearDelay`, becomes non-collidable and invisible for `ResetTime`, and returns safely. Include protection against multiple concurrent touches. 3. Tag `DamageTrap`: part or Model that deals configurable damage via `Damage`, with per-player cooldown defined in `HitCooldown`. If `InstantKill` is true, eliminate the Humanoid in a controlled way on the server. 4. Tag `RotatingObstacle`: rod, arm, or rotating Model around a pivot, configured by `RotationSpeed`, `RotationAxis`, and, if necessary, `Direction`. 5. Tag `PushObstacle`: obstacle that applies a safe, limited physical impulse to the character, configured by `PushForce`, `PushDirection`, and `PushCooldown`. Use modern APIs and avoid legacy `BodyVelocity` when a suitable alternative exists. The controller must work with Parts and Models. For Models, use `PrimaryPart` or `GetPivot`/`PivotTo` appropriately and explain in the configuration comment how to prepare each Model. Continuous movements should use `TweenService` when appropriate, with predictable server behavior. For physical obstacles, consider network ownership, anchoring, and collisions to avoid inconsistent results. Do not use heavy per-object loops with `while true do` without control; prefer connections, managed tasks, Tween callbacks, and modular initialization within the same file. Handle objects added dynamically by Tags during runtime when feasible. Implement clear utility functions to: find the Humanoid and Player from a touched part; apply damage with debounce per player and per trap; read Attributes with default values and type/range validation; locate movement points; register each obstacle type; and emit useful warnings with `warn` for invalid configuration, without bringing down the entire system. Prevent connection leaks and ensure that dead, removed, or respawned characters do not cause errors. Deliver the response in this order: 1. A brief section called `Expected Explorer structure`, explaining folders, Tags, Attributes, and preparation of points/pivots. 2. The full code in **a single Markdown block** exactly in the format ```lua ... ```. Do not use pseudocode, omitted sections, `...`, or incomplete functions. Include comments in Portuguese in the code, especially in areas the user may configure. 3. A section `How to test in Roblox Studio` with practical steps: create Tags/Attributes, test with Play and Start Server/Players, check Output, validate damage, movement, reset, and multiplayer behavior. 4. A short section `Recommended adjustments`, indicating which Attributes to change to modify speed, damage, times, and force. Prioritize compatibility with current Roblox APIs, readability, tolerance for configuration errors, performance for multiple players, and multiplayer safety. Do not invent external systems, assets, or RemoteEvents that are not necessary. If the provided context is incomplete, deliver a functional implementation based on the default structure and highlight all assumptions made.