[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/evaluate-options/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# EvaluateOptions

Options for [`Project.Evaluate`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md>) and [`Project.EvaluateWith`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md#evaluatewith>). They set which baseline the call expects, whether each candidate is also leveled, which tasks get per-task metrics, and whether candidates run against a copy with leveling delays cleared. `new EvaluateOptions()` scores the scheduled stage only, with no focus tasks.

## Declaration

```csharp
public sealed class EvaluateOptions : IDeepCloneable<EvaluateOptions>
{
    public string? BaselineId { get; set; }
    public LevelingOptions? Level { get; set; }
    public List<Id> Focus { get; set; } = [];
    public bool ClearFirst { get; set; }

    public EvaluateOptions DeepClone();
}
```

Set the properties you need with an object initializer: `new EvaluateOptions { Focus = ["B"] }`. `EvaluateOptions` doesn't implement `IEquatable<T>`, so two instances compare by reference.

## Properties

| Property | Type | Default | Description |
|---|---|---|---|
| `BaselineId` | `string?` | `null` | The baseline the call expects. `null` skips the check. |
| `Level` | [`LevelingOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/resources/leveling-options.md>)`?` | `null` | Levels every candidate after scheduling it and fills [`CandidateResult.Leveled`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/candidate-result.md>). `null` scores the scheduled stage only. |
| `Focus` | `List<`[`Id`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/id.md>)`>` | empty | Tasks to report finish and overload for. |
| `ClearFirst` | `bool` | `false` | Scores the baseline and every candidate on a copy with in-scope `LevelingDelay` / `Pauses` cleared. |

### BaselineId

```csharp
public string? BaselineId { get; set; }
```

A baseline token taken from the latest [`ScheduleResult.BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md#baselineid>). When it isn't `null` and doesn't name the project's current baseline, the call throws a [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>) with `Code == ProjectError.StaleBaseline`.

Each candidate's [`SchedulingChanges.BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/scheduling-changes.md>) is checked the same way, independently of this property.

### Level

```csharp
public LevelingOptions? Level { get; set; }
```

When set, each candidate is leveled with these options, unchanged, after it's scheduled. [`CandidateResult.Leveled`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/candidate-result.md>) then holds the leveled-stage [`LeveledMetrics`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/leveled-metrics.md>), and `CandidateResult.Cost` is taken from that stage. A cyclic candidate has no leveled stage, so `Leveled` stays `null`. When `Level` is `null`, `Leveled` is always `null`.

`Level.Basis` (or the basis derived from [`config.DurationUnit`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/scheduling-config.md#durationunit>) when it's `null` or `Level` is `null`) is the bucket size for every overload figure in the result. `Level.Scope.Tasks` also sets the scope of `ClearFirst`.

Options that are invalid against the baseline make the call throw an [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>). To commit the chosen candidate, pass the same `LevelingOptions` to [`Project.Level`](<https://docs.dhtmlx.com/planning-engine/net/api/project-level.md>); otherwise the committed plan isn't the one that was scored.

### Focus

```csharp
public List<Id> Focus { get; set; } = [];
```

The tasks the result reports per-task metrics for. Each focus task gets one entry in [`Finish.Tasks`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/metrics.md#finish>) and one in [`Overload.Focus`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/overload.md#focusoverload>), in the baseline and in every stage of every candidate. With an empty list, both lists are empty.

Every id must name a task in the baseline. An unknown id makes the call throw an [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) with `Path` `focus[i]`. A focus task that a candidate removes reports `null` for its finish and its focus overload in that candidate.

### ClearFirst

```csharp
public bool ClearFirst { get; set; }
```

When `true`, the reference state is a solved copy of the accepted state with `LevelingDelay` and `Pauses` cleared on the tasks in scope. The scope is `Level.Scope.Tasks` when `Level` gives it, otherwise every task, also when `Level` is `null`. The baseline metrics, `Conflicts` and `Cycles` included, are measured on that copy, and every candidate runs on it.

Use it after a [`Project.Level`](<https://docs.dhtmlx.com/planning-engine/net/api/project-level.md>) run: the stored delays already sit in the baseline finish and hide the overload the current assignments cause. `ClearFirst` doesn't depend on `Level.ClearFirst`, so it also works when `Level` is `null`.

`ClearFirst` adds no error. `BaselineId`, candidate tokens, `Level` and `Focus` are checked against the accepted state before anything is cleared, and [`EvaluateResult.BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/evaluate-result.md>) stays the accepted state's. When nothing in scope has a delay or a pause, the result is the same as with `ClearFirst = false`.

## Methods

### DeepClone

```csharp
public EvaluateOptions DeepClone()
```

Returns a copy that shares no nested object (`Level`, `Focus`) with this one.

### ToString

```csharp
public override string ToString()
```

Returns a debug dump of the fields, e.g. `EvaluateOptions { BaselineId: …, Level: …, Focus: …, ClearFirst: … }`.

## Example

```csharp
using Plen;

var monday = Moment.FromYmdHm(2026, 8, 10, 8, 0) ?? throw new InvalidOperationException("invalid date");
var data = new ProjectData
{
    Tasks =
    [
        new TaskData("A") { StartDate = monday, Duration = 2.0 },
        new TaskData("B") { StartDate = monday, Duration = 2.0 },
    ],
    Resources = [new ResourceData { Id = "dev1" }, new ResourceData { Id = "dev2" }],
    Assignments =
    [
        new AssignmentData { Id = "aA", Task = "A", Resource = "dev1", Value = 1.0 },
        new AssignmentData { Id = "aB", Task = "B", Resource = "dev1", Value = 1.0 },
    ],
};
var project = new Project();
var solved = project.Solve(data, new SolveOptions());

var toDev2 = new SchedulingChanges();
toDev2.Assignments.Update.Add(new AssignmentUpdate("aB") { Resource = Patch<Id>.Of("dev2") });

var options = new EvaluateOptions
{
    BaselineId = solved.BaselineId,
    Level = new LevelingOptions(),
    Focus = ["B"],
};
var result = project.Evaluate([new Candidate { Id = "dev2", Changes = toDev2 }], options);

var leveled = result.Candidates[0].Leveled;
Console.WriteLine(leveled?.Metrics.Finish.Tasks[0].Finish?.Delta);
```

## Related

- [`Project.Evaluate`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md>) - the call these options configure
- [`LevelingOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/resources/leveling-options.md>) - the options of the leveling stage set by `Level`
- [`EvaluateResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/evaluate-result.md>) - the returned result
- [`Candidate`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/candidate.md>) - the alternatives to score
- [Evaluating alternatives](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/evaluating-alternatives.md#options>) - choosing between alternatives step by step
