How to create documentation worthy of F.A.N.G.

Andrew Velez
Posted on 4/17/2019Last Modified: 4/18/2019

I wrote about why you should document your code. If you are interested in the reasons documenting will help you in the long run go check out the article.
In this article im going to talk about how you should be documenting your code. I’m going to give you advice for writing documentation that will actually help you in the future. We’ve all experienced that moment when reading some documentation and it’s useless. It might as well not exist.

Write why the code exists/works not how.

When we are going back to our code we want a quick description of the method so we can see if that method is the problem. If you are writing how the code works than it's useless documentation. The code you are writing should explain why it works. We don't need two places telling us how the code works.
The first example below will be of bad documentation and the second will be the good example.
// Example Documentation C#

/// Logs to the console we are starting the program, then creates 
/// an  class to start the program.
setup() {
  Console.log("Starting the program");
  this.example = new Example(); 

/// This method is the starting point of the program. Sets up program to start.
setup() {
  Console.log("Starting the program");
  this.example = new Example(); 
Looking at the first example we can see exactly what the documentation is saying. The code is doing exactly what it the documentation says. There are two problems with this. There is repetition, the code is basically being duplicated in the documentation. We are basically paraphrasing the code into a human readable form. This is useless. The other problem is that if we ever change the code then the documentation also has to be updated. This leaves room for documentation to become outdated. If we change the class Example to be MainExample then we would run into a problem where the documentation no longer matches the code.
With the second example it will always match the code. We could end up adding more code in this method but we know that code should have to do with setting up initial state for starting the program so it should always match. Having a clearly defined why let's us know what the method should do and if it worth looking at deeply.

Learn you languages documentation standard.

I only stick to three main languages. C++, C#, and JavaScript. I will talk about why i only stick to three languages in another article. The value of only having three main languages is that it's easier to know all the nuances of the languages documentation. In C# for example i have learn't how to document exceptions in the xml.
/// <exception cref="NotImplementedException"> </exception>
There are so many cool ways to do things with documentation that it’s best to just learn them overtime by continuing to document. As you document more you‘ll come across different tags you could use. I usually see new ones in the suggestions that help with readability. In JavaScript there is no concept of private, any class you instantiate will have every function public. One convention is to make the method start with a _ if you want it to be private. I also like to add the @private tag to the documentation just to let people know that aren’t familiar with the convention. Later down the road i’ll be able to know how to use the class properly when i instantiate it.

Comments inside of code.

I always try to document any Regex i create. That shit is black magic so once you finally finish it you are definitely gonna forget it. Having a comment saying what the regex is looking for will save you the effort of debugging to figure out what it does.
Really long if statements should either be nested, inverted or pulled into multiple booleans with descriptive names. This is a form of documentation. Having your code be more easily readable should always be a priority. I typically say booleans longer than 3 operators need to be documented some how.
// This is too long
if(isTall && isGreen && isSkinny && isWild){
  Alien alien = new Andrew()

// Inverted
if(!isTall) {

if(isGreen && isSkinny && isWild){
  Alien alien = new Andrew()

//Pulled out
var isLanky = isTall && isSkinny;

if(isLanky && isGreen && isWild){
  Alien alien = new Andrew()

if(isGreen && isSkinny && isWild){

  if(isTall) {
    Alien alien = new Andrew()
You have to decide which one to use at any given time but i tend to lean towards the inverted option. But if it makes sense use another option. The pulled out Boolean method is useful for when you need to test the same AND statement multiple times.

Keep the comments short and sweet

Writing huge paragraphs of text in the documentation will make it hard to change the code later on.
Try to avoid writing to much documentation because every time you have to change the code you will have to look at the comments to make sure it is still matching up. You really only need 1-3 sentences to describe what the code is doing. If you need more than that it is likely that your function is trying to do to much. I would afford more lines to a class but there is also a point where the documentation of a class gets too long. I find the long documentation for classes are most useful when there is an explanation on how to use the class.
Here is an example of a really long documentation from the guys who made substance painter. This long text works, It is really easy to understand what the class does and it was really helpful in being able to integrate live-link with a custom engine.

/* Allows to link Substance Painter with an external program by using a persistent connection between both programs
 * The connection is based on a WebSocket connection with a simple command protocol: "[COMMAND KEY] [JSON DATA]"
 * List of commands to which this plugin is able to answer:
 * - CREATE_PROJECT: Create a project with specified mesh and link it with the integration
 * - OPEN_PROJECT: Open an existing project and link it with the integration
 * - SEND_PROJECT_INFO: Send back info on the current project (project url and integration link identifier)
 * For CREATE_PROJECT and OPEN_PROJECT, we receive a bag of information containing all the configuration
 * allowing to link a project:
 * {
 *     applicationName: "", // External application name
 *     workspacePath: "",   // Workspace path (the workspace of the external application)
 *     exportPath: "",      // Relative path in the workspace in which we want to export textures
 *     materials: {         // List of linked materials
 *         "my_application_material_name": {
 *             assetPath: "",      // External application material ID
 *             exportPreset: "",   // Name or url of the export preset to use
 *             resourceShader: "", // Name or url of the Substance Painter shader to render the material
 *             spToUnityProperties: {
 *                 // Association between Substance Painter exported textures and application textures
 *                 // "texture name as define in the SP template" => "external application ID"
 *                 // Example:
 *                 "$mesh_$textureSet_baseColor": "basecolor_texture_sampler_in_my_shader",
 *                 "...": "..."
 *             }
 *         },
 *         "...", {...}
 *     }
 *     project:
 *     {
 *         meshUrl: "",  // Mesh to use for the new project
 *         normal: "",   // Normal format to use (OpenGL/DirectX)
 *         template: "", // Template url or name to use
 *         url: ""       // Substance Painter project location
 *     },
 *     linkIdentifier: "" // Identifier that will be serialized with the project to allow reconnection
 * }

I hope i helped you write better documentation. If you think i missed anything please comment down below and let me know. Have a wonderful day!

Andrew Velez
Posted on 4/17/2019Last Modified: 4/18/2019


Comments 0

0 / 10