Friday Facts #412 - Undo/Redo improvements & Car Latency driving

Posted by StrangePan, Lou on 2024-05-24

Hello,
We have another exciting batch of facts for you today.


RedoStrangePan

The ability to Redo things has been requested ever since we added the Undo. Adding Redo was one of my first projects at Wube, and one I've been super excited to announce for a long time. Now in addition to using CTRL+Z (or ⌘Z) to reverse a build, deconstruct, or upgrade order, you can now use CTRL+Y (or ⌘⇧Z) to re-issue a previously undone order. You can also use the new redo shortcut in the shortcut bar. It works exactly like you'd expect.

The new "redo" shortcut lights up when there's something to redo, and is disabled when there's nothing to redo.


Undo information and confirmationStrangePan

One thing that is often super annoying and destructive, is undoing actions (sometimes by accident) and something far away from a long time ago is also undone.

For starters, we added a flying text notification that pops up when you use the undo hotkey. This gives you some idea of what the heck you just did.

In addition, when trying to undo an action that is more than a few minutes old, there is a confirmation dialog pop-up. To really bring it all together, Genhis added an awesome visual preview that reveals the entities to be affected, highlights entities to be deconstructed, and shows ghosts of entities to be built.

Another thing we discovered during our playtesting is that it's easy to forget what you had in the undo stack. This is especially true in Space Age, in which players are constantly using Remote View to jump between planets and space platforms. So we added a preview tooltip to the undo and redo shortcut buttons that describes exactly what you're about to undo and on which planet or space platform.


Undo ImprovementsStrangePan

Undo in its general purpose works great, but there is one major issue that has remained for many years. Putting down a blueprint and then using Undo, does not actually undo everything:

  • Recipes set by the blueprint remain.
  • Wires created are not removed.
  • Rotations are not restored to the previous direction.
  • Filters/Requests are not reverted.

This presents a problem, because one of the axioms of Undo is that "anything you do will be undone". Cleaning up a misplaced blueprint should "just work" with undo. So lets get to work.

Undo wire connection

Boskid added the ability to undo wire connections. If you make a mistake while fiddling with combinators or power lines, you can use undo and redo to quickly get back on track.

When placing a blueprint, the created wires are also added to the undo action, so that part of the blueprint problem is fixed.

Undo entity settings

Tobias added the ability to undo entity settings. When you use SHIFT + Right-click to copy an entity's settings and SHIFT + Left-click to paste them onto another entity, that action also gets put onto the undo stack (and redo stack).

This also applies to the settings copied when placing a blueprint over entities, so another blueprint problem checked off the list.

Undo blueprint rotations

Using super-force mode, it is possible to override an entity direction. This is a nice feature and saves robots mining and placing all the entities again. But of course, we need to make it work with undo.

This doesn't apply to rotations made by hand using the R key, as that is easy to correct yourself and could spam up the undo queue.

Conclusion

With all these additions, undoing a blueprint placement is now a fully safe and clean operation, a small whoopsie won't leave your setups in disarray.

A few details are subject to change, but the undo/redo system is feeling way more useful than ever before. These changes are coming to Factorio 2.0 and will be available to all players.


Car latency drivingLou

Anyone who had the dubious pleasure of driving a car in multiplayer with significant latency, probably had their heart skip 100ms just after reading the title :).

For the rest of you, let me describe the problem: Driving around obstacles in Factorio is hard enough, doing so with a delayed reaction of your vehicle to your input is even harder, especially if you want to go fast (which is usually the reason for driving in the first place).


Driving in 1.1 with 30 ticks of latency (500ms with 60 UPS). I swear I was sober.

So when literally doing a slalom with a battle tank, it would be nice to not make it feel like doing so on an ice skating rink right?

The basic idea is the same as all other latency hiding features - predict the future game state from available information and show the player the predicted state instead of their current one. Reaction to inputs is instantaneous = the latency is hidden.

Although there are things that could never be predicted perfectly (actions of other players) or would be too expensive to predict (interaction with enemies, other moving vehicles (like trains), robots (de)constructing obstacles), the basic driving seemed simple enough - static obstacles and state of the car. And in truth, the basic implementation was simple enough.

But like we tend to quip around the office "nothing is simple in Factorio"; and that is doubly so when you are trying to efficiently simulate Factorio in order to hide latency.

Some of the issues were:

  • Incorrectly evaluating the values of speed modifiers (fuel, terrain, stickers (that yellow green slime from spitters and worms that we all love)).
  • Audio issues - some sounds not being played when they should have, others playing multiple times when they shouldn't have.
  • Graphics issues - from simple ones like car lights not drawing properly to incorrectly spawning track and exhaust particles.
  • Many issues with entering and exiting the car in weird circumstances.
  • Issues around remote view, editor, and switching between those.
  • Interesting issue where damage calculations for game state and latency state had different order of operation - which were almost always equivalent, except when doing very little damage to an entity with very little health remaining (due to rounding errors). Which is exactly what happens when you are trying to destroy an obstacle by pushing (or even better turning with stationary tank)
  • Many small issues: selecting latency hidden car, latency hidden car not being moved by belts, interaction with not yet published mechanic, screen positioning when deactivated latency hiding due to combat, etc.

While one would expect some of the prediction imperfections to be barely noticeable, unfortunately that is not the case due to how we handle certain aspects of latency hiding.


A bug where initial speed of the vehicle being entered was not correctly accounted for (latency 60 ticks).
(Ghostly/Transparent visualisation of game state car is a debug option).


A bug where vehicle was not being moved by belts in latency (latency 30 ticks).

Latency One-time effects

There is some stuff that you want to be done only once per client - regardless if during game state or latency update - like spawning a particle or playing a sound.

A major part of how we accomplish this is by turning these into LatencyOneTimeEffects, comparing them with a data-structure of already performed ones (that persists through both latency and game state updates), and only executing the ones that have not yet been performed. Unfortunately, these checks need to be quite strict (to allow for example multiple particles from the same source at the same tick close to each other).

As a result, when there is even a minuscule mismatch between our predictions, we are rewarded by receiving an extra set of sounds and particles for every latency update all at the same time. Or even better, when the not-accounted-for-circumstance is happening for a bunch of ticks in a row, we get an additional set for every game state update tick where our latency predictions differed from the one done previous game state update.

These sound like they would be small and unnoticeable, but they are quite the opposite, so every small imperfection will need to be fixed (of course, the smaller your latency is, any unaccounted for happenstances will be both less observable and less likely).

Result


Driving in current version with 30 ticks of latency (500ms with 60 UPS).

As you can see in the video, the result is that latency is effectively hidden for almost all civilian intents and purposes. We hope you will all enjoy driving together once 2.0 arrives.


As always, redo your thoughts at the usual places.