The Command Pattern: Coding Undo/Redo | Game Engine Concepts #3

preview_player
Показать описание

In this episode I explain what the Command Pattern is and how you can use it. Before I explain what the Command Pattern is I explain what a design pattern is and reference the Gang of Four's original book, Design Patterns. After that, I explain that the Command Pattern is simply a wrapper around executing commands. I then illustrate how this can be used in conjunction with a Command History object to create an undo/redo system, record gameplay sessions, and create instant replays. I describe in detail how you might code this, then I show an actual example that I use in my code to implement undo/redo system.

0:00 Intro
0:31 What is a Programming Pattern?
1:39 What is the Command Pattern?
13:39 What does the Code Look Like?

---------------------------------------------------------------------

Here are some books I recommend if you want to learn about game engine development more thoroughly. I do not profit off any of these sales, these are just some books that have helped me out :)

My Recommended Game Engine Books:

My Recommended Beginning Game Programming Books:

My Recommended Java Books:

Рекомендации по теме
Комментарии
Автор

there is a nice alternative way of handling the 'stack' if you have 2 vectors. One containing done commands and one containing undone commands it makes things even simpler to implement.

RobertFletcherOBE
Автор

That is just the best tutorial on command pattern, thank you. Also, the repository with your engine no longer contains code for this implementation.

andriibilych
Автор

Underrated channel & video, learned a lot

inxomnyaa
Автор

When i first try to implement undo/redo system in my game engine, i do that way, basically create two lists for undo and redo commands. And from perspective undo for example i add function to add/push undo command in my list, with struct that holds recovery data, its can be anything, TransformComponent or maybe single variable. And when i need undo this command i simple call process/execute function, that checks witch command need to be process and get the all recovery data to that specific command and execute it, and after this just decrement pointer/remove command from undo list and push it to redo list, for that case if we need to redo it. In sinple words my commands just changes between lists. And that works perfectly even with ECS that hold every time different ids, cuz im using UUIDs for my game objects.

KennyTutorials
Автор

Good quality content, thank you for your work :)

vfrzvfrz
Автор

Hey Gabe, great video. Might I suggest that rather than delete every command after you add a new one, you instead keep a second pointer for the end of the list? Also, you don't appear to be handling the case when you hit the limit of your undo buffer which leaves you in danger of an overflow issue. If you continue to use an array, you would need to move every element back by one. I potentially better option would be to use a linked list as your undo buffer. In that way, you can just cut the head and append it to the tail. Similarly, you would not need to loop ahead when adding a new command, simply replace the next pointer to the new command and dereference the old tail.

ianlaird