generating scene-style .nfo files in 2026
1. What Is an .nfo File?
If you're unfortunate enough not to have lived through the heyday of .nfo files, I want to provide some context. Because honestly, this project might seem weird or useless without it.
First, an NFO file (short for info/informational) is a file format originally released in 1990. This file format was used by various projects, but especially by warez/scene groups to provide info about their projects. This might include credits, installation instructions, BBS/contact info, greetz/notes, etc.
For example, here's the bonzai.nfo file for a patched save game for Lemmings III, with credits to those involved and instructions to get in touch.
Note: The original file on textfiles.com contains CP437 bytes decoded as Cyrillic, so I converted this example correctly to CP437. If you view the online version, you'll notice that the box drawing and group logo are incomprehensible, which proves my point later on in the CP437 section.
║ ║
█████║ ║
█████║ ║
█████▀███ █████▀███ █████▀███ █████▀███ █████▀███ ▀▀▀▀▀
█████║████ █████ ████ █████ ████ █████ ████ █████ ████ █████
█████║████ █████ ████ █████ ████ ▄▄▄▄▄▄████ █████▄████ ██████
█████║████ █████ ████ █████ ████ █████ ▄▄▄▄ █████ ████ ██████
█████ ████ █████ ████ █████ ████ █████ ████ █████ ████ ██████
█████║████ █████ ████ █████ ████ █████ ████ █████ ████ ██████
█████║████ █████ ████ █████ ████ █████ ████ █████ ████ ██████
█████ ████ █████ ████ █████ ████ █████ ████ █████ ████ ██████
▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀▀
║ ╓────────────────────────────────────────╖ ║
║ ■ BONZAi ─ EVERYTHiNG BUT FRiENDSHiP ■ ║
║ ╙────────────────────────────────────────╜ ║
R E L E A S E D :
║ ║
║ 9O BYTES SAVE GAME PATCHER FOR LEMMiNGS III ║
║ FiLENAME .............. : ........... BNZ-L3T.ZiP ║
║ TYPE .................. : ............... TRAiNER ║
║ COMPANY ............... : ............. PSYGNOSiS ║
║ CODER .. .............. : ................ SCAMPY ║
║ PACKAGER .............. : ................ SCAMPY ║
║ DATE AT RELEASiNG ..... : ............ 11-27-1994 ║
║ TiME AT RELEASiNG ..... : .............. 15:OO PM ║
║ RELEASE NOTES : ..................... READ BELOW! ║
║ ║
║ !!!*!!! IMPORTANT !!!*!!! ║
║ ║
║ NiCE PATCHER FOR A NiCE GAME - THiS PATCHER WAS ║
║ KINDA DiFFiCULT BECAUSE OF THE MANY BYTES TO BE ║
║ PATCHED. BUT PROBLEMS WiTH PATCHiNG TiME AND ║
║ FiLE LENGTH HAVE BEEN SOLVED. ║
║ ║
║ ENJOY PLAYiN' -SCAMPY! ║
║ ║
║ ║
║ MEMBERS OF BONZAi ARE . : ║
║ MOTiV8- SCAMPY- SUM-1- DEViL ║
║ ║
║ BULLETiN BOARD SYSTEMS : ║
═ ═ ══ ═══╝ NONE! SEARCHiNG! ╚═══ ══ ═ ═
GREETiNGS TO:
TOXiC HYBRiD PENTAGRAM PARADOX THHG G.T.A TRSI
#TO GET iN TOUCH WiTH BNZ LEAVE MAiL TO US ANYWHERE YOU FiND US#
CURRENTLY WE ARE SEARCHiNG FOR ALL KiND OF MEMBERS.. LiKE TRADERS
SUPPLiERS.. SYSOPS.. ETC.
═ ═ ══ ══════════════════════════════════════════════════════════ ══ ═ ═If you want to browse an archive of NFO files, head over to textfiles.
2. The Aesthetic
2.1. ASCII Art and Box Drawing
As you can see in the example above, complex ASCII drawings, logos, and structure are a staple of a good NFO file. Commonly, the ASCII art is used to create recognizable logos for specific groups in the scene.
This requires fixed-width fonts to be viewed appropriately. E.g., on Windows, you could open an NFO file in Notepad and ensure a fixed-width font is selected, such as Consolas. Proportional and custom fonts break the flow and structure of these files, which is unfortunately the default in modern browsers (unless you use code blocks, like I did above).
2.2. Codepage 437
One such character set was often used for NFO files: IBM's CP437 character set, released with the 1981 IBM PC. This set was popular because each character could be typed with an alt code in DOS, even if they were not on the user's keyboard. E.g., Alt + 3 would result in the following character: ♥.
3. Introducing: nfogen
So, why am I writing about this now? Well, I was feeling nostalgic for NFO files recently. As part of this, I started using NFO files for my git repos under my new org and wanted a tool that could help me accelerate the generation of these files.
Introducing nfogen, a small Python utility that can generate NFO files for you based on:
- templates
- profiles
- configuration files
- CLI flags
- interactive CLI prompts
This enables fast, customizable, and templatized NFO files you can generate on the fly.
3.1. Sample Output
There's no better way to introduce a project than to show a demo, so here's a demo of how I generated the README.nfo for nfogen itself.
First, I defined nfogen.toml so that I could use this as a configuration file during generation:
group = "KRZ"
site = "krz.sh"
width = 79
style = "double"
layout = "rows"
banner = true
banner_text = "NFOGEN"
footer = true
footer_text = "nfogen // krazy warez // krz.sh"
title = "nfogen 1.2.2"
type = "CLI / library"
publisher = "krazy warez"
language = "Python 3.11+ (any 3.x with a JSON config)"
files = "nfogen.py -- single file, zero deps"
url = "krz.sh"
notes = """
nfogen builds scene-style ASCII .nfo files from CLI flags, a config
file, interactive prompts, or any mix of the three.
FEATURES
- CP437 or UTF-8 output; single / double / block box styles
- two-column release+game info panel, or simple rows
- group profiles: reusable logo, members, couriers, boards
- mediainfo import auto-fills video / audio / resolution / size
- built-in ASCII banner generator for header logos (this one!)
- bundled templates: razor, modern, minimal
QUICKSTART
nfogen.py --title "Some.App.v1-KRZ" --type APP --banner
nfogen.py -c release.toml -p group.toml -o release.nfo
nfogen.py -t razor --title "..." --mediainfo dump.json
nfogen.py -i (prompt for every field)
RESOLUTION ORDER
template < profile < config file < CLI flags < prompts
See examples/ for full release nfos and a group profile, and
templates/ for the bundled presets. This README.nfo was itself
generated by nfogen: nfogen.py -c nfogen.toml
"""Next, I ran the following command, which produced the NFO file below:
nfogen.py -c nfogen.toml -o README.nfo # # ##### ### #### ##### # #
## # # # # # # ## #
# # # ### # # # ## ### # # #
# ## # # # # # # # ##
# # # ### #### ##### # #
╔═════════════════════════════════════════════════════════════════════════════╗
║ N F O G E N 1 . 2 . 2 ║
║ [ KRZ ] krz.sh ║
╠═════════════════════════════════════════════════════════════════════════════╣
║ DATE 2026-08-08 ║
║ TYPE CLI / library ║
║ PUBLISHER krazy warez ║
║ LANGUAGE Python 3.11+ (any 3.x with a JSON config) ║
║ FILES nfogen.py -- single file, zero deps ║
║ URL krz.sh ║
╠═════════════════════════════════════════════════════════════════════════════╣
║ NOTES ║
║ ║
║ nfogen builds scene-style ASCII .nfo files from CLI flags, a config ║
║ file, interactive prompts, or any mix of the three. ║
║ ║
║ FEATURES ║
║ - CP437 or UTF-8 output; single / double / block box styles ║
║ - two-column release+game info panel, or simple rows ║
║ - group profiles: reusable logo, members, couriers, boards ║
║ - mediainfo import auto-fills video / audio / resolution / size ║
║ - built-in ASCII banner generator for header logos (this one!) ║
║ - bundled templates: razor, modern, minimal ║
║ ║
║ QUICKSTART ║
║ nfogen.py --title "Some.App.v1-KRZ" --type APP --banner ║
║ nfogen.py -c release.toml -p group.toml -o release.nfo ║
║ nfogen.py -t razor --title "..." --mediainfo dump.json ║
║ nfogen.py -i (prompt for every field) ║
║ ║
║ RESOLUTION ORDER ║
║ template < profile < config file < CLI flags < prompts ║
║ ║
║ See examples/ for full release nfos and a group profile, and ║
║ templates/ for the bundled presets. This README.nfo was itself ║
║ generated by nfogen: nfogen.py -c nfogen.toml ║
╠═════════════════════════════════════════════════════════════════════════════╣
║ ║
║ nfogen // krazy warez // krz.sh ║
║ ║
╚═════════════════════════════════════════════════════════════════════════════╝For more examples, browse the examples directory within the repository.
4. Usage
4.1. Installation
The fastest installation method is to fetch and use the Python file directly:
curl -O https://raw.githubusercontent.com/krazywarez/nfogen/main/nfogen.py
python3 nfogen.py -i4.2. Generating a File
As noted in the README above, there are numerous ways to generate an NFO file:
# CLI Flags
nfogen.py --title "Some.App.v1-KRZ" --type APP --banner
# TOML Configuration Files
nfogen.py -c release.toml -p group.toml -o release.nfo
# CLI Flags & JSON for mediainfo
nfogen.py -t razor --title "..." --mediainfo dump.json
# Interactive Mode
nfogen.py -i5. How It Works
nfogen itself works by parsing the various inputs, determining a style to use for the box-drawing/character sets, and rendering the characters individually by rows and columns.
5.1. Width
The first issue I ran into was determining the width to use. I settled on 79 characters, border characters included, because terminals were 80 columns wide and a line that hits exactly 80 wraps on its own. This means that my script needs to perform some math to calculate wrapping, padding, and centering of text throughout.
The math is relatively simple because CP437 is single-byte and single-width, which means I can write functions that depend on that one-to-one correlation to calculate the spacing properly.
_Canvas.__init__ defines a few key variables for width:
self.width = width
self.inner = width - 4 # single-column content width
self.cl = (width - 7) // 2 # left panel content width
self.cr = (width - 7) - self.cl
self.rfill = width - self.cl - 5At a width of 79 characters, this breaks down into:
| Variable | Value | What it covers |
|---|---|---|
self.width | 79 | Total line width, borders included |
self.inner | 75 | Single-column content, minus two verticals and two pads |
self.cl | 36 | Left panel content width |
self.cr | 36 | Right panel content, taking the remainder |
self.rfill | 38 | Rule segment right of the joint, cr plus its two pads |
These combine into a cohesive 79-character-width NFO file with consistent padding and alignment.
5.2. Character Sets
nfogen currently supports two different character sets as outputs: UTF-8 and CP437. For example, there are ╔ ═ ║ characters in the UTF-8 example, but a real CP437 file contains the single bytes 0xC9 0xCD 0xBA.
However, this doesn't really change the core generation of the NFO file. The file itself is charset-independent and the charset only comes into play during the final encode of the file.
Referring back to the bonzai.nfo file above, it was decoded improperly as ISO-8859-5, which resulted in Cyrillic characters instead of the proper charset. Defining an appropriate charset and encoding/decoding is critical to ensuring the longevity of NFO files.
5.3. Banner Generator
The banner generator is a function by itself, which renders independent from the rest of the file and separate from the box geometry. This function defines a set of glyphs, takes an input text string from the user, and maps each character to its glyph. The result is rendered above the box and is centered, so it does not depend on the math applied to the canvas.
If an explicit art file is defined, this generator does not run.
# A compact 5-row block font for the banner generator. Each glyph is five
# rows joined by "/". Uppercase letters, digits, space, and a few symbols.
_FONT = {
"A": " ### /# #/#####/# #/# #", "B": "#### /# #/#### /# #/#### ",
"C": " ####/# /# /# / ####", "D": "#### /# #/# #/# #/#### ",
# ... through Z, 0-9, space, -, ., !, :
}
def banner(text: str) -> str:
"""Render text as a 5-row ASCII banner using the built-in block font."""
rows = ["", "", "", "", ""]
for ch in text.upper():
glyph = _FONT.get(ch, _FONT[" "]).split("/")
for i in range(5):
rows[i] += glyph[i] + " "
return "\n".join(r.rstrip() for r in rows)5.4. Resolution Order
Finally, I defined a specific order to the inputs. As stated in the README, the order of importance is: template < profile < config file < CLI flags < prompts.
This was an opinionated design choice, as I felt that if you were to run the script in interactive mode, that meant you wanted those to take precedence over all. Then again, specifying CLI flags directly when running the script should do the same. Finally, specifying configuration files, profiles, and templates will take precedence in descending order.
6. The Future
I'd love to build this tool out to support more character sets, pre-built libraries for ASCII art and table layouts, and more customization options.
For now, the tool works and is sufficient for my personal use cases, so I'm content with it.
If you're interested in helping, feel free to reach out!