First Steps Using MfGames Writing (GitLab, NPM)

Getting started with MfGames Writing can be a bit overwhelming. This is the beginning of how to get started. These directions are mainly focused toward technical users who already have a basic skill in Git.


I appear to be writing a short series of post about the tools I use for publication and writing.

  1. Semantic Versions and Releases: Why semantic versioning helps with the writing process.
  2. Evolution of MfGames Writing: A brief history and reasoning behind the tools.
  3. First Steps Using MfGames Writing: How to get started with a project.
  4. Adding Content to MfGames Writing: Adding front and back matter to novels.
  5. Working with MfGames Writing, CI, and Docker: Adding automatic building with commits.
  6. Additional Formats for MfGames Writing: How to create PDF, MOBI, DOCX, and HTML versions.
  7. Theming for MfGames Writing: A light introduction on how to customize the output.
  8. Integrating Semantic Versioning into MfGames Writing: Tying semantic releases into the process.

Setting up Git

I always start by creating a new Git project on GitLab. You can do the same with GitHub, BitBucket, or just locally. Since I'm focusing on the tools, I'm going to assume you know how to create those projects.

$ git checkout
... stuff happens
$ cd test-project

You could create a new folder, it doens't really matter.

$ mkdir test-project
$ cd test-project
$ git init

Setting up .gitignore

The way builds work, there are quite a few files that will be generated that wouldn't be checked into the repository. This is one thing that makes NPM so powerful. To avoid that, we create a .gitignore file that ignores those files.

# Emacs and VI creates these files and I'm too lazy to turn it off.

# This is the output of the various build processes.

# Sometimes I use `build` for my output but most of the time I just put it in the root.

# This is where Node/NPM puts its file.

Setting up .editorconfig

EditorConfig is a tool for providing some consistency in formatting. For novels, it doesn't make sense but I like to have it there to make sure the supporting files are consistent. This is an optional file, I just like having it.

# EditorConfig is awesome:

# top-most EditorConfig file
root = true

charset = utf-8
end_of_line = lf
indent_brace_style = K&R
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 80
tab_width = 4
trim_trailing_whitespace = true
curly_bracket_next_line = false

quote_type = double

indent_size = 2
tab_width = 2

indent_size = 2
tab_width = 2

Setting up package.json

The versioning and management comes from package.json. This is the file that says which version of which utilities to use. Now, you can use npm init to figure it out but this is the basic file.

    "name": "test-project",
    "private": true,
    "version": "0.0.0"

There is other stuff, but these are the key parts. The name is the slug of the file. For me, it is always the name of the folder in the website and the Git repository. I also use this to build my website, so it is a pretty consistent format. You can call it whatever you want and change it as you need.

The private is to prevent you from accidently publishing your novel on NPM.

Finally the version is used for the semantic release and populates data on the legal page of the resulting book. In general, I start with “0.0.0” and then bump it to “1.0.0” when I finalize the book and publish it for the first time.

Write a Chapter

Now, we need somethig to put into the story or novel. Since I've started this, I organize even my short story into chapters. To do that, you can put it anywhere, but I always put my chapters in (unoriginally) the chapters/ folder. I also use two-digit numbers with zero padding so it sorts correctly (this is useful). You can see this at Sand and Blood's Git Repository.

For example, chapters/

title: Mistakes Were Made

It was a bright and terribly sunny day.

I didn't like it.

Setting up publication.yaml

Because of the flexibility (if you don't want to use chapters/, want to spread it out across deeper folders), nothing is automatic when it comes to formatting the books. To control it, we have a simple file called publication.yaml which tells the system how to create the output. This would go at the top-level file.

    title: Test Project
    author: D. Moonfire
    language: en

    theme: "@mfgames-writing/clean"
    outputDirectory: .
    outputFilename: test-project-{{edition.version}}.{{edition.editionName}}

    epub: # This is the edition.editionName.
        format: "@mfgames-writing/epub2"

    - element: chapter
      number: 1
      directory: chapters
      source: /^chapter-\$/
      start: true
      page: 1

Now, since this file is the core of MfGames Writing, it needs a bunch of details.


Many of the fields use Liquid templates. That is the stuff between {{ and }}. The main reason we use it is so we can simplify some of our logic. For example, instead of putting outputFilename in every edition, we can use variables to fill it in. Also, we can substitute {{ edition.version }}`` to have the version from the package.jsonfile. The{{edition.editionName}}will haveepubfor theepub:line. This means it wil produce a filetest-project-0.0.0.epub` when it runs.


The formatting is driven around the idea of a “theme”. Right now, there are only three themes. Two are private or require custom fonts, the other is @mfgames-writing/clean which is a utilitarian theme based on SASS and some templates. These themes are used to create a consistent style. I also have more specialized themes:

Both of these have custom fonts (Corda and Mr. Eaves) with a bit of logic. I could easily see this being expanded by anyone to create a gallery of formatting for books. Right now, I'm focusing on these three because they are functional enough.

See the later post on theme specifics.


Editions are basically versions of the output. For Sand and Blood, I have one for EPUB, HTML, and PDF. MOBI and DOCX are generated from those three sources. You can have any number of editions, different file names, different output directories, even different variables like ISBN numbers.


Content is what goes into the file. Right now, we only have a single element, all the files in the chapter folder.

- element: chapter
  number: 1
  directory: chapters
  source: /^chapter-\$/
  start: true
  page: 1

The element tells the theme how to format it. Later examples will include more but you can have things like preface or appendix or titles and the like.

The number property basically is used if you want to have “Chapter 1” in the theme but with a custom title. If your chapter is just “One”, “Two”, “Three”, you wouldn't define this. My books do since I use chapter titles.

The directory and source work together to figure out which files are to be included.

start is used by EPUB and MOBI to figure out where to automatically navigate when the reader first goes into the page.

Finally page is used by the PDF system to restart page numbering. Usually this would be left blank.

Installing Tools

At this point, I have a minimum novel project. Time to make it actually produce something. Like in the previous, everything is self-contained in the directory. We use npm to install the packages needed to build the project.

$ npm install @mfgames-writing/format @mfgames-writing/clean @mfgames-writing/epub2

The @mfgames-writing/format provides the command-line tools and does the work. There is also the “clean” theme and a third for the output (EPUB2).

Once these install, running the output should work with the following command.

$ npx mfgames-writing-format build
... lots of colorful output
$ ls *.epub

If all goes well, you'll see test-project-0.0.0.epub in the root directory. It won't pass epubcheck check (we are missing a few things), but this is the basics of the publishing system.