Rosters · Uniforms · New devices · Code

Contribute

New Blitz is free and open source, and it gets better when players build on it. Make a roster pack or a uniform set, bring the game to a device we don't have, or fix what bugs you. Everything starts with a hello on Discord.

How it works

The Discord is where contributors talk: what you're making, where you're stuck, what needs testing. GitHub is where finished code lands.

  1. Say what you're making in #dev. Someone may already be on it, or have half of it done.
  2. Build it with the guides below. Ask in #dev when the docs don't cover something: that's a gap we want to fix.
  3. Get it tested. Post a pak, or a build for your device, in #showcase so others can try it.
  4. Ship it. Finished paks are pinned in #paks, so players can find them. Code goes in as a pull request.

Other channels: #help for playing questions, #bugs for things that break, #announcements for releases.

Roster packs

A roster pack is a folder with one file, pack.json: each team's players, numbers, skin shades and builds, its team-select ratings and its city text. It changes who plays, not the art. Players install it with Settings → Add-Ons → Add… (a folder or a zip) and pick it under Settings → Teams → Rosters. Each pack keeps its own Season saves.

Just for you: no file needed

  • Roster Room (Settings → Teams → Roster Room) opens in your browser and sets any team's default crew: who plays each slot, over this week's lineup.
  • Pick Your Crew (Settings → Rules) lets you choose who plays after team select, game by game.
  • A wrong starter in the weekly lineups? Tell us in #bugs, with the team and the week.

A pack to share

  1. Start from the 2026 Season's pack. Add-Ons → Open Folder opens the app folder; copy paks/season2026/packs/blitz2026 somewhere else and rename the folder to your pack's id.
  2. Give it a new id and title in pack.json, then edit teams. Keep "format": "blitz-pack/2".
  3. Check it with python3 tools/pack.py validate <folder> from the source. The checks are the game's own: the app refuses a pack that fails them, and says why.
  4. Zip the folder and post it in #showcase.
{"franchise": "PIT", "abbr": "PIT",
 "ratings": {"passing": 3, "rushing": 4, "linemen": 4, "defense": 5, "special_teams": 3},
 "players": [{"slot": 3, "last": "Stewart", "number": 10, "skin": 3, "heavy": 0},
             {"slot": 4, "last": "Bettis",  "number": 36, "skin": 0, "heavy": 1}]}
FieldWhat it takes
slot0-15, each with a fixed role: 0-2 OL, 3 QB, 4 RB, 5-6 WR/TE, 7-9 DL, 10-13 LB/DB, 14 K (15 unused)
lastUp to 12 letters to fit the name tags (space, . ' - allowed); shown in capitals
number0-99: on the jersey, at team select and on name tags
skinSix shades, light to dark: 5, 1, 2, 3, 4, 0
heavy1 for the heavier build (linemen, linebackers, big backs)
ratings0-5 each: the team-select bars. The 1999 game rates teams, not players
  • Your own season. A pack can carry its own divisions and schedule for Advanced seasons: the season section.
  • Your own league. A league pack replaces the pro teams with 2 to 31 of your own, with their own names, uniforms and art, played in Arcade. Good for college, high school or a fictional league.

Every field and rule is in packs/README.md. A pack's rosters stay as you wrote them: the weekly lineup updates only change the 2026 Season's own rosters.

Uniforms and art

Uniform sets show up in the Uniform Picker (Settings → Rules): press △ at team select to cycle a team's home, away and alternates. They need the 2026 Season installed. A set is a folder, <TEAM>/<set>/, with the game's ten uniform parts as .wms images and a set.json:

DEN/04_orange_crush_throwback/
  helmet_side.wms   helmet_stripe_front.wms   helmet_stripe_back.wms
  facemask.wms      shoulder.wms              jersey.wms
  pant_stripe.wms   pants.wms   socks.wms     numbers.wms
  set.json   {"name": "Orange Crush Throwback",
              "dark": true, "kind": "alternate"}

Zip the team folder and anyone can add it with Add-Ons → Add…; the app recognises the shape and files it under uniforms/.

Making a set

You paint PNGs and a tool converts them. You'll need the source, built on a Mac, with your own ROM imported (see Bugs and code).

  1. Get templates: tools/uniform_handoff.py --teams DEN writes the team's current parts from your ROM as PNGs at the exact game sizes. They're for size and layout only: keep them to yourself.
  2. Paint your own versions at the same sizes. The helmet side is shown as it looks on the helmet; the tool turns it the way the game wants it. A part you leave out keeps the team's away one.
  3. Convert: put them in <src>/DEN/<set>/<part>.png with the set.json, then run tools/import_uniform_sets.py --src <src> --teams DEN --app-folder <your app folder>.
  4. Check it in the game, from both sides of the field, and post it in #showcase.

Other art and sound

  • Any game image can be replaced: a .wms named after the game's file goes in the app folder's art/files. tools/wms.py encode image.png out.wms makes one. Logos and banners may change size; uniform parts and end zones must keep theirs. tools/team_art_kit.py lists a team's pieces with their sizes.
  • Announcer calls: a team bank is three files (.wbk, .ptr, .bfx); docs/ANNOUNCER.md explains the format.
  • Several kinds at once? Lay them out like the app folder (packs/, uniforms/, art/, announcer/) and zip it. Add… merges each part in.

Draw it yourself. Never share templates, previews or anything else exported from the ROM, or art taken from another mod without its maker's say-so. Art that replaces a game image has to be made from scratch.

New devices

New Blitz is one game core with a thin layer per device. A new device needs a small host file, packaging, and patches to the libraries it runs on. The game code doesn't change. Here's where things stand:

DeviceStateWhat would help
Mac (Apple Silicon)TestedIntel Macs aren't built yet
Windows (x64)PreviewPlay it on your PC and report what breaks
Linux (x86_64), Steam DeckBuilds; not yet run on hardwareRun it on a Steam Deck or a Linux PC and tell us how it goes
iPhone / iPadPreviewSideloading with a free Apple ID; iPads of every size
Android, dual-screen handheldsTested / BetaMore handhelds, tablets and TV boxes; low-end tuning
PS5 (jailbroken)PreviewTesting on more firmwares
Linux ARM handhelds, Raspberry Pi 5WantedAn aarch64 Linux build (Vulkan through Mesa), packaged for PortMaster
Apple TVWantedA tvOS build from the iPhone one, with a controller
Xbox (Developer Mode)WantedA UWP build from the Windows one (the renderer speaks Direct3D 12)
Switch (homebrew), othersWantedBig jobs: no Vulkan, Metal or Direct3D 12 means a renderer of its own. Talk to us first

What a port takes

  • The renderer (RT64) needs Vulkan, Metal or Direct3D 12. Check that first: it decides whether a port is weeks of work or months.
  • A column in include/blitz_platform.h (what the device has: a file dialog, touch, a browser…) and a host file, src/main/platform_<os>, for the OS bits in include/blitz_host.h.
  • Packaging in platform/<os>/, and small library patches made with tools/new_patch.sh.
  • Today every build runs on a Mac, which cross-compiles for Windows, Linux, Android, iPhone and PS5. Making it build on Linux or Windows is a welcome contribution in itself.

The full walkthrough is docs/PLATFORMS.md. Each existing port has its own guide in docs/.

Testing on a device

  • The Frame Counter: press Settings → General → About seven times to show the development rows, then turn on Frame Counter. The game runs at 30 frames a second, each shown for 2 refreshes of a 60 Hz screen; a long gap is a hitch.
  • Save Logs (Settings → General) puts the log, any crash reports, your device details and settings in one zip. Every 5 seconds of play the log gets an [fps] line, so a test run comes with numbers.
  • Post the zip in #bugs or #dev with what you did and what you saw.

Prompts for AI coding agents

If you use an AI coding agent (Claude Code, Codex, Cursor or another), these prompts start it in the right place, with the project's rules. Fill in the <…> parts. You're still the one shipping: read every change it makes, test on the real device, and bring the result to #dev before you open a pull request.

Port New Blitz to a new device

You're helping me port New Blitz 2027 to <DEVICE> (<CPU, OS and version, GPU>).

New Blitz 2027 is a native recompilation of NFL Blitz 2000 for the N64: N64Recomp turns the game's code into C at build time, from the player's own ROM, and a host app (SDL2, the RT64 renderer and N64ModernRuntime) runs it. The source is at https://github.com/blitzrecomp/newblitz. Nothing from the game is in the repository, and nothing may be added.

Read these first, in order:
1. README.md and CONTRIBUTING.md.
2. docs/PLATFORMS.md, especially "Adding a platform".
3. include/blitz_platform.h and include/blitz_host.h.
4. The closest existing port: its src/main/platform_<os> file, platform/<os>/, its Makefile targets (<os>-modern) and its guide in docs/.

Rules:
- Never add a ROM, anything extracted from one, or any team or league content.
- Don't change src/game for the port. A platform is a column in blitz_platform.h, one host-services file, packaging in platform/<os>/, and small library patches made with tools/new_patch.sh (NNNN-<os>.patch, one per library).
- Builds run on a Mac today and cross-compile. If <DEVICE> needs another build host, say so and propose the smallest change.
- RT64 needs Vulkan, Metal or Direct3D 12. Before writing any code, find out which of these <DEVICE> has, which version and which driver, and tell me. If it has none, stop: write down what a separate renderer would take, and don't start one without asking me.

Plan first: the steps, the files you'll add or change, the libraries that need patches, and what can't be checked without the device. Then work in small steps that each build: it compiles, it links, it boots to the title screen, then input, sound, saves, and speed. After each step, give me the exact commands to run on the device and what I should see, and ask me for the zip from Settings → General → Save Logs.

At the end, write docs/<DEVICE>.md: how to build and install it, what works, what doesn't, and what was tested on real hardware.

Linux ARM handhelds and the Raspberry Pi

Help me add an aarch64 Linux build of New Blitz 2027 for <DEVICE, e.g. a Retroid/Anbernic handheld on ROCKNIX, Knulli or muOS, or a Raspberry Pi 5>. The source is at https://github.com/blitzrecomp/newblitz.

There's already a Linux x86_64 build, cross-compiled on a Mac: read platform/linux/toolchain-x86_64.cmake, tools/linux/make_sysroot.sh, src/main/platform_linux.cpp and the linux-modern target in the Makefile, then docs/PLATFORMS.md. Follow the same pattern for aarch64: a toolchain file, a sysroot for <DISTRO> with SDL2, FreeType and Vulkan headers and libraries, and a linux-arm64-modern target.

Things to check before building:
- The device's Vulkan driver (Mesa Panfrost/PanVK, Turnip, or v3dv on the Pi) and its version; RT64 needs Vulkan.
- How much RAM it has. Android's Potato Mode (search the source for potato) shows how the game is slimmed down for weak devices: lower resolution, no antialiasing, no Redo Play.
- How players install games on it. PortMaster is the usual way on these handhelds: propose a port folder (launcher script, controls, the ROM in a rom/ folder beside the app).

Never add a ROM or anything from the game. Don't change src/game. Give me the commands to run on the device after each step, and ask for the Save Logs zip (Settings → General). Finish with docs/LINUX_ARM.md.

Test and tune on my device

I'm running New Blitz 2027 on <DEVICE> and I want it smooth: <WHAT I SEE: stutter, slow menus, heat, a crash…>. The source is at https://github.com/blitzrecomp/newblitz. I've attached the zip from Settings → General → Save Logs.

How to read it:
- blitz.log gets an [fps] line every 5 seconds of play: frames per second, the worst gap between frames, and "VIs per frame 1/2/3/4+". The game runs at 30 fps, each frame shown for 2 VIs (60 Hz refreshes); a frame held 4 or more is a hitch. tools/stutter_report.py sums a log up. src/main/fps_counter.cpp writes these lines.
- The game itself stops drawing for about 65 ms at the top of every play, as play select comes up. That one is the 1999 game's own: ignore it.
- With the environment variable BLITZ_WAITS=1 the log also says where the renderer waited (texture uploads, shader compiles, a full queue, presenting).

Tell me what the numbers show, and where the time goes: the game, the renderer, or the device (heat, memory, the display's refresh). Suggest one change at a time, in Settings first (Graphics: resolution, antialiasing, framerate) and in code only if Settings can't do it. For each, say what to measure before and after. Never add anything from the game to a patch.

Make a roster pack

Help me make a roster pack for New Blitz 2027: <WHAT: e.g. "every team as of the 1999 season", "my friends' fantasy league", "my state's high school champions">.

Read packs/README.md and tools/pack.py in https://github.com/blitzrecomp/newblitz (the format is "blitz-pack/2", and the validator's rules are the game's). My starting point is a copy of the 2026 Season's pack: <PATH TO MY COPY>/pack.json. Don't edit the original in the app folder.

Rules:
- A new "id" (letters, digits, - or _) and "title". Keep "format" and "requires_rom" as they are.
- 16 slots a team, with fixed roles: 0-2 OL, 3 QB, 4 RB, 5-6 WR/TE, 7-9 DL, 10-13 LB/DB, 14 K, 15 unused.
- Last names of up to 12 characters (letters, space, . ' -); numbers 0-99; skin 0-5 (light to dark: 5, 1, 2, 3, 4, 0); heavy 1 for the bigger build; ratings 0-5.
- Use only data I give you or that you can point me to. Don't invent details about real people; ask me instead.

Go team by team. After each one, run python3 tools/pack.py validate <folder> and fix what it reports. When it passes, tell me how to zip the folder, so I can install it with Settings → Add-Ons → Add… and pick it in Settings → Teams → Rosters.

Make a uniform set

Help me make an alternate uniform for <TEAM ID, e.g. DEN> in New Blitz 2027: <DESCRIBE IT: colours, helmet, stripes, numbers>.

I have the source (https://github.com/blitzrecomp/newblitz) built on my Mac with my own ROM imported. Read the top of tools/uniform_handoff.py and tools/import_uniform_sets.py first.

1. Run .venv/bin/python tools/uniform_handoff.py --teams <TEAM>. It writes the team's current parts as PNG templates at the exact game sizes (build/nfl_uniforms/<TEAM>/templates), from my ROM. Use them for size and layout only: they stay on my machine and none of their pixels go into the new set.
2. Draw new versions of the ten parts (helmet_side, helmet_stripe_front, helmet_stripe_back, facemask, shoulder, jersey, pant_stripe, pants, socks, numbers) at the same sizes, as new art, with a script I can rerun. The helmet side is drawn as it looks on the helmet. A part we leave out keeps the team's away one.
3. Save them as build/nfl_uniforms_out/<TEAM>/<NN_set_name>/<part>.png with a set.json: {"name": "<shown name>", "dark": <true for a dark jersey>, "kind": "alternate"}.
4. Run .venv/bin/python tools/import_uniform_sets.py --teams <TEAM> --app-folder "<my app folder>", then tell me how to check it: Settings → Rules → Uniform Picker on, then △ at team select.
5. Show me a contact sheet of the parts at 4x before we call it done, and how to zip <TEAM>/<NN_set_name>/ to share.

Track down a bug

New Blitz 2027 goes wrong on my <DEVICE>: <WHAT HAPPENS, WHEN, AND WHAT I EXPECTED>. I've attached the zip from Settings → General → Save Logs (the log, any crash reports, device details and my settings).

The source is at https://github.com/blitzrecomp/newblitz. Read CONTRIBUTING.md, then the log. Log lines start with a tag ([crash], [savestate], [fps], [pak]…): search the source for a tag to find the code that wrote it.

Tell me what the log shows, your best explanation and how sure you are, and how to make it happen again. Before you change anything, say how we'll know it's fixed. Keep a fix small and to one feature, and match the code around it. Leave out of any patch or issue: my ROM, anything from the game, and personal details from the log.

Bugs and code

  • Found a bug? Post it in #bugs, or open an issue, with the zip from Settings → General → Save Logs and what you were doing.
  • Building it: on a Mac, make env, make venv and tools/build_deps.sh once; put your own NFL Blitz 2000 (USA) v1.1 dump in rom/; then make rom-import && make app-modern. CONTRIBUTING.md has the details and a map of the code.
  • Pull requests: one feature at a time, matching the code around it, with what you tested and how (a screenshot helps for anything you can see). Code is released under the GPL-3.0.
  • Not sure where to start? Ask in #dev. Testing on a device we don't have is as useful as code.

The ground rules

No game data, anywhere. Never share a ROM, a link to one, or anything taken from one: images, sounds, text, templates, saves or save states. Not in a pak, a pull request, an issue or a Discord post. Everyone brings their own cartridge dump.

  • Share your own work. Credit the people you built on, and ask before you include someone else's pak or art.
  • Real people: roster packs use real names at your own risk, for personal use. Don't invent details about real players.
  • Unofficial means unofficial. Nothing you make may claim to be from the NFL, its clubs, Midway or anyone else. New Blitz isn't affiliated with any of them (credits and legal).
  • Be good to each other on Discord and GitHub. This is a game about late hits; the community isn't.

Got an idea? Bring it to #dev