Skip to content

Tags Reference

Tags are special LPCDoc annotations prefixed with @ that provide structured information about code elements. They are placed within doc comments (/** */), after the descriptive text.

/**
* Description of the element.
*
* @tag ...
*/

Documents a function parameter. The {type} can be any primitive, composite, or special type.

Syntax: @param {type} name - Description

Aliases: @arg, @argument

/**
* @param {int} attack - The attack power value.
* @param {string} target - The name of the target.
*/

Wrap the parameter name in brackets to indicate it is optional.

/**
* @param {mapping} [options] - Optional configuration settings.
*/

Append =value inside the brackets to document a default.

/**
* @param {string} [which="door"] - The specific door to unlock.
*/
int unlock(string which) {
which = which || "door";
}

In FluffOS a parameter is passed by reference with the ref keyword, or its & sugar, placed after the type in the function signature — int ref value and int & value are equivalent.

The annotation mirrors that spelling: put the & after the {type}, before the parameter name — @param {int} & value. The & sits outside the braces; placing it inside ({int&}) is read as an intersection type, not a by-reference marker.

/**
* @param {int} & value - A reference to an integer that will be modified.
*/
void increment(int & value) {
value++;
}

Documents the return value of a function. The {type} can be any primitive, composite, or special type.

Syntax: @returns {type} Description

Alias: @return

/**
* @returns {int} The calculated damage amount.
*/

When a function may return different types depending on conditions, use a union type.

/**
* @returns {object | string} The entity if found, or an error message.
*/

A special form of @returns enables type narrowing in conditional branches. Instead of documenting a return type, it declares that the function acts as a type guard for one of its parameters.

Syntax: @returns {paramName is type}

Where paramName is the name of a parameter in the function signature and type is the type it should be narrowed to when the function returns a truthy value.

/**
* @param {mixed} arg
* @returns {arg is string}
*/
int stringp(mixed arg);

When this function is called inside a conditional, the language server narrows the tested variable to the predicate type within the true branch:

void test() {
mixed o;
if(stringp(o)) {
// o is narrowed to string here
string s = o; // OK
}
}

The type predicate does not change the function’s actual return type. The function still returns its declared type (e.g., int); the predicate only informs the language server’s flow analysis.

Type predicates work with any valid type, including primitives, composites, and object file paths:

/**
* @param {mixed} arg
* @returns {arg is mixed*}
*/
int pointerp(mixed arg);
/**
* @param {mixed} o
* @returns {o is "/std/living.c"}
*/
int is_living(mixed o);

Type predicates are not limited to simple type-checking functions. Any function that returns a truthy or falsy value can use a predicate to narrow a parameter. A description may follow the predicate to document the return value for human readers:

/**
* Returns the original object if it is a user, otherwise 0.
*
* @param {object} ob - Some object.
* @returns {ob is "/std/user.c"} The original object if it is a user, or 0.
*/
object get_user(object ob) {
return ob->is_user() ? ob : 0;
}
void test() {
object thing = find_object("/some/npc");
if(get_user(thing)) {
// thing is narrowed to "/std/user.c" here
thing->send_message("Hello!");
}
}

Preprocessor defines are resolved in type predicates, so you can use macros as the target type:

#define STD_USER "/std/user.c"
/**
* @param {object} ob - Some object.
* @returns {ob is STD_USER} 1 if ob is a user object.
*/
int is_user(object ob);

Documents conditions that cause a throw(). A throw() is a soft error — it can be intercepted by catch() and does not generate a stack trace. This is the mechanism for recoverable exceptions.

Syntax: @throws Description of the condition

Alias: @exception

/**
* @throws If the configuration file was not found.
*/

Multiple @throws tags can be used when a function has several throw conditions.

Documents conditions that trigger a hard error — error() in FluffOS or raise_error() in LDMud. Unlike throw(), a hard error generates a full stack trace and is expensive. LPC distinguishes between soft errors (throw()) and hard errors where languages like JavaScript do not, and @errors exists to document that distinction.

Syntax: @errors Description of the condition

/**
* @errors If the crafter lacks required skills.
* @errors If components are missing or of insufficient quality.
*/

Documents the type of a variable or expression.

Syntax: @type {type}

/**
* @type {int} Maximum health points for a player.
*/
int MAX_PLAYER_HP = 1000;
/**
* @type {([ string: int ])} Mapping of damage types to resistance values.
*/
mapping resistances = ([ "fire": 10, "cold": 5, "physical": 3 ]);

You can annotate an expression inline to assert its type.

object p = /** @type {"/std/player.c"} */(get_player());

Documents the type of an inherited variable. Use this when a variable is declared in a parent object and you want to provide type information in the inheriting file.

Syntax: @var {type} name - Description

Unlike @type, the @var tag names the variable it annotates, and the language server enforces several rules for it:

  • It must include both a type and a variable name.
  • The name must refer to an inherited variable — annotating a local variable is an error.
  • It must appear in its own doc comment, not combined with other tags.
/**
* @var {([ string: int ])} skills - Inherited mapping of skill names to levels.
*/

Defines a named type alias or a structured shape. This is useful for documenting complex data structures — like the expected shape of a mapping — without needing a class or struct definition. The language server resolves object paths in @typedef tags and provides IntelliSense for the defined type.

Syntax: @typedef {type} Name or @typedef Name followed by @property tags

/**
* @typedef {int | string} Identifier
*/

Use @property tags to define the members of the type. This is the “shape definer” — it lets you describe what keys a mapping or data structure is expected to have, along with their types.

/**
* @typedef PlayerData
* @property {string} name - The player's display name.
* @property {int} level - Current experience level.
* @property {"/std/guild.c"} guild - The player's guild object.
* @property {int} hp - Current hit points.
* @property {int} max_hp - Maximum hit points.
*/

You can then use the typedef name in other annotations:

/**
* @param {string} player_name - The name to look up.
* @returns {PlayerData} The player's data record.
*/
mapping get_player_data(string player_name) {
// Implementation
}

Object paths used within @typedef are resolved by the language server, giving you full IntelliSense when referencing those types:

/**
* @typedef PartyMember
* @property {"/std/player.c"} player - The player object.
* @property {string} role - Role in the party (tank, healer, etc.).
* @property {int} joined - Timestamp when they joined.
*/

Documents a function that is passed as an argument to another function. Use this to describe the expected signature of callback parameters.

Syntax: @callback name

/**
* @callback sort_func
* @param {mixed} a - The first element to compare.
* @param {mixed} b - The second element to compare.
* @returns {int} Negative, zero, or positive comparison result.
*/

Documents a property of a class or struct. Used in the doc comment immediately above the class/struct definition.

Syntax: @property {type} name - Description

/**
* Represents an item available for purchase.
*
* @property {string} short - Display name shown in shop menus.
* @property {string} file - Full path to the item's source file.
* @property {int} cost - Purchase price.
* @property {int} stock - Current quantity available.
*/
class ShopItem {
string short;
string file;
int cost;
int stock;
}

Provides an example code snippet demonstrating usage.

Syntax: @example followed by code on subsequent lines

/**
* Transfers items between two containers.
*
* @example
* int moved = transfer_items(player, chest, "gold_coin", 100);
* if (moved < 100) {
* write("Could only move " + moved + " coins.");
* }
*/

Marks a function, variable, or other element as deprecated. Include a description of what to use instead.

Syntax: @deprecated Description or replacement

/**
* @deprecated Use query_experience() instead.
*/
int get_exp(string player_name) {
return find_player(player_name)->query_experience();
}

Provides file-level documentation. Placed at the top of a file to describe its purpose.

Syntax: @file path/to/file.c

/**
* @file /d/area/monsters/dragon.c
*
* Implements the elder dragon NPC with fire-breath attacks
* and treasure hoarding behavior.
*/

Creates a reference to another function, file, or resource.

Syntax: @see reference

/**
* @see check_crafting_skills
* @see /std/container.c
*/

Indicates that a function overrides an inherited definition.

/**
* @override
* @param {string} msg - The message to receive.
*/
void receive_message(string msg) {
// Custom implementation
}

Indicates that a function’s documentation should be inherited from the parent definition. When the language server encounters this tag, it pulls the description, parameters, and return documentation from the inherited function.

This is particularly useful in LPC where inherit is common — rather than duplicating documentation across overrides, you can inherit it and only document what changes.

/**
* @inheritdoc
*/
void create() {
::create();
// Additional setup
}

You can also add to the inherited documentation. Your description and any additional tags are merged with the parent’s:

/**
* @inheritdoc
* Also initialises the combat subsystem.
*/
void create() {
::create();
init_combat();
}

Identifies the author of the code.

Syntax: @author name

/**
* @author Wizard
*/

Specifies the version of the code.

Syntax: @version version

/**
* @version 1.2.0
*/

Indicates when a feature was introduced.

Syntax: @since version or date

/**
* @since 2.0
*/

Documents the visibility of a function or variable. These tags are useful when the visibility cannot be inferred from the code or when you want to be explicit.

/**
* @private
* @param {string} name - The name to validate.
* @returns {int} 1 if valid, 0 if invalid.
*/
static int is_valid_name(string name) {
// Implementation
}

Creates an inline link to another element. Used within descriptions, wrapped in {@link ...}.

Syntax: {@link reference}

/**
* This method works like {@link other_function} but has improved performance.
*/