NDL Lexical Elements

Overview

This document defines the lexical elements (tokens, keywords, operators, and literals) that make up the NDL (Natural Description Language) syntax.

Keywords

NDL keywords are reserved action identifiers that have special meaning in the language.

Core Action Keywords

KeywordCategoryDescriptionExample
doActionPrimary action constructordo($"player", "attack")
waitControlPause or wait for conditionwait("response validation")
searchActionSearch for objectssearch("pile of wood")
talkSocialInitiate conversationtalk("Mark", "John")
conveySocialCommunicate message/intentconvey("desire to explore")
targetModifierSpecify action targettarget($"goblin")
resultOutcomeDeclare action outcomeresult("success")
describeOutputTrigger narrative descriptiondescribe()
system_responseMetaSystem-level messagessystem_response("error")
rollMechanicsDice/check resultroll("stealth")
damageMechanicsDamage valuedamage(8)

Properties/Attributes

These are key-value pair identifiers used to add context:

PropertyDescriptionExample
intentionWhy an action is takenintention="test club's combat readiness"
perspectivePoint of view or opinionperspective="adventurous"

Social Dynamics Keywords

NDL has 43+ action types dedicated to social interactions (as of June 2024):

  • Conversation initiation
  • Emotional expression
  • Opinion sharing
  • Relationship management
  • Persuasion attempts
  • Conflict resolution

Note: Full list of social action keywords not fully documented in transcripts, but system tracks 23 exposed states for social interaction.

Operators

Primary Operators

OperatorNamePrecedenceAssociativityDescription
$Entity Reference1PrefixReferences game entities
~Manner Modifier2InfixDescribes how action is performed
=Assignment3InfixAssigns property values
->Sequence4LeftChains actions sequentially
^Conjunction5InfixConnects multiple targets (AND)

Operator Details

$ - Entity Reference Operator

Purpose: Identifies game entities (characters, objects, locations)

Syntax:

$"entity_name"    # Named entity
$                 # Implicit entity (context-dependent)

Examples:

do($"player", "attack")     # Player entity
target($"guard")            # Guard entity
$"you"                      # Second-person reference

~ - Manner Modifier Operator

Purpose: Specifies how an action is performed (method, tool, style)

Syntax:

action ~ "manner_description"

Examples:

do($"player", "attack") ~ "sword"           # Attack with sword
do($"player", "sneak") ~ "carefully"        # Sneak carefully
do($"player", "speak") ~ "menacingly"       # Speak menacingly

Quote from veritasr [04:27]:

”~ (basically with / by)“

= - Assignment Operator

Purpose: Assigns values to properties/attributes

Syntax:

property="value"

Examples:

intention="intimidate"
perspective="adventurous"

-> - Sequence Operator

Purpose: Chains actions in temporal order (left-to-right execution)

Syntax:

action1 -> action2 -> action3

Examples:

do($"player", "attack") -> roll("hit") -> result("success")
search("wood") -> result() -> describe()

Semantics: Each action completes before the next begins. Order is preserved.

^ - Conjunction Operator

Purpose: Connects multiple entities or targets (AND relationship)

Syntax:

entity1 ^ entity2 ^ entity3

Examples:

talk("Mark", "John"^"Sue")    # Mark talks to both John and Sue

Literals

String Literals

Strings are enclosed in double quotes:

"this is a string"
"attack with great force"
"find makeshift club"

Usage:

  • Action descriptions
  • Entity names
  • Property values
  • Messages and dialogue

Escaping: Not explicitly documented, but standard escaping likely applies.

Numeric Literals

Numbers appear in function-like constructs:

damage(8)         # Integer
wait(1s)          # Duration (integer + unit)

Types:

  • Integer: Whole numbers (e.g., 8, 100)
  • Duration: Number + time unit (e.g., 1s, 500ms)

Entity Literals

Entities use the $ prefix with string notation:

$"player"
$"guard"
$"goblin"
$"you"

Delimiters

DelimiterPurposeExample
( )Function/action parametersdo($"player", "attack")
"String boundaries"attack fiercely"
,Parameter separatordo($entity, "action")

Whitespace

Whitespace (spaces, tabs, newlines) is generally ignored except:

  • Within string literals (preserved)
  • As token separators

Comments

Comments are not explicitly documented in the transcripts. Implementation may or may not support comments.

Identifiers

Identifiers follow general programming conventions:

  • Function names: do, wait, search, talk, etc.
  • Property names: intention, perspective, result
  • Entity names: Strings within $"..." notation

Detection Markers

The NDL parser uses these markers to detect NDL syntax:

ndl_markers = ['do(', '->', 'wait(', '~', 'intention=', '$']

Source: veritasr’s implementation (transcript line 31881-31913)

If any of these markers appear in input, it’s likely NDL.

Parse Flags

The parser extracts these flags from NDL input:

FlagTypeDescription
is_ndlbooleanIs input valid NDL?
continue_lastbooleanContinue previous scene?
end_scenebooleanEnd current scene?
transition_scene_typestringTransition type: “time”, “place”, “both”
actionsarrayList of action keywords found

Example Output:

Input String:  do($"you", "write some NDL")->wait("response validation")
is_ndl:  True
continue_last:  False
end_scene:  True
transition_scene_type:  both
Actions:  ['do', 'wait']

Reserved Patterns

TTRPG-Inspired Structure

veritasr [04:24]: “There’s also a sort of recipe on the input, which is the same one you use as a GM for people who don’t know how to play TTRPGs:

  • what (do you do) → do(action)
  • how (do you do it) → ~ manner
  • why (are you doing it) → intention="reason"

This three-part structure is fundamental to NDL’s design philosophy.

Lexical Conventions

  1. Case Sensitivity: Keywords appear to be case-sensitive (lowercase)
  2. Entity References: Always use $ prefix
  3. String Quoting: Always use double quotes "
  4. Operator Spacing: Whitespace around operators is flexible
  5. Chaining: No limit on -> chain length

Implementation Notes

Multi-Model Compatibility

veritasr [04:21]: “And this is all on 8B / 9B LLMs. Nothing that really breaks the bank hardware wise.”

veritasr [18:02]: “NDL works effectively across multiple models. Get’s tricky when there’s back messages, since it sometimes tries to select previous messages, but I’ll be doing it in a multi-step workflow, so that won’t be a problem.”

Models Tested:

  • Gemma (8B/9B)
  • Llama 3 (8B/9B)

Dynamic Vocabulary Growth

veritasr [19:47]: “NDL currently has 43 actions tied to social and is still growing. and 23 different exposed states just tied to social interaction.”

NDL vocabulary continues to expand as new game mechanics are added.


ndl specification lexical syntax