Skip to content
UnjouPublic

Repository files navigation

unred

A browser-based Computer-Assisted Translation (CAT) workbench, KAG/Artemis script dumper, and deterministic Latin word-wrapping engine for visual novel localization pipelines.

Runs entirely client-side via Web Workers and IndexedDB, removing the need for local compiler toolchains or desktop dependencies.


Preview

CAT Workbench & Smart Wrapping

Figure 1: Side-by-side script editor with word-boundary ruler and real-time KAG macro injection.

Additional Interface Screenshots

Mojibake & Bytecode Linter

Mojibake QA Inspector

Live Textbox Viewport Simulator

Dialogue Box Preview

Asset Extractor & Patch Compiler

XP3 Patch Builder


Problem Statement

Translating Japanese visual novel scripts into Latin scripts (Indonesian, English) introduces two recurring structural issues:

  1. Glyph vs. Word-Boundary Breaking: Japanese KAG engines format monospaced glyphs and break lines at arbitrary character boundaries. Latin scripts require whitespace word-boundary wrapping. Without explicit line breaks ([r]), target text overflows textbox boundaries or breaks mid-word.
  2. Bytecode Desynchronization (Mojibake): Mismatches between legacy multi-byte encodings (Shift-JIS / CP932) and UTF-8 corrupt engine control macros and dialogue strings.

unred isolates engine control codes, calculates visible character metrics, and injects engine delimiters before scenario recompilation.


Core Capabilities

  • In-Browser Scenario Tokenization: Parses .ks, .txt, and .ast source scripts into isolated dialogue segments while preserving inline engine macros (@bg, @playse, [wait]).
  • Deterministic Latin Word Wrapping: Splits text along whitespace boundaries and injects KAG line-break macros ([r]) at a configurable character threshold (default: 42 characters/line, 3 lines maximum per frame).
  • Macro-Stripped Line Metrics: Filters formatting tags ([ruby], [l], [p]) prior to width calculation to prevent false-positive overflow warnings.
  • Encoding QA & Bytecode Inspector: Detects unbalanced bracket syntax, broken multi-byte sequences (CP932/Shift-JIS desyncs), and character count threshold violations.
  • Memory-Buffered Patch Export: Rebuilds modified scenario files and packages them into .zip archives directly via browser memory.
  • Offline Persistence: Syncs active translation progress and project states using IndexedDB.

Architecture

unred/
├── app/
│   ├── layout.tsx
│   ├── page.tsx               # CAT workbench & word-wrapping interface
│   ├── linter/page.tsx        # Encoding QA & bytecode inspector
│   ├── patch/page.tsx         # Script dumper & patch compiler
│   ├── preview/page.tsx       # Dialogue box canvas simulator
│   └── globals.css
├── components/
│   ├── HeaderNav.tsx          # Project selector and patch build trigger
│   ├── SidebarExplorer.tsx    # File tree and segment filter list
│   ├── CATSegmentRow.tsx      # Side-by-side translation row
│   ├── SmartWrappingPanel.tsx # Boundary guides & macro injection
│   └── LiveVNTextbox.tsx      # Viewport dialogue renderer
├── docs/
│   └── screenshots/           # Documentation visual assets
├── lib/
│   ├── kag-lexer.ts           # Tokenizer and AST parser for KAG
│   ├── word-wrapper.ts        # Latin word-boundary wrapping logic
│   ├── mojibake-detector.ts   # Multi-byte anomaly detection
│   ├── patch-builder.ts       # Browser-based script bundler
│   └── types.ts               # Core type definitions
└── store/
    └── useVNLocStore.ts       # Zustand store with IndexedDB sync

Getting Started

Prerequisites

  • Node.js 18.17 or later
  • npm, pnpm, or yarn

Installation

git clone https://github.com/Unjou/unred.git
cd unred
npm install

Development Server

npm run dev

Open http://localhost:3000 in your browser.

Production Build

npm run build
npm run start

Wrapping Engine Specification

The wrapping pipeline (lib/word-wrapper.ts) operates under the following sequence:

  1. Strips existing auto-generated [r] delimiters and normalizes whitespace sequences.
  2. Isolates engine macro tokens (\[.*?\]) so non-rendered formatting characters do not contribute to line width.
  3. Iterates over whitespace-separated tokens, accumulating words into the current line buffer.
  4. If adding the next word exceeds maxCharsPerLine (default: 42), writes the buffer and appends the engine delimiter ([r]).
  5. Generates an overflow warning if the line count exceeds maxLinesPerBox (default: 3).

License

MIT

Contributors

Languages