Skip to main content
Reading time: ~35 minutes
ScriptableObjects in CORP are data containers that allow you to define reusable assets and configuration. They provide a Unity-like approach to managing game data separate from your code.

Table of Contents

What are ScriptableObjects?

ScriptableObjects are classes that extend ScriptableObject and define data structures for game assets. They separate data from logic, making it easy to create and modify game content without changing code.

Key Features

  • Data Assets: Store configuration and content as assets
  • Reusability: Create multiple instances with different data
  • Serialization: Automatically serialized and deserialized
  • Type Safety: Full TypeScript type checking
  • Lazy Loading: Load assets on-demand or cache them
  • References: ScriptableObjects can reference other ScriptableObjects

Benefits

  • Designer-Friendly: Non-programmers can create and edit assets
  • Version Control: Assets are separate files, easy to track changes
  • Modularity: Organize game data independently from code
  • Performance: Shared data loaded once and reused

Creating ScriptableObjects

Basic ScriptableObject

ScriptableObject with Complex Data

ScriptableObject with References

ScriptableObjects can reference other ScriptableObjects:

The Data Namespace

The Data namespace provides utilities for working with serialized data in CORP. It defines special data types that are automatically deserialized when loaded, and includes factory methods for creating type-safe references and serialized values.

Available Types

The Data namespace supports these special serialized types:

Factory Methods

Create these special types using the factory:

Type Guards

Check if a value is a special data type:

Why Use Data.factory?

  • Type Safety: Compile-time validation of structure
  • Autocomplete: IDE suggestions for all properties
  • Automatic Deserialization: Special types are automatically converted when loaded
  • Consistency: Standardized format across all assets
  • Maintainability: Easier to refactor and update
  • Documentation: Self-documenting code
Recommendation: Always use Data.factory methods when creating special references or serialized types in ModuleScript assets for better development experience and fewer runtime errors.

Loading ScriptableObjects

Using fetch()

The fetch() method loads any ScriptableObject by path:
VFS Path Convention: Use %assets% to reference the collapsed assets directory. During bootstrap, all Gamepack assets are collected into a centralized location accessible via this path. See Unreal System - Asset Management for more details.

Using fetchThis()

When loading from within a ScriptableObject class:

Using makeLoader()

For lazy-loaded, cached access:

In Components

Asset Files

Create asset files as JSON in your assets folder:
Save as MagicSword.scriptable or MagicSword.json in your assets folder.

ModuleScript Format

Alternatively, use a ModuleScript:

Using the Data Namespace

When creating ModuleScript ScriptableObjects, use the Data namespace for type-safe asset creation:
Benefits of using Data.factory.createScriptableObjectData:
  • Type safety and autocomplete
  • Validates the structure at compile time
  • Cleaner, more readable syntax
  • Consistent format across assets

Referencing Other ScriptableObjects in ModuleScripts

Use Data.factory.createScriptableObjectReference for references:

Serializing Roblox Types

Use Data.factory methods to serialize Vector3, Color3, and other Roblox types:
When loaded, these serialized types are automatically converted back to their Roblox equivalents:
Best Practice: Always use Data.factory methods when creating ModuleScript ScriptableObjects for better type safety and maintainability. The serialization system handles automatic deserialization when assets are loaded.

Configuration Format

For Roblox Studio, use Configuration instances:

With References

Reference other ScriptableObjects in asset data:

With Roblox Types

Use serialized formats for Roblox types:
These are automatically converted to Color3 and Vector3 when loaded.

Registration

ScriptableObjects must be registered in your Gamepack’s exports.

Registering in Gamepack

Create exports/scriptableobjects.ts:
Naming Convention: Always use snake_case for ScriptableObject mapping names. This ensures consistency with components and macros.

Common Use Cases

1. Weapon System

2. Enemy Configuration

3. Level Configuration

4. Item Database

5. Character Presets

Best Practices

1. Use snake_case for Names

2. Provide Default Values

3. Use Data.factory for ModuleScript Assets

4. Use makeLoader for Frequently Accessed Assets

5. Organize Assets by Type

6. Document ScriptableObject Properties

6. Validate Data on Load

Next Steps

  • Macros: Learn about instance transformation
  • Unreal System: Understand Gamepack integration
  • Networking: NetworkedVariables can replicate ScriptableObjects
  • Examples: See complete implementations

Master ScriptableObjects for flexible, designer-friendly game data! 📦