# API

**Assembly:** `Spark.Requirements` **Interface:** `IRequirementsPlugin` **Implementation:** `RequirementsPlugin`

## Interface

```csharp
public interface IRequirementsPlugin
{
    RequirementCheckResult CheckRequirement(RequirementEntry entry,
        RequirementContext context);
    RequirementCheckResult CheckRequirements(
        List<RequirementGroupEntry> groups, RequirementContext context);
    RequirementCheckResult CheckRequirementGroup(
        RequirementGroupEntry group, RequirementContext context);
    DetailedRequirementCheckResult CheckRequirementsDetailed(
        List<RequirementGroupEntry> groups, RequirementContext context);

    List<RequirementEntry> GetAllRequirementEntries();
    RequirementEntry GetRequirementEntry(string id);
}
```

## Methods

### CheckRequirement

```csharp
RequirementCheckResult CheckRequirement(RequirementEntry entry,
    RequirementContext context)
```

Checks a single requirement. Delegates to the entry's `RequirementTypeBase` evaluator.

### CheckRequirements

```csharp
RequirementCheckResult CheckRequirements(
    List<RequirementGroupEntry> groups, RequirementContext context)
```

Checks all requirement groups. All groups must pass for the result to pass.

### CheckRequirementGroup

```csharp
RequirementCheckResult CheckRequirementGroup(
    RequirementGroupEntry group, RequirementContext context)
```

Checks a single group using its configured logic (AND, OR, etc.).

### CheckRequirementsDetailed

```csharp
DetailedRequirementCheckResult CheckRequirementsDetailed(
    List<RequirementGroupEntry> groups, RequirementContext context)
```

Returns per-requirement breakdowns for UI display or debugging.

## RequirementEntry

Extends `SparkDatabaseEntry`. Defines a single requirement.

| Field                 | Type                 | Description                        |
| --------------------- | -------------------- | ---------------------------------- |
| `requirementType`     | RequirementTypeBase  | The evaluator script               |
| `requirementTypeData` | RequirementDataAsset | Configuration for the evaluator    |
| `failureMessage`      | string               | Message shown when the check fails |

## RequirementGroupEntry

Groups multiple requirements with logic operators.

| Field             | Type                         | Description                        |
| ----------------- | ---------------------------- | ---------------------------------- |
| `groupName`       | string                       | Label for the group                |
| `logic`           | RequirementGroupLogic        | How checks combine                 |
| `minimumRequired` | int                          | Required passes for Threshold mode |
| `checks`          | List\<RequirementCheckEntry> | Individual checks                  |

Each `RequirementCheckEntry` references a `RequirementEntry` and has an `invertResult` flag to negate the outcome.

## RequirementGroupLogic

```csharp
public enum RequirementGroupLogic
{
    And,        // All must pass
    Or,         // At least one must pass
    Nand,       // At least one must fail
    Nor,        // All must fail
    Xor,        // Exactly one must pass
    Threshold   // At least N must pass (uses minimumRequired)
}
```

## RequirementContext

Carries data for requirement evaluation.

| Property      | Type                        | Description                     |
| ------------- | --------------------------- | ------------------------------- |
| `Source`      | GameObject                  | The entity being checked        |
| `Target`      | GameObject                  | Optional target entity          |
| `SourceEntry` | SparkDatabaseEntry          | Optional related database entry |
| `CustomData`  | Dictionary\<string, object> | Arbitrary key-value data        |

**Methods:**

```csharp
// Fluent builders
RequirementContext WithTarget(GameObject target)
RequirementContext WithEntry(SparkDatabaseEntry entry)
RequirementContext WithData(string key, object value)

// Data access
T GetData<T>(string key, T defaultValue)
```

## RequirementCheckResult

Returned by all check methods.

```csharp
public struct RequirementCheckResult
{
    public bool Passed;
    public string FailureReason;
    public RequirementEntry RequirementEntry;

    public static RequirementCheckResult Success();
    public static RequirementCheckResult Failure(string reason,
        RequirementEntry entry);
}
```

## DetailedRequirementCheckResult

Extended result with per-group and per-requirement breakdowns, including pass/fail counts.

## Events

| Event                    | Description                                               |
| ------------------------ | --------------------------------------------------------- |
| `RequirementFailedEvent` | Published when a requirement check fails (for logging/UI) |

## Creating Custom Requirement Types

Extend `RequirementTypeBase`:

```csharp
[CreateAssetMenu(menuName = "Spark/Requirements/My Requirement")]
public class MyRequirementType : RequirementTypeBase
{
    public override RequirementCheckResult Check(
        RequirementContext context, RequirementDataAsset data)
    {
        // Your validation logic
        if (conditionMet)
            return RequirementCheckResult.Success();
        return RequirementCheckResult.Failure("Condition not met", null);
    }

    public override Type GetExpectedDataType()
    {
        return typeof(MyRequirementData);
    }
}
```

## Usage

```csharp
var reqPlugin = Spark.GetPlugin<IRequirementsPlugin>();
if (reqPlugin != null)
{
    var context = new RequirementContext { Source = playerObject }
        .WithTarget(npcObject)
        .WithData("questId", "main_quest_01");

    // Simple check
    var result = reqPlugin.CheckRequirements(requirementGroups, context);
    if (result.Passed)
    {
        Debug.Log("All requirements met!");
    }
    else
    {
        Debug.Log($"Failed: {result.FailureReason}");
    }

    // Detailed check for UI display
    var detailed = reqPlugin.CheckRequirementsDetailed(requirementGroups, context);
    // Iterate per-group and per-requirement results
}
```


---

# 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/core-systems/requirements-system/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.
