Skip to content

LLM Skill

If you use an LLM to assist with documentation — whether integrated in your IDE or at a website — you can give it the following skill to produce consistent LPCDoc comment blocks. Click the copy button on the code block to grab the full instruction set.

For Claude Code, save this as .claude/skills/lpcdoc/SKILL.md in your project. For other tools, paste it into your LLM’s system prompt, project instructions, or conversation context.

Select the tab for your driver.

SKILL.md
---
name: lpcdoc
description: LPCDoc comment block generation guide for FluffOS. Consult when writing or updating documentation headers for LPC functions, variables, classes, and modules targeting the FluffOS driver.
---
# LPCDoc Generation Guide
LPCDoc is a documentation format for LPC (Lars Pensjö C) source code.
This guide targets the FluffOS driver. Follow these guidelines to produce
accurate, consistent, and useful documentation.
## Comment Block Structure
LPCDoc comments must be placed directly before the code element they document
and follow this structure:
/**
* Description of the element (function, variable, etc.)
*
* Additional details if needed, forming a complete paragraph.
*
* @tags and other structured elements
*/
Key points:
- Start with /** and end with */
- Each line within the comment begins with ` * ` (space, asterisk, space)
- Always leave a blank doc line (` *`) between the description and the first
tag. This is mandatory even for short one-line descriptions.
- Place tags after the description
## Function Documentation
For functions, document:
1. Purpose/behavior of the function
2. Each parameter
3. Return value
4. Any errors/exceptions
Example:
/**
* Calculates the total damage based on attack power and defense.
*
* @param {int} attack - The attack power value
* @param {int} defense - The defense value
* @returns {int} The calculated damage amount
* @throws If either value is negative
*/
int calculate_damage(int attack, int defense) {
// Implementation
}
## Variable Documentation
For variables, document:
1. Purpose/use of the variable
2. Type information
Example:
/**
* Maximum health points allowed for any player character.
*
* @type {int}
*/
int MAX_PLAYER_HP = 100;
## Essential Tags
### @param
Documents a function parameter.
Syntax: @param {type} name - Description
### @returns
Documents the function's return value.
Syntax: @returns {type} Description
### @throws
Documents what condition(s) result(s) in a throw().
Syntax: @throws Condition that causes a throw
This will be evident by the appearance of throw() in the function body.
### @errors
Documents what condition(s) result(s) in an error().
Syntax: @errors Condition that causes an error
This will be evident by the appearance of error() in the function body.
### @type
Documents a variable's type.
Syntax: @type {type}
### @example
Provides example usage.
Syntax: @example followed by code on subsequent lines
### @property
Documents a property of a class, struct, or @typedef.
Syntax: @property {type} name - Description
### @typedef
Defines a named type alias or structured shape. Use with @property tags to
describe the expected shape of a data structure.
Syntax: @typedef {type} Name (simple alias)
Syntax: @typedef Name followed by @property tags (structured shape)
Example:
/**
* @typedef PlayerData
* @property {string} name - The player's display name.
* @property {int} level - Current experience level.
*/
Then use in annotations: @param {PlayerData} data
### @file
Provides file-level documentation at the top of a file.
Syntax: @file path/to/file.c
### @see
References another function, file, or resource.
Syntax: @see reference
### @override
Indicates a function overrides an inherited definition.
### @inheritdoc
Inherits documentation from the parent function definition. The language
server pulls description, params, and returns from the inherited function.
Can be combined with additional text to extend the inherited docs.
### @deprecated
Marks code as deprecated. Include what to use instead.
Syntax: @deprecated Use replacement() instead.
### @private / @protected / @public
Documents visibility of a function or variable.
### @link
Inline link to another element within descriptions.
Syntax: {@link reference}
## Types Reference
### Primitive Types
- int - Integer
- float - Floating-point number
- string - Text string
- object - Generic object
- mapping - Key-value structure
- function - Function reference
- buffer - Binary data buffer
- class - Structured data type
- struct - Structured data type
- mixed - Any type
- void - No return value
### Named Objects
For objects of specific types, enclose the path in quotes:
{"/path/to/object.c"}
Example: {"/std/player.c"}
If a macro is defined for a common object path
(e.g. #define STD_USER "/std/user.c"), use the macro name directly:
{STD_USER}
### Arrays
Append * to a type:
{type*}
Example: {string*} for string array
### Mappings
For mappings with specific key/value types:
{([ keytype: valuetype ])}
Example: {([ string: int ])} for string-to-int mapping
### Union Types
Separate types with pipe:
{type1 | type2}
Example: {int | string}
### Reference & Variadic Parameters
These markers attach to the parameter, not the type:
- Pass-by-reference: put & after the {type}, before the name.
@param {int} & value (mirrors the signature `int & value` / `int ref value`)
- Variadic (rest): prefix the type with ...
@param {...int} rest (a function taking any number of trailing ints)
### Optional Parameters
Wrap the name in brackets:
@param {type} [name] - Description
With default values:
@param {type} [name=default] - Description
### Undefined Values
For values that might be undefined:
@returns {type | undefined} Description
### Classes
Document with @property tags above the definition:
/**
* Description of the class.
*
* @property {type} name - Description
*/
class ClassName {
// members
}
## Function/Variable Visibility
Visibility tags (@public, @protected, @private) should be the first tag when
applicable. Functions and variables are public by default.
Visibility sections affect everything that follows:
protected:
void func1(); // protected
private:
void func2(); // private
public:
void func3(); // public
## Practical Guidelines
1. Be concise but complete in descriptions
2. Document all parameters and return values
3. Note any side effects or state changes
4. Include @example for complex functions
5. Specify types as precisely as possible
6. Document error conditions with @errors and throw conditions with @throws
7. Do not modify code — only add or update documentation comments

The base skill above covers the LPCDoc format itself. Most projects benefit from appending additional sections that tell the LLM how you want it applied. Below are some common conventions you can copy into your skill.

Establishing a consistent tag order makes doc blocks predictable and scannable.

## Tag Ordering
Tags should appear in the following order:
1. Visibility tags (@public, @protected, @private) always come first
2. @override (if applicable)
3. @apply (if this is a driver apply)
4. @param (one per parameter, in declaration order)
5. @returns
6. @errors (only if error() is called)
7. @throws (only if throw() is called)
8. @example
9. Any other tags

If your project enforces a line width, tell the LLM explicitly.

## Line Length
- All documentation lines should wrap at 79 characters
- Maintain proper indentation when wrapping
- Use complete sentences even when wrapping

Every project has elements that don’t need doc blocks. Listing exclusions prevents the LLM from generating unnecessary noise.

## What Not to Document
Unless specifically instructed, do not document:
1. Forward declarations
2. Preprocessor directives (#include, #define, etc.)
3. inherit statements
4. Standard setup functions (list the function names for your lib)

A structured file header gives every source file a consistent preamble. Tags like @created, @last_modified, and @history are not recognised by the language server, but they are useful metadata for humans and LLMs alike.

## File Header Documentation
Every file should have a header block in this format:
/**
* @file /path/to/file.c
*
* Description of this file and its purpose.
*
* @created YYYY-MM-DD - Author
* @last_modified YYYY-MM-DD - Author
*
* @history
* YYYY-MM-DD - Author - Created
*/

LPCDoc tags do not need to be recognised by the language server to be useful. If your project has conventions that benefit from structured tags, define them.

## Custom Tags
### @apply
Marks a function as a driver apply (called by the driver, not by user code).
Place this tag before @param.
### @errors
Documents conditions that trigger an error() call. Distinct from @throws,
which documents throw() calls.

When using an LLM specifically for documentation passes, it helps to be explicit about scope.

## Imperative Information
Do not touch the code. For documentation purposes, we only need comments.
There will be no reason to opine on things like parens placement, semicolon
changes, etc., by updating the code sections of a file. Restrict activities
to only documentation.