<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: The Nicholas 035</title>
    <description>The latest articles on DEV Community by The Nicholas 035 (@nicholasthegreat).</description>
    <link>https://dev.to/nicholasthegreat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3815828%2F94a787a7-c975-4693-830a-eadfd0a2f50e.jpeg</url>
      <title>DEV Community: The Nicholas 035</title>
      <link>https://dev.to/nicholasthegreat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicholasthegreat"/>
    <language>en</language>
    <item>
      <title>I built the same retro gaming platform two ways: WebRTC and WebAssembly</title>
      <dc:creator>The Nicholas 035</dc:creator>
      <pubDate>Thu, 23 Jul 2026 18:34:18 +0000</pubDate>
      <link>https://dev.to/nicholasthegreat/i-built-the-same-retro-gaming-platform-two-ways-webrtc-and-webassembly-34mg</link>
      <guid>https://dev.to/nicholasthegreat/i-built-the-same-retro-gaming-platform-two-ways-webrtc-and-webassembly-34mg</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What I learned from building two editions of PIXELATED—one that streams games through WebRTC and one that runs them directly in the browser with WebAssembly.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I started PIXELATED with a fairly ambitious idea: what if a browser could be the front door to a retro gaming platform, while the actual game ran somewhere else?&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;PIXELATED Studio&lt;/strong&gt;, a project built around a desktop engine, Docker, and WebRTC streaming. The browser handles the interface and sends controls; the engine runs the emulator and streams the result back.&lt;/p&gt;

&lt;p&gt;It worked, but it also raised an obvious question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For small 8-bit games, do I actually need the streaming layer at all?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question eventually became a second project: &lt;strong&gt;PIXELATED User Edition&lt;/strong&gt;, where compatible games run directly inside the browser through WebAssembly.&lt;/p&gt;

&lt;p&gt;The two editions now share a catalog and much of the same product experience, but they take completely different paths from clicking &lt;strong&gt;Play&lt;/strong&gt; to seeing the first frame. Building both has been a useful lesson in architecture, product boundaries, and the fact that “faster” does not always mean the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  One idea, two editions
&lt;/h2&gt;

&lt;p&gt;The easiest way to explain the split is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PIXELATED Studio&lt;/strong&gt; treats the browser as a client for a separate game engine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PIXELATED User Edition&lt;/strong&gt; turns the browser into the game engine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Studio, the desktop application manages a local Docker runtime. That runtime launches the emulator, captures its video and audio, creates a WebRTC session, and accepts controls sent back by the browser.&lt;/p&gt;

&lt;p&gt;In User Edition, a Libretro emulator core is compiled to WebAssembly and loaded on demand. The ROM is verified and passed to the core, then the browser renders the game locally to a canvas. There is no desktop application, Docker container, video encoder, or WebRTC media path involved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Studio version diagram&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0p32xxxtjzli9t0rc7r5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0p32xxxtjzli9t0rc7r5.png" alt="Studio version diagram" width="799" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  PIXELATED Studio: the system-oriented version
&lt;/h2&gt;

&lt;p&gt;Studio is the version I use when I want to explore the infrastructure around remote and local game streaming.&lt;/p&gt;

&lt;p&gt;The packaged desktop app manages the engine lifecycle, including Docker checks, runtime startup, health polling, and secure browser pairing. Once paired, the web app can ask the engine to boot an approved catalog game or a ROM from the user's Local Vault.&lt;/p&gt;

&lt;p&gt;Some of the more interesting Studio features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WebRTC video, audio, and input transport&lt;/li&gt;
&lt;li&gt;Local and LAN engine pairing&lt;/li&gt;
&lt;li&gt;A persistent Local Vault backed by the engine's Docker volume&lt;/li&gt;
&lt;li&gt;Multiplayer lobbies with player slots and spectators&lt;/li&gt;
&lt;li&gt;Stream-quality profiles, fullscreen play, audio controls, and keyboard remapping&lt;/li&gt;
&lt;li&gt;Creator submissions, browser-compatibility checks, and admin review tools&lt;/li&gt;
&lt;li&gt;Favorites, comments, reactions, reports, and moderation&lt;/li&gt;
&lt;li&gt;Opt-in stream telemetry and exportable research bundles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Studio is more complicated to install and operate, but that complexity buys it flexibility. The browser does not need to emulate the target system itself, and the engine can eventually support runtimes that would be unrealistic inside a normal web page.&lt;/p&gt;

&lt;p&gt;The tradeoff is that every extra stage can affect startup time, reliability, and perceived responsiveness. The engine must start, the emulator must boot, signaling must complete, the media pipeline must become ready, and the browser must receive and display a usable frame.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inside the desktop engine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpjp9vetx7ze6cuykre2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpjp9vetx7ze6cuykre2w.png" alt="Inside the desktop engine" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gameplay with telemetry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjsfuwgfw94ljbu8qs2bb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjsfuwgfw94ljbu8qs2bb.png" alt="Gameplay with telemetry" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  PIXELATED User Edition: the low-friction version
&lt;/h2&gt;

&lt;p&gt;User Edition exists because NES, Game Boy, and Game Boy Color games are small enough that modern browsers can run them very well without streaming.&lt;/p&gt;

&lt;p&gt;The first supported cores are &lt;strong&gt;FCEUmm&lt;/strong&gt; for NES and &lt;strong&gt;Gambatte&lt;/strong&gt; for Game Boy and Game Boy Color. They are loaded only when a compatible game starts, which keeps the regular catalog experience separate from the heavier emulator bundle.&lt;/p&gt;

&lt;p&gt;The launch flow still does more than simply download a file and hope for the best. The app checks the selected build, enforces a size limit, verifies its expected SHA-256 checksum, resolves a compatible emulator core, and reports each stage to the player. Unsupported games remain visible in the shared catalog but are clearly marked as requiring Studio or a future browser core.&lt;/p&gt;

&lt;p&gt;The User Edition currently includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant browser gameplay for eligible NES, GB, and GBC titles&lt;/li&gt;
&lt;li&gt;Three local save-state slots with import and export&lt;/li&gt;
&lt;li&gt;A Personal ROM flow that keeps ROM bytes in memory instead of uploading them&lt;/li&gt;
&lt;li&gt;Local game history without silently persisting the ROM itself&lt;/li&gt;
&lt;li&gt;Browser storage management and a PWA shell&lt;/li&gt;
&lt;li&gt;Optional local performance measurements that stay in the tab until exported&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The privacy boundary around personal ROMs was deliberate. Opening a local file does not upload it to the API, and the current version does not persist the ROM bytes after the session. Save states and harmless recent-file metadata can live locally, but persistent ROM storage will only be added later as an explicit opt-in feature with clear quota and deletion controls.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1f6vpzppclsetq8h7j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1f6vpzppclsetq8h7j7.png" alt="User edition" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not replace Studio with the WASM version?
&lt;/h2&gt;

&lt;p&gt;Because WebAssembly is not automatically a replacement for streaming.&lt;/p&gt;

&lt;p&gt;For the systems User Edition supports today, running locally is usually the simplest experience. It avoids video compression, removes a network round trip from controls, produces a sharp native canvas, and requires no companion software.&lt;/p&gt;

&lt;p&gt;Studio is solving a different problem. It separates the browser from the runtime, supports local-engine and LAN workflows, and gives me a real WebRTC media pipeline to instrument. Its architecture can grow beyond the limits of the browser, while User Edition is intentionally constrained by the emulator cores, memory, storage, and APIs available on the user's device.&lt;/p&gt;

&lt;p&gt;Maintaining both also creates something more useful than either project alone: a controlled comparison.&lt;/p&gt;

&lt;p&gt;The same catalog, visual design, game, and general interaction model can now be exercised through two very different execution paths. That makes architectural tradeoffs visible instead of theoretical.&lt;/p&gt;

&lt;h2&gt;
  
  
  My latency research
&lt;/h2&gt;

&lt;p&gt;PIXELATED Studio is also connected to my thesis work. I am experimenting with a technique I currently describe as &lt;strong&gt;latency fingerprinting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The basic idea is not to reduce an entire session to one latency number. A streamed game has several observable stages and behaviors: backend-session creation, engine startup, signaling, the first remote track, the first non-black frame, frame rate, bitrate, jitter, packet loss, stalls, disconnects, and recovery.&lt;/p&gt;

&lt;p&gt;Together, those measurements form a kind of session fingerprint. Repeating runs under controlled localhost, LAN, and browser-only scenarios may help show where delay and instability are introduced, and whether different architectures produce consistently different patterns.&lt;/p&gt;

&lt;p&gt;Studio can export versioned research bundles containing event timelines, telemetry samples, summary statistics, and graphs. User Edition provides a browser-only baseline with ROM download, verification, core-load, first-frame, frame-pacing, long-task, and supported memory measurements. Recording is opt-in, and the data remains local until the tester exports it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What building both versions taught me
&lt;/h2&gt;

&lt;p&gt;The biggest lesson was to stop treating architecture as a contest with one winner.&lt;/p&gt;

&lt;p&gt;WebAssembly gives User Edition an excellent experience because the workload fits the browser. WebRTC gives Studio a useful boundary between the player and the runtime because Studio is meant to explore streaming, multiplayer, LAN access, and a broader engine.&lt;/p&gt;

&lt;p&gt;I also learned that shared infrastructure needs explicit ownership. Studio is the migration authority for the shared database, while both editions consume a compatible API contract. Edition and runtime metadata are recorded deliberately, and Studio-only administration and publishing features are not copied into the User frontend just because the database is shared.&lt;/p&gt;

&lt;p&gt;That separation has made both projects easier to reason about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Edition can optimize for opening a page and playing quickly.&lt;/li&gt;
&lt;li&gt;Studio can optimize for engine capabilities, networking, and measurement.&lt;/li&gt;
&lt;li&gt;Shared social and catalog features do not need to be rebuilt twice.&lt;/li&gt;
&lt;li&gt;Experimental code stays out of the simpler product unless it has a reason to be there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is still plenty left to do. I want to test more browsers and devices, add browser cores one system at a time, improve the research procedure, and collect enough controlled runs to say something meaningful about the two architectures.&lt;/p&gt;

&lt;p&gt;For now, though, both editions are real, playable projects, and they answer the same question in two very different ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try them or explore the code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PIXELATED User Edition:&lt;/strong&gt; &lt;a href="https://pixelated-user-edition.vercel.app/" rel="noopener noreferrer"&gt;Live app&lt;/a&gt; · &lt;a href="https://github.com/Nghi-creator/Pixelated-User-Edition" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PIXELATED Studio:&lt;/strong&gt; &lt;a href="https://pixelated-studio-edition.vercel.app/" rel="noopener noreferrer"&gt;Live web app&lt;/a&gt; · &lt;a href="https://github.com/Nghi-creator/Pixelated-Studio-Edition" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://github.com/Nghi-creator/Pixelated-Studio-Edition/releases/latest" rel="noopener noreferrer"&gt;Desktop releases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have worked on browser emulation, WebRTC streaming, or performance measurement, I would be interested to hear how you would compare these two paths, and which measurements you would trust most.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The catalog is intended for approved, public-domain, or appropriately licensed homebrew content. Original creators retain ownership of their games and are credited in the project. Personal ROM features are intended for files users are legally allowed to use.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>programming</category>
      <category>opensource</category>
      <category>edgecomputing</category>
    </item>
  </channel>
</rss>
