Алгоритм прост. Нужно запоминать в какой-нибудь структуре данных либо каждое конкретное действие игрока, например, делать записи вида [[действие=клик][позиция:[x=10][y=30]]]; либо записывать изменения постоянного действия, например, когда игрок двигался постоянно вверх, была сделана запись [[действие=движение][направление=вверх][скорость= 6 пикс/сек][длительность= 4 сек]], а когда он изменил направление движения на "влево" - появилась запись [[действие=движение][направление=влево][скорость= 4 пикс/сек][длительность= 3 сек]].
Итого получается структура данных, имеющая примерно такой вид:
Код
[[действие=движение][направление=вверх][скорость= 6 пикс/сек][длительность= 4 сек]]
[[действие=клик][позиция:[x=10][y=30]]]
[[действие=движение][направление=влево][скорость= 4 пикс/сек][длительность= 3 сек]
<...>
[[действие=...][позиция:[x=...][y=...]][направление=...][скорость=...][длительность=...][что-нибудь_ещё=...]]
Эта структура интерпретируется уже в нужные действия в прямом или обратном порядке (в обратном для, например, эффекта возвращения во времени).
***
Если хочешь конкретный код - вот примерный вид подобной записи на языке с паскалевским синтаксисом:
Код
type
TPoint2f=record //запись координат или вектора
x,y:single;
end;
//перечисляемый тип доступных действий:
TActions=(AWalking, AStanding, AJumping, ADoing);
TTimeRecord=record
action:TActions; //какое действие совершается
at:TPoint2f; //где действие происходит (точка)
angle:single; //куда направлено (угол) действие
speed:single; //скорость происходящего действия
duration:single; //продолжительность действия
ex1:byte; //дополнительный параметр действия для уточнения,
//например ADoing означает совершение действия, но
//неизвестно какого (как в РПГ, например, много похожих действий)
end;
var
TimeStack:array of TTimeRecord; //динамический массив записей