LevelingOptions#
Options for Project.Level. new LevelingOptions() levels the whole project with the defaults below. EvaluateOptions.Level and SuggestOptions.Level take the same type.
Declaration#
namespace Plen;
public sealed class LevelingOptions : IDeepCloneable<LevelingOptions>
{
public LevelingScope? Scope { get; set; }
public Basis? Basis { get; set; }
public LevelingOrder Order { get; set; } = LevelingOrder.Standard;
public bool WithinSlackOnly { get; set; } = false;
public bool ClearFirst { get; set; } = true;
public bool AllowSplits { get; set; } = true;
public LevelingStep Step { get; set; } = LevelingStep.Minimal;
public LevelingOptions DeepClone();
}
LevelingOptions doesn't implement IEquatable<T>, so two instances compare by reference.
Properties#
| Property | Type | Default | Description |
|---|---|---|---|
Scope |
LevelingScope? |
null |
Which resources, tasks and dates leveling acts on. null levels the whole project. |
Basis |
Basis? |
null |
Bucket size for detecting overallocation. null derives it from SchedulingConfig.DurationUnit. |
Order |
LevelingOrder |
LevelingOrder.Standard |
Order in which contending tasks give way. |
WithinSlackOnly |
bool |
false |
true caps every delay or pause at the task's total slack, so leveling never pushes the plan past the end it had before leveling. |
ClearFirst |
bool |
true |
true resets LevelingDelay to 0 and clears Pauses on in-scope tasks before leveling starts. false keeps them and levels on top. |
AllowSplits |
bool |
true |
true lets leveling pause a task part-way through (Pauses) instead of delaying it whole. false keeps existing pauses but creates or extends none. |
Step |
LevelingStep |
LevelingStep.Minimal |
How far one correction moves a task. |
Leveling writes its corrections to TaskData.LevelingDelay and TaskData.Pauses. For how the leveler selects and moves tasks, see Leveling resources.
Validation#
A call that reads these options throws an InputException for an unknown id in the scope:
| Path | When |
|---|---|
scope.resources |
Scope.Resources names a resource that isn't in the project |
scope.tasks |
Scope.Tasks names a task that isn't in the project |
Methods#
DeepClone#
public LevelingOptions DeepClone()
Returns a copy whose Scope is a deep copy too, so the two instances share no list.
LevelingScope#
Limits what leveling acts on. Every property defaults to null, which means no limit.
namespace Plen;
public sealed class LevelingScope : IDeepCloneable<LevelingScope>
{
public List<Id>? Resources { get; set; }
public List<Id>? Tasks { get; set; }
public Moment? From { get; set; }
public Moment? To { get; set; }
public LevelingScope DeepClone();
}
| Property | Type | Default | Description |
|---|---|---|---|
Resources |
List<Id>? |
null |
Resources whose overallocation is resolved. null means every resource. |
Tasks |
List<Id>? |
null |
Tasks leveling may move. null means every task. Tasks outside the list are never delayed or paused. |
From |
Moment? |
null |
Start of the range that triggers leveling. A bucket is in range when its start lies in [From, To). null means no lower bound. |
To |
Moment? |
null |
End of the triggering range (exclusive). null means no upper bound. |
From and To limit which overallocated buckets get resolved, not where a task may land: a delayed task can end up after To.
DeepClone() returns a copy that shares no list with this one.
LevelingOrder#
Decides which contending task gives way in an overallocated bucket.
namespace Plen;
public enum LevelingOrder
{
Id = 1,
Standard = 0,
Priority = 2,
}
| Value | Description |
|---|---|
Standard |
Default. A task already running stays, then the standard chain decides: dependency (the successor moves), total slack (more slack moves), start date (later start moves), TaskData.Priority (lower priority moves), constraints (a task with a dated constraint stays), input order (the later task moves). |
Id |
A task already running stays, then the task later in input order moves. |
Priority |
TaskData.Priority decides first (lower priority moves), then the same rules as Standard. |
LevelingStep#
Sets how far one correction moves the selected task.
namespace Plen;
public enum LevelingStep
{
Minimal,
Skip,
}
| Value | Description |
|---|---|
Minimal |
Default. Each correction moves the task past one bucket. The choice of which task moves runs again for the next bucket. |
Skip |
Each correction moves the task past the whole overallocated window in one step. Takes fewer rounds and can give a different result than Minimal. |
Example#
using Plen;
static Moment Day(int day) =>
Moment.FromYmdHm(2026, 1, day, 0, 0) ?? throw new InvalidOperationException("invalid date");
var data = new ProjectData
{
Tasks =
[
new TaskData("a") { StartDate = Day(5), Duration = 3.0 },
new TaskData("b") { StartDate = Day(5), Duration = 2.0 },
],
Resources = [new ResourceData { Id = "dev" }],
Assignments =
[
new AssignmentData { Task = "a", Resource = "dev", Value = 1.0 },
new AssignmentData { Task = "b", Resource = "dev", Value = 1.0 },
],
};
var project = new Project();
project.Solve(data, new SolveOptions());
var result = project.Level(new LevelingOptions
{
Scope = new LevelingScope { Resources = ["dev"] },
Order = LevelingOrder.Priority,
AllowSplits = false,
});
Related#
Project.Level- the call these options configureLevelingResult- the result of a leveling runEvaluateOptions- scoring candidates with a leveling stage- Leveling resources - what each option changes
- Preview leveling - leveling a clone without committing