<?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: Carlos Wang</title>
    <description>The latest articles on DEV Community by Carlos Wang (@wangxiaoxiang5599_57).</description>
    <link>https://dev.to/wangxiaoxiang5599_57</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%2F4193261%2F27a7054e-c5fb-44a0-92dd-130bf7c9090d.jpg</url>
      <title>DEV Community: Carlos Wang</title>
      <link>https://dev.to/wangxiaoxiang5599_57</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wangxiaoxiang5599_57"/>
    <language>en</language>
    <item>
      <title>Tracking DMCA takedowns of AI-made game ports: why a 200 OK isn't enough</title>
      <dc:creator>Carlos Wang</dc:creator>
      <pubDate>Mon, 19 Oct 2026 05:00:12 +0000</pubDate>
      <link>https://dev.to/wangxiaoxiang5599_57/tracking-dmca-takedowns-of-ai-made-game-ports-why-a-200-ok-isnt-enough-13j</link>
      <guid>https://dev.to/wangxiaoxiang5599_57/tracking-dmca-takedowns-of-ai-made-game-ports-why-a-200-ok-isnt-enough-13j</guid>
      <description>&lt;p&gt;In early October a wave of "vibe-coded" browser ports went viral: Halo, The Simpsons: Hit &amp;amp; Run, GTA Vice City, Call of Duty Zombies, all running in a browser tab, many of them built with heavy help from AI coding tools. Lists of them spread on X faster than anyone could check them.&lt;/p&gt;

&lt;p&gt;I run &lt;a href="https://portedgames.com/" rel="noopener noreferrer"&gt;PortedGames&lt;/a&gt;, a directory of these ports (browser builds, PC ports and recompilations). It re-checks every entry once a day, because the first question people ask is "does this one still work?". Within two weeks the more interesting question was "which ones got taken down, and by whom?". So I started a &lt;a href="https://portedgames.com/takedowns/" rel="noopener noreferrer"&gt;takedown tracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post covers what the data shows so far, and why the obvious way to detect a takedown (check the HTTP status) misses many of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers (as of Oct 19, 2026)
&lt;/h2&gt;

&lt;p&gt;12 ports taken down after a copyright claim since Sep 11:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rights holder&lt;/th&gt;
&lt;th&gt;Takedowns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Activision&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mojang / Microsoft&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rockstar Games&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEGA&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SNK&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maddy Makes Games&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Not named by the site&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few things stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Activision took down four Call of Duty browser remakes on the same day&lt;/strong&gt; (Oct 10), all by one developer, plus an unreleased AI-assisted decompilation of Modern Warfare 2 that was reportedly hit a week earlier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time online varies a lot.&lt;/strong&gt; Of the 9 ports with a known release date, the median stayed up for 29 days. The GTA V browser port lasted hours. A Celeste WebAssembly port sat on GitHub for 321 days before its game data was removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It isn't only browser remakes.&lt;/strong&gt; The list includes a static recompilation (Metal Slug XX, Xbox 360), a "clean-room" Minecraft reimplementation that Mojang says contains over 2,000 original files, and a long-running campaign against Eaglercraft repositories (18 GitHub notices since August).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 of the 12 never produced a public GitHub DMCA notice.&lt;/strong&gt; The ports ran on their own domains or on hosts like Railway and Cloudflare Pages, so the usual place to look (&lt;a href="https://github.com/github/dmca" rel="noopener noreferrer"&gt;github.com/github/dmca&lt;/a&gt;) doesn't show them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every row on the tracker links its evidence: the notice, the author's post, or what the site itself now says.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why status codes lie
&lt;/h2&gt;

&lt;p&gt;My first link checker was the obvious one: request the page, 2xx means up, 4xx/5xx means down. It reported the first port below as working even though the game was gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Notice pages return 200 and keep their title.&lt;/strong&gt; The Modern Warfare 2 browser port "Open Victor Zulu" still serves a page titled "Open Victor Zulu". The body is now a short notice saying the game was taken down "due to a DMCA request". A status check sees 200. A title check sees the game's name. Only the body text tells you it's gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Dead addresses get recycled.&lt;/strong&gt; Three &lt;code&gt;pages.dev&lt;/code&gt; addresses that used to host Call of Duty remakes now all redirect to the same unrelated site. Follow the redirect and you get a 200 from a page that has nothing to do with the game.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Bot protection looks like "up".&lt;/strong&gt; Some hosts answer automated requests with a Cloudflare "Just a moment..." challenge page (200) or a 403/429. The first looks up when it might be down. The second looks down when it's probably fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Takedowns don't always reach GitHub.&lt;/strong&gt; As above: if the port isn't on GitHub, there's no public notice to find.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the checker does now
&lt;/h2&gt;

&lt;p&gt;The daily check is a small Node script. For each port:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2xx in under 6 seconds:&lt;/strong&gt; Working. &lt;strong&gt;2xx but slow:&lt;/strong&gt; Slow. &lt;strong&gt;4xx/5xx or a network error after one retry:&lt;/strong&gt; Down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;403/429:&lt;/strong&gt; inconclusive. Keep the previous status and don't bump the "last checked" date, rather than mark a working port as down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the body, not just the status.&lt;/strong&gt; If the visible text is short (game pages are mostly JavaScript; notices are a few lines) and reads like a takedown notice, flag it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A 200 is not enough: taken-down ports often keep serving a short notice page.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TAKEDOWN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b(&lt;/span&gt;&lt;span class="sr"&gt;taken &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;the game |it |this &lt;/span&gt;&lt;span class="se"&gt;)?(&lt;/span&gt;&lt;span class="sr"&gt;down|offline&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;|&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;game|site|project&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;is|has been&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;taken down|removed|shut down|discontinued&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;|offline for now|no longer &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;available|online|playable&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;|due to an&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt; &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;DMCA|copyright|legal&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;|DMCA &lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;request|notice|takedown|complaint&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;|cease and desist|received a takedown&lt;/span&gt;&lt;span class="se"&gt;)\b&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SHORT_PAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// visible characters&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;SHORT_PAGE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TAKEDOWN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Expect something specific.&lt;/strong&gt; Each entry can declare a string that must appear on the page (usually the game's own name). If a recycled domain redirects somewhere else, that string is missing and the entry gets flagged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A person confirms.&lt;/strong&gt; The script only ever flags. "Taken down" is set by hand after reading the page and finding a source, and the script never overwrites it. A regex is good at noticing; it isn't evidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The short-page limit matters more than it looks. Some real game pages mention "DMCA" in a footer or FAQ. Restricting the match to short pages keeps those from being flagged, because a working WebAssembly game page has very little visible text before the game loads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data
&lt;/h2&gt;

&lt;p&gt;The tracker is at &lt;a href="https://portedgames.com/takedowns/" rel="noopener noreferrer"&gt;portedgames.com/takedowns&lt;/a&gt;, and the same rows are available as JSON at &lt;a href="https://portedgames.com/takedowns.json" rel="noopener noreferrer"&gt;portedgames.com/takedowns.json&lt;/a&gt; (rights holder, method, release and takedown dates, days online, sources). It's free to use with a link back. If you know of a takedown I've missed, or I got something wrong, the contact address is on the page.&lt;/p&gt;

&lt;p&gt;One note on scope: the directory never hosts or links game files, ROMs or ISOs, only each project's own page, and ports their authors closed voluntarily aren't counted as takedowns.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I run PortedGames, so take the framing with that in mind; the evidence for each row is linked so you can check it yourself.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>gamedev</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
