Skip to content

EN UO Topic movement

Codex edited this page Oct 12, 2026 · 4 revisions

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

Movement

Home · C# · IDE · UO API · A–Z · Examples · Languages

Character movement, path building, doors, obstacles and step delays. Commands for moving things are located in Items → Moving Items.

Sections

Topic Commands and explanations
Follow UO.Follow - background following, distance and stop.
Move UO.Move
MoveXY UO.MoveXY
MoveXYZ UO.MoveXYZ
NewMoveXY UO.NewMoveXY
Step UO.Step
StepQ UO.StepQ
PMove UO.PMove
Direction UO.Direction
CalcDir UO.CalcDir
AlwaysRun UO.AlwaysRun
Pathfinding UO.GetPathArray · UO.GetPathArray3D · UO.NewMoveXY
GetPathArray UO.GetPathArray
GetPathArray3D UO.GetPathArray3D
ClientPath UO.ClientPath - path to the client folder, not the game route; see Profiles & Configuration.
Doors UO.OpenDoor · UO.LastStepQUsedDoor · UO.moveOpenDoor
Obstacles UO.IsWorldCellPassable · UO.SetBadLocation · UO.moveThroughNPC · UO.moveThroughCorner
Movement Settings UO.moveCheckStamina · UO.moveExitOnDisconnect · UO.moveHeuristicMult · UO.moveTurnCost · UO.moveBetweenTwoCorners
Predicted X / Y / Z UO.PredictedX · UO.PredictedY · UO.PredictedZ
Movement Timers UO.GetRunMountTimer · UO.GetRunUnMountTimer · UO.GetWalkMountTimer · UO.GetWalkUnmountTimer · UO.SetRunMountTimer · UO.SetRunUnmountTimer · UO.SetWalkMountTimer · UO.SetWalkUnmountTimer

All theme commands

Movement

UO.Move · UO.MoveXY · UO.MoveXYZ · UO.NewMoveXY · UO.Step · UO.StepQ · UO.PMove · UO.MoveOn · UO.MoveOff · UO.MoverStop · UO.CancelMove · UO.Moving · UO.IsMoving · UO.GetRun · UO.IsRunning · UO.AlwaysRun · UO.FixWalk

Direction

UO.Dir · UO.Direction · UO.GetDir · UO.GetDirection · UO.CalcDir · UO.PredictedDirection

Pathfinding

UO.GetPathArray · UO.GetPathArray3D · UO.AddStep · UO.AddDir

Doors

UO.OpenDoor · UO.LastStepQUsedDoor

Movement Settings

UO.moveBetweenTwoCorners · UO.moveCheckStamina · UO.moveExitOnDisconnect · UO.moveHeuristicMult · UO.moveOpenDoor · UO.moveThroughCorner · UO.moveThroughNPC · UO.moveTurnCost

Predicted X / Y / Z

UO.PredictedX · UO.PredictedY · UO.PredictedZ

Movement Timers

UO.GetRunMountTimer · UO.GetRunUnMountTimer · UO.GetWalkMountTimer · UO.GetWalkUnmountTimer · UO.SetRunMountTimer · UO.SetRunUnmountTimer · UO.SetWalkMountTimer · UO.SetWalkUnmountTimer

Examples on the topic

Each command card has several independent scenarios: direct code, functions and classes. Below are selected short scenarios; restrictions and full analysis are in the cards.

UO.NewMoveXY

Parameters, result and all scenarios

var x = UO.GetX() + 3;
var y = UO.GetY();
var ok = UO.NewMoveXY(x, y, true, 0, false);
if (Truth(ok))
{
    UO.Print("Destination reached");
}
else
{
    UO.Print("Destination not reached");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

UO.GetPathArray3D

Parameters, result and all scenarios

var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var path = UO.GetPathArray3D(x, y, z, x + 4, y, z, UO.WorldNum(), 0, 0, false);
if (Truth(ArrayLength(path) > 0))
{
    UO.Print("Steps: " + Convert.ToString(ArrayLength(path) - 1));
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

Reference parts

1 · 2

Complete command reference


UO.AddDir

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.AddDir(object? directions);

Parameters

  • directions is a string saved in the legacy list. The meaning and format of the value depend on the compatible script that uses it.

Return value

void. The added entry is not confirmation of the movement.

Behavior

  • The value is added to the list AddDir of the current runtime state. The call itself does not pass a motion packet, does not move the character, and does not have a documented public getter for reading this list.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.AddDir");
UO.AddDir("E");

1. Save the direction as a legacy-compatible entry without moving the character. - direct script

Parameters and execution flow:

  • Save the direction as a legacy-compatible entry without moving the character.
UO.AddDir("E");

2. Pass the value from the variable to the legacy list AddDir. - script function

Parameters and execution flow:

  • Pass the value from the variable to the legacy list AddDir.
return  RunScenario();
 object? RunScenario()
{
    var directionEntry = "north-east";
    UO.AddDir(directionEntry);
    return null;
}

3. Each call adds another string entry to the runtime state. - script class

Parameters and execution flow:

  • Each call adds another string entry to the runtime state.
  • The auxiliary procedure also does not send a motion command.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        AddLegacyDirection("W");
        return null;
    }

    void AddLegacyDirection(dynamic entry)
    {
        UO.AddDir(entry);
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.AddDir(directions) — UO.AddDir(Any)

Parameters: directions (Any)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "adddir":

                case "addfindlist":

                case "addgate":

                case "addrecall":

                case "addstep":

                    LegacyList(name).Add(string.Join("|", arguments.Select(value => value.ToString())));

                    break;

UO.AddStep

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.AddStep(object? directions);

Parameters

  • directions is the value that runtime converts to text and adds to the compatibility list AddStep. The direction itself is not interpretable.

Return value

void. The call does not return a value and does not confirm the move.

Behavior

  • Each call adds a string representation of the argument to the list AddStep of the current runtime state. This legacy entry does not send a motion command and does not have a public getter in the current implementation.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.AddStep");
UO.AddStep(2);

1. Write the value to the legacy list; the character does not move. - direct script

Parameters and execution flow:

  • Write the value to the legacy list; the character does not move.
UO.AddStep(2);

2. Pass text value: it is stored as a record rather than executed as a direction. - script function

Parameters and execution flow:

  • Pass text value: it is stored as a record rather than executed as a direction.
return  RunScenario();
 object? RunScenario()
{
    var legacyValue = "east";
    UO.AddStep(legacyValue);
    return null;
}

3. Each call adds a separate entry to AddStep of the current runtime. - script class

Parameters and execution flow:

  • Each call adds a separate entry to AddStep of the current runtime.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.AddStep(1);
        UO.AddStep(2);
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.AddStep(directions) — UO.AddStep(Any)

Parameters: directions (Any)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "adddir":

                case "addfindlist":

                case "addgate":

                case "addrecall":

                case "addstep":

                    LegacyList(name).Add(string.Join("|", arguments.Select(value => value.ToString())));

                    break;

UO.AlwaysRun

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.AlwaysRun();
void UO.AlwaysRun(object? enabled);

Reads or changes the constant running setting of the current ClassicUO profile.

Parameters

  • enabled - 0 disables constant running; any non-zero value turns it on.

Return value

The no-argument form returns 1 if the setting is enabled, 0 otherwise. The argument form returns null.

Behavior

  • The value is read from the current profile. The setting changes AlwaysRun and saves the current profile. Without an active profile, the getter returns 0, and the setter reports an error to the client log and does not change the setting.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.AlwaysRun();
UO.Print("AlwaysRun: " + Convert.ToString(result));

1. Read the setting; 1 means that constant running is enabled. - direct script

Parameters and execution flow:

  • Read the setting; 1 means that constant running is enabled.
var isAlwaysRunning = UO.AlwaysRun();
UO.Print(Convert.ToString(isAlwaysRunning));

2. Enable constant running and save the current profile settings. - script function

Parameters and execution flow:

  • Enable constant running and save the current profile settings.
return  RunScenario();
 object? RunScenario()
{
    UO.AlwaysRun(1);
    return null;
}

3. Disable constant running only if it is currently enabled. - script class

Parameters and execution flow:

  • Disable constant running only if it is currently enabled.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(UO.AlwaysRun() != 0))
        {
            UO.AlwaysRun(0);
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.AlwaysRun() — UO.AlwaysRun()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int AlwaysRun() => bridge.AlwaysRun();

UO.AlwaysRun(enabled) — UO.AlwaysRun(Integer)

Parameters: enabled (Integer)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

public void AlwaysRun(int enabled) => bridge.AlwaysRun(enabled);

UO.CalcDir

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.CalcDir(object? xfrom, object? yfrom, object? xto, object? yto);

Calculates the direction from one world point to another. The character does not move.

Parameters

  • xfrom — X coordinate of the starting point.
  • yfrom — Y coordinate of the starting point.
  • xto — X coordinate of destination.
  • yto — Y coordinate of destination.

Return value

int — direction code: 0=north, 1=northeast, 2=east, 3=southeast, 4=south, 5=southwest, 6=west, 7=northwest. Matching points give 100. This is not a bool: 0 means north, not failure; 1 means northeast, not success. Do not pass 100 to the step command as a direction.

Behavior

  • Calculate coordinates only: no batches, no waiting, no map loading, no obstacle checking, no Z, no world map. The team does not search for a passable route and does not guarantee the achievement of the goal. The points must belong to the same coordinate system; avoiding obstacles can lengthen the path.
  • All four parameters are needed. Send world coordinates int in the documented range 0..65535. object? in the signature indicates a universal adapter, not the item's ID. These commands do not have default values, coordinates inside the chest, fifth Z and overload with one object.
  • The original coordinates are subtracted from the destination coordinates, then the signs of the differences are checked. Decreasing Y is north, increasing X is east. If both coordinates change, the diagonal is chosen regardless of the magnitude of the differences. If both differences are zero - 100.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.CalcDir(100, 100, 101, 100);
UO.Print("CalcDir: " + Convert.ToString(result));

1. Direct calculation - direct script

Parameters and execution flow:

  • Origin (100,100), destination (101,100): X increases, Y does not change. Main returns int 2 - east. The move command is not called.
  • int — direction code: 0=north, 1=northeast, 2=east, 3=southeast, 4=south, 5=southwest, 6=west, 7=northwest. Matching points give 100. This is not a bool: 0 means north, not failure; 1 means northeast, not success. Do not pass 100 to the step command as a direction.
  • The original coordinates are subtracted from the destination coordinates, then the signs of the differences are checked. Decreasing Y is north, increasing X is east. If both coordinates change, the diagonal is chosen regardless of the magnitude of the differences. If both differences are zero - 100.
return UO.CalcDir(100,100,101,100);

2. Correctly checking the result is a function of the script

Parameters and execution flow:

  • Both points are equal (100,100). direction=100 means a match, so Main returns string "already there". At different points, another branch will work. It is 100 that is checked, not true.
  • int — direction code: 0=north, 1=northeast, 2=east, 3=southeast, 4=south, 5=southwest, 6=west, 7=northwest. Matching points give 100. This is not a bool: 0 means north, not failure; 1 means northeast, not success. Do not pass 100 to the step command as a direction.
  • The original coordinates are subtracted from the destination coordinates, then the signs of the differences are checked. Decreasing Y is north, increasing X is east. If both coordinates change, the diagonal is chosen regardless of the magnitude of the differences. If both differences are zero - 100.
return  RunScenario();
 object? RunScenario()
{
    var direction = UO.CalcDir(100, 100, 100, 100);
    if (Truth(direction == 100))
    {
        return "already there";
    }

    return "different point";
    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Full script parsing - script class

Parameters and execution flow:

  • When going from (20,20) to (19,21), X decreases, Y increases: UO.CalcDir returns 5. RebuildDirection shows all branches of this algorithm and also gives 5. Main returns "5:5". All four assistant parameters have the same coordinate meaning.
  • int — direction code: 0=north, 1=northeast, 2=east, 3=southeast, 4=south, 5=southwest, 6=west, 7=northwest. Matching points give 100. This is not a bool: 0 means north, not failure; 1 means northeast, not success. Do not pass 100 to the step command as a direction.
  • The original coordinates are subtracted from the destination coordinates, then the signs of the differences are checked. Decreasing Y is north, increasing X is east. If both coordinates change, the diagonal is chosen regardless of the magnitude of the differences. If both differences are zero - 100.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var actual = UO.CalcDir(20, 20, 19, 21);
        var rebuilt = RebuildDirection(20, 20, 19, 21);
        return Convert.ToString(actual) + ":" + Convert.ToString(rebuilt);
        return null;
    }

    dynamic RebuildDirection(dynamic Xfrom, dynamic Yfrom, dynamic Xto, dynamic Yto)
    {
        var dx = Xto - Xfrom;
        var dy = Yto - Yfrom;
        if (Truth(dx == 0) && Truth(dy == 0))
        {
            return 100;
        }

        if (Truth(dx == 0))
        {
            if (Truth(dy < 0))
            {
                return 0;
            }

            return 4;
        }

        if (Truth(dy == 0))
        {
            if (Truth(dx > 0))
            {
                return 2;
            }

            return 6;
        }

        if (Truth(dx > 0))
        {
            if (Truth(dy < 0))
            {
                return 1;
            }

            return 3;
        }

        if (Truth(dy > 0))
        {
            return 5;
        }

        return 7;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.CalcDir(xfrom, yfrom, xto, yto) — UO.CalcDir(Any,Any,Any,Any)

Parameters: xfrom (Any), yfrom (Any), xto (Any), yto (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "calcdir": return new InjectionValue(CalculateDirection(Arg(0), Arg(1), Arg(2), Arg(3)));

UO.CancelMove

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.CancelMove();

Disables allowing further movement by the script via MoveOff.

Parameters

There are no parameters.

Return value

void - no return value.

Behavior

  • Calls MoveOff, which puts the runtime/manager in the MoveEnabled=false state. To enable movement again, MoveOn is needed. The command does not roll back steps that have already been sent.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.CancelMove");
UO.CancelMove();

1. Deny movement - direct script

Parameters and execution flow:

  • The following motion commands respect the resolution being turned off.
UO.CancelMove();

2. Allow movement again - script function

Parameters and execution flow:

  • MoveOn explicitly restores resolution.
return  RunScenario();
 object? RunScenario()
{
    UO.CancelMove();
    UO.MoveOn();
    return null;
}

3. Protective Stop on No Connection - Script Class

Parameters and execution flow:

  • A disconnected connection is used as a condition to prohibit subsequent steps.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (!(Truth(UO.Connected())))
        {
            UO.CancelMove();
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.CancelMove() — UO.CancelMove()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "cancelmove": MoveOff(); break;

UO.Dir

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.Dir();

Reads the character direction from the client model.

Parameters

There are no parameters.

Return value

int — mobile direction without running bit: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. For unknown mobile, 0 is returned, which also means north.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.Dir();
UO.Print("Dir: " + Convert.ToString(result));

1. Display the current value of your character - direct script

Parameters and execution flow:

  • A call without arguments refers to self. The character's direction is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.Dir();
UO.Print("Dir: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The character's direction is used in the calculation or condition shown.
  • Numerical thresholds are examples of script conditions and not new client limits. The field stores the server units and restrictions described above.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.Dir();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Watch change in one second - script class

Parameters and execution flow:

  • Both calls without an argument read their current value. UO.Wait(1000) gives a pause in milliseconds between shots.
  • Change compared: character direction. An example does not change anything in the world and does not wait endlessly. Events within this second may be missed.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.Dir();
        await Delay(1000);
        var after = UO.Dir();
        if (Truth(before != after))
        {
            UO.Print("Before: " + Convert.ToString(before) + "; after: " + Convert.ToString(after));
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Dir() — UO.Dir()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.GetDir(bridge.Self)

API creation: These functions register the API. They do not run again for every command call.


UO.Direction

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.Direction();

Reads the character direction from the client model.

Parameters

There are no parameters.

Return value

int — mobile direction without running bit: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. For unknown mobile, 0 is returned, which also means north.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.Direction();
UO.Print("Direction: " + Convert.ToString(result));

1. Display the current value of your character - direct script

Parameters and execution flow:

  • A call without arguments refers to self. The character's direction is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.Direction();
UO.Print("Direction: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The character's direction is used in the calculation or condition shown.
  • Numerical thresholds are examples of script conditions and not new client limits. The field stores the server units and restrictions described above.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.Direction();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Watch change in one second - script class

Parameters and execution flow:

  • Both calls without an argument read their current value. UO.Wait(1000) gives a pause in milliseconds between shots.
  • Change compared: character direction. An example does not change anything in the world and does not wait endlessly. Events within this second may be missed.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.Direction();
        await Delay(1000);
        var after = UO.Direction();
        if (Truth(before != after))
        {
            UO.Print("Before: " + Convert.ToString(before) + "; after: " + Convert.ToString(after));
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Direction() — UO.Direction()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.GetDir(bridge.Self)

API creation: These functions register the API. They do not run again for every command call.


UO.FixWalk

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.FixWalk();

Prints a notice that the legacy native client patch FixWalk is not required by ClassicUO.

Parameters

There are no parameters.

Return value

void - no return value.

Behavior

  • The ExecuteLegacyManualAlias branch only calls SystemMessage. It does not correct motion, speech, containers, or network protocol.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.FixWalk");
UO.FixWalk();

1. Compatibility Notice - Direct Script

Parameters and execution flow:

  • The message describes the lack of need for the old patch.
UO.FixWalk();

2. Call in procedure - script function

Parameters and execution flow:

  • The compatibility procedure does not change the game world.
return  RunScenario();
 object? RunScenario()
{
    CompatibilityNotice();
    return null;
}

void CompatibilityNotice()
{
    UO.FixWalk();
}

3. Script Continuation - Script Class

Parameters and execution flow:

  • After the diagnostic message, execution continues.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.FixWalk();
        UO.Print("continued");
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.FixWalk() — UO.FixWalk()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "boxhack":

                case "fixtalk":

                case "fixwalk":

                    SystemMessage($"{name}: obsolete native-client patch; ClassicUO does not require it.");

                    break;

UO.Follow

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.Follow();
int UO.Follow(object? target);
int UO.Follow(object? target, object? distance);
int UO.Follow(object? target, object? distance, object? running);
int UO.Follow(object? target, object? distance, object? running, object? stopConditions);
int UO.Follow(object? x, object? y, object? z, object? distance, object? running);
int UO.Follow(object? x, object? y, object? z, object? distance, object? running, object? stopConditions);

Enables background tracking of the loaded character/NPC or movement to point X, Y, Z. During movement, the client checks the transmitted stopping conditions; the script continues execution immediately after the call.

Parameters

  • target — Character Serial/NPC: int, hex/decimal string, lasttarget or name previously saved via AddObject. This is not a graphic/type and not coordinates. You cannot follow yourself or an object. 0 stops following. Without arguments, Follow() also stops it; the sight does not appear.
  • distance — X/Y tolerance in cells: maximum |dx| and |dy|. For character int 1..18, default 1; Z difference up to 16 is acceptable. For point int 0..18, the argument is required: 0 requires exact X/Y, 2 allows stopping within two cells; Z must match exactly. An invalid value does not replace the previous behavior.
  • running — bool-compatible value: true/1 — running, false/0 — walking; default is true. Server speed limits, stamina, paralysis and obstacles remain. The flag does not speed up server steps.
  • stopConditions — Optional array of stopping conditions: fourth argument for character, sixth for coordinates. Each element is an array of exactly three values ​​[field, comparison, threshold]. field and comparison are strings, threshold is int/double; true/false (1/0) are suitable for flags. Triggering of ANY condition is terminated by Follow (OR). An empty array does not add conditions. The number of elements is not limited to fixed 3/5/10 items, but is limited by memory; Large lists are checked in chunks. Allowed fields and units are listed below; an unknown field, operator, or invalid array form causes an error before the former Follow is replaced.
  • x - Only forms with 5/6 arguments: integer world coordinates on the current map, 0..65535 and inside loaded map boundaries. These are not window/gump coordinates and not serial. There is no transfer to another card.
  • y - Only forms with 5/6 arguments: integer world coordinates on the current map, 0..65535 and inside loaded map boundaries. These are not window/gump coordinates and not serial. There is no transfer to another card.
  • z — Only forms with 5/6 arguments: integer world height -128..127. This height is required for completion, so specify the Z of the available surface of the desired floor. There are no separate “any Z” values ​​or automatic height selection.

Return value

int 1 (true) — the following mode has been accepted by the client, or a stop request has been completed; int 0 (false) - there is no suitable character loaded, the player is unavailable/dead, the target is out of sight, the distance is incorrect, or the client does not support the team. This is not the result of arrival, not serial, and not the number of steps. In C# use if (result != 0) or if (result == 1); result is of type int, not bool. Type errors/unknown object name can cause a script error. For coordinates, 0 also means invalid X/Y/Z or tolerance. 1 means accepting the background task only; arrival and future occupancy are yet to be confirmed.

Behavior

  • Exactly one Follow mode per client: character or coordinates. A successful call again replaces the target and parameters. An unsuccessful challenge does not cancel the previous goal. To follow a character, he must already be in the loaded Mobiles list within ClientViewRange; the coordinate point may be further than the view.
  • When reaching distance near the character, walking stops, but the mode remains turned on and resumes movement when the target moves away. Near the fiducial point, the task completes if the X/Y tolerance and exact Z are met. The command does not report a guaranteed reachability of the route when launched.
  • Follow(), Follow(0), MoverStop(), manual mouse/arrow movement, a new script route, or standard client following will stop this mode. TerminateAll/Terminate("all") also stops it. Canceling an owner script that is still running stops it Follow.
  • Both modes end when the map or character changes, the player dies, or the connection is disconnected. Following the character additionally stops when the target disappears from memory/view. The appearance of a target later does not automatically trigger the mode: a new Follow is needed.
  • Closing IDE does not stop the mode. Normal termination of the running script leaves Follow enabled. A script pause is not itself a pause for that client mode; before pausing, use Follow(0) when the movement needs to stop.
  • Pathfinder calculates the path in chunks on the game thread; an incomplete search is not restarted. For mobile, the normal route update is limited to 500 ms. After a failure or termination of a route without approach, the first three retry delays are 1000 ms, then 2000, 4000, and a maximum of 5000 ms. The bounce counter is reset when the X/Y/Z of the player or target changes; changing the target can reduce the wait to 500 ms. There is no general limit on the number of retries for an available mobile target: the mode can remain active without movement, so set it to elapsed or explicitly stop it. The coordinate task ends when the path fails completely.
  • Distance/time fields: distance — current distance to the target in cells max(abs(dx),abs(dy)); height — absolute difference Z in world units; elapsed - milliseconds since accepting this Follow. distance > 12 stops when moving further than 12 cells, elapsed >= 30000 - after 30 seconds. A repeated successful Follow starts the countdown again.
  • Your character's state: self.hp / self.mana / self.stam - current values; self.hppercent / self.manapercent / self.stampercent - percentages 0..100 from the corresponding maximum. Unknown maximum (<=0) means unknown value: the condition for this characteristic is not triggered, rather than receiving the fictitious 0.
  • Logical fields for your character: self.poisoned (poisoned), self.paralyzed (paralyzed), self.hidden (hidden). Values ​​1/0. In the condition array Follow, the rule for the field "self.paralyzed" with the operator "=" and the value true stops following when paralyzed. This is the string name of the rule field, not the C# variable self.
  • Target fields: target.dead - dead mobile, target.hidden - hidden, target.visible - visible to the client (not CheckLOS), target.hp / target.hppercent - loaded HP/percent. If HP max is unknown, the HP condition fails. The server can send the relative scale HP of someone else's character, so hppercent is more convenient for it.
  • Additional target fields: target.notoriety - status 0..7 (0 unknown, 1 Innocent, 2 Ally, 3 Gray, 4 Criminal, 5 Enemy, 6 Murderer, 7 Invulnerable); target.body — numeric graphic of the body. These are not type clothes. For example target.notoriety != 2 stops tracking when Ally status is lost.
  • A copy of the conditions is captured when called, including numeric thresholds. Changing the source array/variable does not update the mode; repeat Follow with the new array. The canceled mode does not itself resume when the condition is no longer met.
  • Conditions are checked both during movement and when the character is already standing near the target. A regular list of up to 64 elements is checked in one game frame, the next check is not earlier than after 250 ms. A larger list - 64 elements per frame, then a pause 250 ms. The elapsed field may stop later than the threshold for the duration of the check/frame: it is not an accurate timer.
  • Until the first check of the entire list is completed, a new route does not begin. If the condition is already met, Follow will return 1 for the accepted request, then stop at updating without the first step. Packets of steps from the previous movement may have already been sent.
  • The new conditions do not disable mandatory stop reasons: loss of target/player/card/connection, player death, owner cancellation, Terminate all, and manual/other movement. Script code is not executed on the game thread; Only listed local values ​​are checked.
  • Coordinate forms: Follow(x,y,z,distance,running) and Follow(x,y,z,distance,running,stopConditions). The first five arguments are required. Follow(x,y,z) is not a shorthand for coordinates: the three arguments still mean target,distance,running.
  • In coordinate mode, distance in the condition means the remaining X/Y distance to the point, height is the absolute difference from its Z; elapsed and all self.* work as usual. The target.* fields are not valid: the point has no HP, body, or status. Trying to pass them causes a script error until the old mode is replaced.
  • Conditions are checked before the first route, during its calculation and while the character is moving. Triggering of any condition removes the task and cancels the path belonging to it. The frequency and processing of large lists is the same as following a character; steps already sent to the server may complete.
  • The coordinate task ends when the point is reached or the search and movement fails/ends without reaching it. Infinite retries to an unreachable point are not triggered. Pathfinder's normal internal recalculations for obstacles are retained. Once completed, leaving the location does not resume the task.
  • If Pathfinder has already sent the last steps and completed the path, but those steps are still executing/waiting for confirmation, the task continues to check conditions. The queue of sent steps itself is not erased: it must be processed by the normal server movement and confirmation mechanism.
  • The list can be assembled via List.Add at DO ... end of loop or FOR and then passed once to checks.ToArray() as the last argument of the appropriate form. There is no need to call Follow again on each iteration: this replaces the mode and resets elapsed. The number of rows is not limited to a small number, but the set of supported fields is limited to the fields listed above.
  • After 2000 ms without changing the player's X/Y/Z, mobile-Follow can re-request the path to the stationary target. The check is performed only when the next deadline occurs, outside of search, after Player.Steps and the Walker queue are released, and when the next step is allowed. There is no cost to moving at a slow pace and waiting for confirmations; Sent steps are not erased. Coordinate Follow does not trigger such an external endless repeat: the restoration of its path is handled by the limited Pathfinder.
  • The general Pathfinder stores up to 8 temporary X/Y/Z directional prohibitions for 2000 ms, only on rejected movement of the corresponding active request. Rotation, unknown sequence, resynchronization and old/foreign request do not create such a prohibition. A new external request and loss of map/player context clears them. Loaded geometry search attempts to bypass the transition; it's not knowing all the server obstacles. Without changing the player's X/Y/Z, up to 8 internal recalculations are allowed with a pause of at least 40 ms. There is no complete path or this budget has been exhausted - the route ends. The coordinate task then completes after processing the submitted steps; mobile-Follow may try again due to its delay.
  • The controller compares the number of its own motion request, not the fact AutoWalking: the natural end of the path is not considered a foreign command. StopOwnedPath transfers the stored number to StopAutoWalkIfRequestGeneration. The new external request terminates the old Follow; stopping it does not cancel someone else's new route.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.Follow();
UO.Print("Follow: " + Convert.ToString(result));

1. Run after the last target - direct script

Parameters and execution flow:

  • leader — serial of the last target. The unit confirms acceptance of the regime, not arrival. After the end of the method, the mode continues to work until the target stops/loss.
var leader = UO.GetSerial("lasttarget");
var accepted = UO.Follow(leader);
if (Truth(Truth(accepted) == true))
{
    UO.Print("Following is enabled; script continues");
}
else
{
    UO.Print("Select a loaded nearby character");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Walk three squares away, then stop - script function

Parameters and execution flow:

  • UO.Wait is measured in milliseconds. Follow(0) turns off general follow mode; subsequent movements of the target no longer cause movement.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var leader = UO.GetSerial("lasttarget");
    if (Truth(UO.Follow(leader, 3, false) == 1))
    {
        await Delay(10000);
        UO.Follow(0);
        UO.Print("Following stopped");
    }

    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Limit the travel time and guarantee to turn it off - scenario class

Parameters and execution flow:

  • distance=2, running=true; maximum 20 expectations over 500 ms. Exists checks for the presence of an object, but not for the reachability of the path. finally stops the mode during normal exit/error; emergency owner cancellation is additionally handled by the client.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var leader = UO.GetSerial("leader");
        if (Truth(UO.Follow(leader, 2, true) == 0))
        {
            UO.Print("Cannot start following");
            return null;
        }

        try
        {
            var attempts = 0;
            while (Truth(attempts < 20) && Truth(UO.Exists(leader)))
            {
                await Delay(500);
                attempts = attempts + 1;
            }
        }
        finally
        {
            UO.Follow();
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

4. Stop by distance, your HP or time - direct script

Parameters and execution flow:

  • Stopping for ANY condition: the target is further than 12 cells OR our HP no more than 40% OR 30 seconds have passed. This is not AND. StopWhen is given in full, it can be included in Include. One means acceptance, not arrival.
var leader = UO.GetSerial("lasttarget");
dynamic[] conditions = new dynamic[checked((int)(2) + 1)];
conditions[0] = StopWhen("distance", ">", 12);
conditions[1] = StopWhen("self.hppercent", "<=", 40);
conditions[2] = StopWhen("elapsed", ">=", 30000);
var accepted = UO.Follow(leader, 2, true, conditions);
if (Truth(accepted == 0))
{
    UO.Print("Cannot follow this target");
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

5. Add conditions via a list without a predefined size - script function

Parameters and execution flow:

  • We stop if the target has disappeared/died/is no longer Ally, there is no more than 5 stamina left, or the Z difference has exceeded 16. false means walk. ToArray passes a list of condition lines; the size is not specified in advance. If the target is no longer Ally, movement will not begin.
return  RunScenario();
 object? RunScenario()
{
    var checks = new List<object?>();
    checks.Add(StopWhen("target.hidden", "=", true));
    checks.Add(StopWhen("target.dead", "=", true));
    checks.Add(StopWhen("target.notoriety", "<>", 2));
    checks.Add(StopWhen("self.stam", "<=", 5));
    checks.Add(StopWhen("height", ">", 16));
    var leader = UO.GetSerial("lasttarget");
    var conditions = checks.ToArray();
    UO.Follow(leader, 2, false, conditions);
    return null;
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

6. Follow until approaching, then turn off mode completely - scenario class

Parameters and execution flow:

  • Maintained distance 1, stopping condition <=3; checking every 250 ms may notice a delayed achievement. Timeout 15000 ms does not allow tracking indefinitely. Returning Follow still means accepting, not reaching three squares.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        dynamic[] conditions = new dynamic[checked((int)(1) + 1)];
        conditions[0] = StopWhen("distance", "<=", 3);
        conditions[1] = StopWhen("elapsed", ">=", 15000);
        UO.Follow(UO.GetSerial("lasttarget"), 1, true, conditions);
        return null;
    }

    dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
    {
        dynamic[] rule = new dynamic[checked((int)(2) + 1)];
        rule[0] = field;
        rule[1] = comparison;
        rule[2] = threshold;
        return rule;
    }
}

7. Collect conditions in DO ... end of cycle: stop at status 5 or 6 - direct script

Parameters and execution flow:

  • while collects a separate condition for each statuses element. Stop at status 5 OR 6, own HP <=40% OR after 30000 ms. Empty statuses will skip the loop, but the next two conditions will remain. Add new lines up to Follow; a subsequent change to List does not change the already installed copy. For background checks, the loop body does not need to be repeated.
var statuses = new List<object?>();
statuses.Add(5);
statuses.Add(6);
var checks = new List<object?>();
var index = 0;
while (index < statuses.Count)
{
checks.Add(StopWhen("target.notoriety", "=", statuses[index]));
index += 1;
}
checks.Add(StopWhen("self.hppercent", "<=", 40));
checks.Add(StopWhen("elapsed", ">=", 30000));
var accepted = UO.Follow(UO.GetSerial("lasttarget"), 2, true, checks.ToArray());
if (Truth(accepted == 0))
{
    UO.Print("Select a loaded nearby character");
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

8. Own expressions at the end of the loop UNTIL and a mandatory stop at Finally - script function

Parameters and execution flow:

  • StopEscort(leader, startedAt) returns bool-compatible 1/0: target beyond 12 cells OR own HP <=30 OR 30 seconds have passed. Add || (another_condition); For a mandatory combination of two checks, use (conditionA && conditionB). Unknown HP can be read as 0; the example then refuses to start. While the script is running, it checks expressions approximately every 250 ms; pausing the script pauses these checks. Finally dispatches a stop on normal exit/error; Owner cancellation is additionally tracked by the client. If the target has disappeared and the client has already stopped Follow, this loop will end on its own terms, no later than the timeout check. To work after the end of the method, use the fourth argument, as in the previous examples.
return  RunScenario();
 object? RunScenario()
{
    var leader = UO.GetSerial("lasttarget");
    var startedAt = Now();
    if (Truth(leader == "0x00000000") || Truth(StopEscort(leader, startedAt)))
    {
        return null;
    }

    if (Truth(UO.Follow(leader, 2, true) == 0))
    {
        return null;
    }

    try
    {
        do
        {
            UO.Wait(250);
        }
        while (!StopEscort(leader, startedAt));
    }
    finally
    {
        UO.Follow(0);
    }

    return null;
}

dynamic StopEscort(dynamic leader, dynamic startedAt)
{
    return (UO.GetDistance(leader) > 12) || (UO.GetHP("self") <= 30) || (Now() - startedAt >= 30000);
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

9. Run to Exact X, Y, Z - Script Class

Parameters and execution flow:

  • Five arguments: X=1445, Y=1690, Z=0, tolerance X/Y=0, run. Return 1 means acceptance, not arrival already completed. Once there, the task will turn off completely. To manually stop early, call UO.Follow(0).
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var accepted = UO.Follow(1445, 1690, 0, 0, true);
        if (Truth(accepted == 0))
        {
            UO.Print("Coordinate task was not accepted");
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

10. To a point with a stop according to your HP, paralysis or time - direct script

Parameters and execution flow:

  • At HP <=40%, paralysis, or after 30 seconds, the client stops its current path. Otherwise, the task will end within two X/Y cells of (1445,1690), strictly at Z=0. Checks continue both during pathfinding and while moving; This is not a one-time check before the start. target.* does not apply here.
var checks = new List<object?>();
checks.Add(StopWhen("self.hppercent", "<=", 40));
checks.Add(StopWhen("self.paralyzed", "=", true));
checks.Add(StopWhen("elapsed", ">=", 30000));
UO.Follow(1445, 1690, 0, 2, true, checks.ToArray());

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

11. Going to the point, but ending the escort three cells before it is a function of the script

Parameters and execution flow:

  • distance=0 in the call specifies an exact arrival, but the distance<=3 condition terminates the task earlier, when the next check notices such a distance. false means walking. A difference Z>16 or 20000 ms also stops the task. The direction does not guarantee passability; replace the offset with your route point.

Standard driving speed

Minimum step interval: walking - walking 400 ms, running 200 ms; riding - walking 200 ms, running 100 ms.

These are standard client limits, not automatically defined settings for your shard. Server speed and flight modes are counted separately. Script timers can slow down movement, but do not reduce these limits.

Steps, Routes, Follow, Mouse/Key Controls, and Map all use the character's shared queue. Replacing the route, turning, or adjusting the position by the server does not cancel the remaining pause after the step request. After the delay, there is no fast burst to compensate for the dropped frames. Waiting for confirmation, obstacles and poor communication can slow down the movement.

return  RunScenario();
 object? RunScenario()
{
    var checks = new List<object?>();
    checks.Add(StopWhen("distance", "<=", 3));
    checks.Add(StopWhen("height", ">", 16));
    checks.Add(StopWhen("elapsed", ">=", 20000));
    var x = UO.GetX("self") + 10;
    var y = UO.GetY("self");
    var z = UO.GetZ("self");
    UO.Follow(x, y, z, 0, false, checks.ToArray());
    return null;
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Follow() — UO.Follow()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target) — UO.Follow(Any)

Parameters: target (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target, distance) — UO.Follow(Any,Any)

Parameters: target (Any), distance (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target, distance, running) — UO.Follow(Any,Any,Any)

Parameters: target (Any), distance (Any), running (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target, distance, running, stopConditions) — UO.Follow(Any,Any,Any,Any)

Parameters: target (Any), distance (Any), running (Any), stopConditions (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values =>

                {

                    FollowStopCondition[] conditions = FollowStopCondition.Parse(values[3]);

                    return new InjectionValue(bridge is IApiConditionalFollowBridge follow

                        ? follow.Follow(GetObject(values[0]), NumberConversions.ToInt(values[1]), ToBoolean(values[2]), conditions) : 0);

                }

UO.Follow(x, y, z, distance, running) — UO.Follow(Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), distance (Any), running (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values =>

                    {

                        FollowStopCondition[] conditions = count == 6

                            ? FollowStopCondition.Parse(values[5], coordinateGoal: true) : Array.Empty<FollowStopCondition>();

                        return new InjectionValue(bridge is IApiCoordinateFollowBridge follow

                            ? follow.FollowPoint(NumberConversions.ToInt(values[0]), NumberConversions.ToInt(values[1]),

                                NumberConversions.ToInt(values[2]), NumberConversions.ToInt(values[3]), ToBoolean(values[4]), conditions) : 0);

                    }

UO.Follow(x, y, z, distance, running, stopConditions) — UO.Follow(Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), distance (Any), running (Any), stopConditions (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values =>

                    {

                        FollowStopCondition[] conditions = count == 6

                            ? FollowStopCondition.Parse(values[5], coordinateGoal: true) : Array.Empty<FollowStopCondition>();

                        return new InjectionValue(bridge is IApiCoordinateFollowBridge follow

                            ? follow.FollowPoint(NumberConversions.ToInt(values[0]), NumberConversions.ToInt(values[1]),

                                NumberConversions.ToInt(values[2]), NumberConversions.ToInt(values[3]), ToBoolean(values[4]), conditions) : 0);

                    }

UO.GetDir

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.GetDir();
int UO.GetDir(object? id);

Reads the character direction from the client model.

Parameters

  • id — Optional object only in the specified one-parameter forms: serial number/hex string, "self", "lasttarget" or name AddObject. This is not a graphic/type. Without argument, one's own character is read. Before reading another object, check UO.Exists; an unknown name does not open the target cursor.

Return value

int — mobile direction without running bit: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. For unknown mobile, 0 is returned, which also means north.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.GetDir();
UO.Print("GetDir: " + Convert.ToString(result));

1. Display the current value of your character - direct script

Parameters and execution flow:

  • A call without arguments refers to self. The character's direction is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.GetDir();
UO.Print("GetDir: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The character's direction is used in the calculation or condition shown.
  • Numerical thresholds are examples of script conditions and not new client limits. The field stores the server units and restrictions described above.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.GetDir();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Read property of selected object - script class

Parameters and execution flow:

  • The single argument selects the lasttarget object; its serial must be known to the client. Graphic/type is not passed here.
  • The data of another object may be unknown even with positive Exists. For the coordinates of an item in a bag, the position of the container is obtained, not the world point.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(UO.Exists("lasttarget")))
        {
            var targetValue = UO.GetDir("lasttarget");
            UO.Print("Selected value: " + Convert.ToString(targetValue));
        }
        else
        {
            UO.Print("Target is not loaded");
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetDir() — UO.GetDir()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetDir() => GetDir("self");

UO.GetDir(id) — UO.GetDir(Integer)

Parameters: id (Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetDir(int id) => bridge.GetDir(id);

UO.GetDir(id) — UO.GetDir(String)

Parameters: id (Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetDir(string id) => GetDir(GetObject(id));

UO.GetDirection

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.GetDirection();
dynamic UO.GetDirection(object? objID);

Reads the character direction from the client model.

Parameters

  • objID — Optional object only in the specified one-parameter forms: serial number/hex string, "self", "lasttarget" or name AddObject. This is not a graphic/type. Without argument, one's own character is read. Before reading another object, check UO.Exists; an unknown name does not open the target cursor.

Return value

int — mobile direction without running bit: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. For unknown mobile, 0 is returned, which also means north.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.GetDirection();
UO.Print("GetDirection: " + Convert.ToString(result));

1. Display the current value of your character - direct script

Parameters and execution flow:

  • A call without arguments refers to self. The character's direction is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.GetDirection();
UO.Print("GetDirection: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The character's direction is used in the calculation or condition shown.
  • Numerical thresholds are examples of script conditions and not new client limits. The field stores the server units and restrictions described above.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.GetDirection();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Read property of selected object - script class

Parameters and execution flow:

  • The single argument selects the lasttarget object; its serial must be known to the client. Graphic/type is not passed here.
  • The data of another object may be unknown even with positive Exists. For the coordinates of an item in a bag, the position of the container is obtained, not the world point.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(UO.Exists("lasttarget")))
        {
            var targetValue = UO.GetDirection("lasttarget");
            UO.Print("Selected value: " + Convert.ToString(targetValue));
        }
        else
        {
            UO.Print("Target is not loaded");
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetDirection() — UO.GetDirection()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.GetDir(bridge.Self)

API creation: These functions register the API. They do not run again for every command call.

UO.GetDirection(objID) — UO.GetDirection(Any)

Parameters: objID (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getdirection": return new InjectionValue(bridge.GetDir(Arg(0)));

UO.GetPathArray

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.GetPathArray(object? xdst, object? ydst, object? optimized, object? accuracy);

Returns the path from the character's current position to X/Y without performing a move.

Parameters

  • xdst — World X coordinate of destination, 0..65535. This is not serial and not a position inside the gump.
  • ydst — World Y coordinate of destination, 0..65535.
  • optimized - true allows diagonal transitions; false leaves four straight directions in this compatible form. This is different from MoveXY's Optimized meaning.
  • accuracy — Tolerance for X and Y in cells: both deviations must fit within it. The value is limited to the range 0..20; 0 requires precise X/Y.

Return value

Array of [x,y,z] records, each field is an int. [0] of the outer array is the starting point; the last entry is within the specified target tolerance. The number of steps is ArrayLength(path)-1 only for a non-empty array. An empty array [] means that the full valid path is not obtained (unreachable target/map, restrictions or search limit). If the starting point is already suitable, one record is returned and the number of steps is 0. The partial path is not returned.

Behavior

  • The team only calculates the route; it does not start movement or open doors. To execute, use NewMoveXY/MoveXYZ and check their own result.
  • The search avoids obstacles by considering adjacent moves to be of equal cost; on a constant map, the path with the least number of steps is sought. The actual patency of each rib is checked, including the height and limitations of the client’s diagonals.
  • No more than 4096 nodes opened and no more than 4096 steps. The work limit can result in an empty array even if there is a long, complex path; divide long routes into sections.
  • In the client, the calculation is divided into portions of up to 32 nodes with a budget check of about 1 ms between nodes. Cancellation is checked between servings. Reading the card remains on the game thread; it is not a promise of a fixed individual disk read time.
  • The map may change after verification: characters move, doors close, the server corrects the situation. The resulting array is a plan for available local data, not a server confirmation.
  • SetBadLocation excludes cells, SetBadObject excludes areas around suitable loaded world objects. A snapshot of your runtime lists at the time of the request is used; prohibitions from another launch are not inherited. The starting cell is not checked for standing: it is specified by the calling code. You cannot use an arbitrary Z inside a wall as a valid starting position.
  • The current card, source X/Y/Z and target Z are taken from the character. Tolerance Z=255. There are no additional mobiles/statics filters or permission for closed doors in four-argument form.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetPathArray(UO.GetX() + 5, UO.GetY(), true, 0);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Find out the number of steps - direct script

Parameters and execution flow:

  • Xdst - five cells to the east; Ydst former; Optimized=true; Accuracy=0.
  • count includes the starting point. Subtraction 1 is performed only after checking for a non-empty array.
var path = UO.GetPathArray(UO.GetX() + 5, UO.GetY(), true, 0);
var count = ArrayLength(path);
if (Truth(count > 0))
{
    UO.Print("Steps: " + Convert.ToString(count - 1));
}
else
{
    UO.Print("Complete path is unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Enumerate route coordinates - script function

Parameters and execution flow:

  • Target 1445/1690; Optimized=false excludes diagonals; Accuracy=1 resolves the closest cell in the tolerance square.
  • point[0]/[1]/[2] - X/Y/Z. It is not a graphic, serial or surface type.
return  RunScenario();
 object? RunScenario()
{
    var path = UO.GetPathArray(1445, 1690, false, 1);
    var i = 0;
    while (Truth(i < ArrayLength(path)))
    {
        var point = path[i];
        UO.Print(Convert.ToString(point[0]) + "," + Convert.ToString(point[1]) + "," + Convert.ToString(point[2]));
        i = i + 1;
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Check Path Before Individual Move Command - Script Class

Parameters and execution flow:

  • The first team only counts the path. The second one checks/executes the movement again, callback=0, timeout=5000.
  • If you just need to go, the preliminary GetPathArray is optional and adds work.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var x = UO.GetX() + 3;
        var y = UO.GetY();
        var path = UO.GetPathArray(x, y, true, 0);
        if (Truth(ArrayLength(path) > 0))
        {
            var ok = UO.NewMoveXY(x, y, true, 0, false, 0, 5000);
            UO.Print("Movement result: " + Convert.ToString(ok));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetPathArray(xdst, ydst, optimized, accuracy) — UO.GetPathArray(Any,Any,Any,Any)

Parameters: xdst (Any), ydst (Any), optimized (Any), accuracy (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getpatharray":

                    return BuildPortablePath(bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), bridge.GetZ(bridge.Self),

                        Arg(0), Arg(1), bridge.GetZ(bridge.Self), bridge.WorldNumber, Arg(3), 255, Arg(2) != 0, false);

UO.GetPathArray3D

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles, object? avoidStatics);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles, object? avoidStatics, object? allowDoors);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles, object? avoidStatics, object? allowDoors, object? allowDiagonal);

Calculates an array of the complete path between two points in the world with height control and additional filters.

Parameters

  • startX — Initial world X, 0..65535.
  • startY — Initial world Y, 0..65535.
  • startZ — Initial height -128..127.
  • finishX — Target world X, 0..65535.
  • finishY — Target world Y, 0..65535.
  • finishZ — Target height -128..127.
  • map — Number of the currently loaded card, for example UO.WorldNum(). The other map gives an empty array including matching X/Y/Z.
  • accuracyXY — Tolerance for X and Y in cells: both deviations must fit within it. The value is limited to the range 0..20; 0 requires precise X/Y.
  • accuracyZ — Height tolerance: abs(actual Z - required Z), limited by 0..255. Zero requires a precise altitude; 255 virtually disables the Z limit.
  • run - Required compatible run flag. The request doesn't move anything; in this form, Optimized is always true, so run does not change the sequence of cells or the number of steps.
  • maxSteps — Optional limit on the number of path edges, without a starting point. 0/negative/absent use the general limit 4096. Cells are considered here, in contrast to the observed changes in NewMoveXY.
  • maxDistance — Optional limit on the initial distance max(abs(dx),abs(dy)) to the target. 0/absence disables it. This is not the allowed deviation during the traversal and not the length of the found path.
  • avoidMobiles - true excludes X/Y loaded characters, except self, by snapshot at the beginning of the call; The height of this filter is not taken into account. Default is false. The normal client clearance check still applies.
  • avoidStatics - true excludes a cell with any static entry, even traversable or at a different height. Default is false. This is a strict filter, and not just a ban on impassable walls.
  • allowDoors - true allows a tentative path through a found door tile, even if the closed door fails the normal check. Default is false. The door doesn't open; access, Z and permeability must be checked again during execution.
  • allowDiagonal - true/absent allows eight directions with angle checking; false - only four forward directions.

Return value

Array of [x,y,z] records, each field is an int. [0] of the outer array is the starting point; the last entry is within the specified target tolerance. The number of steps is ArrayLength(path)-1 only for a non-empty array. An empty array [] means that the full valid path is not obtained (unreachable target/map, restrictions or search limit). If the starting point is already suitable, one record is returned and the number of steps is 0. The partial path is not returned.

Behavior

  • The team only calculates the route; it does not start movement or open doors. To execute, use NewMoveXY/MoveXYZ and check their own result.
  • The search avoids obstacles by considering adjacent moves to be of equal cost; on a constant map, the path with the least number of steps is sought. The actual patency of each rib is checked, including the height and limitations of the client’s diagonals.
  • No more than 4096 nodes opened and no more than 4096 steps. The work limit can result in an empty array even if there is a long, complex path; divide long routes into sections.
  • In the client, the calculation is divided into portions of up to 32 nodes with a budget check of about 1 ms between nodes. Cancellation is checked between servings. Reading the card remains on the game thread; it is not a promise of a fixed individual disk read time.
  • The map may change after verification: characters move, doors close, the server corrects the situation. The resulting array is a plan for available local data, not a server confirmation.
  • SetBadLocation excludes cells, SetBadObject excludes areas around suitable loaded world objects. A snapshot of your runtime lists at the time of the request is used; prohibitions from another launch are not inherited. The starting cell is not checked for standing: it is specified by the calling code. You cannot use an arbitrary Z inside a wall as a valid starting position.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetPathArray3D(UO.GetX(), UO.GetY(), UO.GetZ(), UO.GetX() + 4, UO.GetY(), UO.GetZ(), UO.WorldNum(), 0, 0, false);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Path at the same height with precise tolerance - direct script

Parameters and execution flow:

  • The first three values ​​are the original X/Y/Z; the next three are the purpose.
  • map=WorldNum(), accuracyXY=0, accuracyZ=0 require precise position. run=false does not trigger walking.
var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var path = UO.GetPathArray3D(x, y, z, x + 4, y, z, UO.WorldNum(), 0, 0, false);
if (Truth(ArrayLength(path) > 0))
{
    UO.Print("Steps: " + Convert.ToString(ArrayLength(path) - 1));
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. All parameters with filters are a script function

Parameters and execution flow:

  • Target 1445/1690/20; accuracyXY=1, accuracyZ=2; run=true remains a compatibility flag.
  • maxSteps=80, maxDistance=30; avoidMobiles=true, avoidStatics=false, allowDoors=true, allowDiagonal=false. The array may be empty.
  • Door clearance is a planning assumption; there is no guarantee of opening and passage.
return  RunScenario();
 object? RunScenario()
{
    var path = UO.GetPathArray3D(UO.GetX(), UO.GetY(), UO.GetZ(), 1445, 1690, 20, UO.WorldNum(), 1, 2, true, 80, 30, true, false, true, false);
    UO.Print("Points: " + Convert.ToString(ArrayLength(path)));
    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

3. Read Last Point Reached - Script Class

Parameters and execution flow:

  • accuracyXY=2/accuracyZ=5 resolve the nearest suitable point; maxSteps=100.
  • last is the last entry in the plan, not the character's current position. The team doesn't move him.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var path = UO.GetPathArray3D(UO.GetX(), UO.GetY(), UO.GetZ(), 1445, 1690, 0, UO.WorldNum(), 2, 5, false, 100);
        var count = ArrayLength(path);
        if (Truth(count > 0))
        {
            var last = path[count - 1];
            UO.Print("X=" + Convert.ToString(last[0]) + " Y=" + Convert.ToString(last[1]) + " Z=" + Convert.ToString(last[2]));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles, avoidStatics) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any), avoidStatics (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles, avoidStatics, allowDoors) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any), avoidStatics (Any), allowDoors (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles, avoidStatics, allowDoors, allowDiagonal) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any), avoidStatics (Any), allowDoors (Any), allowDiagonal (Any)

Result: dynamic / Array.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetPathArray3D(values)

UO.GetRun

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.GetRun();
int UO.GetRun(object? id);

Checks the running flag in the last known direction mobile.

Parameters

  • id — Mandatory serial/ID of a specific object: int, hex-string or alias self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse or name AddObject. This is not a graphic/type. Unspecified name resolves to 0; the command does not open any new target. GetRun also has a form GetRun() for self.

Return value

int 1 — the loaded mobile has the Direction.Running attribute. int 0 - the attribute is missing, the object is not mobile, unknown or deleted. The last running flag may be retained after stopping. This is not the activity of the route, not the speed or the number of steps remaining. To move self, also use Moving().

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The local client model is read; There are no requests to the server, no waiting or moving.
  • The result refers to the moment of reading. After UO.Wait or other action, the object and its flags may change.
  • The last running flag may be retained after stopping. This is not the activity of the route, not the speed or the number of steps remaining. To move self, also use Moving().

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.GetRun("self");
UO.Print("GetRun: " + Convert.ToString(result));

1. Check your own state - direct script

Parameters and execution flow:

  • The self argument explicitly selects its character. state - 1/0 only.
  • The last running flag may be retained after stopping. This is not the activity of the route, not the speed or the number of steps remaining. To move self, also use Moving().
var state = UO.GetRun("self");
var moving = UO.Moving();
UO.Print("Running flag: " + Convert.ToString(state));
UO.Print("Self movement active: " + Convert.ToString(moving));

2. Check selected mobile - script function

Parameters and execution flow:

  • IsNpc excludes subject and unknown object. target stores one serial, not a live link to a changing lasttarget.
  • The result refers to the Direction.Running field. The data is updated only after the client receives the appropriate state.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.IsNPC(target)))
    {
        var state = UO.GetRun(target);
        UO.Print("Selected mobile state 1/0: " + Convert.ToString(state));
    }
    else
    {
        UO.Print("No loaded mobile selected");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Compare state before and after pause - script class

Parameters and execution flow:

  • UO.Wait(500) — pause in milliseconds. After it, it is separately checked that mobile still exists.
  • Two photographs are compared. Intermediate changes may be missed, and this is not a continuous subscription to server events.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var target = UO.GetSerial("lasttarget");
        if (Truth(UO.IsNPC(target)))
        {
            var before = UO.GetRun(target);
            await Delay(500);
            if (Truth(UO.IsNPC(target)))
            {
                var after = UO.GetRun(target);
                if (Truth(before != after))
                {
                    UO.Print("Flag changed: " + Convert.ToString(before) + " -> " + Convert.ToString(after));
                }
            }
            else
            {
                UO.Print("Mobile left the local world");
            }
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetRun() — UO.GetRun()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetRun() => bridge.GetRun(bridge.Self);

UO.GetRun(id) — UO.GetRun(Any)

Parameters: id (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetRun(InjectionValue id) => bridge.GetRun(GetObject(id));

UO.GetRunMountTimer

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.GetRunMountTimer();

Shows the configured interval of one horse running step in milliseconds. Useful for checking the mode, estimating the timing and saving the setting before slowing down temporarily.

Parameters

There are no parameters.

Return value

int from 100 to 2000 inclusive - configured interval in milliseconds. Default is 100. This is the number of times, not true/false, not ID, and not the number of cells passed.

Behavior

  • The setting applies to the riding mode. The standard and minimum allowed value is 100 ms; the upper limit is 2000 ms. The other three modes have separate settings.
  • This is the character's local movement interval, not ping, FPS, pathfinding timeout, or measured server step duration. Increasing the number slows down the movement; decreasing below the standard interval does not speed up the sending of packets.
  • The team itself does not start moving, does not mount the mount and does not change the walking/running mode. The mode is selected while driving; the speed mode and flight specified by the server are also taken into account by the client.
  • The setting is general for the movement of this client: it can be used by manual control, map route and other scripts. Temporarily changing it, keep the previous value and restore it after the operation; do not change one mode at the same time from several procedures.
  • Turning and deviating steps are different from normal moves. Server confirmation, communication delays and obstacles may increase the actual time. The client does not send a series of accelerated steps to catch up on missing frames.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetRunMountTimer();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Check current interval - direct script

Parameters and execution flow:

  • UO.GetRunMountTimer() is called without arguments. delayMs — interval of running on horseback; other modes are not measured here.
var delayMs = UO.GetRunMountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Estimate the contribution of delays to a short route - scenario function

Parameters and execution flow:

  • steps=5 is the number of steps to evaluate, not a command parameter. Multiplication gives only the contribution of the configured delays; it is not a promise of arrival time or a route timeout.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetRunMountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

3. Remove previously added slowdown - script class

Parameters and execution flow:

  • previous is compared to 100 ms. The standard interval is set, the other three modes are saved. The character doesn't move anywhere from the challenge itself.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = UO.GetRunMountTimer();
        if (Truth(previous > 100))
        {
            UO.SetRunMountTimer(100);
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetRunMountTimer() — UO.GetRunMountTimer()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getrunmounttimer": return new InjectionValue(state.RunMountTimer);

UO.GetRunUnMountTimer

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.GetRunUnMountTimer();

Shows the configured interval of one walking step in milliseconds. Useful for checking the mode, estimating the timing and saving the setting before slowing down temporarily.

Parameters

There are no parameters.

Return value

int from 200 to 2000 inclusive - configured interval in milliseconds. Default is 200. This is the number of times, not true/false, not ID, and not the number of cells passed.

Behavior

  • The setting applies to walking mode. The standard and minimum allowed value is 200 ms; the upper limit is 2000 ms. The other three modes have separate settings.
  • This is the character's local movement interval, not ping, FPS, pathfinding timeout, or measured server step duration. Increasing the number slows down the movement; decreasing below the standard interval does not speed up the sending of packets.
  • The team itself does not start moving, does not mount the mount and does not change the walking/running mode. The mode is selected while driving; the speed mode and flight specified by the server are also taken into account by the client.
  • The setting is general for the movement of this client: it can be used by manual control, map route and other scripts. Temporarily changing it, keep the previous value and restore it after the operation; do not change one mode at the same time from several procedures.
  • Turning and deviating steps are different from normal moves. Server confirmation, communication delays and obstacles may increase the actual time. The client does not send a series of accelerated steps to catch up on missing frames.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetRunUnMountTimer();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Check current interval - direct script

Parameters and execution flow:

  • UO.GetRunUnmountTimer() is called without arguments. delayMs - interval of running on foot; other modes are not measured here.
var delayMs = UO.GetRunUnMountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Estimate the contribution of delays to a short route - scenario function

Parameters and execution flow:

  • steps=5 is the number of steps to evaluate, not a command parameter. Multiplication gives only the contribution of the configured delays; it is not a promise of arrival time or a route timeout.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetRunUnMountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

3. Remove previously added slowdown - script class

Parameters and execution flow:

  • previous is compared to 200 ms. The standard interval is set, the other three modes are saved. The character doesn't move anywhere from the challenge itself.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = UO.GetRunUnMountTimer();
        if (Truth(previous > 200))
        {
            UO.SetRunUnmountTimer(200);
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetRunUnMountTimer() — UO.GetRunUnMountTimer()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getrununmounttimer": return new InjectionValue(state.RunUnmountTimer);

UO.GetWalkMountTimer

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.GetWalkMountTimer();

Shows the configured interval of one step of horseback walking in milliseconds. Useful for checking the mode, estimating the timing and saving the setting before slowing down temporarily.

Parameters

There are no parameters.

Return value

int from 200 to 2000 inclusive - configured interval in milliseconds. Default is 200. This is the number of times, not true/false, not ID, and not the number of cells passed.

Behavior

  • The setting applies to the riding mode. The standard and minimum allowed value is 200 ms; the upper limit is 2000 ms. The other three modes have separate settings.
  • This is the character's local movement interval, not ping, FPS, pathfinding timeout, or measured server step duration. Increasing the number slows down the movement; decreasing below the standard interval does not speed up the sending of packets.
  • The team itself does not start moving, does not mount the mount and does not change the walking/running mode. The mode is selected while driving; the speed mode and flight specified by the server are also taken into account by the client.
  • The setting is general for the movement of this client: it can be used by manual control, map route and other scripts. Temporarily changing it, keep the previous value and restore it after the operation; do not change one mode at the same time from several procedures.
  • Turning and deviating steps are different from normal moves. Server confirmation, communication delays and obstacles may increase the actual time. The client does not send a series of accelerated steps to catch up on missing frames.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetWalkMountTimer();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Check current interval - direct script

Parameters and execution flow:

  • UO.GetWalkMountTimer() is called without arguments. delayMs — interval of walking on horseback; other modes are not measured here.
var delayMs = UO.GetWalkMountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Estimate the contribution of delays to a short route - scenario function

Parameters and execution flow:

  • steps=5 is the number of steps to evaluate, not a command parameter. Multiplication gives only the contribution of the configured delays; it is not a promise of arrival time or a route timeout.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetWalkMountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

3. Remove previously added slowdown - script class

Parameters and execution flow:

  • previous is compared to 200 ms. The standard interval is set, the other three modes are saved. The character doesn't move anywhere from the challenge itself.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = UO.GetWalkMountTimer();
        if (Truth(previous > 200))
        {
            UO.SetWalkMountTimer(200);
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetWalkMountTimer() — UO.GetWalkMountTimer()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getwalkmounttimer": return new InjectionValue(state.WalkMountTimer);

UO.GetWalkUnmountTimer

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.GetWalkUnmountTimer();

Shows the configured interval of one walking step in milliseconds. Useful for checking the mode, estimating the timing and saving the setting before slowing down temporarily.

Parameters

There are no parameters.

Return value

int from 400 to 2000 inclusive - configured interval in milliseconds. Default is 400. This is the number of times, not true/false, not ID, and not the number of cells passed.

Behavior

  • The setting applies to walking mode. The standard and minimum allowed value is 400 ms; the upper limit is 2000 ms. The other three modes have separate settings.
  • This is the character's local movement interval, not ping, FPS, pathfinding timeout, or measured server step duration. Increasing the number slows down the movement; decreasing below the standard interval does not speed up the sending of packets.
  • The team itself does not start moving, does not mount the mount and does not change the walking/running mode. The mode is selected while driving; the speed mode and flight specified by the server are also taken into account by the client.
  • The setting is general for the movement of this client: it can be used by manual control, map route and other scripts. Temporarily changing it, keep the previous value and restore it after the operation; do not change one mode at the same time from several procedures.
  • Turning and deviating steps are different from normal moves. Server confirmation, communication delays and obstacles may increase the actual time. The client does not send a series of accelerated steps to catch up on missing frames.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetWalkUnmountTimer();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Check current interval - direct script

Parameters and execution flow:

  • UO.GetWalkUnmountTimer() is called without arguments. delayMs — walking interval; other modes are not measured here.
var delayMs = UO.GetWalkUnmountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Estimate the contribution of delays to a short route - scenario function

Parameters and execution flow:

  • steps=5 is the number of steps to evaluate, not a command parameter. Multiplication gives only the contribution of the configured delays; it is not a promise of arrival time or a route timeout.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetWalkUnmountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

3. Remove previously added slowdown - script class

Parameters and execution flow:

  • previous is compared to 400 ms. The standard interval is set, the other three modes are saved. The character doesn't move anywhere from the challenge itself.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = UO.GetWalkUnmountTimer();
        if (Truth(previous > 400))
        {
            UO.SetWalkUnmountTimer(400);
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetWalkUnmountTimer() — UO.GetWalkUnmountTimer()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getwalkunmounttimer": return new InjectionValue(state.WalkUnmountTimer);

UO.IsMoving

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.IsMoving();

Checks the movement of your character.

Parameters

There are no parameters.

Return value

int bool (1/0): 1 - automatic Pathfinder is active or there are still steps in the character’s queue; 0 - both are missing or the character is not loaded. This is not a confirmation of achieving a goal or the number of steps.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.IsMoving();
UO.Print("IsMoving: " + Convert.ToString(result));

1. Check your own state - direct script

Parameters and execution flow:

  • Empty parentheses read self. active — number 1 or 0; The message text serves as an example of branch processing.
  • 1 - automatic Pathfinder is active or there are still steps in the character’s queue; 0 - both are missing or the character is not loaded. This is not a confirmation of achieving a goal or the number of steps.
var active = UO.IsMoving();
if (Truth(active))
{
    UO.Print("State is active");
}
else
{
    UO.Print("State is inactive or unavailable");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Checking against the presence of a character is a function of the script

Parameters and execution flow:

  • The command has no object argument: even after Exists(self), it only reads its own state.
  • Exists(self) checks the player's load separately from the requested flag. The world can change between checks.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Exists("self")))
    {
        var state = UO.IsMoving();
        UO.Print("State 1/0: " + Convert.ToString(state));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Notice state change without waiting indefinitely - script class

Parameters and execution flow:

  • The two calls without arguments read self; UO.Wait(500) - pause for half a second.
  • Two flag snapshots are compared. Transitions between shots may be skipped; it is not a subscription to all server events.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.IsMoving();
        await Delay(500);
        var after = UO.IsMoving();
        if (Truth(before != after))
        {
            UO.Print("State changed from " + Convert.ToString(before) + " to " + Convert.ToString(after));
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.IsMoving() — UO.IsMoving()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int IsMoving() => bridge.IsMoving();

UO.IsRunning

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.IsRunning(object? objID);

Checks the running flag in the last known direction mobile.

Parameters

  • objID — Mandatory serial/ID of a specific object: int, hex-string or alias self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse or name AddObject. This is not a graphic/type. Unspecified name resolves to 0; the command does not open any new target. The argument is required; for yourself, pass self.

Return value

int 1 — the loaded mobile has the Direction.Running attribute. int 0 - the attribute is missing, the object is not mobile, unknown or deleted. The last running flag may be retained after stopping. This is not the activity of the route, not the speed or the number of steps remaining. To move self, also use Moving().

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The local client model is read; There are no requests to the server, no waiting or moving.
  • The result refers to the moment of reading. After UO.Wait or other action, the object and its flags may change.
  • The last running flag may be retained after stopping. This is not the activity of the route, not the speed or the number of steps remaining. To move self, also use Moving().

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.IsRunning("self");
UO.Print("IsRunning: " + Convert.ToString(result));

1. Check your own state - direct script

Parameters and execution flow:

  • The self argument explicitly selects its character. state - 1/0 only.
  • The last running flag may be retained after stopping. This is not the activity of the route, not the speed or the number of steps remaining. To move self, also use Moving().
var state = UO.IsRunning("self");
var moving = UO.Moving();
UO.Print("Running flag: " + Convert.ToString(state));
UO.Print("Self movement active: " + Convert.ToString(moving));

2. Check selected mobile - script function

Parameters and execution flow:

  • IsNpc excludes subject and unknown object. target stores one serial, not a live link to a changing lasttarget.
  • The result refers to the Direction.Running field. The data is updated only after the client receives the appropriate state.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.IsNPC(target)))
    {
        var state = UO.IsRunning(target);
        UO.Print("Selected mobile state 1/0: " + Convert.ToString(state));
    }
    else
    {
        UO.Print("No loaded mobile selected");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Compare state before and after pause - script class

Parameters and execution flow:

  • UO.Wait(500) — pause in milliseconds. After it, it is separately checked that mobile still exists.
  • Two photographs are compared. Intermediate changes may be missed, and this is not a continuous subscription to server events.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var target = UO.GetSerial("lasttarget");
        if (Truth(UO.IsNPC(target)))
        {
            var before = UO.IsRunning(target);
            await Delay(500);
            if (Truth(UO.IsNPC(target)))
            {
                var after = UO.IsRunning(target);
                if (Truth(before != after))
                {
                    UO.Print("Flag changed: " + Convert.ToString(before) + " -> " + Convert.ToString(after));
                }
            }
            else
            {
                UO.Print("Mobile left the local world");
            }
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.IsRunning(objID) — UO.IsRunning(Any)

Parameters: objID (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "isrunning": return new InjectionValue(bridge.GetRun(Arg(0, bridge.Self)));

UO.LastStepQUsedDoor

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.LastStepQUsedDoor();
dynamic UO.LastStepQUsedDoor(object? value);

Reads or manually changes the door opening attempt flag of the last StepQ command.

Parameters

  • value — Optional integer. Exactly this number is stored with the argument; without an argument, the read is performed.

Return value

int — saved mark. The usual StepQ resets it to 0 and, with moveOpenDoor enabled, writes the result TryOpenDoorForStep: 1 if an attempt is detected, 0 otherwise. The manual form allows other numbers. This is not a door serial or confirmation of its opening.

Behavior

  • The check does not read the door status from the server. The fallback call OpenDoor does not change the zero mark.
  • If StepQ fails early due to connection/endurance, the reset is not yet performed, so the previous value may remain.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.LastStepQUsedDoor();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Read mark - direct script

Parameters and execution flow:

  • Without arguments, the stored number is read.
  • Don't use it like ID for UseObject.
UO.Print(Convert.ToString(UO.LastStepQUsedDoor()));

2. Reset before attempting a step - script function

Parameters and execution flow:

  • value=0 clears the previous mark. direction=2 — E; run=false.
  • The StepQ result and the door mark have different meanings.
return  RunScenario();
 object? RunScenario()
{
    UO.LastStepQUsedDoor(0);
    var status = UO.StepQ(2, false);
    UO.Print(Convert.ToString(UO.LastStepQUsedDoor()));
    return null;
}

3. Save and Restore Mark - Script Class

Parameters and execution flow:

  • previous — saved value.
  • Manual recovery does not perform any action on the door.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = UO.LastStepQUsedDoor();
        UO.LastStepQUsedDoor(0);
        UO.Print(Convert.ToString(UO.LastStepQUsedDoor()));
        UO.LastStepQUsedDoor(previous);
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.LastStepQUsedDoor() — UO.LastStepQUsedDoor()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "laststepquseddoor":

                    if (arguments.Length > 0) state.LastStepUsedDoor = Arg(0);

                    return new InjectionValue(state.LastStepUsedDoor);

UO.LastStepQUsedDoor(value) — UO.LastStepQUsedDoor(Any)

Parameters: value (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "laststepquseddoor":

                    if (arguments.Length > 0) state.LastStepUsedDoor = Arg(0);

                    return new InjectionValue(state.LastStepUsedDoor);

UO.Move

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.Move();

Reads if there is an automatic route or character steps that have not yet been completed.

Parameters

There are no parameters.

Return value

int 1 — Pathfinder is active or steps remain in the character animation queue; 0 - both are missing or the character is not loaded. This is not the number of steps, the result of reaching a previous goal, or a sign of holding the mouse.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The command only reads the state. If the result is non-zero, the compatible timer TicksAnim is updated. Steps requested by mouse/keys are also counted while they remain in the queue.
  • To stop the automatic route, use MoverStop. MoveOff controls other, keyboard steps.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.Move();
UO.Print("Move: " + Convert.ToString(result));

1. Show status - direct script

Parameters and execution flow:

  • There are no arguments.
  • 0 does not prove that the goal was achieved: the route could have been cancelled.
UO.Print("Movement active or queued: " + Convert.ToString(UO.Move()));

2. Boundedly wait for stop - script function

Parameters and execution flow:

  • 100 waits over 50 ms set the approximate limit of 5 seconds.
  • Performing this check does not itself start or stop movement.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var attempts = 0;
    while (Truth(UO.Move()) && Truth(attempts < 100))
    {
        await Delay(50);
        attempts = attempts + 1;
    }

    UO.Print("Still moving: " + Convert.ToString(UO.Move()));
    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Stop Active Route - Script Class

Parameters and execution flow:

  • Move() checks for activity, MoverStop() removes the route.
  • Already sent packets can still be confirmed by the server.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(UO.Move()))
        {
            UO.MoverStop();
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Move() — UO.Move()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int Move()

        {

            int result = bridge.Move();

            if (result != 0)

                ticksAnim = Timer();

            return result;

        }

UO.MoveOff

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.MoveOff();

Disables compatible PMove key steps.

Parameters

There are no parameters.

Return value

void - no return value. Call on a separate line; it's not true/false or number of steps.

Behavior

  • Changes the MoveEnabled flag in the runtime state. This is not a universal character lock: NewMoveXY, MoveXYZ, Step and mouse are not controlled by this flag.
  • MoveOff does not stop an already running Pathfinder; it requires MoverStop.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.MoveOff");
UO.MoveOff();

1. Change Key Step Resolution - Direct Script

Parameters and execution flow:

  • There are no arguments.
  • The PMove flag is changed, with no return value.
UO.MoveOff();

2. Explicitly allow next PMove - script function

Parameters and execution flow:

  • MoveOn enables key steps before PMove; MoveOff turns off after its normal completion.
  • These are sequential commands; a disabled flag does not mean an emergency stop for all procedures.
return  RunScenario();
 object? RunScenario()
{
    UO.MoveOn();
    UO.PMove(UO.GetX() + 1, UO.GetY());
    UO.MoveOff();
    return null;
}

3. Turn off steps and remove automatic route separately - script class

Parameters and execution flow:

  • The two teams control different movement mechanisms.
  • Move() reads the automatic route; don't consider it a test of MoveEnabled.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.MoveOff();
        UO.MoverStop();
        UO.Print(Convert.ToString(UO.Move()));
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.MoveOff() — UO.MoveOff()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

public void MoveOff() => bridge.EnableMove(false);

UO.MoveOn

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.MoveOn();

Enables compatible PMove key steps.

Parameters

There are no parameters.

Return value

void - no return value. Call on a separate line; it's not true/false or number of steps.

Behavior

  • Changes the MoveEnabled flag in the runtime state. This is not a universal character lock: NewMoveXY, MoveXYZ, Step and mouse are not controlled by this flag.
  • MoveOff does not stop an already running Pathfinder; it requires MoverStop.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.MoveOn");
UO.MoveOn();

1. Change Key Step Resolution - Direct Script

Parameters and execution flow:

  • There are no arguments.
  • The PMove flag is changed, with no return value.
UO.MoveOn();

2. Explicitly allow next PMove - script function

Parameters and execution flow:

  • MoveOn enables key steps before PMove; MoveOff turns off after its normal completion.
  • These are sequential commands; a disabled flag does not mean an emergency stop for all procedures.
return  RunScenario();
 object? RunScenario()
{
    UO.MoveOn();
    UO.PMove(UO.GetX() + 1, UO.GetY());
    UO.MoveOff();
    return null;
}

3. Restore Key Move Before PMove - Script Class

Parameters and execution flow:

  • MoveOn enables compatible PMove key steps and does not return a value. The result of the movement is checked by coordinates; MoveOn does not control all modes of movement.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.MoveOn();
        int destinationX = UO.GetX() + 1;
        int destinationY = UO.GetY();
        UO.PMove(destinationX, destinationY);
        UO.Print($"Reached requested tile: {UO.GetX() == destinationX && UO.GetY() == destinationY}");
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.MoveOn() — UO.MoveOn()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

public void MoveOn() => bridge.EnableMove(true);

UO.MoveXY

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

dynamic UO.MoveXY(object? xdst, object? ydst, object? optimized, object? accuracy, object? running);

Moves the character to X/Y with five required parameters and waits for the result.

Parameters

  • xdst — World X coordinate of destination, 0..65535. This is not serial and not a position inside the gump.
  • ydst — World Y coordinate of destination, 0..65535.
  • optimized - true - normal mode of searching and checking the path forward; false - reduced heuristics and closest step checking. false does not disable obstacle avoidance.
  • accuracy — Tolerance for X and Y in cells: both deviations must fit within it. The value is limited to the range 0..20; 0 requires precise X/Y.
  • running - true/1 - run request, false/0 - step. Server motion delays persist; It's not a speed multiplier.

Return value

int 1 - at the end of the check the character is in the given X/Y/Z tolerance, including when he was already there before the challenge. int 0 - invalid coordinates, trigger failure, unreached point, or triggered stop condition. This is not a number of steps or serial; In case of emergency cancellation, the procedure is aborted instead of returning normally 0.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The complete A* route is built before the first step, in short portions between client updates. When Optimized=true the next 4 cells of the path are checked; when false is the nearest step. This is a check of the already calculated path, and not the distance of the entire route and not the detour sliders when moving the mouse.
  • Server failure DenyWalk or a new obstacle requests a recalculation from the current position after completing the queue of steps. The number of repetitions and recalculation frequency are limited; no path may end the movement with 0.
  • The route belongs to the procedure that started it: its emergency stop cancels the remaining automatic path. If another run or user has already replaced the route, canceling the previous owner does not affect the new route. Steps already sent are not recalled.
  • SetBadLocation and SetBadObject are used as a snapshot of the current runtime's prohibitions when the route is started. They are saved during its internal recalculation. Changing or clearing lists affects the next route, rather than overwriting one already in progress.
  • After accepting the request, the call waits on the script thread. The initial search and recalculation are performed on the game thread in chunks: a maximum of 32 node expansion and a soft budget of about 1 ms per chunk. One complex cell check or card reading can exceed this budget. Between portions, the client continues to update; the total search limit remains 10000 nodes.
  • timeout is counted after the request is accepted and includes subsequent portions of search and recalculation. stopOnStuck does not consider a running search to be a character stuck; After planning is completed, no position changes are taken into account again. The final 1/0 checks the actual coordinates, not just the readiness of the path.
  • The result takes into account the local position of the client; subsequent server correction is still possible. Running competing movement commands from different routines changes the character's overall route.
  • The settings moveCheckStamina, moveExitOnDisconnect, moveOpenDoor, moveThroughCorner, moveThroughNPC, moveHeuristicMult, moveTurnCost and moveBetweenTwoCorners affect the performance. Explicit avoidMobiles/openDoors override the corresponding values ​​for this call.
  • Result 0 does not indicate the exact cause. Check coordinates, connection, stamina and log; do not repeat the movement endlessly without UO.Wait and a limit of attempts.
  • The target Z is taken when called, tolerance Z=255. For additional restrictions, use NewMoveXY; to select the height - MoveXYZ.
  • The main bridge records the request number, player/Pathfinder/map instances, and map index. A new request, context change, or final refusal gives 0; the check is repeated after reading the coordinates and the last callback. Timeout, maxSteps and callback=0 only stop the saved request, not a new foreign route. Temporary Blocked, while recovery is still active, does not lose possession: the wait continues. For external legacy-bridge without IApiMovementOwnershipBridge, the previous compatible mechanism is retained.
  • The general Pathfinder stores up to 8 temporary X/Y/Z directional prohibitions for 2000 ms, only on rejected movement of the corresponding active request. Rotation, unknown sequence, resynchronization and old/foreign request do not create such a prohibition. A new external request and loss of map/player context clears them. Loaded geometry search attempts to bypass the transition; it's not knowing all the server obstacles. Without changing the player's X/Y/Z, up to 8 internal recalculations are allowed with a pause of at least 40 ms. There is no complete path or this budget has been exhausted - the route ends. The coordinate task then completes after processing the submitted steps; mobile-Follow may try again due to its delay.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.MoveXY(UO.GetX() + 2, UO.GetY(), true, 0, false);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Exact point on foot - direct script

Parameters and execution flow:

  • Xdst - two cells to the east; Ydst does not change.
  • Optimized=true, Accuracy=0, Running=false. The call returns the result when completed.
var ok = UO.MoveXY(UO.GetX() + 2, UO.GetY(), true, 0, false);
UO.Print(Convert.ToString(ok));

2. Approach object - script function

Parameters and execution flow:

  • Xdst/Ydst are read from the selected object; it must be an object of the world, not an object inside the container.
  • Accuracy=1 allows you to get close; Running=true. Heights are not limited to this challenge.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Exists("lasttarget")))
    {
        var ok = UO.MoveXY(UO.GetX("lasttarget"), UO.GetY("lasttarget"), true, 1, true);
        UO.Print("Approach result: " + Convert.ToString(ok));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Temporarily set minimum endurance - scenario class

Parameters and execution flow:

  • Replace the target 1445/1690 with your own. The endurance threshold is set by a separate setting, not the sixth MoveXY parameter.
  • After a normal return, the original value is restored. If an abort occurs, no further lines are executed.

Standard driving speed

Minimum step interval: walking - walking 400 ms, running 200 ms; riding - walking 200 ms, running 100 ms.

These are standard client limits, not automatically defined settings for your shard. Server speed and flight modes are counted separately. Script timers can slow down movement, but do not reduce these limits.

Steps, Routes, Follow, Mouse/Key Controls, and Map all use the character's shared queue. Replacing the route, turning, or adjusting the position by the server does not cancel the remaining pause after the step request. After the delay, there is no fast burst to compensate for the dropped frames. Waiting for confirmation, obstacles and poor communication can slow down the movement.

return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = UO.moveCheckStamina();
        UO.moveCheckStamina(15);
        var ok = UO.MoveXY(1445, 1690, true, 0, false);
        UO.moveCheckStamina(previous);
        UO.Print(Convert.ToString(ok));
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.MoveXY(xdst, ydst, optimized, accuracy, running) — UO.MoveXY(Any,Any,Any,Any,Any)

Parameters: xdst (Any), ydst (Any), optimized (Any), accuracy (Any), running (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "movexy":

                    return new InjectionValue(MoveTo(Arg(0), Arg(1), bridge.GetZ(bridge.Self), Arg(3), Arg(4) != 0, 255, Arg(2) != 0));

UO.MoveXYZ

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout, object? maxSteps);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout, object? maxSteps, object? avoidMobiles);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout, object? maxSteps, object? avoidMobiles, object? openDoors);

Moves the character to a point in the world with separate horizontal and vertical tolerances.

Parameters

  • x — Required int: the world X coordinate of the destination, 0..65535, on the current map. Not the gump coordinate.
  • y — Required int: the world Y coordinate of the destination, 0..65535, on the current map.
  • z — Required int: target world height -128..127. This is the surface height, not the floor number.
  • accuracyXY — Required int. Tolerance for X and Y in cells: both deviations must fit within it. The value is limited to the range 0..20; 0 requires precise X/Y.
  • accuracyZ — Required int. Height tolerance: abs(actual Z - required Z), limited by 0..255. Zero requires a precise altitude; 255 virtually disables the Z limit.
  • running — Mandatory Boolean flag. true/1 — run request, false/0 — step. Server motion delays persist; It's not a speed multiplier.
  • timeout — Optional wait limit in milliseconds; a missing argument, 0 and a negative value indicate the absence of this additional limit. The countdown begins after the route is accepted for execution; this is not a hard limit on the duration of the entire call along with route preparation.
  • maxSteps — Optional limit of observed position changes, not network packets. 0/negative/absent - without this limit. There may be several steps between polls, so this is not an accurate cell counter.
  • avoidMobiles — Optional flag: true prohibits passing through the characters being taken into account; false allows the attempt. Without an argument, moveThroughNPC is used. The server may still deny access.
  • openDoors — Optional flag for opening doors along the way. Without an argument, moveOpenDoor is used; true does not provide access to locked doors.

Return value

int 1 - at the end of the check the character is in the given X/Y/Z tolerance, including when he was already there before the challenge. int 0 - invalid coordinates, trigger failure, unreached point, or triggered stop condition. This is not a number of steps or serial; In case of emergency cancellation, the procedure is aborted instead of returning normally 0.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • How it works, step 1: checks coordinates, configured connection and endurance conditions. If the character is already within accuracyXY and accuracyZ, immediately returns 1 without a new route.
  • Step 2: builds a route on the current map taking into account the surface height, obstacles and selected passage conditions. Optimized mode is enabled within the command here; There is no need to pass such a parameter to MoveXYZ.
  • Step 3: starts walking or running along the route and waits for the result in the current procedure. The line after the call is executed after it completes; the client interface continues to work.
  • Step 4: If a step fails or a new obstacle occurs, the client can recalculate the route from the current position. Attempts are limited. When a timeout occurs or the limit of observable movements beyond the target is reached, the movement stops with 0.
  • Step 5: After the movement ends, compares the client's actual X/Y/Z with the target. Both abs(X-x)<=accuracyXY, abs(Y-y)<=accuracyXY and abs(Z-z)<=accuracyZ are required. For example, for the target 1279/540/20 with tolerances 1 and 2 X=1278..1280, Y=539..541 are suitable, Z=18..22.
  • The minimal form contains six arguments: UO.MoveXYZ(1279,540,20,1,2,true). Additional arguments are added to the right in the order timeout, maxSteps, avoidMobiles, openDoors. To specify openDoors, the previous positions must also be passed; blank spaces between commas are not supported.
  • Difference from NewMoveXY: MoveXYZ takes the target height as the third argument. NewMoveXY has a third argument of Optimized; You can't transfer altitude there. MoveXYZ does not have callback in this runtime.
  • The route belongs to the procedure that started it: its emergency stop cancels the remaining automatic path. If another run or user has already replaced the route, canceling the previous owner does not affect the new route. Steps already sent are not recalled.
  • SetBadLocation and SetBadObject are used as a snapshot of the current runtime's prohibitions when the route is started. They are saved during its internal recalculation. Changing or clearing lists affects the next route, rather than overwriting one already in progress.
  • After accepting the request, the call waits on the script thread. The initial search and recalculation are performed on the game thread in chunks: a maximum of 32 node expansion and a soft budget of about 1 ms per chunk. One complex cell check or card reading can exceed this budget. Between portions, the client continues to update; the total search limit remains 10000 nodes.
  • timeout is counted after the request is accepted and includes subsequent portions of search and recalculation. stopOnStuck does not consider a running search to be a character stuck; After planning is completed, no position changes are taken into account again. The final 1/0 checks the actual coordinates, not just the readiness of the path.
  • The result takes into account the local position of the client; subsequent server correction is still possible. Running competing movement commands from different routines changes the character's overall route.
  • The settings moveCheckStamina, moveExitOnDisconnect, moveOpenDoor, moveThroughCorner, moveThroughNPC, moveHeuristicMult, moveTurnCost and moveBetweenTwoCorners affect the performance. Explicit avoidMobiles/openDoors override the corresponding values ​​for this call.
  • Result 0 does not indicate the exact cause. Check coordinates, connection, stamina and log; do not repeat the movement endlessly without UO.Wait and a limit of attempts.
  • The main bridge records the request number, player/Pathfinder/map instances, and map index. A new request, context change, or final refusal gives 0; the check is repeated after reading the coordinates and the last callback. Timeout, maxSteps and callback=0 only stop the saved request, not a new foreign route. Temporary Blocked, while recovery is still active, does not lose possession: the wait continues. For external legacy-bridge without IApiMovementOwnershipBridge, the previous compatible mechanism is retained.
  • The general Pathfinder stores up to 8 temporary X/Y/Z directional prohibitions for 2000 ms, only on rejected movement of the corresponding active request. Rotation, unknown sequence, resynchronization and old/foreign request do not create such a prohibition. A new external request and loss of map/player context clears them. Loaded geometry search attempts to bypass the transition; it's not knowing all the server obstacles. Without changing the player's X/Y/Z, up to 8 internal recalculations are allowed with a pause of at least 40 ms. There is no complete path or this budget has been exhausted - the route ends. The coordinate task then completes after processing the submitted steps; mobile-Follow may try again due to its delay.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.MoveXYZ(UO.GetX() + 1, UO.GetY(), UO.GetZ(), 0, 0, false);
UO.Print("MoveXYZ: " + Convert.ToString(result));

1. Neighboring cell at the same height - direct script

Parameters and execution flow:

  • x/y/z is the target point. accuracyXY=0 and accuracyZ=0 require precise position.
  • running=false - walking. If the adjacent surface has a different height, the result may be 0.
var ok = UO.MoveXYZ(UO.GetX() + 1, UO.GetY(), UO.GetZ(), 0, 0, false);
UO.Print(Convert.ToString(ok));

2. Approach a point at the required height and check the result - script function

Parameters and execution flow:

  • Preparation: the character must be in the game, and the point must exist on the current map. 1279/540/20 are training coordinates: replace them with your available point, including the actual height of the surface.
    1. destinationX=1279 is the first argument, the X world coordinate of the target.
    1. destinationY=540 is the second argument, the Y world coordinate of the target.
    1. destinationZ=20 — third argument, height. The team must find a passage or staircase; the value 20 by itself does not transfer to the floor.
    1. accuracyXY=1 allows you to finish within one cell along each horizontal coordinate. The diagonally adjacent cell is also suitable.
    1. accuracyZ=2 allows heights from 18 to 22 inclusive. An X/Y match on another floor is not enough for success.
    1. running=true requests running. For walking, replace true with false.
    1. timeout=8000 limits the wait after the route starts to eight seconds. After this time, while the movement is still in progress, the command stops it and returns 0.
    1. maxSteps=100 limits the number of position changes observed. This is not the exact number of squares traversed; multiple steps may occur between polls.
    1. avoidMobiles=true prohibits passing through the characters taken into account when calculating the route.
    1. openDoors=true allows attempts to open doors along the way. This flag does not bypass a locked door or server restrictions.
  • reached receives int 1 or 0 after the call ends. if reached == 1 executes success branch; else handles failure to achieve the goal without endlessly repeating the command.
  • The last line prints the current X/Y/Z for checking. If the procedure aborts, no further lines, including this output, are executed.
return  RunScenario();
 object? RunScenario()
{
    var destinationX = 1279;
    var destinationY = 540;
    var destinationZ = 20;
    var accuracyXY = 1;
    var accuracyZ = 2;
    dynamic running = true;
    var timeout = 8000;
    var maxSteps = 100;
    dynamic avoidMobiles = true;
    dynamic openDoors = true;
    var reached = UO.MoveXYZ(destinationX, destinationY, destinationZ, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors);
    if (Truth(reached == 1))
    {
        UO.Print("Destination reached");
    }
    else
    {
        UO.Print("Destination not reached; check the path and limits");
    }

    UO.Print("Position: " + Convert.ToString(UO.GetX()) + "," + Convert.ToString(UO.GetY()) + "," + Convert.ToString(UO.GetZ()));
    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Running with limits and a ban on opening doors - scenario class

Parameters and execution flow:

  • x/y/z=1445/1690/0; accuracyXY=1, accuracyZ=3; running=true.
  • timeout=5000, maxSteps=60 of observed movements, avoidMobiles=true and openDoors=false.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var ok = UO.MoveXYZ(1445, 1690, 0, 1, 3, true, 5000, 60, true, false);
        UO.Print("Result: " + Convert.ToString(ok));
        return null;
    }
}

4. Ready-made function with comments inside the script - direct script

Parameters and execution flow:

  • Lines with # are C# comments: they are saved during copying and are not executed. The example contains both necessary parts: the function GoToPoint and the runnable procedure Main.
  • All six parameters GoToPoint are passed to MoveXYZ without modification. Four additional parameters are specified within the function: 8000 ms, 100 observed position changes, character traversal, and door opening.
  • For the purpose 1279/540/20 with tolerances 1/2 X=1278..1280, Y=539..541, Z=18..22 are suitable. A point at another altitude beyond 18..22 is not considered to be reached.
  • This is a wrapper around the real command, and not a second implementation of pathfinding in the script. It doesn't call an extra GetPathArray and doesn't trigger endless retries. If not achieved, the calling procedure receives 0 and chooses further action.

Standard driving speed

Minimum step interval: walking - walking 400 ms, running 200 ms; riding - walking 200 ms, running 100 ms.

These are standard client limits, not automatically defined settings for your shard. Server speed and flight modes are counted separately. Script timers can slow down movement, but do not reduce these limits.

Steps, Routes, Follow, Mouse/Key Controls, and Map all use the character's shared queue. Replacing the route, turning, or adjusting the position by the server does not cancel the remaining pause after the step request. After the delay, there is no fast burst to compensate for the dropped frames. Waiting for confirmation, obstacles and poor communication can slow down the movement.

var reached = GoToPoint(1279, 540, 20, 1, 2, true);
if (Truth(Truth(reached) == true))
{
    UO.Print("Destination reached");
}
else
{
    UO.Print("Destination not reached");
}

dynamic GoToPoint(dynamic x, dynamic y, dynamic z, dynamic accuracyXY, dynamic accuracyZ, dynamic running)
{
    var timeout = 8000;
    var maxSteps = 100;
    dynamic avoidMobiles = true;
    dynamic openDoors = true;
    var reached = UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors);
    return reached;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any), maxSteps (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any), maxSteps (Any), avoidMobiles (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any), maxSteps (Any), avoidMobiles (Any), openDoors (Any)

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoverStop

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

void UO.MoverStop();

Stops Pathfinder's automatic route.

Parameters

There are no parameters.

Return value

void - no return value. Call on a separate line; it's not true/false or number of steps.

Behavior

  • Removes local automatic movement. Already sent steps and server confirmations are not recalled.
  • This is not TerminateAll: execution of the remaining script lines and other procedures continues.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.MoverStop");
UO.MoverStop();

1. Remove route - direct script

Parameters and execution flow:

  • There are no arguments.
  • The command does not return a success code.
UO.MoverStop();

2. Stop only when route is active - script function

Parameters and execution flow:

  • Move() reads automatic movement.
  • Print — local script message; it is not a server confirmation.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Move()))
    {
        UO.MoverStop();
        UO.Print("Route stopped");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Stop moving and check position - script class

Parameters and execution flow:

  • UO.Wait=100 ms allows the client to process the next events.
  • After stopping, the coordinates are read separately; the delay does not guarantee receipt of all network acknowledgments.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        UO.MoverStop();
        await Delay(100);
        UO.Print(Convert.ToString(UO.GetX()) + "," + Convert.ToString(UO.GetY()));
        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.MoverStop() — UO.MoverStop()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "moverstop": bridge.StopMoving(); return InjectionValue.Unit;

UO.Moving

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C# signatures

int UO.Moving();

Checks the movement of your character.

Parameters

There are no parameters.

Return value

int bool (1/0): 1 - automatic Pathfinder is active or there are still steps in the character’s queue; 0 - both are missing or the character is not loaded. This is not a confirmation of achieving a goal or the number of steps.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

var result = UO.Moving();
UO.Print("Moving: " + Convert.ToString(result));

1. Check your own state - direct script

Parameters and execution flow:

  • Empty parentheses read self. active — number 1 or 0; The message text serves as an example of branch processing.
  • 1 - automatic Pathfinder is active or there are still steps in the character’s queue; 0 - both are missing or the character is not loaded. This is not a confirmation of achieving a goal or the number of steps.
var active = UO.Moving();
if (Truth(active))
{
    UO.Print("State is active");
}
else
{
    UO.Print("State is inactive or unavailable");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Checking against the presence of a character is a function of the script

Parameters and execution flow:

  • The command has no object argument: even after Exists(self), it only reads its own state.
  • Exists(self) checks the player's load separately from the requested flag. The world can change between checks.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Exists("self")))
    {
        var state = UO.Moving();
        UO.Print("State 1/0: " + Convert.ToString(state));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Notice state change without waiting indefinitely - script class

Parameters and execution flow:

  • The two calls without arguments read self; UO.Wait(500) - pause for half a second.
  • Two flag snapshots are compared. Transitions between shots may be skipped; it is not a subscription to all server events.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.Moving();
        await Delay(500);
        var after = UO.Moving();
        if (Truth(before != after))
        {
            UO.Print("State changed from " + Convert.ToString(before) + " to " + Convert.ToString(after));
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Moving() — UO.Moving()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.IsMoving()

API creation: These functions register the API. They do not run again for every command call.

Clone this wiki locally