TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

How to build undo/redo in a multiplayer environment by Liveblocks

174 pointsby moritzplassnigalmost 3 years ago

14 comments

munificentalmost 3 years ago
I&#x27;ve implemented undo&#x2F;redo a number of times. I agree whole-heartedly that the Command pattern is the way to do it. Undo has a reputation for being difficult, but my experience is that it&#x27;s smooth sailing <i>as long as you build it into the tool on day 1</i>. If the app is architected around undo, it&#x27;s easy, but trying to retrofit it onto an application later is always a nightmare.<p>This is very similar to the experience of writing a networked multiplayer game. If you build a single-player game and try to bolt multiplayer on later, you&#x27;re gonna have a bad time. But if you design it for multiplayer initially and treat single-player mode as essentially just a multiplayer game with only one player, it&#x27;s relatively easy.<p>I think both of these come down to the same core issue: mutating state.<p>When playing a game, or editing a document, you are mutating some state. To support undo, you need to capture all of those mutations so that you can reverse them. To support multiplayer, you need to capture them so that they can be synchronized with the other players.<p>It&#x27;s trivially easy in most programs to just directly mutate some state by setting fields or by calling methods that do that under the hood. So, if you just start coding, you will end up with mutation happening everywhere. At that point, you have already lost.<p>But if you design your application for undo, you isolate the document state from the rest of the application so that the <i>only</i> way to modify it is by going through the undo&#x2F;redo mechanism. (In other words, the only way to apply a change is to create a Command object which does it on your behalf.) Likewise, if you design for multiplayer, you&#x27;ll build a separation between game state and the rest of the application. Then the program has a well-defined interface that can modify the state.<p>Once all mutation goes through a narrow well-defined interface, it&#x27;s relatively easy to grow the application over time without compromising undo or multiplayer.<p>But if you&#x27;re adding that afterwards, you have to dig through the program to find every single piece of code that changes some state. It&#x27;s hell.
评论 #31752013 未加载
评论 #31688000 未加载
评论 #31688562 未加载
maccardalmost 3 years ago
I know slightly too much about the problem space to have questions about how it&#x27;s implemented, but I just want to say this is one of the neatest presentations I&#x27;ve seen on this site. It&#x27;s a great article on an interesting topic and made 100x better by the visualisations
评论 #31681759 未加载
评论 #31700559 未加载
mfesteralmost 3 years ago
Nice work! Regarding your question on how to handle undoing a command on a shape that doesn&#x27;t exist anymore, is there a way we could automatically recreate the shape?
评论 #31682073 未加载
aranchelkalmost 3 years ago
&gt; Depending on the use case, the state of features like user selection, user page selection, user zoom setting, etc. could be included in the undo&#x2F;redo stack to provide a great experience.<p>Does anyone have an idea what these use cases could be? My mental model for undo&#x2F;redo is based on productivity applications and I’m at a loss; I’m genuinely curious though since this is something I’ve been implementing.
评论 #31682853 未加载
评论 #31700667 未加载
评论 #31683384 未加载
iKlsRalmost 3 years ago
Light mode for the site please, those of us with Astigmatism can&#x27;t use it. Supabase launched the same and they eventually had to add it because of demand, not sure why dark mode is so heavily default nowadays. <a href="https:&#x2F;&#x2F;jessicaotis.com&#x2F;academia&#x2F;never-use-white-text-on-a-black-background-astygmatism-and-conference-slides&#x2F;" rel="nofollow">https:&#x2F;&#x2F;jessicaotis.com&#x2F;academia&#x2F;never-use-white-text-on-a-b...</a>
评论 #31736504 未加载
stevenfabrealmost 3 years ago
Hi HN,<p>We&#x27;ll be here today to answer any questions you may have. Hope you enjoy the article!<p>Thanks, Steven
评论 #31681192 未加载
yodonalmost 3 years ago
As someone who&#x27;s built this kind of multi-player undo&#x2F;redo in the past all I can say is this looks amazing and I can&#x27;t wait to try it in one of my projects - Thanks for building this!
评论 #31686542 未加载
pphyschalmost 3 years ago
&gt; In a multiplayer command-based undo&#x2F;redo system, we can also solve [intermediary commands] by pausing and resuming the history stack at the right time.<p>Suppose that instead of managing the overall state of the history stack, you gave each command a unique ID and allowed commands to be updated&#x2F;overwritten as they develop? Apart from a few bytes of memory overhead per command, what am I missing?
tmikaeldalmost 3 years ago
Nice to see someone make a product out of Cloudflare Workers (and Durable Objects for sync?).<p>Also, excellent explanation and visualizations :)<p>Good luck with all of it
评论 #31682907 未加载
cyralalmost 3 years ago
Love this style of interactive posts. I recently had to solve the same problem for my own app and did it pretty similarly.
评论 #31681764 未加载
Xeoncrossalmost 3 years ago
For deleted items, could you not store a memo of the object in addition to the user-local changes they did?<p>So if you undo a change to an object that was delete by a different user, you can restore that object first to the last known state, then apply the undo?<p>I&#x27;m not sure this makes sense for other cases besides object deletion.
评论 #31682958 未加载
kbyatnalalmost 3 years ago
What a fantastic, well-written blog post - well done.<p>Out of curiosity, what&#x27;s the max # of simultaneous connections per room that LiveBlocks can support? (it&#x27;s hidden behind the enterprise signup flow today)
评论 #31687041 未加载
upupandupalmost 3 years ago
Is there a provider that has &quot;websockets all over the world on edge&quot; ? Right off the bat I am not a target customer because I don&#x27;t use React. Coming from Vue&#x2F;Svelte
评论 #31683626 未加载
评论 #31684005 未加载
schneegansmariealmost 3 years ago
Love the interactive visuals. Would be awesome to see how that would work with other use cases at some point. Is that something you’re planning to do?
评论 #31684552 未加载