Some details in test case 10.3 in #1567
move type random has some unique behaviors. Needs more investigation and fix to replicate RPG_RT
move_frequency=8, move_speed=6, move_type=randomMake it trigger parallel and put this code:
Loop:
OpenSaveMenu
Despite having move_frequency==8, we see sometimes the event waits for some stop count.
Here are some results for the number of frames waited between each step.
| Wait | Num Samples |
| -- | -- |
| 0 | 26 |
| 1 | 4 |
Result event stays facing down and stop_count just increments.
There is a table that maps frequency to max_stop_count:
|move_frequency|max_stop_count|
|-|-|
|1|256|
|2|128|
|3|64|
|4|32|
|5|16|
|6|8|
|7|4|
|8|0 (not 2, as one might have thought)|
Now it seems that the max_stop_count that is set after each move is further modified with a multiplier based on the move_type:
|move_type|max_stop_count multiplier|
|-|-|
|random|(random(0...4) + 3) / 5|
|custom|1 or 0.5*|
|All other types|1|
*: This is a strange case which I discovered only now. From how it looks to me, the normal value is used after each move step, but when a new event page is chosen in an event, that event's max_stop_count is once set to half the normal value when the move_type is custom.
Then there is a probability table for the different move actions in case of random movement:
|Probability|Action|
|-|-|
|30%|Move forward|
|20%|Turn left, move forward|
|20%|Turn right, move forward|
|10%|Turn around, move forward|
|20%|Set stop_count to random(0...max_stop_count) (effectively waiting between 1 and max_stop_count (inclusive) frames)|
Note that random's high value is exclusive!
*: This is a strange case which I discovered only now. From how it looks to me, the normal value is used after each move step, but when a new event page is chosen in an event, that event's
max_stop_countis once set to half the normal value when themove_typeiscustom.
I discovered this in #1601. There is the max_stop_count table for stepping and the max_stop_count table for turning. For some reason RPG_RT defaults to the turning max_stop_count when the move type is custom. This is only temporary though. As soon as you do any movement action like taking a step, max_stop_count is reset to its proper table value for step, turn, or wait as needed.
random(random(0...4) + 3) / 5
20% Wait for random(0...max_stop_count)
Are you sure about these? From my testing I observed something different.
With move type random, I saw the max_stop_count was always set to the stepping value from your table above. However I did notice that rarely (Maybe 20% of the time?) stop_count would tick up to max_stop_count+1 and then a move action would trigger.
At least that's RM2k behavior, pretty sure. Not sure about RM2k3 though.
It's possible though that the multiplier for random doesn't even take effect because something else sets the normal value afterwards...
What about random step in a move route? Is it just direction = rand(0,3) or does it have a probability table like above?
It is simply a random turn with equal distribution plus a step forward.
Also I fixed a mistake above, it should be:
Set
stop_countto random(0...max_stop_count) (effectively waiting between 1 andmax_stop_count(inclusive) frames)
instead of
Wait for random(0...
max_stop_count)
It's possible though that the multiplier for
randomdoesn't even take effect because something else sets the normal value afterwards...
That seems plausible. Just setting max_stop_count wouldn't do much as you'd also have to set stop_count back to 0.
Also in one of my tests I remember observing that during a step, the max_stop_count gets reset to the stepping value every frame.
All of that combined would lead to what I observed where it only waits 1 frame.
you'd also have to set
stop_countback to 0.
This happens automatically after each move action, I was only concerned about the value of max_stop_count now.
One more question, for determining direction here. Are we using direction or sprite_direction?
In what context?
In this table, the turn actions. What is the input direction used?
This would mostly come into account for a spinning event.
Probability Action
30% Move forward
20% Turn left, move forward
20% Turn right, move forward
10% Turn around, move forward
20% Setstop_countto random(0...max_stop_count) (effectively waiting between 1 andmax_stop_count(inclusive) frames)
The turn action in this table simply reads and writes direction, in the same way the regular turn action does (i.e. if it was a h/v direction then rotate, if it was a diagonal direction reset to Down).
The move action in this table updates sprite_direction based on direction (unless lock_facing is set) with the usual rules (which basically means sprite_direction is set to direction if it is h/v, or based on a complex ruleset including the previous sprite_direction in case direction is diagonal, although the latter is irrelevant in our case) - again the same as the regular move action does.
Hm, even though it's not relevant here, maybe it's relevant somewhere else - this is the ruleset for updating the sprite_direction upon movement:
|direction|Previous sprite_direction|New sprite_direction|
|-|-|-|
|Up|Up, Right, Left, Down|Up|
|Right|Up, Right, Left, Down|Right|
|Down|Up, Right, Left, Down|Down|
|Left|Up, Right, Left, Down|Left|
|UpRight|Up, Down|Up|
|UpRight|Right, Left|Right|
|DownRight|Up, Down|Down|
|DownRight|Right, Left|Right|
|DownLeft|Up, Down|Down|
|DownLeft|Right, Left|Left|
|UpLeft|Up, Down|Up|
|UpLeft|Right, Left|Left|
EDIT: Looks like you already have this properly anyway, in a simpler way using math ^^ https://github.com/EasyRPG/Player/blob/f07e49e10baa1053972535f3525bc076d33a15cf/src/game_character.cpp#L463
Most helpful comment
Hm, even though it's not relevant here, maybe it's relevant somewhere else - this is the ruleset for updating the
sprite_directionupon movement:|
direction|Previoussprite_direction|Newsprite_direction||-|-|-|
|
Up|Up,Right,Left,Down|Up||
Right|Up,Right,Left,Down|Right||
Down|Up,Right,Left,Down|Down||
Left|Up,Right,Left,Down|Left||
UpRight|Up,Down|Up||
UpRight|Right,Left|Right||
DownRight|Up,Down|Down||
DownRight|Right,Left|Right||
DownLeft|Up,Down|Down||
DownLeft|Right,Left|Left||
UpLeft|Up,Down|Up||
UpLeft|Right,Left|Left|EDIT: Looks like you already have this properly anyway, in a simpler way using math ^^ https://github.com/EasyRPG/Player/blob/f07e49e10baa1053972535f3525bc076d33a15cf/src/game_character.cpp#L463