<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi" -->

---
title: Reviving Valve's 15-year-old e-book | daily.dev
description: A developer documents reviving The Final Hours of Portal 2, a 15-year-old Adobe AIR/Flash e-book whose online features (videos, polls, music, 3D...
canonical: https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Reviving Valve's 15-year-old e-book | daily.dev
og:description: A developer documents reviving The Final Hours of Portal 2, a 15-year-old Adobe AIR/Flash e-book whose online features (videos, polls, music, 3D...
og:url: https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi
og:image: https://api.daily.dev/og/posts/93wMtYoBi.png
og:image:alt: Reviving Valve's 15-year-old e-book
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Reviving Valve's 15-year-old e-book

**[Lobsters](https://daily.dev/sources/lobsters)** · 12 min read · 1 upvotes · 0 comments

## Summary

A developer documents reviving The Final Hours of Portal 2, a 15-year-old Adobe AIR/Flash e-book whose online features (videos, polls, music, 3D visualizations, feedback forms) had broken due to dead services and domain rot. Using JPEXS Flash decompiler, yt-dlp, Archive.org IPA dumps, and AI assistance to write ActionScript, the author recovered assets, rehosted content via a self-hostable FastAPI/SQLite server, and built an open-source SWF patcher that redirects legacy URLs and fixes panorama rendering bugs on modern Windows. Both the server and patcher are open source on GitHub, with a Steam guide for end users.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://nikolan.net/posts/portal2>

## Questions this post answers

### How do you decompile and modify SWF files that use Adobe AIR and ActionScript 3?

JPEXS Free Flash Decompiler can be used to search SWF files for URL strings and ActionScript code, then a patcher can locate the relevant SWFs, back them up, decompress them, modify specific URL strings in compiled ActionScript, and rebuild and verify the files before replacing the originals. More complex fixes, like panorama rendering bugs, require recompiling a patched SWF and applying a binary diff to the user's copy.

_daily.dev surfaces reverse engineering writeups like this for developers tackling legacy Flash or AIR codebases._

### Why do old YouTube ActionScript 3 Player API integrations stop working?

YouTube's ActionScript 3 Player API, which loaded a player SWF and controlled it with methods like loadVideoById, playVideo, and pauseVideo, was discontinued over a decade ago, breaking any legacy application still depending on it. A workaround involves writing a replacement ActionScript player that mimics the old API but plays local MP4 files downloaded via yt-dlp instead of streaming from YouTube.

_developers maintaining legacy apps against sunset APIs can find similar migration writeups through daily.dev._

### Why would Adobe AIR panorama viewers stop working on Windows 11 despite running the same AIR version that worked on Windows 10?

Newer Windows sandbox behavior appears to interfere with how HTMLLoader embeds a nested SWF, producing error #3207 around Security.allowDomain calls and error #3226 when loading compiled code from a nested SWF without allowCodeImport. Replacing HTMLLoader with a native Loader and explicitly allowing code imports resolves both errors and restores panorama functionality.

_daily.dev helps developers debugging platform-specific regressions in legacy desktop runtimes stay informed._

## Similar posts on daily.dev

- [Half-Life 2 is now playable in your browser thanks to a three-month project from a teenager](https://daily.dev/posts/half-life-2-is-now-playable-in-your-browser-thanks-to-a-three-month-project-from-a-teenager-4f1oga4qq) · XDA Developers · 113 upvotes · 15 comments
- [Flashpoint Archive](https://daily.dev/posts/flashpoint-archive-h8xiib4ux) · Hacker News · 0 upvotes · 0 comments
- [The Source engine should've died a decade ago, but Valve kept finding ways to keep it alive](https://daily.dev/posts/the-source-engine-should-ve-died-a-decade-ago-but-valve-kept-finding-ways-to-keep-it-alive-n34dim4y9) · XDA Developers · 0 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#reverse-engineering](https://daily.dev/tags/reverse-engineering)

[View this post on daily.dev](https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Reviving Valve's 15-year-old e-book","url":"https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi"},"datePublished":"2026-10-01T13:55:02.212Z","dateModified":"2026-10-01T13:55:24.886Z","description":"A developer documents reviving The Final Hours of Portal 2, a 15-year-old Adobe AIR/Flash e-book whose online features (videos, polls, music, 3D...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/c629138714fb14ea5675c6391f207d59?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/c629138714fb14ea5675c6391f207d59?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Lobsters","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Lobsters","logo":"https://media.daily.dev/image/upload/s--tl8v_Fku--/f_auto,t_logo/v1698841318/logos/lobste.jpg","url":"https://daily.dev/sources/lobsters"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,reverse-engineering","timeRequired":"PT12M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Lobsters","item":"https://daily.dev/sources/lobsters"},{"@type":"ListItem","position":3,"name":"Reviving Valve's 15-year-old e-book"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/reviving-valve-s-15-year-old-e-book-93wmtyobi#faq","mainEntity":[{"@type":"Question","name":"How do you decompile and modify SWF files that use Adobe AIR and ActionScript 3?","acceptedAnswer":{"@type":"Answer","text":"JPEXS Free Flash Decompiler can be used to search SWF files for URL strings and ActionScript code, then a patcher can locate the relevant SWFs, back them up, decompress them, modify specific URL strings in compiled ActionScript, and rebuild and verify the files before replacing the originals. More complex fixes, like panorama rendering bugs, require recompiling a patched SWF and applying a binary diff to the user's copy. daily.dev surfaces reverse engineering writeups like this for developers tackling legacy Flash or AIR codebases."}},{"@type":"Question","name":"Why do old YouTube ActionScript 3 Player API integrations stop working?","acceptedAnswer":{"@type":"Answer","text":"YouTube's ActionScript 3 Player API, which loaded a player SWF and controlled it with methods like loadVideoById, playVideo, and pauseVideo, was discontinued over a decade ago, breaking any legacy application still depending on it. A workaround involves writing a replacement ActionScript player that mimics the old API but plays local MP4 files downloaded via yt-dlp instead of streaming from YouTube. developers maintaining legacy apps against sunset APIs can find similar migration writeups through daily.dev."}},{"@type":"Question","name":"Why would Adobe AIR panorama viewers stop working on Windows 11 despite running the same AIR version that worked on Windows 10?","acceptedAnswer":{"@type":"Answer","text":"Newer Windows sandbox behavior appears to interfere with how HTMLLoader embeds a nested SWF, producing error #3207 around Security.allowDomain calls and error #3226 when loading compiled code from a nested SWF without allowCodeImport. Replacing HTMLLoader with a native Loader and explicitly allowing code imports resolves both errors and restores panorama functionality. daily.dev helps developers debugging platform-specific regressions in legacy desktop runtimes stay informed."}}]}
```

