# API

**Assembly:** `Spark.Progression` **Interface:** `IProgressionPlugin` **Implementation:** `ProgressionPlugin`

## Interface

```csharp
public interface IProgressionPlugin
{
    // Create/destroy
    ProgressionInstance CreateProgression(string entityId,
        LevelingEntry levelingEntry, string progressionId = null);
    ProgressionInstance CreateProgressionFromInstance(string entityId,
        ProgressionInstanceEntry instanceEntry, string progressionId = null);
    bool DestroyProgression(string progressionId);

    // Queries
    ProgressionInstance GetProgression(string progressionId);
    ProgressionInstance GetEntityProgression(string entityId,
        string levelingId);
    ProgressionInstance GetEntityProgressionByInstance(string entityId,
        string progressionInstanceId);
    ProgressionInstance[] GetAllEntityProgressions(string entityId);

    // XP and leveling
    bool AwardExperience(string progressionId, int amount,
        string sourceId = null, GameObject source = null);
    bool SetLevel(string progressionId, int targetLevel,
        GameObject source = null);

    // State queries
    int GetLevel(string progressionId);
    int GetExperience(string progressionId);
    int GetExperienceForNextLevel(string progressionId);
    float GetLevelProgress(string progressionId);
    bool CanLevelUp(string progressionId);
    bool HasReachedLevelCap(string progressionId);

    // Persistence
    void LoadEntityProgressionsFromSave(string entityId);
}
```

## Database Entries

### LevelingEntry

Extends `SparkDatabaseEntry`. Defines an XP curve.

| Field                      | Type                | Description                         |
| -------------------------- | ------------------- | ----------------------------------- |
| `progressionType`          | ProgressionType     | Finite or Infinite                  |
| `startingLevel`            | int                 | Initial level (default 1)           |
| `levelCap`                 | int                 | Maximum level for Finite type       |
| `softCapLevel`             | int                 | Soft cap for Infinite type          |
| `postCapXpMultiplier`      | float               | XP scaling after soft cap           |
| `curveType`                | ExperienceCurveType | Linear, Exponential, or Logarithmic |
| `baseExperienceRequired`   | int                 | XP for first level-up               |
| `experienceGrowthFactor`   | float               | Per-level scaling factor            |
| `logarithmicScale`         | float               | Scale for logarithmic curve         |
| `customExperiencePerLevel` | List\<int>          | Manual per-level XP values          |

**Methods:**

```csharp
int GetExperienceRequiredForLevel(int level)
int GetTotalExperienceForLevel(int level)
bool IsValidLevel(int level)
```

### ProgressionInstanceEntry

Extends `SparkDatabaseEntry`. Pre-configured progression template.

| Field                    | Type                 | Description                |
| ------------------------ | -------------------- | -------------------------- |
| `levelingTemplate`       | LevelingEntry        | XP curve reference         |
| `allowRuntimeAssignment` | bool                 | Can unlock during gameplay |
| `defaultUnlocked`        | bool                 | Starts unlocked            |
| `levelUpRewards`         | List\<LevelUpReward> | Rewards on level-up        |

### LevelUpReward

Rewards triggered at specific levels.

| Field      | Type                | Description                            |
| ---------- | ------------------- | -------------------------------------- |
| `level`    | int                 | Trigger at this level (or range start) |
| `triggers` | List\<TriggerEntry> | Actions to execute                     |

## ProgressionInstance

Runtime progression state.

| Field                   | Type   | Description                           |
| ----------------------- | ------ | ------------------------------------- |
| `progressionId`         | string | Unique identifier                     |
| `entityId`              | string | Owner entity                          |
| `progressionInstanceId` | string | Reference to ProgressionInstanceEntry |
| `levelingEntryId`       | string | Reference to LevelingEntry            |
| `currentLevel`          | int    | Current level (1-based)               |
| `currentExperience`     | int    | XP toward next level                  |
| `createdTimestamp`      | long   | When created                          |
| `lastLevelUpTimestamp`  | long   | When last leveled up                  |

**Methods:**

```csharp
void AddExperience(int amount)
void SetLevel(int level)
void SetExperience(int amount)
int GetExperienceRequiredForNextLevel()
float GetProgressToNextLevel()
bool CanLevelUp()
bool HasReachedLevelCap()
ProgressionSnapshot CreateSnapshot()
void RestoreFromSnapshot(ProgressionSnapshot snapshot)
```

## Events

| Event                   | Key Fields                                             | Description            |
| ----------------------- | ------------------------------------------------------ | ---------------------- |
| `ExperienceGainedEvent` | progressionId, amount, totalXp, currentLevel, sourceId | XP awarded             |
| `LevelUpEvent`          | progressionId, entityId, newLevel, previousLevel       | Level increased via XP |
| `LevelChangedEvent`     | progressionId, entityId, newLevel, oldLevel            | Level set directly     |

## Commands

| Command                  | Fields                          | Description        |
| ------------------------ | ------------------------------- | ------------------ |
| `AwardExperienceCommand` | ProgressionId, Amount, SourceId | Award XP           |
| `SetLevelCommand`        | ProgressionId, TargetLevel      | Set level directly |

## Components

### ProgressionEntity

MonoBehaviour managing multiple progressions on an entity.

| Field              | Type | Description                  |
| ------------------ | ---- | ---------------------------- |
| `isPersistent`     | bool | Save to disk                 |
| `autoSaveOnChange` | bool | Auto-save on XP/level change |
| `loadOnStart`      | bool | Load from save on enable     |

**Methods:**

```csharp
void UnlockProgression(ProgressionInstanceEntry entry)
bool IsProgressionUnlocked(string progressionInstanceId)
ProgressionInstance GetProgression(string levelingId)
ProgressionInstance GetProgressionByInstance(string instanceId)
ProgressionInstance[] GetAllProgressions()
void AwardExperience(string levelingId, int amount)
int GetLevel(string levelingId)
int GetExperience(string levelingId)
float GetLevelProgress(string levelingId)
void SaveProgressionState()
void LoadProgressionState()
```

**Events:** `OnProgressionCreated`, `OnExperienceGained`, `OnLevelUp`

## Save Data

`ProgressionSaveData` stores `ProgressionSnapshot` objects per entity for persistence.

## Usage

```csharp
var progression = Spark.GetPlugin<IProgressionPlugin>();
if (progression != null)
{
    // Create a progression
    var instance = progression.CreateProgressionFromInstance(
        entityId, combatLevelingInstance);

    // Award XP
    progression.AwardExperience(instance.progressionId, 500, "quest_reward");

    // Check level
    int level = progression.GetLevel(instance.progressionId);
    float progress = progression.GetLevelProgress(instance.progressionId);

    // Set level directly
    progression.SetLevel(instance.progressionId, 10);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sparkframework.dev/documentation/developer-guide/plugins/progression/api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
