LLM Skill
If you use an LLM to assist with writing configuration files — whether integrated in your IDE or at a website — you can give it the following skill to produce correct LPML. Click the copy button on the code block to grab the full instruction set.
For Claude Code, save this as .claude/skills/lpml/SKILL.md in your project.
For other tools, paste it into your LLM’s system prompt, project instructions,
or conversation context.
The Skill
Section titled “The Skill”---name: lpmldescription: LPML (LPC Markup Language) specification reference. Consult when reading, writing, editing, or validating .lpml files. Covers syntax, data types, string concatenation, spacey keys, file includes, multiline folding, and all extensions over JSON5.---
# LPML (LPC Markup Language) Specification v1.0.0
LPML is a human-friendly data serialization format designed for MUDconfiguration files. It extends JSON5 with LPC-environment-specific features.
## Design Goals
1. Easy to read and write by hand2. Optional file includes for modular configs3. Natural multiline strings without escape hell4. Full JSON/JSON5 compatibility5. Fast enough for config files (not hot paths)
## File Extension
The recommended extension is `.lpml`. Alternatives `.json` or `.json5` may beused for editor syntax highlighting.
## Base Syntax (JSON5)
LPML inherits all JSON5 features:
### Comments
// Single-line comment/* Multi-line comment */
### Unquoted Keys
Keys can be written without quotes if they are valid identifiers:
{ name: "Gesslar", level: 10 }
### Trailing Commas
Permitted in objects and arrays:
{ a: 1, b: 2, }[1, 2, 3,]
### Single-Quoted Strings
{ name: 'single quotes work too' }
### Number Formats
{ hex: 0xFF, octal: 0o77, binary: 0b1010, decimal: 3.14, leading_dot: .5, trailing_dot: 5., plus_sign: +42,}
## LPML Extensions
These features go beyond JSON5:
### Spacey Keys
An unquoted key can be almost anything, YAML-style. The parser reads everythingfrom the start of the key until the first `:`, then trims surroundingwhitespace — so spaces, hyphens, dots, digits, and UTF-8 letters are all valid:
{ hit points: 100, max hit points: 120, experience points: 1500, admin-heal: "sound.wav", café: "value",}
The first `:` always ends the key (LPML differs from YAML here, which ends a keyonly at a colon followed by whitespace). Quote a key only when it must contain aliteral colon:
{ "key: with colon": "value",}
### String Concatenation
Adjacent string values automatically concatenate. The joining rule depends onwhether the preceding string ends with `\n`:
- If a string ends with `\n`, the next string concatenates **without** adding a space.- Otherwise, strings are joined with a single space.
This works across quote styles (double and single quotes can be mixed).
{ // These join with spaces (no trailing \n): bio: "A seasoned adventurer from the West." "Known for incredible fashion sense." "Has a pet dragon named Sparky.", // Result: "A seasoned adventurer from the West. Known for incredible fashion sense. Has a pet dragon named Sparky."
// Lines ending with \n concatenate WITHOUT a space: poem: "Roses are red,\n" "Violets are blue,\n" "LPML is awesome,\n" "And so are you.", // Result: "Roses are red,\nViolets are blue,\nLPML is awesome,\nAnd so are you."
// Mixed: \n suppresses the space, no \n adds a space help: "Usage: command [options]\n" "\n" "This command does something useful." "It has multiple paragraphs.\n" "\n" "See 'help topics' for more info.", // Result: "Usage: command [options]\n\nThis command does something useful. It has multiple paragraphs.\n\nSee 'help topics' for more info."}
### Multiline Strings (Source Line Folding)
Actual newlines in the source (pressing Enter) are converted to spaces. Escapesequences like `\n` remain as literal newline characters. This means you writelong strings naturally across source lines without worrying about embeddednewlines.
### File Includes
Values beginning with `#` followed by a path denote file includes.
{ stats: "#./stats.lpml", inventory: "#./inventory.lpml", database: "#./db-config.lpml",}
Rules:- A conforming implementation SHOULD replace the `#path` value with the parsed contents of the referenced file.- File includes are processed recursively (included files may themselves contain includes).- If a file cannot be found, an implementation SHOULD keep the include string as its literal value.- To produce a literal `#` at the start of a string (preventing include processing), escape it: `\#`.
{ color_code: "\#FF0000", // Literal string "#FF0000", not a file include}
## Data Types
### Primitives
{ string: "text", number: 42, float: 3.14, boolean: true, null: null,}
### Arrays
Arrays support homogeneous, mixed-type, and nested elements with trailingcommas:
{ array: [1, 2, 3], mixed: ["string", 42, true, null], nested: [[1, 2], [3, 4]], trailing: [1, 2, 3,],}
### Objects (Mappings)
Objects support nesting and trailing commas:
{ simple: { x: 1, y: 2 }, nested: { stats: { str: 10, dex: 15 }, }, trailing: { a: 1, b: 2, },}
### Special Values
#### Infinity and NaN
`Infinity`, `-Infinity`, and `NaN` are valid values. In LPC, these map to`undefined` (equivalent to `([])[0]`) because LPC does not have nativeInfinity/NaN support.
{ inf: Infinity, neg_inf: -Infinity, nan: NaN,}
#### MAX_INT and MAX_FLOAT
LPC-specific constants that support sign prefixes (`+`/`-`):
{ maxInt: MAX_INT, minInt: -MAX_INT, maxFloat: MAX_FLOAT, minFloat: -MAX_FLOAT,}
### Escape Sequences
Standard JSON escape sequences are supported in strings:
| Escape | Meaning ||--------|---------|| `\"` | Double quote || `\'` | Single quote || `\\` | Backslash || `\/` | Forward slash || `\b` | Backspace || `\f` | Form feed || `\n` | Newline || `\r` | Carriage return || `\t` | Tab || `\uXXXX` | Unicode character || `\#` | Literal `#` (prevents file include processing) |
## Differences from JSON5
| Feature | JSON5 | LPML ||---------|-------|------|| Comments | yes | yes || Trailing commas | yes | yes || Unquoted keys | yes | yes || Spacey keys | no | yes || Single quotes | yes | yes || Hex numbers | yes | yes || Octal/binary numbers | no | yes || MAX_INT/MAX_FLOAT | no | yes || String concatenation | no | yes || File includes | no | yes || Multiline folding | no | yes |
## Formatting Guidelines
- Keep lines within 80 columns. LPML files are MUD configuration data consumed in terminal contexts where 80 columns is the norm.- Break long string concatenation values across multiple lines to stay within the limit.- Break long arrays across multiple lines if they would exceed 80 columns.
## Complete Example
// character.lpml{ name: "Gesslar", title: "Wielder of Sharp Things",
// File includes stats: "#./stats.lpml", inventory: "#./inventory.lpml",
// Spacey keys hit points: 100, max hit points: 120, experience points: 1500,
// String concatenation (space-joined) bio: "A seasoned adventurer from the West." "Known for incredible fashion sense." "Has a pet dragon named Sparky.",
skills: { combat: 85, magic: 60, social: 75, },}
## Item Configuration Example
// cat_fur.lpml{ id: ["fur"], additional ids: ["hide", "piece"], adj: ["cat", "soft"], name: "cat fur", short: "a piece of cat fur", long: "This is a soft piece of fur from a wild cat." "It could be useful for crafting.", mass: 20, material: ["fur"], properties: { autovalue: "yes", crafting material: "yes", },}
## Modular Configuration Example
// main.lpml{ game: { name: "My MUD", port: 4000, database: "#./db-config.lpml", features: "#./features.lpml", discord: "#./discord-config.lpml", },}
// db-config.lpml{ host: "localhost", port: 5432, name: "mud_db", pool_size: 10,}
## Credits
LPML was created by Gesslar, based on the JSON5 specification. Licensed underthe Unlicense (public domain).Fleshing Out Your Skill
Section titled “Fleshing Out Your Skill”The base skill above covers the LPML 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 add to your skill.
Project-Specific Keys
Section titled “Project-Specific Keys”If your project uses a known schema, describe it so the LLM can produce valid files without guessing.
## Project Schema
Our item configuration files use the following structure:
{ id: ["primary_id"], additional ids: ["alias1", "alias2"], adj: ["adjective1", "adjective2"], name: "display name", short: "a short description", long: "A longer description of the item." "Can use string concatenation for readability.", mass: 0, material: ["material_type"], properties: { // Item-specific properties }}Style Preferences
Section titled “Style Preferences”If your project has formatting conventions, state them explicitly.
## Style Preferences
- Always use trailing commas- Use spacey keys for multi-word property names- Use string concatenation for values longer than 72 characters- Add a comment header at the top of each file describing its purpose- Use relative file includes (#./) rather than absolute pathsModular Configuration
Section titled “Modular Configuration”If your project uses file includes to organize configs, describe the expected structure.
## File Organization
Our configuration is split across files using includes:
- main.lpml — Top-level entry point- db-config.lpml — Database connection settings- features.lpml — Feature flags and toggles- discord-config.lpml — Discord integration settings
Each sub-config is included from main.lpml:
{ game: { name: "My MUD", database: "#./db-config.lpml", features: "#./features.lpml", discord: "#./discord-config.lpml", }}