Skip to content

EN UO Topic record playback

Codex edited this page Oct 12, 2026 · 4 revisions

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

Record / Playback

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

Record and repeat supported actions. The composition of the recording and playback restrictions are determined by the implementation of the commands.

Sections

Topic Commands and explanations
SetRec UO.SetRec
UseRec UO.UseRec

All theme commands

Recording

UO.SetRec · UO.UseRec

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.SetRec

Parameters, result and all scenarios

UO.SetRec();
UO.Light(15);

UO.UseRec

Parameters, result and all scenarios

UO.SetRec();
UO.Light(15);
UO.UseRec();

Complete command reference


UO.SetRec

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

C# signatures

void UO.SetRec();

Prepares the recording of the next legacy command UO.

Parameters

There are no parameters.

Return value

void - no value. Call on a separate line; completion does not confirm the server's action.

Behavior

  • ExecuteLegacyManualAlias clears state. RecordedAction and sets recordNextLegacyAction=true. The next call to the same legacy-dispatcher, except SetRec/UseRec, serializes the name and arguments before executing the command, then clears the flag.
  • This does not record all mouse actions, any UO getters or server events. Repeats only one command from a supported legacy-dispatcher. The old save is erased immediately.
  • 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.
  • The entry preserves the argument types int, double, string, recursive Array, and void. Other Objects are written as text ToString; the live object/handle is not restored when repeated.
  • RecordedAction is the general state of the profile, and recordNextLegacyAction/replayingLegacyAction are the private fields of this InjectionApiUO. Only this instance records its next legacy call. Another script can clear or redo a shared write, but does not consume that instance's write wait flag.
  • Only SetRec() is registered, strictly without arguments. It clears RecordedAction immediately, so remain() returns 0 before a subsequent legacy action is written by that instance; Enabling write wait does not itself create a saved action. remain() only reads and does not consume the wait flag.

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.SetRec");
UO.SetRec();

1. Direct call - direct script

Parameters and execution flow:

  • Prepares the recording of the next legacy command UO.
UO.SetRec();
UO.Light(15);

2. Explicit option - script function

Parameters and execution flow:

  • ExecuteLegacyManualAlias clears state. RecordedAction and sets recordNextLegacyAction=true. The next call to the same legacy-dispatcher, except SetRec/UseRec, serializes the name and arguments before executing the command, then clears the flag.
return  RunScenario();
 object? RunScenario()
{
    UO.SetRec();
    UO.Sound(0x0040);
    UO.UseRec();
    return null;
}

3. Full Helper Function - Script Class

Parameters and execution flow:

  • This does not record all mouse actions, any UO getters or server events. Repeats only one command from a supported legacy-dispatcher. The old save is erased immediately.
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.SetRec();
        UO.TextPrint("This is not a legacy recording route");
        UO.Light(15);
        UO.UseRec();
        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.SetRec() — UO.SetRec()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "setrec":

                    state.RecordedAction = string.Empty;

                    recordNextLegacyAction = true;

                    break;

UO.UseRec

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

C# signatures

void UO.UseRec();

Repeats the saved legacy command UO.

Parameters

There are no parameters.

Return value

void - no value. Call on a separate line; completion does not confirm the server's action.

Behavior

  • TryDeserializeRecordedLegacyAction checks the YOKOREC1 prefix and typed arguments. No/invalid entry - local message, no action. A valid entry calls ExecuteLegacyManualAlias with the saved name and arguments.
  • The replayingLegacyAction flag protects the replay from writing itself and is cleared finally, even on error. The entry is not deleted after repeating: UseRec can be called again. Names/serial are resolved according to saved types and the current world.
  • 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.
  • The entry preserves the argument types int, double, string, recursive Array, and void. Other Objects are written as text ToString; the live object/handle is not restored when repeated.
  • RecordedAction is the general state of the profile, and recordNextLegacyAction/replayingLegacyAction are the private fields of this InjectionApiUO. Only this instance records its next legacy call. Another script can clear or redo a shared write, but does not consume that instance's write wait flag.

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.UseRec");
UO.UseRec();

1. Direct call - direct script

Parameters and execution flow:

  • Repeats the saved legacy command UO.
UO.SetRec();
UO.Light(15);
UO.UseRec();

2. Explicit option - script function

Parameters and execution flow:

  • TryDeserializeRecordedLegacyAction checks the YOKOREC1 prefix and typed arguments. No/invalid entry - local message, no action. A valid entry calls ExecuteLegacyManualAlias with the saved name and arguments.
return  RunScenario();
 object? RunScenario()
{
    UO.SetRec();
    UO.Sound(0x0040);
    UO.Wait(250);
    UO.UseRec();
    return null;
}

3. Full Helper Function - Script Class

Parameters and execution flow:

  • The replayingLegacyAction flag protects the replay from writing itself and is cleared finally, even on error. The entry is not deleted after repeating: UseRec can be called again. Names/serial are resolved according to saved types and the current world.
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.SetRec();
        UO.Light(15);
        UO.UseRec();
        UO.Wait(250);
        UO.UseRec();
        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.UseRec() — UO.UseRec()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "userec":

                    if (!TryDeserializeRecordedLegacyAction(state.RecordedAction, out string recordedName, out InjectionValue[] recordedArguments))

                    {

                        if (bridge != null) SystemMessage("UseRec: no recorded UO action is available. Call UO.SetRec() before the action to record.");

                        break;

                    }

                    replayingLegacyAction = true;

                    try

                    {

                        ExecuteLegacyManualAlias(recordedName, recordedArguments);

                    }

                    finally

                    {

                        replayingLegacyAction = false;

                    }

                    break;

Clone this wiki locally