> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolisk.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Core Concepts

> GameObjects, Components, Behaviors, and lifecycle fundamentals

<Note>**Reading time:** \~25 minutes</Note>

This guide covers the fundamental building blocks of CORP: GameObjects, Components, and Behaviors. Understanding these concepts is essential for developing games with the framework.

## GameObjects

GameObjects are the fundamental entities in your game world. Like Unity, every object in your game is represented by a GameObject. They act as containers for Components and form hierarchies through parent-child relationships.

### Creating GameObjects

```typescript theme={null}
import { GameObject } from "CORP/shared/componentization/game-object";

// Create a new GameObject
const player = new GameObject("Player");

// Create with a specific Roblox Instance
const actor = new Instance("Actor");
const npc = GameObject.fromInstance(actor, "NPC");
```

### GameObject Hierarchy

GameObjects can be organized in parent-child hierarchies:

```typescript theme={null}
const parent = new GameObject("Parent");
const child = new GameObject("Child");

// Set parent
child.setParent(parent);

// Get parent
const parentObj = child.getParent(); // Returns GameObject | Scene | undefined

// Get children
const children = parent.getChildren(); // Returns GameObject[]

// Get all descendants
const descendants = parent.getDescendants(); // Returns GameObject[]
```

### GameObject Transform

Each GameObject has a transform (CFrame) that defines its position and rotation:

```typescript theme={null}
// Get transform
const transform = gameObject.getTransform();

// Set transform
gameObject.setTransform(new CFrame(0, 10, 0));

// Get position
const position = gameObject.getPosition();

// Get the underlying Roblox Instance
const instance = gameObject.getInstance();
```

### GameObject Lifecycle

```typescript theme={null}
const gameObject = new GameObject("MyObject");

// Add components
gameObject.addComponent(MyComponent);

// Get components
const component = gameObject.getComponent(MyComponent);

// Check if has component
if (gameObject.hasComponent(MyComponent)) {
    // Do something
}

// Remove a component
gameObject.removeComponent(MyComponent);

// Destroy the GameObject (removes all components and cleans up)
gameObject.destroy();
```

### GameObject Events

GameObjects fire events during their lifecycle:

```typescript theme={null}
// Fired when a component is added
gameObject.componentAdded.connect((component) => {
    print(`Component added: ${component}`);
});

// Fired when a component is about to be removed
gameObject.componentRemoving.connect((component) => {
    print(`Component removing: ${component}`);
});

// Fired when a component spawns (for NetworkBehaviors)
gameObject.componentSpawned.connect((component) => {
    print(`Component spawned: ${component}`);
});

// Fired when GameObject is being removed
gameObject.removing.connect(() => {
    print("GameObject is being destroyed!");
});

// Fired when parent changes
gameObject.ancestryChanged.connect((gameObject, newParent) => {
    print(`Ancestry changed to: ${newParent}`);
});
```

## Components

Components define the behavior and data of GameObjects. All functionality in CORP is built using Components.

### The Component Base Class

The `Component` class is the abstract base for all components:

```typescript theme={null}
import { Component } from "CORP/shared/componentization/component";
import { GameObject } from "CORP/shared/componentization/game-object";

export class MyComponent extends Component {
    // Execution order (lower numbers run first)
    public readonly executionOrder = 0;

    public constructor(gameObject: GameObject) {
        super(gameObject);
    }

    // Required lifecycle methods
    public onStart(): void {
        // Initialization logic
    }

    public willRemove(): void {
        // Cleanup logic
    }

    // Required: return the ModuleScript that defines this component
    protected getSourceScript(): ModuleScript {
        return script as ModuleScript;
    }
}
```

### Component Lifecycle

Components follow a strict lifecycle:

#### 1. Construction

```typescript theme={null}
public constructor(gameObject: GameObject) {
    super(gameObject);
    // Component is instantiated
    // Don't access other components here!
}
```

#### 2. willStart() (Optional)

```typescript theme={null}
public willStart(): void {
    // Called before onStart
    // Use for pre-initialization setup
}
```

#### 3. initialize()

```typescript theme={null}
public initialize(): void {
    // Called internally by CORP
    // Calls onStart() by default
}
```

#### 4. onStart() (Required)

```typescript theme={null}
public onStart(): void {
    // Main initialization
    // Safe to access other components here
    const other = this.getComponent(OtherComponent);
}
```

#### 5. onPropertiesApplied() (Optional)

```typescript theme={null}
public onPropertiesApplied(): void {
    // Called after properties are set via serialization
    // Use to react to deserialized data
}
```

#### 6. willRemove() (Required)

```typescript theme={null}
public willRemove(): void {
    // Called before component is destroyed
    // Clean up connections, instances, etc.
}
```

#### 7. remove()

```typescript theme={null}
// Call to destroy the component
component.remove();
```

### Accessing Other Components

```typescript theme={null}
export class PlayerController extends Behavior {
    private health: HealthComponent | undefined;

    public onStart(): void {
        // Get a component on the same GameObject
        this.health = this.getComponent(HealthComponent);

        // Get a component by string path
        const comp = this.getComponent("path.to.Component");

        // Check if component exists
        if (this.gameObject.hasComponent(HealthComponent)) {
            // Do something
        }
    }

    protected getSourceScript(): ModuleScript {
        return script as ModuleScript;
    }

    public willRemove(): void {}
}
```

### Component Shortcuts

Components provide convenient shortcuts for common operations:

```typescript theme={null}
export class MyComponent extends Behavior {
    public onStart(): void {
        // Get transform
        const transform = this.getTransform();

        // Set transform
        this.setTransform(new CFrame(0, 10, 0));

        // Get position
        const pos = this.getPosition();

        // Get GameObject name
        const name = this.getName();

        // Get underlying Roblox Instance
        const instance = this.getInstance();

        // Get another component
        const other = this.getComponent(OtherComponent);

        // Destroy the entire GameObject
        this.destroy();
    }

    protected getSourceScript(): ModuleScript {
        return script as ModuleScript;
    }

    public willRemove(): void {}
}
```

### Execution Order

Control the order in which components are initialized:

```typescript theme={null}
export class FirstComponent extends Behavior {
    public readonly executionOrder = 0; // Runs first

    // ... rest of component
}

export class SecondComponent extends Behavior {
    public readonly executionOrder = 10; // Runs second

    // ... rest of component
}
```

## Behaviors

`Behavior` is a specialized subclass of `Component` that adds serialization support. Most of your components should extend `Behavior` rather than `Component`.

### Why Use Behavior?

* **Serialization**: Automatically serialize component state
* **State Management**: Track and restore component data
* **Editor Support**: Enable properties to be edited in the future editor

### Creating a Behavior

```typescript theme={null}
import { Behavior } from "CORP/shared/componentization/behavior";
import { GameObject } from "CORP/shared/componentization/game-object";
import { SerializeField } from "CORP/shared/serialization/serialize-field";

export class PlayerStats extends Behavior {
    @SerializeField
    public maxHealth: number = 100;

    @SerializeField
    public speed: number = 16;

    private currentHealth: number = 100;

    public constructor(gameObject: GameObject) {
        super(gameObject);
    }

    public onStart(): void {
        this.currentHealth = this.maxHealth;
    }

    public takeDamage(amount: number): void {
        this.currentHealth = math.max(0, this.currentHealth - amount);
        
        if (this.currentHealth === 0) {
            this.onDeath();
        }
    }

    private onDeath(): void {
        print(`${this.getName()} has died!`);
        this.destroy();
    }

    public willRemove(): void {
        // Cleanup
    }

    protected getSourceScript(): ModuleScript {
        return script as ModuleScript;
    }
}
```

### Serializable Properties

Use the `@SerializeField` decorator to mark properties for serialization:

```typescript theme={null}
import { SerializeField } from "CORP/shared/serialization/serialize-field";

export class ItemPickup extends Behavior {
    @SerializeField
    public itemName: string = "Health Potion";

    @SerializeField
    public value: number = 50;

    @SerializeField
    public respawnTime: number = 30;

    // This won't be serialized
    private timeSincePickup: number = 0;

    // ... rest of component
}
```

### Serialization Support

Behavior supports serializing various types:

```typescript theme={null}
export class ComplexComponent extends Behavior {
    @SerializeField
    public position: Vector3 = new Vector3(0, 0, 0); // ✓ Supported

    @SerializeField
    public color: Color3 = new Color3(1, 1, 1); // ✓ Supported

    @SerializeField
    public enabled: boolean = true; // ✓ Supported

    @SerializeField
    public count: number = 0; // ✓ Supported

    @SerializeField
    public name: string = "Default"; // ✓ Supported

    @SerializeField
    public config: { [key: string]: number } = {}; // ✓ Supported (plain tables)

    // Note: Functions, threads, and userdata cannot be serialized
}
```

### State Serialization

```typescript theme={null}
export class Checkpoint extends Behavior {
    @SerializeField
    public checkpointId: number = 1;

    @SerializeField
    public position: Vector3 = new Vector3(0, 5, 0);

    public saveState(): void {
        // Get serialized state
        const state = this.serializeState();
        print("Saved state:", state);
    }

    protected getSourceScript(): ModuleScript {
        return script as ModuleScript;
    }

    public onStart(): void {}
    public willRemove(): void {}
}
```

## Garbage Collection

CORP provides a `Collector` utility for managing resources:

```typescript theme={null}
import { Behavior } from "CORP/shared/componentization/behavior";
import { GameObject } from "CORP/shared/componentization/game-object";

export class ConnectionManager extends Behavior {
    // Collector is available in all Behaviors
    public onStart(): void {
        // Add connections to be cleaned up automatically
        const connection = someSignal.connect(() => {});
        this.collector.add(connection);

        // Add instances to be destroyed
        const part = new Instance("Part");
        this.collector.add(part);

        // Add custom cleanup functions
        this.collector.add(() => {
            print("Custom cleanup!");
        });
    }

    public willRemove(): void {
        // Collector.teardown() is called automatically
        // All added connections and instances are cleaned up
    }

    protected getSourceScript(): ModuleScript {
        return script as ModuleScript;
    }
}
```

## Component Configuration

When adding components, you can configure their initial properties:

```typescript theme={null}
import { GameObject } from "CORP/shared/componentization/game-object";

const player = new GameObject("Player");

// Add component with configuration
player.addComponent(PlayerStats, {
    maxHealth: 150,
    speed: 20
});

// The component will have these values when onStart() is called
```

## Component Dependencies

Use the `@RequiresComponent` decorator to enforce dependencies:

```typescript theme={null}
import RequiresComponent from "CORP/shared/componentization/decorators/requires-component";
import { NetworkObject } from "CORP/shared/networking/network-object";

@RequiresComponent(NetworkObject)
export class NetworkedPlayerController extends NetworkBehavior {
    public onStart(): void {
        // NetworkObject is guaranteed to exist
        const netObj = this.getComponent(NetworkObject)!;
    }

    // ... rest of component
}
```

## Best Practices

### 1. Use Behaviors for Game Logic

```typescript theme={null}
// ✓ Good
export class GameLogic extends Behavior { }

// ✗ Avoid (unless you need the base Component)
export class GameLogic extends Component { }
```

### 2. Initialize in onStart(), Not Constructor

```typescript theme={null}
// ✓ Good
export class MyComponent extends Behavior {
    private other: OtherComponent | undefined;

    public onStart(): void {
        this.other = this.getComponent(OtherComponent);
    }
}

// ✗ Bad (other components may not exist yet)
export class MyComponent extends Behavior {
    private other: OtherComponent;

    public constructor(gameObject: GameObject) {
        super(gameObject);
        this.other = this.getComponent(OtherComponent)!; // May be undefined!
    }
}
```

### 3. Clean Up Resources

```typescript theme={null}
export class ResourceManager extends Behavior {
    public onStart(): void {
        const connection = myEvent.connect(() => {});
        this.collector.add(connection); // Will be cleaned up automatically
    }

    public willRemove(): void {
        // collector.teardown() is called automatically
    }
}
```

### 4. Use Execution Order When Needed

```typescript theme={null}
// Initialize game manager first
export class GameManager extends Behavior {
    public readonly executionOrder = -100;
}

// Initialize player after game manager
export class PlayerController extends Behavior {
    public readonly executionOrder = 0;
}
```

### 5. Mark Serializable Fields

```typescript theme={null}
export class Configuration extends Behavior {
    @SerializeField
    public playerSpeed: number = 16; // Can be edited and saved

    private runtime: number = 0; // Won't be saved
}
```

## Next Steps

* **[Networking](./networking)**: Learn about multiplayer features
* **[Scene Management](./scene-management)**: Organize your game world
* **[Decorators](./decorators)**: Use powerful component decorators
* **[Examples](./examples)**: See practical implementations

***

Understanding these core concepts will enable you to build complex games with CORP's component-based architecture! 🎮
