Download

← All updates

Update

quark 1.18.10

Everything that changed in this version, and why.

A UI font update: Rubik Bold as the default, a SETTINGS > FONT page with the built-in fonts, free look-alikes of game fonts, the player's own copies of the real game fonts and their own mods/fonts files. Network protocol unchanged (43): 1.18.10 plays with 1.18.7 and 1.18.9 games and servers, and demos are unchanged.

The default UI font: Rubik Bold (tools/make_font_atlas.py, src/client/font_ui.h)

  • What: the UI text (menus, HUD, chat, scoreboard, editor) is Rubik at wght 700 (Bold), was Work Sans Bold. The console stays monospaced.
  • Why Rubik: it's already the logo's, the launcher's and the website title's font (assets/fonts/Rubik.ttf, SIL OFL 1.1), so the game's text now matches its branding.
  • How: tools/make_font_atlas.py bakes it into src/client/font_ui.h as before: raw R8 distance-field texels, uploaded at startup with no decoding, so startup costs the same. Rubik.ttf is a variable font whose default instance is Light; the tool sets wght 700 (Pillow).
  • Layouts: Rubik Bold's widths are within 0.1% of Work Sans Bold's at the same em, so every label fits as before. Capitals are 5.25 units (kUiCapHeight), the height every other font is sized to.
  • Asset override: fonts/Rubik.ttf / .otf (in assets/overrides/ or the Asset Studio) now replaces the default font. fonts/WorkSans.* used to replace the UI font. It now replaces only the WORK SANS entry. The asset export lists font/rubik (fonts/Rubik.ttf) as the default font, beside font/worksans.

SETTINGS > FONT (src/client/uifonts.cpp, src/client/game.cpp)

  • The page: a FONT button beside BACK on the settings page opens settings/fonts, in the menus and in game. It lists the built-ins (kBuiltinFonts: RUBIK, WORK SANS, QUARK CLASSIC, then the game-styled entries), then every .ttf / .otf in the game folder's mods/fonts (OPEN FOLDER, REFRESH; the wheel scrolls a long list). The page rises over the logo when the list is long, so all 10 built-ins fit unscrolled at 1280x720 and 1024x768.
  • Picking: a click builds that font once (a baked PNG atlas about 3 ms, a TTF about 55 ms) and saves it as ui_font in quark.cfg (a built-in's id or the file's name). A font that can't be loaded changes nothing and shows a notice. One that's gone at startup falls back to Rubik with a notice, and the setting is kept, so the font comes back with its file.
  • Applied once, never per frame: Game::frame applies ui_font only when it differs from the last one tried (a string compare), so the console's ui_font x and the UI test's settings reset work too. Renderer::setUiFont replaces the font texture's texels in place (glTexSubImage2D, same layout) and swaps the advance / kerning tables every text call reads. Nothing changes in the per-frame text path, so frame times and the F3 1% / 0.1% lows are unaffected.
  • Sizing: buildFontAtlas sizes any font so its capitals are as tall as Rubik's (FontAtlasLayout::cap), so a picked font doesn't break layouts. Before, a fixed em made fonts with small capitals look tiny.
  • QUARK CLASSIC: the original 5x7 pixel font (the kFont table removed in 8678b00) with its original metrics, baked as a max-norm distance field so its edges and outline stay square (17 KB).
  • Built-ins are baked PNG atlases (new src/client/font_builtin.h), not font files rasterised at run time:
    • Pillow can set a variable font's weight; stb_truetype only draws the default instance (Work Sans would come out Regular).
    • The bake sizes every font to Rubik's capitals.
    • A distance field compresses about 5:1 as a PNG: Work Sans Bold is 65 KB instead of 488 KB of raw texels or the 361 KB font file.

The game-styled fonts (assets/fonts, src/client/uifonts.cpp)

  • Seven free look-alikes, bundled (owner-approved downloads, each with its licence beside it in assets/fonts/):
EntryBundled fontLicence
OVERWATCHBebas NeueSIL OFL 1.1
COCAINE DIESELDecalotype Bold (the font Cocaine Diesel itself uses)SIL OFL 1.1
QUAKELibreQuake's CONCHARS (a 16x16 sheet of 8x8 characters)BSD-3-Clause
HALF-LIFE 2DejaVu Sans BoldBitstream Vera licence
TF2Lilita OneSIL OFL 1.1
TF2 SECONDARYJost, baked at wght 600 (SemiBold)SIL OFL 1.1
APEX LEGENDSBarlow Condensed BoldSIL OFL 1.1

Why look-alikes: the real fonts can't be shipped. Big Noodle Titling's EULA forbids redistribution, the fan "Apex" family is personal use only, and the TF2, Quake and Verdana files belong to their games and Windows.

  • The player's own real font comes first: each entry has a list of places the real font may be, and the first one found is used instead of the look-alike. Those places are mods/fonts under its known names, the system's Verdana Bold (Half-Life 2's menu font; Windows, macOS, Linux msttcorefonts), Steam's Team Fortress 2/tf/resource/tf2build.ttf / tf2secondary.ttf, and Quake's gfx.wad or pak0.pak (CONCHARS read from the WAD2 or the PAK, palette index 0 as paper). These files are read only on the player's computer, when the menu opens, on REFRESH and when picked. They are never shipped, and the search never runs per frame. An entry with neither a bundled file nor a found real font isn't listed.
  • Tuning (from screenshots of each font on the main menu, settings and FONT pages, and the UI test's layout checks run in every font with QUARK_UITEST_FONT):
    • Bebas Neue is baked 20% taller. It's capitals only and very condensed, and at Rubik's cap height its 1-pixel strokes broke up in small labels.
    • The pixel fonts (QUARK CLASSIC, LibreQuake, a player's own CONCHARS) are 1 unit a pixel and may be drawn down to scale 1 (FontAtlas / BakedFont::minScale, Renderer::minTextScale), where Rubik stops at 1.3.
    • Quake sheets are proportional (each glyph as wide as its ink): fixed 8-pixel cells clipped 6 settings labels at 1280x720.
    • A sheet's dark drop shadow is treated as paper, because the UI draws its own outline.
  • Quake sheets (buildSheetAtlas, quakeConchars): a 16x16 pixel font sheet becomes a max-norm distance field sized by its H, from a PAK (its gfx.wad), a WAD2, the raw lump or a PNG / JPEG sheet.
  • Asset overrides: each look-alike can be replaced under its own file name (fonts/BebasNeue-Regular.ttf, fonts/LibreQuake-CONCHARS.png a 16x16 sheet, ...), and each is in the asset export (the Asset Studio lists them). A player's own copy of the real game font still comes first.
  • Text scale: the UI's shrink-to-fit (Ui::fit, fitText, sliders, the reset hint) uses the font in use's smallest scale (Renderer::minTextScale()) instead of the fixed 1.3, so a pixel font can shrink to 1 pixel a pixel before clipping.

mods/fonts

  • New mods/fonts/README.txt: how to add a font, and the real fonts' file names the game-styled entries look for.
  • A variable font in mods/fonts is drawn at its default instance (stb_truetype). A name in ui_font can't leave that folder.

Size

  • The nine baked atlases in font_builtin.h add about 440 KB (Work Sans 65 KB, QUARK CLASSIC 17 KB, LibreQuake 15 KB, the other six 53-65 KB each). quark.exe is about 0.5 MB bigger.

Asset provenance (assets/provenance, tools/provenance.py)

  • The seven bundled look-alikes are registered in fonts.json as third-party (made by people, under their licences), like Rubik and Work Sans. Rubik's and Work Sans's descriptions now say which is the UI font. The new FONT page is ui/settings/fonts (ai).
  • tools/provenance.py sync now finds a font's licence by its family (<family>-OFL.txt, -LICENSE.txt or -COPYING.txt, the font's file name starting with <family>), so DejaVuSans-Bold.ttf (DejaVu-LICENSE.txt, Bitstream Vera) and LibreQuake-CONCHARS.png (LibreQuake-COPYING.txt, BSD-3-Clause) are read as third-party too. Before, it only matched <file name>-OFL.txt and would have called them ai. The fonts category now also lists a .png sheet in assets/fonts.
  • Human-made assets: 18.1% (100 of 550), was 17.1% (93 of 542).

Tests

  • testUiFonts (assets tests):
    • every listed built-in loads;
    • a font is sized to Rubik's capitals, and QUARK CLASSIC keeps its original metrics;
    • a Quake-style sheet (raw, in a WAD2, in a PAK) becomes a pixel atlas, and a bad WAD or a sheet without an H fails;
    • a mods/fonts name can't leave that folder.
  • The asset export test checks fonts/Rubik.* is listed.
  • UI test: the FONT page is settings/fonts:
    • each entry is cfg("ui_font") with the font's name as a stable id (the one in use is inert);
    • REFRESH is state("fontscan"), and OPEN FOLDER is url();
    • --fonts and --settingsmenu open the pages for screenshots;
    • QUARK_UITEST_FONT runs the layout checks in another font.

Docs and credits

  • README's Fonts section credits Rubik Bold as the UI font and every bundled font with its copyright and licence. The site footer and the Asset Studio's font hint name Rubik.
  • docs/ASSETS.md: how each font is built and why the built-ins are baked, mods/fonts, QUARK CLASSIC, the game-styled entries (look-alike, licence, where the real font is looked for), the sources of the bundled files, the tuning, and how to add a built-in.
  • docs/RELEASE_CHECKLIST.md: a FONT row. docs/UI_TEST.md: the fonts page and QUARK_UITEST_FONT. docs/PROVENANCE.md: the font licence rule.