Skip to content

Character Import System — Architecture Overview

Goals

The Character Import System is responsible for ingesting character sheets from multiple formats (XLSX, PDF, image-based PDFs), extracting accurate character data (attributes, modifiers, skills, feats, powers, equipment, etc.), and normalizing it into a strict, verifiable internal schema suitable for downstream use (VTT, rules engine, validation, or editing).

Primary goals:

  • Accuracy over convenience (no silent hallucination of numbers).
  • Deterministic extraction where possible.
  • Clear provenance (where did each value come from).
  • Extensibility to new systems and sheet layouts.
  • Local-first compatibility (cloud optional).

High-Level Architecture

+––––––––––+ | Input Files | | XLSX / PDF / IMG | +———+–––––+ | v +––––––––––+ | Format Detection | | (MIME + heuristics| +———+–––––+ | v +—————————––+ | Extraction Strategy Selector | +———+–––––+–––––+ | | | | v v +––––––––+ +———————–+ | Deterministic | | Vision-Based Extract | | Parsers | | (VLM) | | (XLSX/Text PDF)| | (Scanned / Image PDF)| +––––+—––+ +–––––+————+ | | v v +—————————––+ | Raw Field Candidates | | (key, value, provenance) | +—————+—————+ | v +————————————+ | LLM Normalization & Schema Mapping | +—————+––––––––––+ | v +————————————+ | Validation & Consistency Checks | +—————+––––––––––+ | v +————————————+ | Final Character JSON + Import Log | +————————————+


Format Handling Strategy

1. XLSX (Spreadsheet Character Sheets)

Preferred path: deterministic parsing

Rationale

  • XLSX contains structured data (cells, types, sheets).
  • Deterministic parsing is more accurate, cheaper, and auditable than vision.

Pipeline

  1. Parse XLSX using a native Excel parser.
  2. Extract:
    • Cell coordinates
    • Raw values
    • Sheet names
  3. Convert extracted data into:
    • A flat key → value candidate list
    • Or a table dump with coordinates
  4. Pass extracted data to an LLM only for semantic mapping, not reading.

Example Provenance

{
  "strength": {
    "value": 18,
    "source": "Sheet1!C14"
  }
}


⸻

2. PDF with Selectable Text / Form Fields

Preferred path: deterministic PDF text extraction

Pipeline
	1.	Extract:
	•	Form field values (if fillable)
	•	Text blocks with coordinates
	2.	Preserve:
	•	Page number
	•	Bounding boxes
	3.	Send extracted text to LLM for normalization.

Notes
	•	Layout information is useful but not mandatory if labels are clear.
	•	Avoid OCR if text is selectable.

⸻

3. Scanned PDFs / Image-Heavy PDFs

Preferred path: Vision-Language Model (VLM)

Model Recommendation
	•	Qwen2.5-VL (7B+) for local execution.
	•	Operates on rendered page images.

Pipeline
	1.	Render each PDF page to images.
	2.	Feed images + prompt to VLM:
	•	Extract label/value pairs
	•	Extract tables (skills, spells, equipment)
	•	Return bounding boxes when possible
	3.	Convert vision output into raw field candidates.

Notes
	•	Vision is more compute-intensive.
	•	Accuracy depends on layout clarity and image quality.
	•	Used only when deterministic extraction is not possible.

⸻

LLM Normalization Layer

Purpose

Transform raw field candidates into a strict internal character schema.

Responsibilities
	•	Canonicalize names (e.g., STR, Strength Score, Strength → strength.score)
	•	Resolve system-specific terminology.
	•	Group related fields (e.g., abilities → skills).
	•	Preserve provenance for every value.
	•	Emit confidence scores where ambiguous.

Input

[
  { "label": "STR", "value": "18", "source": "Sheet1!C14" },
  { "label": "Proficiency Bonus", "value": "+3", "source": "Page 1 Box 12" }
]

Output (Strict JSON)

{
  "abilities": {
    "strength": {
      "score": 18,
      "modifier": 4,
      "source": ["Sheet1!C14"]
    }
  },
  "proficiency_bonus": {
    "value": 3,
    "source": ["Page 1 Box 12"]
  }
}


⸻

Validation & Consistency Checks

Purpose

Detect extraction errors before import.

Examples
	•	Ability modifier matches ability score.
	•	Skill bonuses = ability mod + proficiency + misc.
	•	Passive scores match formulas.
	•	Duplicate feats/powers merged correctly.

Output
	•	Errors (blocking)
	•	Warnings (non-blocking)
	•	Auto-corrections (logged)

⸻

Why Not Use Vision for Everything?

Tradeoffs of “Vision-Only” Approach

Issue	Impact
Higher compute cost	Slower & more expensive
Numeric misreads	Lower accuracy
Lost cell provenance	Harder debugging
No data typing	Everything becomes text

Conclusion: Vision is a fallback, not a default.

⸻

Design Principles
	•	Deterministic first, probabilistic last
	•	Never trust an LLM with raw numbers if structure exists
	•	Every value has a source
	•	Validation is mandatory
	•	System-agnostic core, system-specific adapters

⸻

Extensibility
	•	Add new game systems via schema adapters.
	•	Add new sheet layouts via prompt templates.
	•	Support future formats (JSON exports, API-based sheets).
	•	Swap cloud LLMs for local models without pipeline changes.

⸻

Execution Notes for Agent
	•	Implement format detection early.
	•	Keep extraction and normalization separate.
	•	Make schema strict and versioned.
	•	Log everything; assume imports will be debugged.

⸻

Summary

This architecture balances accuracy, performance, and flexibility by:
	•	Using deterministic parsing wherever possible.
	•	Using vision models only when necessary.
	•	Constraining LLMs to semantic interpretation, not raw data reading.
	•	Treating validation as a first-class step.

This minimizes hallucinations while remaining flexible enough to support messy real-world character sheets.