There are two types of movements, Item Component Movement, and Pure Movement.

Base Class

public abstract class Movement {}

Move

It defines how to move.

public virtual async Task Move(Item item, float temperature) { }

An example.

public override async Task Move(Item item, float temperature)
{
    var prob = probability.Evaluate(Random.Range(-1f, 1f));
    
    int change = Mathf.CeilToInt(range * prob);
    if(byTemperature)
        change = Mathf.CeilToInt(change * temperature);
    
    // Apply
    var i = item.GetItemComponent(attribute);
    
    if(i==null)
        Debug.LogError($"[MCMC] Item {item} has no {attribute} Item Component.");
    
    i.SetValue( (int)i.GetValue()+ change);
    
    await Task.Yield();
}

Item Component Movement

It supports up to 5 Item Components invokes in one movement.

public abstract class ItemComponentMovement<T0> : Movement {}

//...

public abstract class ItemComponentMovement<T0, T1, T2, T3, T4> : 
	ItemComponentMovement<T0, T1, T2, T3>

You can create an evaluator that supports more inputs according to this format.