Observed the public URL serving the previous build for ~3.5 minutes after a push. Responses carry x-pages-cache: true and cache-control: max-age=600, and a cache-busting query does not bypass it. The earlier claim of ~15s was wrong. AGENTS.md and deploy.sh now say to check the repo raw file FIRST: if that matches the local build the push landed and only the cache is behind, so don't start changing things. |
||
|---|---|---|
| build | ||
| tools | ||
| .gitignore | ||
| AGENTS.md | ||
| deploy.sh | ||
| index.html | ||
| LICENSE | ||
| README.md | ||
| steam-proxy-worker.js | ||
| steam-sync.py | ||
la-li-lu-le-lo
The Patriots have restricted access to this information.
A single-file, offline-friendly companion page for 100%-ing Metal Gear Solid 2: Sons of Liberty — Master Collection Version (51 achievements).
Files
| File | What it is |
|---|---|
index.html |
The whole guide. Self-contained — data, styles, logic and your progress all live in this one file. |
steam-sync.py |
Optional local helper. Serves this folder and proxies Steam achievement lookups so the page can auto-tick what you already own. |
steam-proxy-worker.js |
Optional Cloudflare Worker. Same job as the Python helper, but for when the page is hosted somewhere instead of run locally. |
build/ |
The sources. index.html is generated from these, so edit here rather than in the built file. |
deploy.sh |
Rebuilds and pushes to pages in one step. |
tools/ |
verify.js (headless smoke test) and theme-contrast.py (WCAG check). Both run before deploying. |
AGENTS.md |
Orientation for anyone picking this up cold: architecture, conventions, and the traps already hit. |
Hosting it (GitHub Pages, Netlify, Cloudflare Pages, Neocities…)
This copy is deployed at https://rain.pages.melonbread.xyz/la-li-lu-le-lo/, served from the pages branch of https://git.melonbread.xyz/rain/la-li-lu-le-lo.
Updating the live site
node tools/verify.js # smoke test
python3 tools/theme-contrast.py # after touching any colour
./deploy.sh "what you changed"
That rebuilds index.html from build/, commits, and pushes to pages. The Pages site redeploys itself in about 15 seconds — no separate publish step.
Edit the sources in build/, not the built index.html. The built file is generated: build/template.html holds the page, build/*_src.py the written content, and build/*.json the extracted data (achievements, dog tags, maps, photo pins). build/build.py stitches them together.
Steam sync on the deployed site
A hosted page cannot read Steam directly — the achievement page sends no CORS headers. So the deployed page talks to steam-sync.py running on your own machine:
nohup python3 ~/Desktop/la-li-lu-le-lo/steam-sync.py > /tmp/steam-sync.log 2>&1 &
Then sync just works on the Pages site. steam-sync.py answers the Private Network Access preflight that Chrome requires when a public page calls into 127.0.0.1; without that header the request is blocked before it is sent. If the helper is not running you get a message saying so, and everything except sync still works.
If you would rather not keep the helper running, deploy steam-proxy-worker.js to Cloudflare and put its URL in STEAM_PROXY at the top of the page's script — ALLOW_ORIGIN in the Worker is already pinned to the Pages origin.
The page itself hosts fine as-is. It is one static HTML file with all the guide data, the 10 area maps and the colour coding baked in, and it stores progress in the browser's localStorage. Drop it in a repo, enable Pages, done. No build step, no dependencies.
Two things behave differently on a static host:
1. Live Steam sync needs a server. Steam's achievement page sends no CORS headers, so a browser cannot read it from another origin — that is the whole reason steam-sync.py exists. Hosted with no proxy, the page says so instead of failing silently, and everything except sync still works. To get sync back you have two options:
-
Run it locally (
python3 steam-sync.py) — simplest, and what the sync feature was built for. -
Deploy the Worker — paste
steam-proxy-worker.jsinto a free Cloudflare Worker, then set at the top ofindex.html:const STEAM_PROXY = 'https://your-worker-name.yourname.workers.dev';Any serverless function works the same way — it just has to forward
/api/steam?profile=…to Steam and return JSON with a permissiveAccess-Control-Allow-Origin.
2. Your ticks do not follow you between addresses. localStorage is scoped per origin, so http://127.0.0.1:8765/ and https://you.github.io/mgs2/ are separate checklists. Use Export on one and Import on the other — that is exactly what those buttons are for.
There is also a deliberate default in the page: DEFAULT_PROFILE is pre-filled so it syncs on load. Set it to '' before publishing if you would rather it started blank, and change ALLOW_ORIGIN in the Worker from * to your site so nobody else can point their own page at your function.
A note on the images
The 62 location screenshots are hot-linked from the Steam Community CDN and Dayngl's Guides, with referrerpolicy="no-referrer" so they load from any domain. That keeps the page small and credits the original authors, but it does mean the page depends on two external hosts. If you plan to publish it widely rather than keep it for yourself, download the images into an img/ folder and rewrite the URLs — that also removes any question about borrowing someone else's bandwidth.
Run it locally (recommended)
cd ~/Desktop/la-li-lu-le-lo
python3 steam-sync.py
Then open http://127.0.0.1:8765/ and leave it on your second screen.
python3 steam-sync.py --open launches the browser for you. PORT=9000 python3 steam-sync.py uses a different port.
No dependencies, no Steam API key, no install. Requires Python 3 (already on macOS/Linux; on Windows use py steam-sync.py).
Keep it running in the background (so it survives closing the terminal):
nohup python3 steam-sync.py > /tmp/steam-sync.log 2>&1 &
To stop it later: pkill -f steam-sync.py
If the port is already in use, either it is already running or you can pick another: PORT=9000 python3 steam-sync.py.
Just want the checklist, no sync?
Double-click index.html. Everything works except live Steam sync. Note that opening it as a file:// page makes browser storage less reliable — use Export to keep a backup of your ticks.
Steam sync
- Enter your vanity name (e.g.
gaben) or SteamID64 on the 🔄 Steam Sync tab and hit Sync now. - It re-syncs automatically every time the page loads.
- Achievements you already own get a
STEAM ✓badge and a blue edge, and are counted as done. - Use the ⬇ Missing on Steam filter on the Achievements tab to see only what is left.
- No profile is pre-filled in the public repo — type yours on the Steam Sync tab once and it is remembered in this browser (per origin, so the Pages site and a local copy keep separate memories).
If it fails, the page tells you why. The usual cause is a private profile: Steam → your profile → Edit Profile → Privacy Settings → Game details → Public.
What's inside
- 🗺️ Roadmap — the 5-pass plan, plus a 48-step ordered walkthrough of the Tanker and Plant with every collectible, box, weapon and one-shot achievement flagged in the order you hit them.
- Every step has sub-checkboxes underneath it listing exactly what to get there — the dog tags by name and area, the achievements, and the items.
- The dog-tag boxes are the same checklist as the Dog Tags tab. Tick a tag in the walkthrough and it ticks in the Dog Tags tab, and vice versa — same key, same saved state. Achievements and items sync to their own tabs the same way.
- A difficulty selector at the top picks which tag list the steps show (defaults to Very Easy, for run 1). Coverage is complete: all 67/70/82/87/88 tags for Very Easy/Easy/Normal/Hard/Extreme appear exactly once.
- Text is colour coded so you can scan a step at a glance: teal = guard whose dog tag it is, violet = weapon/box, blue = achievement, amber = missable achievement, red = boss.
- 🏆 Achievements — all 51 with official Steam icons, missable/cumulative flags, category filters, search, and a full how-to for each.
- 🏷️ Dog Tags — all 394 tags across 10 difficulty lists, with guard names, areas, and 81 conditional/missable spawn notes.
- 🗺️ Area Maps — the guard-position maps from the tracking spreadsheet, rebuilt cell-by-cell as real images (no internet needed). Colour-coded: orange = guard with a tag, magenta = tough guard, red = boss with a tag, green = conditional guard. Zoomable, with the spreadsheet's own Keys and numbered guard legend rendered in place, plus a label-size control. Reachable from the Dog Tags tab via Open … area map.
- 📷 Location photos — 48 in-game screenshots of the exact spots (locker poster, fire extinguisher, Hold No. 2 screens, the Book, the orange boxes, and more), drawn from two guides: the Steam Community guide and Dayngl's Guides. Each one is pinned to the specific step where that thing is — the seven Moving Day boxes are spread across the six steps that actually contain them, and the two Johnny on the Spot microphone moments go to their own steps. Hot-linked at thumbnail size.
- Duplicates are removed: Dayngl's guide reuses the same screenshots as the Steam guide, so 22 pairs were detected by perceptual hash (dHash, ≤14/240 bits apart) and de-duplicated — you will not see the same picture twice.
- Click any photo to zoom it in a full-screen viewer. Then: click the image (or press Space) to toggle fit ↔ full resolution, drag to pan while zoomed, ← / → to move between the photos in that step, Esc or a backdrop click to close, and open original ↗ to jump to the source site.
- 🔄 Steam Sync — see above.
- 💀 Big Boss Run — every codename requirement, the heal points, time checkpoints, save points, and a strategy for each of the 8 bosses.
- ⚠️ Missables — everything that can be permanently missed, in story order.
- 🕹️ VR / Extra Modes — Snake Tales, Boss Survival, VR missions, Casting Theater, plus the special-item unlock table.
- 📚 Sources & Notes — credits, links, and Master Collection version differences.
Colour themes
The theme dropdown in the header switches the whole page. It is remembered in localStorage and applied before first paint, so there is no flash on reload. All of them are dark.
Codec |
the default teal/blue |
Gruvbox Dark · Monokai · Dracula · Nord |
|
Solarized Dark |
|
Tokyo Night · Catppuccin Mocha · One Dark · Rosé Pine |
Everything is themed through CSS custom properties — panels, borders, the walkthrough colour code, pills, callouts, the lightbox and the progress bars. The area maps keep their white background on purpose: they are reproductions of a spreadsheet, and inverting them would make the colour legend lie.
Every foreground/background pair in all 10 themes was checked against WCAG contrast; the worst case is 3.1:1 (Nord's red), which is above the 3:1 threshold for UI text and components.
Progress & backups
Ticks save automatically to this browser's localStorage, under the key mgs2mc-guide-v1.
They are per-browser and per-origin — if you switch browser or open the file from a different path you'll get a fresh checklist.
Use Export to download mgs2-progress.json and Import to restore it. Export before each playthrough.
Credits
Compiled from community work — full links are on the Sources & Notes tab:
- Steam Community guide by Cole ヴ Viper (achievement write-ups, boss strategies, Big Boss criteria)
- Video Chums dog tag checklist (all 394 tags)
- u/Spikeyroxas dog tag spreadsheet (conditional spawn notes)
- Dayngl's Guides (cross-check)
- TrueSteamAchievements (authoritative 51-achievement list)
Unofficial fan-made companion, for personal use. MGS2 © Konami.
Licence
The code here (index.html, steam-sync.py, steam-proxy-worker.js) is MIT — see LICENSE.
Two carve-outs worth knowing before you fork it:
- The guide content is compiled from other people's work. The achievement write-ups, the 394 dog tags, the guard-position maps and the Big Boss strategies all come from the community guides credited above. This repo reorganises and presents them; it does not claim authorship. If you reuse the text, credit the original authors.
- The screenshots are not in this repo, and are not mine. All 48 are hot-linked from the Steam Community CDN and Dayngl's Guides and remain the property of their authors. If you fork this and republish it widely, download them into an
img/folder or drop them — see the note under Hosting it.
Metal Gear Solid 2: Sons of Liberty is © Konami. This is an unofficial, non-commercial fan project.