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


# LevelingOptions

Options for [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>). They set which resources, tasks and dates leveling acts on, the bucket size it detects overallocation with, which contender moves first, and how a task may be moved. The same type is the `level` field of [`EvaluateOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/evaluate-options.md#level>) and [`SuggestOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/suggest/suggest-options.md#level>). `new LevelingOptions()` levels the whole project with the defaults.

## Declaration

```java
package org.dhtmlx.plen;

public class LevelingOptions extends ValueRecord implements DeepCloneable<LevelingOptions> {
    public LevelingScope scope = null;
    public Basis basis = null;
    public LevelingOrder order = LevelingOrder.STANDARD;
    public boolean withinSlackOnly = false;
    public boolean clearFirst = true;
    public boolean allowSplits = true;
    public LevelingStep step = LevelingStep.MINIMAL;
}
```

`LevelingOptions` is a mutable record. `equals` and `hashCode` compare the public fields, and `toString()` prints them as `LevelingOptions{scope=…, basis=…, …}`.

## Constructors

### LevelingOptions()

```java
public LevelingOptions()
```

Creates options with every field at its default.

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `scope` | [`LevelingScope`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md#levelingscope>) | `null` | Limits the resources, tasks and date range leveling acts on. `null` levels the whole project. |
| `basis` | [`Basis`](<https://docs.dhtmlx.com/planning-engine/java/api/data/basis.md>) | `null` | Detection bucket, `HOUR` or `DAY`. `null` derives it from [`SchedulingConfig.durationUnit`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#durationunit>): `DAY` for `DAY`, `HOUR` for `HOUR` and `MINUTE`. |
| `order` | [`LevelingOrder`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md#levelingorder>) | `LevelingOrder.STANDARD` | Which contender of an overallocated bucket moves first. |
| `withinSlackOnly` | `boolean` | `false` | Caps each delay or added pause at the task's total slack, so leveling never pushes past the base plan's end. |
| `clearFirst` | `boolean` | `true` | Clears `levelingDelay` and `pauses` on in-scope tasks before leveling starts. |
| `allowSplits` | `boolean` | `true` | Allows proposals that add or extend [`pauses`](<https://docs.dhtmlx.com/planning-engine/java/api/data/pause.md>). |
| `step` | [`LevelingStep`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md#levelingstep>) | `LevelingStep.MINIMAL` | How far one proposal moves a task. |

### scope

```java
public LevelingScope scope = null;
```

A [`LevelingScope`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md#levelingscope>) that restricts the run. Overallocation outside the scope is left as it is; its windows come back in the result with reason `out-of-scope`.

### basis

```java
public Basis basis = null;
```

The bucket size used to find overallocated periods. With `null`, the basis matches the one every plan result already uses for its overallocation report, so leveling and detection see the same buckets.

### order

```java
public LevelingOrder order = LevelingOrder.STANDARD;
```

The selection order among contenders for one overallocated bucket. See [`LevelingOrder`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md#levelingorder>).

### withinSlackOnly

```java
public boolean withinSlackOnly = false;
```

When `true`, a task is delayed or paused only within its current total slack. A task whose slack can't clear the bucket is skipped, and a window left that way carries reason `slack-exhausted`.

### clearFirst

```java
public boolean clearFirst = true;
```

When `true`, the run first sets `levelingDelay` to `0` and clears `pauses` on every in-scope task that carries either, then levels from that state. When `false`, existing delays and pauses stay and new proposals add to them.

### allowSplits

```java
public boolean allowSplits = true;
```

When `false`, every correction is a whole-task delay. Existing `pauses` are kept (unless `clearFirst` clears them), but none are created or extended.

### step

```java
public LevelingStep step = LevelingStep.MINIMAL;
```

The size of one proposal. See [`LevelingStep`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-options.md#levelingstep>).

## Methods

### withScope, withBasis, withOrder, withWithinSlackOnly, withClearFirst, withAllowSplits, withStep

```java
public LevelingOptions withScope(LevelingScope value)
public LevelingOptions withBasis(Basis value)
public LevelingOptions withOrder(LevelingOrder value)
public LevelingOptions withWithinSlackOnly(boolean value)
public LevelingOptions withClearFirst(boolean value)
public LevelingOptions withAllowSplits(boolean value)
public LevelingOptions withStep(LevelingStep value)
```

Each setter assigns its field and returns this instance, for chaining.

### copy

```java
public LevelingOptions copy()
```

Returns a shallow copy. The copy shares the `scope` object with this instance.

### deepClone

```java
public LevelingOptions deepClone()
```

Returns a copy with its own `LevelingScope` and scope lists.

## LevelingScope

Restricts a leveling run to some resources, tasks and a date range. Each field set to `null` means no restriction on that axis.

```java
public class LevelingScope extends ValueRecord implements DeepCloneable<LevelingScope> {
    public Vec<Id> resources = null;
    public Vec<Id> tasks = null;
    public Moment from = null;
    public Moment to = null;
}
```

| Field | Type | Default | Description |
|---|---|---|---|
| `resources` | `Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>)`>` | `null` | Resources whose overallocation is resolved. `null` means every resource. |
| `tasks` | `Vec<Id>` | `null` | Tasks leveling may move. Tasks outside the list are never delayed or paused. `null` means every task. |
| `from` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | `null` | Start of the triggering range. A bucket is in scope 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. |

The date range selects which overallocation triggers a move. It doesn't limit where a moved task lands: a delay can place a task after `to`.

Unknown ids in `resources` or `tasks` make `Project#level` throw an [`InputException`](<https://docs.dhtmlx.com/planning-engine/java/api/errors/input-exception.md>) at path `scope.resources` or `scope.tasks`.

Setters: `withResources`, `withTasks`, `withFrom`, `withTo`, each returning this scope. `withResources` and `withTasks` also take a `java.util.Collection<? extends Id>` and copy it into a new `Vec`, so `List.of(...)` works; `null` sets the field to `null`. `copy()` is shallow and shares the lists; `deepClone()` copies them.

## LevelingOrder

Which contender of an overallocated bucket moves first. Every order ends with the same tie-break: the task later in input order moves.

```java
public enum LevelingOrder { ID, STANDARD, PRIORITY }
```

| Value | Description |
|---|---|
| `ID` | A task already running in the bucket stays; among the rest, the task later in input order moves. |
| `STANDARD` | Default. A running task stays, then, in this order: a predecessor stays and its successor moves; more total slack moves; a later start moves; lower `priority` moves; a task with a dated constraint stays over one without. |
| `PRIORITY` | Lower [`TaskData.priority`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#fields>) moves first, even against a running task; equal priorities fall through to `STANDARD`. |

## LevelingStep

How far one proposal moves the selected task.

```java
public enum LevelingStep { MINIMAL, SKIP }
```

| Value | Description |
|---|---|
| `MINIMAL` | Default. Each proposal moves the task past one bucket; selection runs again at the next bucket. |
| `SKIP` | Each proposal moves the task past the whole overallocated window in one step. Takes fewer rounds, and the result can differ from `MINIMAL`. |

## Example

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class LevelingOptionsExample {
    public static void main(String[] args) throws Exception {
        Moment monday = Moment.fromYmdHm(2026, 1, 5, 0, 0);

        ProjectData data = new ProjectData()
            .withTasks(List.of(
                new TaskData(Id.str("design")).withStartDate(monday).withDuration(3.0),
                new TaskData(Id.str("review")).withStartDate(monday).withDuration(2.0)))
            .withResources(List.of(new ResourceData().withId(Id.str("dev1"))))
            .withAssignments(List.of(
                new AssignmentData().withTask(Id.str("design")).withResource(Id.str("dev1")).withValue(1.0),
                new AssignmentData().withTask(Id.str("review")).withResource(Id.str("dev1")).withValue(1.0)));

        Project project = new Project();
        project.solve(data, new SolveOptions());

        LevelingOptions options = new LevelingOptions()
            .withScope(new LevelingScope().withResources(List.of(Id.str("dev1"))))
            .withOrder(LevelingOrder.PRIORITY)
            .withAllowSplits(false);

        LevelingResult result = project.level(options);
        System.out.println("rounds: " + result.rounds);
        for (Mutation update : result.schedule.updates) {
            System.out.println(update.id + " " + update.startDate + " delay=" + update.levelingDelay);
        }
        // rounds: 3
        // review 2026-01-08 00:00 delay=3.0
    }
}
```

## Related

- [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) - the call that takes these options
- [`LevelingResult`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-result.md>) - what `level` returns
- [`ResourceOverallocation`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/resource-overallocation.md>) - the windows leveling resolves
- [Leveling Resources](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/leveling-resources.md#leveling-options>) - the options in practice
- [Preview leveling](<https://docs.dhtmlx.com/planning-engine/java/how-to/preview-leveling.md>) - trying leveling without committing it
