Skip to content

Writing pages

Pages are markdown files in the open bullet-hero/docs repository. A change arrives as a pull request: a fork, a branch, the change in every language, a check against the style guide

Repositories

Every repository of the project lives in the bullet-hero organization. The open ones:

RepositoryWhat it holds
bullet-hero/releasesreleases hold every public build of the game, issues hold bugs and requests about the game from players
bullet-hero/sdkthe SDK code, issues hold bugs and requests about the SDK
bullet-hero/docsthese pages and their translations
bullet-hero/backendthe server, empty for now

The code of the game (bullet-hero/game) and of the site (bullet-hero/frontend) is closed

This page is about bullet-hero/docs

How to send a change

  1. Fork bullet-hero/docs and create a branch
  2. Edit or add pages in the format described below
  3. Change the page in every language, or say in the pull request which languages still need the change. More - Translating
  4. Check the text against the Style guide
  5. Open a pull request with a short description of what changed and why

Facts come from the game, the SDK or their documentation. Numbers, field names, file names, shortcuts and addresses are never guessed. Not sure something is true? Say so in the pull request, not on the page

An accepted change does not appear on bullethero.space at once, but with the next site update

Tip

You cannot build the site yourself, since its code is closed. The closest preview is Obsidian: a link that Obsidian cannot find will not be found on the site either

How the repository works

  • Markdown only. There is no build of its own and no scripts
  • It is an Obsidian vault. Open the repository's root folder as a vault, and links, embeds and previews work the same way they do on the site. Any other markdown editor works too
  • It is a submodule of the site. The site includes the repository as its content/ folder, compiles the pages when it is built and prerenders every one. A change reaches the site when the site's pointer to this repository is moved forward

What goes where

PathWhat it holdsAddress on the site
<lang>/docs/1_game/for players: installing, playing, settings, the mechanics/<lang>/docs/game
<lang>/docs/2_editor/for level authors: the editor guide and reference/<lang>/docs/editor
<lang>/docs/3_sdk/for developers: the open SDK and the level format/<lang>/docs/sdk
<lang>/docs/4_server/for server hosts: official and community servers/<lang>/docs/server
<lang>/docs/5_changelog/the changelog, one page per game version/<lang>/docs/changelog
<lang>/notes/articles, community, editing rules, public documents and policies, by date/<lang>/notes/<name>
<lang>/tags/tag pages/<lang>/tags/<tag>
<lang>/download.mdthe download page/<lang>/download
assets/images for every languageembedded in pages

<lang> is a language folder: en, ru or zh. A file outside docs/, notes/, tags/ and download.md does not become a page

Docs describe how things work now. A history of changes, an opinion or an essay is a note in notes/

File names and order

  • The order in the sidebar is set by an N_ prefix on every file and folder inside docs/: 1_, 2_ and onward, up to 10_ and beyond
  • The prefix never reaches the address. 1_game/3_controls.md opens at /<lang>/docs/game/controls
  • index.md has no prefix. It is the landing page of its folder. It takes the folder's position and gives the sidebar group its name
  • To change the order, rename the files. Enable "Automatically update internal links" in Obsidian and it fixes every link itself
  • A name without its prefix is unique within a language. If two files collapse to the same address, the site build reports it
  • A prefixed name is identical in every language. en/docs/2_editor/4_craft/3_difficulty-curve.md and ru/docs/2_editor/4_craft/3_difficulty-curve.md are the same page
  • notes/ has no prefixes and no subfolders. Never rename notes/cookie-policy: the cookie banner on the site links to it

Frontmatter, title and description

Every page starts like this:

---
title: Difficulty and the curve
date: 2026-09-24
tags: [level_author]
---

# Difficulty and the curve

One line that says what the page is, up to 200 characters, no markup
  • title, the H1 and the description are written in the page's language. The example above is from the English version
  • Frontmatter is title, date and tags. Nothing else is read. date in the YYYY-MM-DD format is the date of the last update, not of creation. When you edit a file, set date to the day of the edit
  • # H1 is required and equals title. The site shows only the body of the page, so the H1 is the visible title
  • The first paragraph after the H1 is the description in listings, search and link previews. It is cut at 200 characters. Write it as one line, with no links or formatting. It briefly answers the page's question instead of describing what is on the page, Style guide › Page opening
  • Sections are ##, subsections ###. They produce anchors and the table of contents. Deeper levels are not needed

Audience tags

Every docs page has 1 to 3 tags from this list. Tags are written in snake_case without #. The site shows them on the page

TagOn the siteWho
playerPlayera regular player
advanced_playerAdvanced playera player interested in the mechanics
level_authorLevel authormakes levels in the editor
developerDeveloperbuilds something on the SDK or extends the game
server_hostServer hostruns a server for themselves and friends
server_advancedAdvanced server hosta large server host, ready to extend or write a server
contributorContributoredits the texts and translations in this repository

Notes in notes/ use topic tags instead, currently legal (Legal documents)

The reader never sees the tag code. The label comes from the tag page <lang>/tags/<code>.md:

  • its title is the label
  • its first paragraph describes the audience
  • the site adds the list of tagged pages itself

A new tag needs such a page in every language

To mention a tag in the text, link its page: [[level_author]]. The link shows the label in the reader's language

WhatHow
Another page[[3_difficulty-curve]], by the full file name with its prefix
A section of a page[[3_difficulty-curve#Anchor]]
A folder landing page[[2_editor/4_craft/index]], with the path, since every such page is called index
An external site[text](https://…), with the full address and scheme

Links lead to an address without a language, so one source works in every language. [[cookie-policy]] sends an English reader to the English page, a Russian reader to the Russian one and a Chinese reader to the Chinese one

Link only to pages that exist. The site build reports every link it could not resolve

Images

Images live in assets/ at the root of the repository and are embedded with ![[file.png]]

One folder serves every language. Text drawn on an image is not translated with the page

Callouts

SyntaxColourUse
> [!note], > [!info], > [!tip]bluecontext, a shortcut, a recommendation
> [!warning], > [!caution]yellowcosts time or quality, destroys work
> [!danger], > [!bug]redrendered, but the style guide does not use them

Which callout to pick, its title and the limit of two per page - Style guide

Code and other markup

  • Code highlighting exists only for ts, tsx, js, json, csharp, bash, yaml, css and md. Other languages are shown as plain text
  • GFM tables, task lists, footnotes and ==highlights== work
  • No MDX and no JSX. { and < are shown as they are

Linked from