Skip to content

SF4Enhanced 1.0.0 — public lobbies

Choose a tag to compare

@fabeloper fabeloper released this 29 Sep 12:46
· 4 commits to main since this release

Superseded by 1.0.1. 1.0.0 ended some matches at the first second with a false desync message. Download 1.0.1 instead; both players need it. The 1.0.0 client zip has been removed from this page.


Rollback netcode for Ultra Street Fighter IV.

Play USF4 online with rollback netcode, public lobbies, lobby codes and spectating. No port forwarding, and nothing to configure on your router.

Install

  1. Download sf4e-1.0.0-win32.zip below
  2. Unzip anywhere
  3. Run SF4Enhanced.exe

Requires Ultra Street Fighter IV on Steam. The game is not included.
If SmartScreen warns you: More info → Run anyway (the build is unsigned).

Both players need the same version. Trying to join someone on a different one tells you so instead of silently failing.

⚠️ Read this or you will desync

In the game's graphics options, set "frames per second" / "imágenes por segundo" to Fixed (Fija). This changed from Variable: frame pacing works through the fixed-rate limiter, and the game now tells you on the match-over screen if the setting is wrong. Never use Smooth / Fluida. Both players must use the same setting.


Public lobbies

You no longer need to know anyone to play.

BROWSE PUBLIC LOBBIES on the online menu shows every open lobby on every server, each with the flag of the region it lives in — who made it, how many are in it, how long it has been waiting. Pick one and press A. That is the whole process.

A lobby whose match has already started stays on the list as IN MATCH. Press Y on it to watch.

When you create a lobby it is public by default, so anyone browsing can find and join it. Press Left or Right on CREATE LOBBY to make it private; a private lobby works exactly as before — only someone you give the code to can join. The choice is remembered.

The list shows a lobby's title and player counts and nothing else. Nobody's address is shared with anyone through the list.

The mid-round desync has a cause, and a fix

Some of you hit a desync in the middle of a round — most often during a throw or a grab ultra — that would not reproduce no matter how long the game ran against itself on one PC. The cause turned out to be inside the engine.

The game updates both fighters on separate threads at the same time. During a throw, the thrown fighter's position is read from the thrower's hand while the thrower's own update may still be changing it. Depending on which thread wins that race, the two PCs place the fighter a hair apart — and from there the two games are no longer the same match. A single PC tends to win the race the same way every time, which is why we could never see it alone.

Both fighters now update one after the other on the game thread, so both PCs always get the same result. This is not specific to any character and should fix other "random" mid-round desyncs as well.

Shadow moves roll back correctly

Yun's Genei Jin, Yang's Seiei Enbu, Rose's Soul Illusion and every other move that leaves shadows behind the fighter had a rollback problem of their own. The game saved each shadow's picture but not its state, so after a rollback the shadows kept the animation frame and hitboxes of the timeline that had just been thrown away. On screen they froze or fell behind the fighter; underneath, a shadow's hit could land on a different frame on each PC and desync the match.

Shadows are now saved and restored with the rest of the fighter. If you main one of these characters, please tell us how it looks online.

Credit where it is due: the root cause and the way to fix it were worked out by the SF4 Ember Netplay project. Our implementation follows their analysis.

Smoother frame pacing

When one PC runs a little ahead of the other, GGPO used to tell it to skip whole frames, which landed as small hitches. The game now measures the gap every frame and stretches or shrinks each frame by a few milliseconds instead, so the two PCs drift back into line without a skip. It works through the game's own frame limiter, which runs under the Fixed frames-per-second setting. Under any other setting the match-over screen tells you to change it, and the old behaviour stays until you do.

Desync detection reaches further

The check that decides whether two games have diverged now also compares each fighter's current move, its frame and posture. A fork there is caught a few frames before it shows in health or position, and the log names it.

Input delay is shared

Each player's delay used to apply only to their own inputs, so whoever chose less got the responsive controls while the other absorbed the rollbacks. Both players now play at the higher of the two choices. If yours is raised, the log says so and by how much.

Smoother under bad connections

Several improvements to how the game and GGPO cope when packets are late or lost:

  • Ping readings are fresh. The connection was measured once a second; it is now ten times a second, so the number you see is the number you are playing on.
  • Lost inputs are re-sent sooner — after 33 ms of silence instead of waiting 200 ms — within a strict budget, so a brief hiccup costs a frame rather than a stall.
  • Three crashes became clean disconnects. A peer that dropped before sending any input, a sender that skipped frames, and a receiver that stopped acknowledging each used to kill the game outright. All three now end the match and return you to the lobby.
  • Malformed packets are rejected by type and size before anything reads them.

Faster rollback

Every frame, GGPO releases its oldest saved state before saving a new one. That release used to save the whole live game, restore the old state, clear it, and restore the live game again — a full record and two full restores, every single frame. It now takes about as long as freeing a buffer. A rematch also starts from a clean save-state pool instead of whatever the last match left behind.

What's in this build

  • Rollback netcode with adjustable input delay (1–8), shared between players
  • Public lobbies — browse and join anyone waiting on your server
  • Lobby codes — share a 6-character code for a private match
  • Peer-to-peer connections with automatic server-relay fallback, and UPnP to open the port on your router
  • Servers in 🇪🇸 Spain, 🇩🇪 Germany and 🇺🇸 USA. For a private lobby by code, both players pick the same one; joining from the public list switches you to the right server on its own.
  • Spectator mode
  • Shadow moves (Genei Jin, Seiei Enbu, Soul Illusion) roll back with the fighter
  • Honest desync handling — if the two games genuinely diverge, the match ends cleanly on both PCs and says so

Privacy

The servers record aggregate, anonymous usage only — how many matches are played, how long they last, how busy each region is. No player names and no IP addresses are stored. The public lobby list shows a title and player counts, nothing more.

Status

This is 1.0.0 because the core does what it set out to do: rollback that stays in sync, and a way to find an opponent without knowing one. Known rough edges:

  • Some networks cannot make a direct connection at all and will always use the relay. This is normal and the match plays fine; it is a property of your router.
  • Three regions cover Europe and North America. Elsewhere, expect higher ping unless you get a direct connection.
  • The build is unsigned.

If something breaks, the log at %APPDATA%\sf4e\logs\sf4e.log is what makes it fixable — please include it, from both players if you can. If your game crashed, %APPDATA%\sf4e\crash may hold a dump; that is even better.

Credits

  • Built on the sf4e project by adanducci.

Disclaimers

  • Not affiliated with, endorsed by or associated with Capcom. Street Fighter and Ultra Street Fighter IV are trademarks of Capcom. Unofficial, non-commercial fan project.
  • No game assets are included. You must own the game on Steam.
  • Use at your own risk — provided as-is with no warranty, and intended for private play with friends rather than official online modes.