diff --git a/README.md b/README.md
index 7eb7b59..8f6e5e6 100644
--- a/README.md
+++ b/README.md
@@ -30,8 +30,9 @@ PS: This is my first public library, then I'm sorry for the lack of knowledge of
- [x] Develop a native objects for csharp
- [x] Migrate last fixes and changes from rivescript-java since jan-2016 (some push a lot)
- [x] Create a RSBot Demo Script (By [Efface Studios](https://github.com/effacestudios/))
+- [x] Create documentation with C4 architecture diagrams and DocFX live documentation
- [ ] Complete test based on rsts
-- [ ] Complete the code documentation and adjust appveyor to build and release on tag
+- [ ] Adjust appveyor to build and release on tag
- [ ] [...]
@@ -44,7 +45,24 @@ PS: This is my first public library, then I'm sorry for the lack of knowledge of
## DOCUMENTATION
-:TODO - C# API documentation
+Full documentation lives in the [`docs/`](./docs/) folder and is served as a [DocFX](https://dotnet.github.io/docfx/) site.
+
+| Section | Description |
+|---|---|
+| [Getting Started](./docs/getting-started.md) | Install and create your first bot |
+| [API Reference](./docs/api/index.md) | Full public API reference |
+| [Architecture — C4 Model](./docs/architecture/index.md) | System Context, Container, Component, and Code diagrams |
+
+### Generating the Live Documentation Site
+
+Install [DocFX](https://dotnet.github.io/docfx/) and run:
+
+```bash
+dotnet tool install -g docfx
+docfx docfx.json --serve
+```
+
+Then open http://localhost:8080 in your browser to browse the documentation.
Also check out the [**RiveScript Community Wiki**](https://github.com/aichaos/rivescript/wiki)
for common design patterns and tips & tricks for RiveScript.
diff --git a/docfx.json b/docfx.json
new file mode 100644
index 0000000..25aadb6
--- /dev/null
+++ b/docfx.json
@@ -0,0 +1,48 @@
+{
+ "metadata": [
+ {
+ "src": [
+ {
+ "files": [ "RiveScript/**.csproj" ],
+ "src": ".."
+ }
+ ],
+ "dest": "docs/api",
+ "disableGitFeatures": false,
+ "disableDefaultFilter": false
+ }
+ ],
+ "build": {
+ "content": [
+ {
+ "files": [ "**/*.{md,yml}" ],
+ "src": "docs",
+ "dest": "."
+ },
+ {
+ "files": [ "docs/api/**.yml", "docs/api/index.md" ]
+ }
+ ],
+ "resource": [
+ {
+ "files": [ "docs/images/**" ]
+ }
+ ],
+ "output": "_site",
+ "globalMetadataFiles": [],
+ "fileMetadataFiles": [],
+ "template": [ "default", "modern" ],
+ "globalMetadata": {
+ "_appTitle": "RiveScript C# — Documentation",
+ "_appName": "RiveScript C#",
+ "_appFooter": "RiveScript C# — MIT License | GitHub",
+ "_enableSearch": true,
+ "_appLogoPath": "",
+ "_appFaviconPath": "",
+ "description": "C# implementation of the RiveScript chatbot scripting language interpreter"
+ },
+ "sitemap": {
+ "baseUrl": "https://fabioravila.github.io/rivescript-csharp"
+ }
+ }
+}
diff --git a/docs/api/index.md b/docs/api/index.md
new file mode 100644
index 0000000..5421a0d
--- /dev/null
+++ b/docs/api/index.md
@@ -0,0 +1,67 @@
+# API Reference
+
+This section documents the complete public API of the **RiveScript C#** library.
+
+---
+
+## Primary Entry Point
+
+| Class | Description |
+|-------|-------------|
+| [`RiveScriptEngine`](RiveScriptEngine.md) | Main interpreter class — load scripts, configure the engine, and get replies |
+| [`Config`](Config.md) | Configuration options passed to the `RiveScriptEngine` constructor |
+| [`ErrorMessages`](ErrorMessages.md) | Customise the error reply strings returned by the engine |
+
+---
+
+## Session Management
+
+| Type | Description |
+|------|-------------|
+| [`ISessionManager`](ISessionManager.md) | Interface for user-session storage backends |
+| [`ConcurrentDictionarySessionManager`](ConcurrentDictionarySessionManager.md) | Default thread-safe in-memory implementation |
+| [`NoOpSessionManager`](NoOpSessionManager.md) | No-op implementation (stateless bots) |
+| [`UserData`](UserData.md) | Per-user variable bag, history, and topic pointer |
+| [`History`](History.md) | Rolling window of the last N input/reply pairs |
+| [`ThawAction`](ThawAction.md) | Enumeration controlling what happens to a thawed session snapshot |
+
+---
+
+## Object Handlers & Macros
+
+| Type | Description |
+|------|-------------|
+| [`IObjectHandler`](IObjectHandler.md) | Interface for language handlers that execute `> object` blocks |
+| [`ISubroutine`](ISubroutine.md) | Minimal single-method interface for a named subroutine |
+| [`DelegateMacro`](DelegateMacro.md) | Wraps a `Func<>` as an `ISubroutine` |
+
+---
+
+## AST (Abstract Syntax Tree)
+
+| Class | Description |
+|-------|-------------|
+| [`Root`](Root.md) | Root of the parsed AST |
+| [`Begin`](Begin.md) | Holds global `!define` data |
+| [`Topic`](Topic.md) | Groups triggers by topic name |
+| [`Trigger`](Trigger.md) | Single `+` pattern with its replies and conditions |
+| [`ObjectMacro`](ObjectMacro.md) | Represents one `> object` block |
+
+---
+
+## Logging
+
+| Type | Description |
+|------|-------------|
+| [`ILogger`](ILogger.md) | Four-level logging interface |
+| [`ConsoleLogger`](ConsoleLogger.md) | Console-based logger |
+| [`EmptyLogger`](EmptyLogger.md) | Silent (no-op) logger (default) |
+
+---
+
+## Enumerations & Constants
+
+| Type | Description |
+|------|-------------|
+| [`ConcatMode`](ConcatMode.md) | Line continuation mode: `NONE`, `NEWLINE`, `SPACE` |
+| [`Constants`](Constants.md) | Library-wide string constants |
diff --git a/docs/architecture/c4-code.md b/docs/architecture/c4-code.md
new file mode 100644
index 0000000..0e47602
--- /dev/null
+++ b/docs/architecture/c4-code.md
@@ -0,0 +1,319 @@
+# C4 Level 4 — Code
+
+The Code (class) diagram shows the key classes, their public members, and relationships inside the **RiveScript C# library**.
+
+> Only the most important public members are shown for clarity.
+
+---
+
+## Core Classes
+
+```mermaid
+classDiagram
+ class RiveScriptEngine {
+ +bool IsErrReply(string reply)
+ +string getVersion()
+ +bool loadFile(string file)
+ +bool loadDirectory(string path)
+ +bool loadDirectory(string path, string[] exts)
+ +bool stream(string code)
+ +bool stream(string[] code)
+ +void sortReplies()
+ +string reply(string username, string message)
+ +bool setGlobal(string name, string value)
+ +string getGlobal(string name)
+ +bool setVariable(string name, string value)
+ +string getVariable(string name)
+ +bool setUservar(string user, string name, string value)
+ +string getUserVar(string user, string name)
+ +bool setSubroutine(string name, ISubroutine sub)
+ +void setHandler(string name, IObjectHandler handler)
+ +ISessionManager getSessionManager()
+ +string currentUser()
+ +ErrorMessages errors
+ }
+
+ class Config {
+ +bool debug
+ +bool utf8
+ +bool strict
+ +bool throwExceptions
+ +bool forceCase
+ +int depth
+ +ConcatMode concat
+ +ILogger logger
+ +ISessionManager sessionManager
+ +ErrorMessages errors
+ +Action~string~ onDebug
+ +string unicodePonctuations
+ +$Config Default
+ +$Config UTF8
+ +$Config Debug
+ +$Config DebugUTF8
+ }
+
+ class ErrorMessages {
+ +string deepRecursion
+ +string replyNotMatched
+ +string replyNotFound
+ +string objectNotFound
+ +$ErrorMessages Default
+ +ErrorMessages AdjustDefaults()
+ }
+
+ RiveScriptEngine --> Config : configured by
+ RiveScriptEngine --> ErrorMessages : uses
+```
+
+---
+
+## Parser & AST
+
+```mermaid
+classDiagram
+ class Parser {
+ +Parser(TopicManager topicManager)
+ +Parser(ParserConfig config, TopicManager topicManager)
+ +Root parse(string filename, string[] code)
+ }
+
+ class ParserConfig {
+ +bool strict
+ +bool utf8
+ +bool forceCase
+ +ConcatMode concat
+ +ILogger logger
+ +$ParserConfig Default
+ }
+
+ class Root {
+ +Begin begin
+ +List~ObjectMacro~ objects
+ +IDictionary~string,Topic~ topics
+ +void addTopic(Topic topic)
+ +void addObject(ObjectMacro obj)
+ }
+
+ class Begin {
+ +IDictionary~string,string~ globals
+ +IDictionary~string,string~ vars
+ +IDictionary~string,string~ subs
+ +IDictionary~string,string~ person
+ +IDictionary~string,ICollection~string~~ arrays
+ }
+
+ class Topic {
+ +string name
+ +bool hasPrevious
+ +ICollection~string~ includes
+ +ICollection~string~ inherits
+ +Trigger getTrigger(string pattern)
+ +void addIncludes(string topic)
+ +void addInherits(string topic)
+ +void sortTriggers()
+ +string[] getTopics()
+ }
+
+ class Trigger {
+ +string pattern
+ +ICollection~string~ reply
+ +ICollection~string~ condition
+ +string redirect
+ +bool hasOwnCode
+ +IDictionary~string,ICollection~string~~ previous
+ }
+
+ class ObjectMacro {
+ +string Name
+ +string Language
+ +List~string~ Code
+ }
+
+ Parser --> ParserConfig : uses
+ Parser ..> Root : produces
+ Root *-- Begin : contains
+ Root *-- "0..*" Topic : contains
+ Root *-- "0..*" ObjectMacro : contains
+ Topic *-- "0..*" Trigger : contains
+```
+
+---
+
+## Topic Manager & Sorting
+
+```mermaid
+classDiagram
+ class TopicManager {
+ +Topic getTopic(string name)
+ +bool exists(string name)
+ +string[] listTopicsName()
+ +IDictionary~string,Topic~ listTopics()
+ +void sortReplies()
+ }
+
+ class SortBuffer {
+ +string[] topics
+ +IDictionary~string,string[]~ thats
+ }
+
+ class SortTrack {
+ +int wildcards
+ +int optionals
+ +int namedWildcards
+ +int wordCount
+ }
+
+ class SortedTriggerEntry {
+ +string trigger
+ +Trigger pointer
+ }
+
+ TopicManager --> "0..*" Topic : manages
+ TopicManager --> SortBuffer : builds
+ SortBuffer --> "0..*" SortedTriggerEntry : contains
+ SortTrack ..> SortedTriggerEntry : helps rank
+```
+
+---
+
+## Session Management
+
+```mermaid
+classDiagram
+ class ISessionManager {
+ <>
+ +UserData init(string username)
+ +void set(string username, string name, string value)
+ +void set(string username, IDictionary~string,string~ vars)
+ +void addHistory(string username, string input, string reply)
+ +void setLastMatch(string username, string trigger)
+ +string get(string username, string name)
+ +UserData get(string username)
+ +IDictionary~string,UserData~ getAll()
+ +string getLastMatch(string username)
+ +History getHistory(string username)
+ +void clear(string username)
+ +void clearAll()
+ +void freeze(string username)
+ +void thaw(string username, ThawAction action)
+ +void remove(string username, string name)
+ }
+
+ class ConcurrentDictionarySessionManager {
+ +UserData init(string username)
+ +void set(...)
+ +UserData get(string username)
+ +void freeze(string username)
+ +void thaw(string username, ThawAction action)
+ }
+
+ class NoOpSessionManager {
+ +UserData init(string username)
+ +void set(...)
+ }
+
+ class UserData {
+ +string username
+ +string lastMatch
+ +History history
+ +void setVariable(string name, string value)
+ +string getVariable(string name)
+ +bool removeVariable(string name)
+ +IDictionary~string,string~ getVariables()
+ +History getHistory()
+ }
+
+ class History {
+ +IList~string~ input
+ +IList~string~ reply
+ +void add(string input, string reply)
+ }
+
+ class ThawAction {
+ <>
+ KEEP
+ THAW
+ DISCARD
+ }
+
+ ISessionManager <|.. ConcurrentDictionarySessionManager : implements
+ ISessionManager <|.. NoOpSessionManager : implements
+ ISessionManager ..> UserData : returns
+ UserData *-- History : contains
+ ISessionManager ..> ThawAction : uses
+```
+
+---
+
+## Object Handlers & Macros
+
+```mermaid
+classDiagram
+ class IObjectHandler {
+ <>
+ +void Load(string name, string[] code)
+ +string Call(string name, RiveScriptEngine rs, string[] args)
+ }
+
+ class CSharpObjectHandler {
+ +void Load(string name, string[] code)
+ +string Call(string name, RiveScriptEngine rs, string[] args)
+ +void AddSubroutine(string name, ISubroutine sub)
+ }
+
+ class ISubroutine {
+ <>
+ +string Call(RiveScriptEngine rs, string[] args)
+ }
+
+ class DelegateMacro {
+ +DelegateMacro(Func~RiveScriptEngine,string[],string~ func)
+ +string Call(RiveScriptEngine rs, string[] args)
+ }
+
+ IObjectHandler <|.. CSharpObjectHandler : implements
+ CSharpObjectHandler --> "0..*" ISubroutine : hosts named
+ ISubroutine <|.. DelegateMacro : implements
+```
+
+---
+
+## Logging
+
+```mermaid
+classDiagram
+ class ILogger {
+ <>
+ +bool IsDebugEnable
+ +bool IsWarnEnable
+ +bool IsTraceEnable
+ +bool IsErrorEnable
+ +void Debug(string text)
+ +void Warn(string text)
+ +void Warn(string text, string filename, int lineno)
+ +void Error(string text)
+ +void Error(Exception exception)
+ +void Trace(string text)
+ }
+
+ class ConsoleLogger {
+ +void Debug(string text)
+ +void Warn(string text)
+ +void Error(string text)
+ +void Trace(string text)
+ }
+
+ class EmptyLogger {
+ +void Debug(string text)
+ +void Warn(string text)
+ +void Error(string text)
+ +void Trace(string text)
+ }
+
+ ILogger <|.. ConsoleLogger : implements
+ ILogger <|.. EmptyLogger : implements
+```
+
+---
+
+[← Component Diagram](c4-component.md) | [Architecture Overview ↑](index.md)
diff --git a/docs/architecture/c4-component.md b/docs/architecture/c4-component.md
new file mode 100644
index 0000000..2560f6d
--- /dev/null
+++ b/docs/architecture/c4-component.md
@@ -0,0 +1,137 @@
+# C4 Level 3 — Component
+
+The Component diagram zooms into the **RiveScriptEngine** and the supporting subsystems to show the key classes and their responsibilities.
+
+```mermaid
+C4Component
+ title Component Diagram — RiveScript C# Library (RiveScript.dll)
+
+ Container_Boundary(engine_b, "RiveScriptEngine") {
+ Component(rse, "RiveScriptEngine", "Public API Class", "Exposes loadFile(), stream(), sortReplies(), reply(), setUservar(), etc.")
+ Component(config, "Config", "POCO", "Holds all startup options: debug, utf8, strict, depth, sessionManager, logger, etc.")
+ Component(errorMessages, "ErrorMessages", "POCO", "Customisable reply strings for deep-recursion, not-found, etc.")
+ }
+
+ Container_Boundary(parser_b, "Parser Subsystem") {
+ Component(parser, "Parser", "Class", "Tokenises RiveScript source line by line and produces an AST Root object")
+ Component(parserConfig, "ParserConfig", "POCO", "strict, utf8, forceCase, concat settings for the parser")
+ Component(ast_root, "Root (AST)", "Class", "Root of the parsed AST — holds Begin data and ObjectMacros")
+ Component(ast_begin, "Begin (AST)", "Class", "Holds !global, !var, !sub, !person, !array definitions")
+ Component(ast_topic, "Topic (AST)", "Class", "Holds all triggers for one topic")
+ Component(ast_trigger, "Trigger (AST)", "Class", "One + trigger with its replies, conditions, redirects, and %Previous")
+ Component(ast_macro, "ObjectMacro (AST)", "Class", "Holds code for an embedded > object ... < object block")
+ }
+
+ Container_Boundary(topic_b, "Topic Subsystem") {
+ Component(topicMgr, "TopicManager", "Class", "Registry of all Topic instances; orchestrates inheritance / includes resolution")
+ Component(sortBuffer, "SortBuffer", "Class", "Per-topic sorted trigger array produced by sortReplies()")
+ Component(sortTrack, "SortTrack", "Class", "Tracks sort weight for each trigger during sort phase")
+ }
+
+ Container_Boundary(session_b, "Session Subsystem") {
+ Component(iSession, "ISessionManager", "Interface", "Contract for user session storage")
+ Component(concSession, "ConcurrentDictionarySessionManager", "Default Impl", "Thread-safe in-memory session store")
+ Component(noopSession, "NoOpSessionManager", "Impl", "No-op implementation (useful for stateless bots)")
+ Component(userData, "UserData", "Class", "Per-user bag of variables, history, frozen snapshot, and current topic")
+ Component(history, "History", "Class", "Rolling window of last N inputs and replies for a user")
+ }
+
+ Container_Boundary(macro_b, "Object Handler Subsystem") {
+ Component(iHandler, "IObjectHandler", "Interface", "Contract for loading and calling embedded code objects")
+ Component(csharpHandler, "CSharpObjectHandler", "Default Impl", "Compiles and executes C# snippets embedded in .rive scripts")
+ Component(iSubroutine, "ISubroutine", "Interface", "Single-method contract for a named subroutine callable from scripts")
+ Component(delegateMacro, "DelegateMacro", "Impl", "Wraps a C# Func<> as an ISubroutine")
+ }
+
+ Container_Boundary(log_b, "Logging") {
+ Component(iLogger, "ILogger", "Interface", "Debug/Info/Warn/Error logging contract")
+ Component(consoleLogger, "ConsoleLogger", "Impl", "Writes to Console.WriteLine")
+ Component(emptyLogger, "EmptyLogger", "Impl", "Discards all log calls (default)")
+ }
+
+ Rel(rse, config, "Configured by")
+ Rel(rse, parser, "Delegates script loading to")
+ Rel(rse, topicMgr, "Queries trigger matches from")
+ Rel(rse, iSession, "Reads/writes user data via")
+ Rel(rse, iHandler, "Calls macro code via")
+ Rel(rse, iLogger, "Logs via")
+ Rel(parser, parserConfig, "Uses settings from")
+ Rel(parser, ast_root, "Produces")
+ Rel(ast_root, ast_begin, "Contains")
+ Rel(ast_root, ast_topic, "Contains many")
+ Rel(ast_root, ast_macro, "Contains many")
+ Rel(ast_topic, ast_trigger, "Contains many")
+ Rel(topicMgr, ast_topic, "Manages")
+ Rel(topicMgr, sortBuffer, "Builds and caches")
+ Rel(sortBuffer, sortTrack, "Uses during sort")
+ Rel(iSession, userData, "Returns")
+ Rel(userData, history, "Contains")
+ Rel(concSession, iSession, "Implements")
+ Rel(noopSession, iSession, "Implements")
+ Rel(csharpHandler, iHandler, "Implements")
+ Rel(delegateMacro, iSubroutine, "Implements")
+ Rel(csharpHandler, iSubroutine, "Hosts named")
+ Rel(consoleLogger, iLogger, "Implements")
+ Rel(emptyLogger, iLogger, "Implements")
+```
+
+## Component Descriptions
+
+### RiveScriptEngine Boundary
+
+| Component | Description |
+|---|---|
+| `RiveScriptEngine` | The sole public entry-point. Coordinates all subsystems. |
+| `Config` | Immutable (or default) options passed at construction time. |
+| `ErrorMessages` | Override the reply strings returned on known error conditions. |
+
+### Parser Subsystem
+
+| Component | Description |
+|---|---|
+| `Parser` | Reads source lines, recognises command symbols (`+`, `-`, `^`, `@`, `*`, `>`, `<`, `!`, `%`), and builds the AST. |
+| `ParserConfig` | Carries parser-specific settings derived from the top-level `Config`. |
+| `Root` | Tree root; holds the global `Begin` node, all `Topic` nodes, and `ObjectMacro` nodes. |
+| `Begin` | Stores `! global`, `! var`, `! sub`, `! person`, and `! array` definitions. |
+| `Topic (AST)` | An AST node that groups triggers by topic name. |
+| `Trigger` | An AST node for one `+` pattern together with its replies, conditions, and redirects. |
+| `ObjectMacro` | An AST node for one `> object` block, carrying its language name and code lines. |
+
+### Topic Subsystem
+
+| Component | Description |
+|---|---|
+| `TopicManager` | Central registry. Resolves `includes` and `inherits` links between topics and drives sorting. |
+| `SortBuffer` | Holds the sorted trigger array for one topic after `sortReplies()` is called. |
+| `SortTrack` | Accumulates weighting metrics (word count, wildcards) for each trigger during the sort pass. |
+
+### Session Subsystem
+
+| Component | Description |
+|---|---|
+| `ISessionManager` | Plug-in interface for user-data storage. |
+| `ConcurrentDictionarySessionManager` | Default, thread-safe, in-memory implementation. |
+| `NoOpSessionManager` | Ignores all writes; useful for stateless or read-only scenarios. |
+| `UserData` | Holds a user's variables map, current topic, history, and frozen snapshot. |
+| `History` | Rolling buffer of the last N (default 9) input/reply pairs for a user. |
+
+### Object Handler Subsystem
+
+| Component | Description |
+|---|---|
+| `IObjectHandler` | Interface that all language handlers must implement (`Load`, `Call`). |
+| `CSharpObjectHandler` | Default handler; compiles and caches C# macro code with Roslyn/CodeDOM. |
+| `ISubroutine` | Minimal interface for a single named subroutine. |
+| `DelegateMacro` | Bridges a `Func` to `ISubroutine`. |
+
+### Logging
+
+| Component | Description |
+|---|---|
+| `ILogger` | Four-level (`Debug`, `Info`, `Warn`, `Error`) logging interface. |
+| `ConsoleLogger` | Writes all log events to `Console.WriteLine`. |
+| `EmptyLogger` | Default; silently discards all log events. |
+
+---
+
+[← Container Diagram](c4-container.md) | [Code Diagram →](c4-code.md)
diff --git a/docs/architecture/c4-container.md b/docs/architecture/c4-container.md
new file mode 100644
index 0000000..9325d7f
--- /dev/null
+++ b/docs/architecture/c4-container.md
@@ -0,0 +1,52 @@
+# C4 Level 2 — Container
+
+The Container diagram zooms into the **RiveScript C# Library** and shows the high-level deployable / runnable units.
+
+> For a library project a "container" is the assembly itself plus the external assets it works with.
+
+```mermaid
+C4Container
+ title Container Diagram — RiveScript C# Library
+
+ Person(developer, "Application Developer")
+
+ System_Boundary(lib, "RiveScript C# Library (RiveScript.dll)") {
+ Container(engine, "RiveScriptEngine", "C# Class", "Primary entry-point. Loads scripts, exposes reply() API, manages bot state")
+ Container(parser, "Parser", "C# Class", "Lexes and parses RiveScript source into an AST")
+ Container(topicMgr, "TopicManager", "C# Class", "Stores and indexes topics, triggers, and sort buffers")
+ Container(sessionMgr, "SessionManager", "C# Interface + Impl", "Manages per-user variables, history, and topic state")
+ Container(objectHandler, "ObjectHandler", "C# Interface + Impl", "Executes embedded code macros inside scripts")
+ Container(sorting, "Sorting Engine", "C# Classes", "Sorts triggers by specificity for accurate matching")
+ }
+
+ System_Ext(scripts, "RiveScript Scripts (.rive/.rs)", "Plain-text conversation rules")
+ System_Ext(externalStore, "External Session Store", "Optional: database, Redis, etc.")
+
+ Rel(developer, engine, "Creates and configures", "new RiveScriptEngine(config)")
+ Rel(developer, engine, "Calls", "loadFile() / stream() / reply()")
+ Rel(engine, parser, "Delegates script loading to")
+ Rel(parser, topicMgr, "Populates")
+ Rel(engine, topicMgr, "Queries for matching triggers")
+ Rel(engine, sessionMgr, "Reads/writes user session data")
+ Rel(engine, objectHandler, "Invokes embedded code macros via")
+ Rel(engine, sorting, "Calls sortReplies() on")
+ Rel(parser, scripts, "Reads")
+ Rel(sessionMgr, externalStore, "Optionally persists to", "custom ISessionManager impl")
+
+ UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
+```
+
+## Container Descriptions
+
+| Container | Technology | Responsibility |
+|---|---|---|
+| **RiveScriptEngine** | C# class | Main public API. Orchestrates loading, sorting, and reply generation |
+| **Parser** | C# class | Tokenises `.rive` source and builds the AST (`Root`, `Begin`, `Topic`, `Trigger`) |
+| **TopicManager** | C# class | In-memory store of all topics and their triggers; produces sorted lookup tables |
+| **SessionManager** | C# interface (`ISessionManager`) + default impl | Stores per-user variables, conversation history, and current topic |
+| **ObjectHandler** | C# interface (`IObjectHandler`) + default C# impl | Executes code defined in `> object … < object` blocks |
+| **Sorting Engine** | C# utility classes | Ranks triggers by word-count and specificity so the best match wins |
+
+---
+
+[← System Context](c4-context.md) | [Component Diagram →](c4-component.md)
diff --git a/docs/architecture/c4-context.md b/docs/architecture/c4-context.md
new file mode 100644
index 0000000..904f982
--- /dev/null
+++ b/docs/architecture/c4-context.md
@@ -0,0 +1,38 @@
+# C4 Level 1 — System Context
+
+The System Context diagram shows the **RiveScript C# library** in relation to its users and the external artefacts it depends on.
+
+```mermaid
+C4Context
+ title System Context — RiveScript C# Interpreter
+
+ Person(developer, "Application Developer", "Builds a .NET application that needs a chatbot")
+
+ System(rivescript, "RiveScript C# Library", "Interprets RiveScript scripts and returns replies for user messages")
+
+ System_Ext(scripts, "RiveScript Scripts (.rive/.rs)", "Plain-text script files that define the bot's conversation rules")
+ System_Ext(hostApp, "Host Application", "Any .NET app: web API, desktop, console, service, etc.")
+ System_Ext(sessionStore, "Session Storage", "Optional external storage for user session data (e.g., database, Redis)")
+
+ Rel(developer, hostApp, "Builds and runs")
+ Rel(hostApp, rivescript, "Uses", "calls loadFile/stream, reply()")
+ Rel(developer, scripts, "Authors", "writes .rive files")
+ Rel(rivescript, scripts, "Reads and parses")
+ Rel(rivescript, sessionStore, "Reads / writes user vars", "via ISessionManager (optional)")
+
+ UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
+```
+
+## Description
+
+| Actor / System | Role |
+|---|---|
+| **Application Developer** | Authors `.rive` script files and integrates the library into a .NET application |
+| **RiveScript C# Library** | The core system — parses scripts, matches user input to triggers, and returns replies |
+| **RiveScript Scripts** | Plain-text `.rive` / `.rs` files that define conversation rules |
+| **Host Application** | Any .NET application (web API, console, desktop, background service) that embeds the library |
+| **Session Storage** | Optional external store for user variables/history; defaults to an in-memory `ConcurrentDictionary` |
+
+---
+
+[← Architecture Overview](index.md) | [Container Diagram →](c4-container.md)
diff --git a/docs/architecture/index.md b/docs/architecture/index.md
new file mode 100644
index 0000000..da25a2f
--- /dev/null
+++ b/docs/architecture/index.md
@@ -0,0 +1,31 @@
+# Architecture — C4 Model
+
+This section describes the architecture of the **RiveScript C#** library using the [C4 model](https://c4model.com/).
+The C4 model provides four levels of abstraction: **Context**, **Container**, **Component**, and **Code**.
+
+---
+
+## Contents
+
+| Level | Description |
+|-------|-------------|
+| [Level 1 — System Context](c4-context.md) | Who uses the library and what external things it interacts with |
+| [Level 2 — Container](c4-container.md) | High-level building blocks of the system |
+| [Level 3 — Component](c4-component.md) | Key components inside the library |
+| [Level 4 — Code](c4-code.md) | Class-level design of the core components |
+
+---
+
+## Architecture Overview
+
+RiveScript C# is a **single-assembly .NET library** (`RiveScript.dll`). It:
+
+- Reads `.rive` / `.rs` script files (or streamed strings)
+- Parses them into an in-memory Abstract Syntax Tree (AST)
+- Sorts and indexes the triggers for efficient matching
+- Responds to user messages by matching triggers and evaluating replies
+- Manages per-user session data through a pluggable `ISessionManager`
+- Allows embedding of C# code inside scripts via `IObjectHandler` / `ISubroutine`
+
+The library is designed to be embedded directly into any .NET application —
+desktop, web, mobile, or service — without any external dependencies.
diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 0000000..fda21e4
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,224 @@
+# Getting Started
+
+This guide walks you through installing the library and building your first chatbot.
+
+---
+
+## Installation
+
+### Via NuGet (recommended)
+
+```bash
+dotnet add package RiveScript
+```
+
+Or in the NuGet Package Manager Console:
+
+```powershell
+Install-Package RiveScript
+```
+
+### From Source
+
+```bash
+git clone https://github.com/fabioravila/rivescript-csharp.git
+cd rivescript-csharp
+# Build with Visual Studio or MSBuild
+msbuild RiveScript.sln /p:Configuration=Release
+```
+
+---
+
+## Creating Your First Bot
+
+### 1 — Create a RiveScript Engine
+
+```csharp
+using RiveScript;
+
+// Default engine (strict mode, no debug, UTF-8 disabled)
+var rs = new RiveScriptEngine();
+
+// Or with custom options
+var rs = new RiveScriptEngine(new Config
+{
+ debug = false,
+ utf8 = true,
+ strict = true,
+ depth = 50
+});
+```
+
+### 2 — Load RiveScript Content
+
+There are three ways to load script content into the engine:
+
+**a) Load a single file**
+
+```csharp
+rs.loadFile("brain/greetings.rive");
+```
+
+**b) Load an entire directory**
+
+```csharp
+rs.loadDirectory("brain/"); // loads all .rive and .rs files
+rs.loadDirectory("brain/", new[] { ".rive" }); // custom extension filter
+```
+
+**c) Stream a string directly (great for tests)**
+
+```csharp
+rs.stream(@"
+ + hello
+ - Hi there!
+
+ + goodbye
+ - Bye bye!
+");
+```
+
+### 3 — Sort Replies
+
+After loading all scripts, call `sortReplies()` **once** before the first `reply()` call.
+This builds the internal sort buffers for accurate trigger matching.
+
+```csharp
+rs.sortReplies();
+```
+
+### 4 — Get a Reply
+
+```csharp
+string answer = rs.reply("user123", "hello");
+Console.WriteLine(answer); // Hi there!
+```
+
+---
+
+## RiveScript Syntax Cheat-Sheet
+
+| Symbol | Meaning | Example |
+|--------|---------|---------|
+| `!` | Define | `! var name = Aiden` |
+| `+` | Trigger | `+ hello bot` |
+| `-` | Reply | `- Hello, human!` |
+| `^` | Continue (multi-line reply) | `^ More text here` |
+| `@` | Redirect | `@ greetings` |
+| `%` | Previous | `% what is your name` |
+| `*` | Condition | `* > 18 => You are an adult.` |
+| `>` | Label (topic/object) | `> topic mytopic` |
+| `<` | End label | `< topic` |
+
+---
+
+## Configuration Reference
+
+| Property | Type | Default | Description |
+|----------|------|---------|-------------|
+| `debug` | `bool` | `false` | Enable debug logging |
+| `strict` | `bool` | `true` | Strict parse mode — throw on invalid syntax |
+| `utf8` | `bool` | `false` | Enable UTF-8 mode (allows Unicode in triggers) |
+| `depth` | `int` | `50` | Maximum recursion depth for reply redirections |
+| `forceCase` | `bool` | `false` | Force lowercase on all triggers and user input |
+| `concat` | `ConcatMode` | `NONE` | Line continuation mode (`NONE`, `NEWLINE`, `SPACE`) |
+| `throwExceptions` | `bool` | `false` | Throw `RiveScriptException` instead of returning error strings |
+| `logger` | `ILogger` | `EmptyLogger` | Inject a custom logger |
+| `sessionManager` | `ISessionManager` | `ConcurrentDictionarySessionManager` | Custom session storage |
+| `errors` | `ErrorMessages` | `ErrorMessages.Default` | Customise error reply strings |
+
+---
+
+## Topics
+
+Topics let you group triggers and create context-aware conversations:
+
+```rivescript
+> topic greetings
+
+ + hello
+ - Hi! How can I help you today?
+
+ + bye
+ - Goodbye! {topic=random}
+
+< topic
+```
+
+Switch a user to a topic programmatically:
+
+```csharp
+rs.setUservar("user123", "topic", "greetings");
+```
+
+---
+
+## Object Macros (Embedded C#)
+
+You can embed C# code directly in `.rive` scripts:
+
+```rivescript
+> object add csharp
+ int a = int.Parse(args[0]);
+ int b = int.Parse(args[1]);
+ return (a + b).ToString();
+< object
+
++ add [*] and [*]
+- The sum is: add
+```
+
+Or register a subroutine from C#:
+
+```csharp
+rs.setSubroutine("greet", new DelegateMacro((engine, args) =>
+{
+ return $"Hello, {args[0]}!";
+}));
+```
+
+---
+
+## Custom Session Manager
+
+Implement `ISessionManager` to store user data in a database, Redis, or any other backend:
+
+```csharp
+public class MySessionManager : ISessionManager
+{
+ // Implement all interface members ...
+}
+
+var rs = new RiveScriptEngine(new Config
+{
+ sessionManager = new MySessionManager()
+});
+```
+
+---
+
+## Error Handling
+
+By default the engine returns error strings (e.g. `"ERR: Deep Recursion"`) instead of throwing.
+You can check for errors with:
+
+```csharp
+if (rs.IsErrReply(reply))
+{
+ // handle error
+}
+```
+
+Or enable exception throwing:
+
+```csharp
+var rs = new RiveScriptEngine(new Config { throwExceptions = true });
+```
+
+---
+
+## Next Steps
+
+- [API Reference](api/index.md) — full API documentation
+- [Architecture](architecture/index.md) — C4 diagrams and design overview
+- [RiveScript Community Wiki](https://github.com/aichaos/rivescript/wiki)
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..16c8800
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,69 @@
+# RiveScript C# — Documentation
+
+[](https://ci.appveyor.com/project/fabioravila/rivescript-csharp/branch/master)
+[](../LICENSE)
+
+## What is RiveScript C#?
+
+**RiveScript C#** is a C# implementation of the [RiveScript](http://www.rivescript.com/) scripting language interpreter. RiveScript is a simple scripting language for authoring chatbots and gives you a simple, yet powerful, way to define conversational flows.
+
+This library implements the [RiveScript 2.0 Working Draft](http://www.rivescript.com/wd/RiveScript.html) and was initially developed based on the official [rivescript-java](https://github.com/aichaos/rivescript-java) interpreter.
+
+---
+
+## Contents
+
+| Section | Description |
+|---|---|
+| [Getting Started](getting-started.md) | Install and create your first bot in minutes |
+| [API Reference](api/index.md) | Full public API reference for `RiveScriptEngine` and related types |
+| [Architecture](architecture/index.md) | C4 architecture diagrams and design overview |
+
+---
+
+## Quick Example
+
+```csharp
+using RiveScript;
+
+// Create an engine instance
+var rs = new RiveScriptEngine();
+
+// Load script from a string
+rs.stream(@"
+ + hello bot
+ - Hello, human!
+
+ + what is your name
+ - My name is Aiden.
+");
+
+// Sort replies (required before first call to reply())
+rs.sortReplies();
+
+// Get a reply
+string answer = rs.reply("localuser", "hello bot");
+Console.WriteLine(answer); // → Hello, human!
+```
+
+---
+
+## Key Features
+
+- **RiveScript 2.0** compliant interpreter
+- **UTF-8** support for multilingual bots
+- **Topic inheritance & includes** for modular scripts
+- **Wildcards & alternations** in triggers
+- **Conditionals** (`*condition - reply`)
+- **Substitutions** (input and person substitutions)
+- **Object macros** — embed C# code inside `.rive` scripts
+- **Custom session managers** (in-memory by default; implement `ISessionManager` for custom storage)
+- **Thread-safe** design using `ThreadLocal` user context
+- **Configurable** via the `Config` class
+
+---
+
+## Community & Support
+
+- [RiveScript Community Wiki](https://github.com/aichaos/rivescript/wiki)
+- [GitHub Issues](https://github.com/fabioravila/rivescript-csharp/issues)
diff --git a/docs/toc.yml b/docs/toc.yml
new file mode 100644
index 0000000..00fabef
--- /dev/null
+++ b/docs/toc.yml
@@ -0,0 +1,19 @@
+- name: Home
+ href: index.md
+- name: Getting Started
+ href: getting-started.md
+- name: API Reference
+ href: api/index.md
+- name: Architecture (C4)
+ href: architecture/index.md
+ items:
+ - name: Overview
+ href: architecture/index.md
+ - name: L1 — System Context
+ href: architecture/c4-context.md
+ - name: L2 — Container
+ href: architecture/c4-container.md
+ - name: L3 — Component
+ href: architecture/c4-component.md
+ - name: L4 — Code
+ href: architecture/c4-code.md