conlang
A partial-spec constructed-language generator.
You describe only what you care about — phonology, syllable shapes, a handful of words — and the generator samples the rest from typologically-plausible defaults. Same spec plus same seed always produces byte-identical output, and sampled entries can be locked so they survive re-sampling.
spec (YAML) ──▶ generate ──▶ model (canonical JSON) ──▶ render ──▶ dictionary + grammar sketch
│
├── lint (machine-checkable invariants)
└── bench (plausibility scorecard vs. Kah)
The model JSON is the single source of truth; the dictionary, grammar sketch, and every other view are rendered from it.
Install
pip install conlanggen
The distribution is conlanggen, but the import package and the command are both
conlang — import conlang, conlang generate.
Quickstart
# Generate from the example spec and render a Markdown dictionary.
conlang generate --spec spec\example.yaml --render
# Happy with it? Freeze it into an explicit spec so the values stick.
conlang accept --model out\veshtari.json
Output lands in out/: a model JSON and a rendered .md. Then:
conlang lint --model out\veshtari.json
conlang render --model out\veshtari.json --out out\veshtari.md
Documentation
- Getting started — install, first language, freeze it.
- Spec reference — every
spec/*.yamlkey. - Feature guide — phonotactics, scripts, data packs, the benchmark,
evolve, and syntax. - The translation pipeline — translate the fixed story end to end.
- Releasing — the Codeberg CI setup and how to cut a release.
- Domain glossary and architecture decisions.
- Stability and the changelog.
Guarantees and lint rules
Reproducibility is the one hard guarantee: spec + seed ⇒ identical bytes.
Everything else is reported by lint as errors or warnings, and a broken
language is still generated (conlangers want to explore broken states).
| rule | severity | meaning |
|---|---|---|
schema |
error/warning | schema version present and known (a recognised older version warns; an unknown one errors) |
lexeme.root |
error | lexeme has a non-empty root |
phonotactics.lexeme |
error | every root is a legal word |
phonotactics.word |
error | every inflected form is a legal word |
lexicon.homophones |
warning | two roots collide (Kah has polysemy too) |
morphology.paradigm |
warning | a word is missing a form for a category its class realises |
morphology.class |
error | a word names an inflection class the language does not define |
lexicon.nonempty |
warning | the lexicon is empty |
orthography.unknown |
warning | the spelling map names a symbol that is not in the inventory |
orthography.collision |
warning | two symbols would spell the same thing |
script.coverage |
warning | the script does not cover every segment/syllable it must |
Every rule above has a test in tests/test_lint.py, tests/test_lint_invariants.py,
or tests/test_morphology.py.
Stability
Starting with 1.0.0, the model schema, the conlang command line, and the Spec
format are stable; within 1.x we make only additive, backwards-compatible changes. See
STABILITY.md for the promise and how deprecation works.
Development
.\.venv\Scripts\python.exe -m pytest
.\.venv\Scripts\python.exe -m ruff check .
.\.venv\Scripts\python.exe -m mypy src
The package layout:
src/conlang/
model/ canonical pydantic schema (the source of truth)
sampling/ deterministic RNG, inventory presets, concepts, defaults
phonology/ tokenization, syllabification, legality checks
lexicon/ seeded root generation, stable per-item seeding
morphology/ affixes, inflection classes, and word-form assembly
soundchange/ ordered sound changes; derive a daughter language
syntax/ word order, alignment, clause linearisation, place structure
script/ writing systems (glyphs)
render/ Markdown dictionary + grammar sketch
lint/ machine-checkable invariants
bench/ Kah adapter + scorecard
cli.py thin command-line view over the library
Roadmap
Shipped so far (1.0 froze the core; 1.1–1.3 add tiers):
- Phonology — inventory, phonotactics, seeded word generation.
- IPA inventories — declare the inventory phonemic (
ipa: true) and derive a romanised orthography alongside the phonemic forms. - Morphology — affix breadth, inflection classes, and stacking.
- Diachrony —
conlang evolve: ordered sound changes (with environments) derive a daughter language, recorded inlineage. - Syntax — sampled word order and alignment, case marking with subject agreement, the predication tier, clause sequencing, and aspect.
- Translation pipeline —
conlang new/grow/translate/validate-translation/extras, including a grammar-match port from a sibling. - Writing systems —
conlang script: a sampled script (alphabet / syllabary / impure abjad / featural) rendered as deterministic SVG glyphs. - Data packs — optional, pinned PHOIBLE and WALS ground sampling (
conlang data fetch), with a graceful fallback to the built-in presets. - Feature-driven phonology — natural classes and feature-based sound-change rules.
- Place structure — an ordered list of semantic roles per predicate; role-labelled clauses.
- Semantics — negation, quantifiers, coordination, and topic/focus markers.
- Complex clauses — relative, complement, and reported clauses.
- Adverbial clauses — causal (because), temporal (when), and conditional (if) adjuncts, positioned by head direction.
- Numerals — a closed digit class that composes cardinals in base 10 (ordered by word
order) and derives ordinals with an
ORDaffix. - Infinitives & quotation — non-finite complements with subject control (an
infmarker before a bare verb) and aquotparticle for direct, verbatim quotation.
Planned after 1.0: formal semantics.
License
MIT (code). Kah dictionary and grammar content remains Kwesho's and is not part of this repository.
Metadata
Release files for conlanggen 1.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| conlanggen-1.3.0.tar.gz | 239.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| conlanggen-1.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 329.3 kB
Release files / conlanggen-1.3.0.tar.gz
| Download URL | conlanggen-1.3.0.tar.gz |
|---|---|
| Size | 239.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5083a85730a489ce80f7ee0a84437c1d8b16db33f0eb1f0acc02a44bc895cc63
|
|
BLAKE2b-256 checksum How to use checksums |
fe21e952dfb75bcc933502bb3c34e585705504abeb8e5a137904918acb808919
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / conlanggen-1.3.0-py3-none-any.whl
| Download URL | conlanggen-1.3.0-py3-none-any.whl |
|---|---|
| Size | 89.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dc3afae35f231696fa17b42ac2477d0863ef2d11805e6523fecfdbb483df84f9
|
|
BLAKE2b-256 checksum How to use checksums |
e5403ef27dfdee6d869131d7098407ba65b35af4a7143abca2fc8cb72ec3eb81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|