spiritsnails 46bd0f6709 fix: battle screens keep their composition when they open a menu or prompt
BATTLE SIZE "fixed" draws the battle as a discrete letterbox rather than
filling the window, and BATTLE BG "world" composes it over the live map.
Everything the battle then opens broke out of that composition, because
each piece of the frame's geometry was read off a fact about THIS FRAME
instead of about the battle:

* Renderer:uiScale follows the survey zoom only while a world is behind
  the UI, gated on worldActive -- this frame's world pass.  PartyMenu and
  ListMenu are opaque, so pushing one makes StateStack:visibleBase skip
  the map, no world pass runs, and the menu loses the step-down and blits
  a whole integer scale larger than the battle it just covered.  Held
  with uiWorldHold, the same whole-stack rule uiFill and the battle dim
  already use.  ("fill" hid this: it overrides the scale outright.)

* Game:draw started the frame at visibleBase, so that same opaque menu
  cut the overworld -- and the world pass with it -- out of the frame
  entirely, collapsing a "world" backdrop to endFrame's flat black clear.
  A world-bg battle now keeps the frame starting from underneath itself
  (drawBaseInStack).  Only the START of the draw moves; the clear stays
  keyed to the real visibleBase, so the menu still gets its opaque canvas
  and draws exactly as before.

* worldZones was keyed to that same clear base, so it came out nil for a
  frame whose world pass HAD run -- dropping endFrame's world blit onto
  the UI zone list instead, smearing the party menu's own HP-bar palettes
  across a world-canvas-sized image.  Keyed to whether the map drew.

* endFrame's letterbox clear read letterboxWhite off visibleBase alone,
  so an opaque menu over a BG "white" battle flipped its surround to
  black the same way.  Same whole-stack hold.

* ChoiceBox bottom-anchored unconditionally, docking it to the WINDOW
  edge.  That is only right when it rides the dialogue box beneath it,
  which is anchored there too; TextBox now passes the anchor and nothing
  else does, so the battle's switch offer and the shop/PC confirms stay
  over the screen that pushed them.

* TextBox anchors likewise: a battle is a self-contained SCREEN, not the
  window, and pokered prints its text box in the same 160x144 tilemap as
  the HUD.  The caught-mon nickname prompt was landing a whole letterbox
  below the blanked battle field it is printed on.  BattleState.holdsUI-
  Anchors holds setUIAnchor off while a battle is in the stack; the
  overworld's own dialogue box still docks to the screen edge.
2026-08-01 22:55:58 -06:00
2026-08-01 00:32:00 -03:00
2026-07-31 14:35:40 +00:00
2026-07-31 14:35:40 +00:00
2026-07-19 16:18:18 -04:00
2026-07-31 23:47:28 -04:00
2026-08-01 20:54:08 -04:00

Gen1Recomp

A native LÖVE2D recreation of Poke Red, Blue and Yellow. The engine and map behavior are hand-written Lua; game data and graphics are decoded from a ROM supplied by the player.

Warning

We are NOT affiliated with the website gen1recomp[.]com That website is not run by this project, was not authorized by us, and we have no idea who operates it. It is impersonating this project; do not download anything from it, and treat anything it hosts or claims as untrustworthy. Even if the site currently links back to this repository, the people behind it can change its content at any time, so nothing on it should ever be trusted. This GitHub repository and the Discord linked below are the only official sources for this project.

SUPPORT / ANNOUNCEMENTS / MODS: Discord

YouTube TikTok X Bluesky Instagram

As seen on Polygon As seen on KOTAKU As seen on Digital Foundry As seen on Android Authority As seen on XDA Developers

Watch the latest update video

Watch the latest update video

This project does not include a ROM, emulate the Game Boy, transpile assembly, or download a disassembly. A canonical US Poke Red, Blue, or Yellow ROM is the only game content input.

The ROM is verified, used during import, and then released from memory. It is not copied into the cache. Later launches load the private generated cache and do not ask for the ROM again. Red, Blue, and Yellow can all be imported and played side by side.

Quick Start

Open the desktop app. On first boot, choose your legally obtained .gb / .gbc file or drop it onto the window. Import takes a few seconds and the game starts automatically.

Only the canonical 1 MiB US Red, Blue, and Yellow ROMs are accepted. The importer verifies SHA-1 before creating any game data:

  • Red: ea9bcae617fdf159b045185467ae58b2e4a48b9a
  • Blue: d7037c83e1ae5b39bde3c30787637ba1d4c48ce2
  • Yellow: cc7d03262ebfaf2f06772c1a480c7d9d5f4a38e1

The packaged app contains neither a ROM nor pre-extracted game data. Music, sound effects, and cries are synthesized while the game runs from compact audio channel programs copied out of the verified ROM.

A note on Windows Defender warnings

Windows Defender sometimes flags the Windows build with a generic machine-learning detection such as Trojan:Win32/Wacatac!ml (#621). This is a known false positive: the exe is the official LÖVE runtime with the game archive appended (the standard way LÖVE games ship), and Defender's heuristics distrust unsigned executables with appended data. Every release publishes SHA-256 checksums (sha256sums.txt) so you can verify your download, and you can confirm a flagged file yourself on VirusTotal, where these builds come back clean on every engine except Defender's heuristic. False positives are reported to Microsoft as they come up.

Controls

Action Keyboard Controller
Move Arrow keys / WASD D-pad / left stick
A Z / Enter / Space A
B X / Backspace B
Start Escape Start
Select Tab / Shift Back / Select

Rebind any of these in-game under OPTIONS → CONTROLS. Controllers are supported out of the box.

Hotkeys

Key What it does
- / = Zoom out / in (overworld; also mouse wheel)
2 Cycle COLORS
3 Cycle TILT (free-roam overworld)
4 Cycle ZOOM through every level (free-roam overworld)
5 Cycle GBC FX
F1 Save
F2 Load
F10 Open / close the mod manager

COLORS, TILT, ZOOM, GBC FX, and VOID FILL are also in the Options menu and persist in options.lua.

Low-end devices

OPTIONS → PERFORMANCE scales the port's optional extras for weaker hardware: HIGH (everything on), BALANCED (no 3D tilt or GBC FX), LOW (also no survey zoom, FPS capped), or AUTO — the default, which picks a tier from your device (ARM handhelds → LOW, phones → BALANCED, normal desktops → HIGH, unchanged). It only scales presentation; the fixed-step game logic is identical on every tier, and a lower tier hides your tilt/zoom/GBC-FX preferences without forgetting them. Details in docs/new-features.md.

Rulesets

OPTIONS → RULESET picks which set of Gen 1 battle behaviors to run. Both rulesets share the same damage formulas; they differ only in whether the original's quirks are kept. The setting persists in options.lua, and mods can register their own.

gen1_faithful is the default and reproduces the original cartridge, famous bugs included:

Rule Behavior
oneIn256Miss A 100%-accurate move still misses on a roll of 255
critUsesBaseSpeed Crit rate reads base speed, not the current stat
critIgnoresStages Crit rate ignores stat stages
focusEnergyBug FOCUS ENERGY quarters the crit rate instead of x4
enemyUnlimitedPP Enemies never spend PP, so they never Struggle
hyperBeamSkipRechargeOnKO HYPER BEAM skips its recharge when the target faints
randMin / randMax Damage random factor 217-255

modern_clean keeps the formulas but removes the notorious quirks:

Rule Behavior
oneIn256Miss Off: a 100%-accurate move always hits
critUsesBaseSpeed Unchanged: crit rate still reads base speed
critIgnoresStages Off: stat stages count toward the crit rate
focusEnergyBug Off: FOCUS ENERGY raises the crit rate as intended
enemyUnlimitedPP Off: enemies deplete PP and Struggle when empty
hyperBeamSkipRechargeOnKO Off: HYPER BEAM always recharges, like Gen 2+
randMin / randMax Damage random factor 217-255, same as faithful

Running From Source

Requires LÖVE 11.x. Place a Red, Blue, or Yellow ROM in the project folder and double-click Play-Mac.command or Play-Windows.bat, or run:

scripts/setup.sh --rom "/path/to/Poke Red.gb"   # or Blue.gb / Yellow.gbc
scripts/run.sh

then love . for later launches. Windows PowerShell scripts, the optional developer data build, test suites, and cache management are covered in Developer Setup.

Portable Mode

By default the game keeps your save, options, and the private ROM-derived data cache in your OS's normal per-user app data folder. To keep everything next to the game instead (handy for a USB stick or portable drive you carry between computers), drop an empty file named portable.txt next to the app (next to gen1recomp.app/.exe, or next to main.lua/conf.lua when running from source), then launch the game. Portable mode is desktop-only (Windows, Linux, macOS); it has no effect on Android or iOS, where the app runs from a read-only package.

With portable.txt present:

  • save.lua, save.lua.bak, and options.lua are read from and written to that same folder instead of the OS save directory.
  • A ROM import writes the generated data/generated and assets/generated cache straight into that folder too (nothing is left in the OS save directory), so a later launch reuses it without asking for the ROM again even on a different computer, as long as the same folder comes along.
  • Deleting portable.txt switches back to the normal OS save directory; nothing already written to either location is touched automatically, so copy files over yourself if you want to carry existing progress across the switch.

iOS

Every release ships gen1recomp-*-ios.ipa. Sideload it with AltStore (Windows or Mac) — see docs/ios-sideload.md. To build and install from source on a Mac instead, see docs/ios-install.md.

Handhelds

A PortMaster-style port for the Anbernic RG34XXSP on Stock OS 64-bit MOD ships with every release as gen1recomp-*-rg34xxsp-stockos64-mod.zip. Install steps, controls, and troubleshooting live in docs/anbernic-rg34xxsp.md.

Modding

The game ships a native mod platform: content registries, events and hooks, per-mod saves and options, and an in-game manager. The full modding book — getting started, a twelve-rung tutorial ladder, a cookbook, and the generated reference — lives on the project wiki.

Shipped example mods, one per kind of author, live in [mods/](mods/).

Maps can be edited in our own build of Tiled, bryanthaboi/tiled_gen1recomp, and exported back out as a mod; see docs/tiled-map-editing.md.

Bugs and Ideas

Found a bug? A warp dropping you somewhere it shouldn't, a battle doing math that looks wrong, text in the wrong box, anything that does not match the original game. Open a bug report. Attach a screenshot if you can. It saves a lot of back and forth, and if you can't get one, the form asks you to describe what you saw instead.

Thought of a feature that could be good, or a way to improve one that already exists? Open a feature request. Say what you want, why it is worth doing, and how you picture it working. A request with real detail is one that can actually get built.

More

  • Link play — START > LINK connects two copies directly over UDP.
  • Save editor — edit party, boxes, items, events, and Pokédex flags outside the game.
  • docs/architecture.md — runtime details; docs/behavior-porting-notes.md — formula provenance.

Special Thanks

This project would not be possible without pret > the pret band of decompiling maniacs > and their pokered disassembly.

S
Description
No description provided
Readme 63 MiB
Languages
C 48.3%
Lua 23.1%
C++ 17%
Shell 2.4%
HTML 1.7%
Other 7%