roblox-core
Choose Roblox services, script locations, and execution contexts. Use for Luau types, serialization, module loading, streaming, and client-server data model questions.
Install
npx skills add https://github.com/nonlooped/roblox-suite/tree/main/roblox-core
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install nonlooped-roblox-suite@llmmart
git clone https://github.com/nonlooped/roblox-suite.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole nonlooped/roblox-suite collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
roblox-core
Key sources: https://create.roblox.com/docs/en-us/scripting/services, https://create.roblox.com/docs/en-us/luau, https://create.roblox.com/docs/en-us/luau/tables, https://create.roblox.com/docs/en-us/luau/type-checking, https://create.roblox.com/docs/en-us/scripting/locations, https://create.roblox.com/docs/en-us/projects/data-model, https://create.roblox.com/docs/en-us/projects/client-server, https://create.roblox.com/docs/en-us/workspace/streaming, https://create.roblox.com/docs/en-us/scripting/multithreading, https://create.roblox.com/docs/en-us/scripting/attributes
Script initialization
local Service = game:GetService("ServiceName"). Do this once, name the variable after the service.local Module = require(ReplicatedStorage:WaitForChild("Module"))- Local helper functions.
- Connect to events.
Services are the primary way you access engine functionality instead of a traditional standard library.
Modern task library
Use the modern task API; the legacy globals wait(), spawn(), and delay() are deprecated/soft-deprecated:
task.wait(n?): yields for aboutnseconds (default one frame) and returns elapsed time.task.spawn(f, ...): schedulesfto run asynchronously.task.defer(f, ...): defersfuntil after the current event cycle.task.cancel(thread): cancels a thread returned bytask.spawn/task.defer.
For parallel code, task.desynchronize() and task.synchronize() move the current thread between the parallel and serial phases.
Services by purpose
Container / hierarchy services (visible in Explorer, part of the DataModel):
- Workspace (3D content)
- Lighting (environment, atmosphere, post effects)
- ReplicatedStorage / ReplicatedFirst (shared code & assets)
- ServerScriptService (server-only logic)
- StarterGui / StarterPlayer / StarterPack (templates cloned to players)
- Players, Teams, SoundService, etc.
Core runtime & scripting services:
- RunService: Heartbeat fires after physics on both sides; PreSimulation fires before physics on both sides; PreRender is client-only and fires before rendering.
- TweenService (see animation skill)
- CollectionService (tags)
- ContextActionService, UserInputService, GuiService
- ContentProvider (preloading)
Cloud / persistence / cross-server:
- DataStoreService, MemoryStoreService, MessagingService (see roblox-datastores skill)
Monetization:
- MarketplaceService (gamepasses, dev products; see dedicated skill)
- BadgeService, etc.
Other high-value ones: TeleportService, AnalyticsService, HttpService (outbound only + JSONEncode/Decode), PathfindingService, etc.
Discover services with game:GetService (known services) or game:FindService (optional). Avoid using game:GetChildren() for service discovery. Not every DataModel child is a service, and services can be lazily created. Acquire each service once per script/module.
Instance creation best practice
Configure an instance before parenting it to avoid redundant replication and extra changed events:
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(4, 1, 2)
part.Position = Vector3.new(0, 10, 0)
part.Parent = workspace
Set Parent last; do not use the Instance.new("Part", parent) two-argument form.
Types and serialization
Read luau-data-types-and-serialization.md before designing persisted values or debugging serialization. DataStores, JSON, and remotes have different supported types. A successful JSONEncode is a useful check, but it does not prove that a value meets every DataStore constraint.
Type checking
Gradual and opt-in. Use --!strict at the top of a file (it is file-level) or a .luaurc project configuration for project-wide type checking. Add annotations (local x: number, function signatures) for large modules. Inference does a lot of the work. Catches bugs at edit time with zero runtime cost.
Script locations and execution contexts
- ServerScriptService + Script (
RunContext.Server) → server only, with access to server APIs such as DataStores. - ReplicatedStorage → stores shared ModuleScripts/assets. A Script here only runs if its
RunContextis set toClientorServer; use ModuleScripts for shared logic. - StarterGui + LocalScript → per-player client only (inside the cloned PlayerGui).
- ReplicatedFirst + LocalScript → very early client execution (loading screens).
- Actor + Script with
RunContext.Client/Server→ can run Parallel Luau when the code callstask.desynchronize()or usesConnectParallel(). The Actor must be parented to the DataModel and the Script must have an explicit RunContext; placing a Script inside an Actor alone does not parallelize it.require()can be called from parallel contexts only when the module itself is parallel-safe; most engine APIs and many modules are not. - Tools have special execution contexts. HopperBins are deprecated/legacy and should not be used for new work.
Modern Roblox uses BaseScript.RunContext (Legacy, Server, Client, Plugin). Legacy exists only for backward compatibility and is location-dependent; prefer explicit Server or Client for new code. RunContext is set in Studio's Properties window and is read-only at runtime.
Always branch runtime authority with RunService:IsServer() and IsClient(). IsStudio() detects the environment (Studio vs. live), not runtime context, so use it only for test/development guards.
Never put datastore writes, economy, or authoritative gameplay logic anywhere a client can influence it directly.
"Files" and data in Luau/Roblox
Inside a running experience there is no direct filesystem access (security). You cannot open arbitrary files or write player-visible logs.
What you have instead:
- DataStores / MemoryStores for persistent or temporary "save data".
- ModuleScripts for reusable code (
requireworks like a cached module system: a ModuleScript runs once and returns the same value on subsequent requires). - HttpService:JSONEncode/Decode + web calls for external data exchange.
- In Studio: plugins have limited file APIs, and external tools (Rojo, Script Sync) can sync code from the filesystem, but experience scripts never have arbitrary filesystem access.
For complex data you often serialize tables to JSON strings for storage or transmission.
Additional runtime considerations
- Attributes: use
:SetAttribute/GetAttributefor lightweight per-instance data; prefer them over legacy Value objects. - Random: use the
Randomclass (Random.new(seed)) for deterministic or independent random streams instead of globalmath.randomseed. - StreamingEnabled: on the client, instances can stream in/out; always use
WaitForChild/Instance.StreamingModedefensively and avoid hard references to far-away parts. - table utilities:
table.create(n, value),table.find(t, value),table.clone(t), andtable.freeze(t)/table.isfrozen(t)are the modern helpers. - BaseScript.Enabled: disables/enables a script without deleting it.
- ModuleScript caching:
requireexecutes a ModuleScript once per environment and caches the returned value. - Sequence / physical types:
NumberSequence,ColorSequence, andPhysicalPropertiesare common Roblox datatypes for particles, beams, and part materials.
Architecture foundations
- Server authority is the default safe posture.
- Replication is selective and streaming-aware.
- Use ReplicatedStorage for shared modules/assets, ServerScriptService for server logic, StarterGui for client UI entry points.
- CollectionService tags + Attributes for lightweight grouping and data without heavy Instance hierarchies.
- Parallel Luau + Actors when you need CPU-bound work off the main thread.
Scripts
scripts/ServiceHelper.lua: small utilities for safely acquiring services and requiring modules with timeouts.
Reference index
- luau-data-types-and-serialization.md: Choose data types or diagnose serialization failures.
- script-locations-contexts-and-architecture.md: Decide where scripts run or debug loading and replication.
- services-catalog-and-usage.md: Choose a service or load services and modules.
Files (roblox-suite)
-
references
-
luau-data-types-and-serialization.md 4.8 KB
--- read_when: "Choose data types or diagnose serialization failures" last_reviewed: 2026-06-17 --- # Luau data types and serialization rules **Main sources:** https://create.roblox.com/docs/en-us/luau, https://create.roblox.com/docs/en-us/luau/tables, https://create.roblox.com/docs/en-us/luau/type-checking, https://create.roblox.com/docs/en-us/scripting/attributes ## Primitive types - **nil**: The only value that represents "nothing". Different from `false` or `0`. Assigning `nil` to an array index creates a hole; dictionary tables can conceptually hold a nil value for a key, but in practice the key/value pair is removed and `pairs` will not visit it. - **boolean**: `true` or `false`. - **number**: 64-bit double-precision floating point. Be careful with very large integers and money (consider fixed-point or libraries). - **string**: UTF-8 encoded. Must be valid UTF-8 to be stored in DataStores. The `utf8` library iterates Unicode codepoints, not grapheme clusters; for UI text that must respect user-perceived characters, additional handling is required. - **Enum** values: `Enum.Foo.Bar` values (Roblox-specific datatypes, not built-in Luau types). ## Tables Use tables as 1-based arrays or dictionaries. Important limitations for storage (DataStores, JSON): - No functions - No cycles - No custom metatables on the table being serialized (metatables are not preserved) - Only the supported primitives inside Modern table helpers: - `table.create(n, value?)`: preallocate/initialize arrays efficiently. - `table.find(t, value, init?)`: linear search. - `table.clone(t)`: shallow copy. - `table.freeze(t)` / `table.isfrozen(t)`: make a table read-only. ## Roblox datatypes / instances These are engine objects exposed to Luau: - **Instances** (Parts, Models, GUIs, etc.) - **Math / value types**: Vector3, CFrame, UDim2, Color3, Ray, Region3, NumberRange, buffer, etc. `typeof()` returns the type name (e.g. `"CFrame"`, `"Vector3"`). - **Sequences / physical types**: NumberSequence, ColorSequence, PhysicalProperties: commonly used for particle/beam curves and part physical material settings. - **Attributes**: lightweight key/value storage on any Instance via `:SetAttribute`/`:GetAttribute`; prefer over legacy Value objects. - **userdata**: Rarely used directly in modern Luau; most engine objects are Instances or datatypes. These have properties and methods but are opaque for pure Luau operations like `pairs()` in some cases. ## Serialization for DataStores vs networking **DataStores** store data as JSON. Supported: nil, boolean, number, string, buffer, and tables containing only those types recursively. **RemoteEvent / RemoteFunction** use Roblox's own binary replication, not JSON. They can pass many Roblox datatypes including `Instance`, `Enum`, `CFrame`, `Vector3`, `Color3`, etc. DataStores cannot store those values directly. Supported after JSON round-trip (DataStores / HttpService): - nil, boolean, number, string, buffer - Tables containing only the above (recursively, with no cycles) **Never store in DataStores / JSON:** - `inf`, `-inf`, `nan` (they are not JSON numbers; Open Cloud represents existing values with tagged objects) - Functions - Threads / coroutines - **Instances** or other Roblox datatypes (`Vector3`, `CFrame`, `Color3`, `NumberSequence`, etc.) unless you convert them to plain tables or strings first - Invalid UTF-8 byte sequences in strings - Cyclic tables **Debugging tip**: ```lua local HttpService = game:GetService("HttpService") print(HttpService:JSONEncode(yourData)) ``` A clean JSONEncode is a good sanity check, but it does not guarantee DataStore success. In particular, DataStores have their own key/value size limits, quotas, and constraints such as invalid UTF-8 and non-finite numbers. `nil` values become `null` in JSON but are allowed in DataStores. ## Randomness Use the `Random` class for deterministic or independent random streams: ```lua local rng = Random.new(12345) local roll = rng:NextInteger(1, 6) ``` Avoid global `math.randomseed` in new code; it mutates shared state and can cause surprising interactions across modules. ## Type checking Luau supports gradual typing: - `--!strict` is file-level; add it at the top of a script. - A `.luaurc` file is the common way to enable type checking project-wide. - Use annotations: `local gold: number = 100` - Function signatures: `function grantGold(player: Player, amount: number): boolean` This catches many bugs at edit time with zero runtime cost. See the type-checking subpage for more. Open Cloud returns existing non-finite numbers as `{"m": null, "t": "numeric", "v": "inf"}`, with `"-inf"` or `"nan"` for the other cases. Handle these objects explicitly in inspection/export tools; keep new player data finite. Source: https://create.roblox.com/docs/cloud/guides/data-stores#non-finite-numbers. -
script-locations-contexts-and-architecture.md 4.1 KB
--- read_when: "Decide where scripts run or debug loading and replication" last_reviewed: 2026-06-17 --- # Script locations, execution contexts, and architecture **Main source:** https://create.roblox.com/docs/en-us/scripting/locations **Related:** https://create.roblox.com/docs/en-us/projects/client-server, https://create.roblox.com/docs/en-us/projects/data-model, https://create.roblox.com/docs/en-us/workspace/streaming, https://create.roblox.com/docs/en-us/scripting/multithreading ## Where code runs - **ServerScriptService + Script**: Runs only on the server. Has full access to DataStoreService, TeleportService, etc. Never replicates to clients. Use `RunContext.Server`; the `Legacy` setting exists only for backward compatibility. - **ReplicatedStorage**: Holds shared ModuleScripts and assets. A Script placed here only runs if its `RunContext` is explicitly `Client` or `Server`; it does **not** run by default. Put shared logic in ModuleScripts and require them from client/server scripts. - **StarterGui + LocalScript**: Clones into each player's PlayerGui. Runs only on that client's machine. All UI logic belongs here or in required client modules. - **ReplicatedFirst + LocalScript**: Runs as early as possible on the client (before most other content replicates). Use for loading screens and critical early code. - **Actor + Script** (placed inside models): Can run Parallel Luau when the Script uses `RunContext.Client`/`Server`, the Actor is parented to the DataModel, and the code explicitly calls `task.desynchronize()` / `task.synchronize()` (or uses `ConnectParallel()`). Placing a Script inside an Actor alone does not parallelize it. `require()` can be called from parallel contexts only when the module itself is parallel-safe; most engine APIs and many modules are not. - Tools have special execution contexts. HopperBins are deprecated/legacy and should not be used for new work. Modern execution is controlled by `BaseScript.RunContext` (`Legacy`, `Server`, `Client`, `Plugin`). `Legacy` is location-dependent and exists only for backward compatibility; prefer explicit `Server`/`Client` for new code. `RunContext` is set in Studio's Properties window and is read-only at runtime. ## Context checking Always use: ```lua local RunService = game:GetService("RunService") if RunService:IsServer() then -- authoritative logic elseif RunService:IsClient() then -- UI, input, prediction, cosmetics end ``` `IsStudio()` detects the environment (Studio vs. live), not runtime context. Use it only for test/development guards, never as a substitute for `IsServer`/`IsClient`. ## Recommended Folder structure - **ServerScriptService** - DataManager - Economy - GamepassHandler - ServerMain (or multiple small scripts) - **ReplicatedStorage** - Modules (pure functions, constants, types) - SharedAssets (animations, sounds, models that both sides need) - Remotes (folder containing all RemoteEvent/RemoteFunction) - **StarterGui** - MainHUD (ScreenGui) - Menus (multiple ScreenGuis) - ClientControllers (LocalScripts or folders with required modules) - **Workspace** - Map, interactive objects, etc. - **ServerStorage** - Server-only assets and temporary data. ## Parallel Luau (Actors) For CPU-heavy work that doesn't need to yield often: 1. Create an Actor instance. 2. Parent the Actor to the DataModel. 3. Put your Script inside the Actor and set its `RunContext` to `Client` or `Server`. 4. Use `task.desynchronize()` / `task.synchronize()` around the heavy work. See the multithreading docs for details and limitations. ## Load order Roblox does not guarantee load order. Always use: - `WaitForChild` - `FindFirstChild` + defensive checks - Proper initialization events or module setup functions ## Script control - `BaseScript.Enabled` can stop or start a Script/LocalScript without deleting it. - A `ModuleScript` runs once per requiring environment and caches its returned value. ## Architecture summary - Server = truth - Client = presentation + input - ReplicatedStorage = shared pure logic and assets - Clear boundaries + consistent naming prevent most "why doesn't this replicate" and "why can the client do this" bugs. -
services-catalog-and-usage.md 3.4 KB
--- read_when: "Choose a service or load services and modules" last_reviewed: 2026-06-17 --- # Services catalog and usage patterns **Main source:** https://create.roblox.com/docs/en-us/scripting/services ## The fundamental pattern Acquire the services a script needs at initialization: ```lua local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") -- etc. ``` Acquire each service **once** per script or module. Name the variable exactly after the service (convention). Use `WaitForChild` when requiring modules or waiting for objects whose load order is uncertain. ## Container services (DataModel children) These form the structure of every place: - **Workspace**: Everything that exists in the 3D world. - **Lighting**: Global lighting, Atmosphere, Sky, Clouds, post-processing effects. - **ReplicatedStorage**: Shared assets and ModuleScripts available to both client and server. ModuleScripts can be required from either side; Scripts here only run with the correct `RunContext`. - **ReplicatedFirst**: Content that must replicate before anything else (use sparingly; mostly for loading screens). LocalScripts here run early. - **ServerScriptService**: Server-only scripts and modules (never replicates to clients). - **StarterGui / StarterPlayer / StarterPack**: Templates that get cloned into each player. - **Players**: Contains all Player instances and their characters. - **SoundService**: Global audio configuration and SoundGroups. For service discovery, use: - `game:GetService("ServiceName")` for known services. - `game:FindService("Name")` for optional services (returns nil if missing). `GetChildren` and `GetDescendants` return DataModel descendants, not a reliable service list; prefer `GetService`/`FindService` for services. ## Core scripting services - **RunService**: PreSimulation fires before physics on both client and server; Heartbeat fires every frame after physics on both sides; PreRender is client-only and fires before rendering; IsServer(), IsClient(), IsStudio(), BindToRenderStep. - **TweenService**: Property interpolation (see animation skill). - **CollectionService**: Tag instances for easy grouping without folders. Tags replicate. - **ContextActionService**: Bind actions to input in a context-aware way (great for tools and menus). - **ContentProvider**: PreloadAsync for assets to avoid hitches. ## Cloud and cross-server services - **DataStoreService** - **MemoryStoreService** (high-throughput temporary data) - **MessagingService** (publish/subscribe between servers in the same universe) ## Monetization and social - **MarketplaceService** - **BadgeService** - **GroupService** - **AvatarEditorService**, **AvatarCreationService** ## Other services - **TeleportService** - **AnalyticsService** - **HttpService** (outbound HTTP + JSONEncode/Decode only) - **PathfindingService** - **Debris** (schedule automatic cleanup of objects) - **GuiService**, **UserInputService**, **VRService** ## Best practices - Never call `GetService` inside a hot loop. - Cache the service reference at the top of the file. - For optional services, use `FindService` and check for nil. - Many services have both global methods and events: read the class reference. - Prefer `task.wait`, `task.spawn`, `task.defer`, and `task.cancel` over deprecated `wait()`, `spawn()`, and `delay()`. See the other references in this folder for Luau types, script locations, and architecture.
-
-
scripts
-
ServiceHelper.lua 1 KB · in bundle
-
-
SKILL.md 8.5 KB
--- name: roblox-core description: "Choose Roblox services, script locations, and execution contexts. Use for Luau types, serialization, module loading, streaming, and client-server data model questions." last_reviewed: 2026-06-17 --- # roblox-core **Key sources:** https://create.roblox.com/docs/en-us/scripting/services, https://create.roblox.com/docs/en-us/luau, https://create.roblox.com/docs/en-us/luau/tables, https://create.roblox.com/docs/en-us/luau/type-checking, https://create.roblox.com/docs/en-us/scripting/locations, https://create.roblox.com/docs/en-us/projects/data-model, https://create.roblox.com/docs/en-us/projects/client-server, https://create.roblox.com/docs/en-us/workspace/streaming, https://create.roblox.com/docs/en-us/scripting/multithreading, https://create.roblox.com/docs/en-us/scripting/attributes ## Script initialization 1. `local Service = game:GetService("ServiceName")`. Do this once, name the variable after the service. 2. `local Module = require(ReplicatedStorage:WaitForChild("Module"))` 3. Local helper functions. 4. Connect to events. Services are the primary way you access engine functionality instead of a traditional standard library. ## Modern task library Use the modern `task` API; the legacy globals `wait()`, `spawn()`, and `delay()` are deprecated/soft-deprecated: - `task.wait(n?)`: yields for about `n` seconds (default one frame) and returns elapsed time. - `task.spawn(f, ...)`: schedules `f` to run asynchronously. - `task.defer(f, ...)`: defers `f` until after the current event cycle. - `task.cancel(thread)`: cancels a thread returned by `task.spawn`/`task.defer`. For parallel code, `task.desynchronize()` and `task.synchronize()` move the current thread between the parallel and serial phases. ## Services by purpose **Container / hierarchy services** (visible in Explorer, part of the DataModel): - Workspace (3D content) - Lighting (environment, atmosphere, post effects) - ReplicatedStorage / ReplicatedFirst (shared code & assets) - ServerScriptService (server-only logic) - StarterGui / StarterPlayer / StarterPack (templates cloned to players) - Players, Teams, SoundService, etc. **Core runtime & scripting services:** - RunService: Heartbeat fires after physics on both sides; PreSimulation fires before physics on both sides; PreRender is client-only and fires before rendering. - TweenService (see animation skill) - CollectionService (tags) - ContextActionService, UserInputService, GuiService - ContentProvider (preloading) **Cloud / persistence / cross-server:** - DataStoreService, MemoryStoreService, MessagingService (see roblox-datastores skill) **Monetization:** - MarketplaceService (gamepasses, dev products; see dedicated skill) - BadgeService, etc. **Other high-value ones:** TeleportService, AnalyticsService, HttpService (outbound only + JSONEncode/Decode), PathfindingService, etc. Discover services with `game:GetService` (known services) or `game:FindService` (optional). Avoid using `game:GetChildren()` for service discovery. Not every DataModel child is a service, and services can be lazily created. Acquire each service once per script/module. ## Instance creation best practice Configure an instance before parenting it to avoid redundant replication and extra changed events: ```lua local part = Instance.new("Part") part.Anchored = true part.Size = Vector3.new(4, 1, 2) part.Position = Vector3.new(0, 10, 0) part.Parent = workspace ``` Set `Parent` last; do not use the `Instance.new("Part", parent)` two-argument form. ## Types and serialization Read [luau-data-types-and-serialization.md](references/luau-data-types-and-serialization.md) before designing persisted values or debugging serialization. DataStores, JSON, and remotes have different supported types. A successful `JSONEncode` is a useful check, but it does not prove that a value meets every DataStore constraint. ## Type checking Gradual and opt-in. Use `--!strict` at the top of a file (it is file-level) or a `.luaurc` project configuration for project-wide type checking. Add annotations (`local x: number`, function signatures) for large modules. Inference does a lot of the work. Catches bugs at edit time with zero runtime cost. ## Script locations and execution contexts - ServerScriptService + Script (`RunContext.Server`) → server only, with access to server APIs such as DataStores. - ReplicatedStorage → stores shared ModuleScripts/assets. A Script here only runs if its `RunContext` is set to `Client` or `Server`; use ModuleScripts for shared logic. - StarterGui + LocalScript → per-player client only (inside the cloned PlayerGui). - ReplicatedFirst + LocalScript → very early client execution (loading screens). - Actor + Script with `RunContext.Client/Server` → can run Parallel Luau when the code calls `task.desynchronize()` or uses `ConnectParallel()`. The Actor must be parented to the DataModel and the Script must have an explicit RunContext; placing a Script inside an Actor alone does not parallelize it. `require()` can be called from parallel contexts only when the module itself is parallel-safe; most engine APIs and many modules are not. - Tools have special execution contexts. HopperBins are deprecated/legacy and should not be used for new work. Modern Roblox uses `BaseScript.RunContext` (`Legacy`, `Server`, `Client`, `Plugin`). `Legacy` exists only for backward compatibility and is location-dependent; prefer explicit `Server` or `Client` for new code. `RunContext` is set in Studio's Properties window and is read-only at runtime. Always branch runtime authority with `RunService:IsServer()` and `IsClient()`. `IsStudio()` detects the environment (Studio vs. live), not runtime context, so use it only for test/development guards. **Never** put datastore writes, economy, or authoritative gameplay logic anywhere a client can influence it directly. ## "Files" and data in Luau/Roblox Inside a running experience there is **no direct filesystem access** (security). You cannot open arbitrary files or write player-visible logs. What you have instead: - DataStores / MemoryStores for persistent or temporary "save data". - ModuleScripts for reusable code (`require` works like a cached module system: a ModuleScript runs once and returns the same value on subsequent requires). - HttpService:JSONEncode/Decode + web calls for external data exchange. - In Studio: plugins have limited file APIs, and external tools (Rojo, Script Sync) can sync code from the filesystem, but experience scripts never have arbitrary filesystem access. For complex data you often serialize tables to JSON strings for storage or transmission. ## Additional runtime considerations - **Attributes**: use `:SetAttribute`/`GetAttribute` for lightweight per-instance data; prefer them over legacy Value objects. - **Random**: use the `Random` class (`Random.new(seed)`) for deterministic or independent random streams instead of global `math.randomseed`. - **StreamingEnabled**: on the client, instances can stream in/out; always use `WaitForChild`/`Instance.StreamingMode` defensively and avoid hard references to far-away parts. - **table utilities**: `table.create(n, value)`, `table.find(t, value)`, `table.clone(t)`, and `table.freeze(t)`/`table.isfrozen(t)` are the modern helpers. - **BaseScript.Enabled**: disables/enables a script without deleting it. - **ModuleScript caching**: `require` executes a ModuleScript once per environment and caches the returned value. - **Sequence / physical types**: `NumberSequence`, `ColorSequence`, and `PhysicalProperties` are common Roblox datatypes for particles, beams, and part materials. ## Architecture foundations - Server authority is the default safe posture. - Replication is selective and streaming-aware. - Use ReplicatedStorage for shared modules/assets, ServerScriptService for server logic, StarterGui for client UI entry points. - CollectionService tags + Attributes for lightweight grouping and data without heavy Instance hierarchies. - Parallel Luau + Actors when you need CPU-bound work off the main thread. ## Scripts - `scripts/ServiceHelper.lua`: small utilities for safely acquiring services and requiring modules with timeouts. <!-- catalog:references:start --> ## Reference index - [luau-data-types-and-serialization.md](references/luau-data-types-and-serialization.md): Choose data types or diagnose serialization failures. - [script-locations-contexts-and-architecture.md](references/script-locations-contexts-and-architecture.md): Decide where scripts run or debug loading and replication. - [services-catalog-and-usage.md](references/services-catalog-and-usage.md): Choose a service or load services and modules. <!-- catalog:references:end -->
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.