Add comprehensive design and specification documentation (#1)

* Write the Unreal documentation set: design, steps, ideas, decisions and specs

Rewrites the design and engineering docs of the two earlier Unity projects
(Adventurer Guild, Project Malleable) for an Unreal Engine 5 prototype that
builds and proves three things in order: a movement controller, fighting and
crafting. Neither earlier core loop is carried; their ideas are catalogued as
features with what each needs.

- Docs/Design.md: the human summary (pillars, fixed decisions, glossary)
- Docs/Steps.md: a ladder of fifteen proofs, the first six in full
- Docs/Ideas.md: salvaged ideas from both projects, none scheduled
- Docs/Decisions.md: D-01..D-36, open decisions OD-01..OD-08, deferrals
- Docs/Spec/: notation, Architecture, Movement, Interaction, Combat,
  Crafting, Networking, Telemetry, UI, written as Unreal C++ skeletons
- CLAUDE.md and README.md for the repository


* Add the stat block: one attribute set on every body, every influence an effect

Every body (player, enemy, NPC) carries the same UStatBlockAttributeSet, and
every outside influence on it is a gameplay effect: base values, buffs,
debuffs, ground surfaces, carried weight, gear, being downed. Counters are
tags and attributes on the receiver: immunity blocks by tag, resistance
scales by attribute, cleanse removes by tag. Same status from several
sources: strongest wins; different statuses multiply.

- Docs/Spec/Stats.md: the block, effects and their five sources (abilities,
  areas, surfaces, items, the world), stacking, counters, readers, tests
- Movement: the movement component's tagged speed-multiplier map is removed;
  speed is tuning times the MoveSpeed attribute; the ground surface trace
  turns mud into an effect; the gym gets mud and ice patches
- Combat: the attribute set moves to Stats; enemies and kits carry
  FStatBlockDefaults; the funnel reads MagicResist and Immune.Damage tags;
  taunt and mark are statuses
- Interaction: carried weight is GE_Encumbered against CarryCapacity
- Crafting: class bonuses are the WorkSpeed and WorkQuality attributes;
  enchantments may grant a holder effect
- Steps: step 5 builds the block with mud, a volume and an immunity
- Decisions D-37 and D-38; design summary, CLAUDE.md, indexes, worklog
This commit is contained in:
2026-09-15 17:54:00 +03:00
committed by GitHub
parent abac63da16
commit 0e61a77346
18 changed files with 4026 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
# Design
A fantasy world you move through, fight in and craft for. This project builds those three things, in that order,
and proves each one feels right before anything is built around it. There is no game loop yet, no economy, no
hall, no dungeon, and no roadmap that says when there will be. The world this is headed for is large, persistent
and shared, so nothing built now may assume otherwise; and nothing built now needs to be that yet.
This is the human summary. The specifications an implementer works from are in [`Spec/`](Spec/README.md), the
order of work is in [`Steps.md`](Steps.md), and the ideas carried over from the two earlier projects but not yet
built are in [`Ideas.md`](Ideas.md).
## The three things
Each has a rejection clause, because a pillar that never rules anything out is decoration.
| | What it means | What we say no to |
| --- | --- | --- |
| **Move** | A body that feels good to walk, run, jump and look with, in first or third person, on a server that has the final say. Proved in a level made of nothing but movement problems, against a written checklist, with a person at the keyboard. | Movement the client owns. Movement tuned once against one enemy and never written down. A camera the server has to know about. A speed number that lives anywhere but the stat block. |
| **Fight** | Melee that lands where the animation says, one funnel every point of damage goes through, enemies with a readable tell, classes with a signature nobody else can have, and going down before dying so a friend can pick you up. | Friendly fire. A second damage path. A class that is a stat block. An ability that writes health directly. |
| **Craft** | Items assembled from pieces, each with a shape, a substance and an ornament; a name and a quality derived from what you put in, never picked from a list; hands-on station work where skill raises the ceiling and never gates the floor; and a crafted sword that is a sword when you swing it. | Recipes. Stacks. A minigame you can fail. A crafting system that does not know combat exists. |
The order is the dependency: fighting needs a body, crafting needs something to make weapons for. It is also the
risk order. The controller is the cheapest thing to get wrong and the most expensive to fix late.
## Fixed decisions
Settled, with the reason, so nobody relitigates them in month four. The full log with ids is
[`Decisions.md`](Decisions.md).
| Decision | Why |
| --- | --- |
| **Unreal Engine 5, C++ first** | The engine's native answers (subsystems, Gameplay Ability System, Gameplay Tags, character movement, replication) are the systems the earlier projects hand-built in Unity. Blueprints compose and tune; they never hold a rule. |
| **The server decides, always** | Every mutation is validated on the authority; the client predicts only its own body and its own animation. The dedicated server is the real target; standalone and listen-server are dev conveniences. This is the one posture that stays right as the world grows. |
| **One funnel per consequence** | All damage through one execution, all interactions through one service, all activity quality through one result. A second path is where rules quietly diverge. |
| **One stat block, and everything is an effect on it** | Every body, player or not, carries the same set of numbers. Mud, a debuff, a buff, a heavy crate, gear and a class's base values are all effects on that set, so anything that can affect one body affects every body, and a counter (immunity, resistance, cleanse) works against every source at once. No system keeps a number of its own. |
| **Rules are pure and shared** | A preview and the real thing call the same function. Preview and reality cannot disagree, and the same rules run headless on a server and in a test. |
| **Content is data, addressed by tag** | A new sword, enemy or substance is an asset. Strings never identify anything. |
| **One rig, two cameras** | First and third person on the same mannequin; the camera is presentation and never touches the simulation. Which is the default is decided by playing, not arguing. |
| **Bonuses, never locks** | Class, level and gear change speed, quality and numbers. They never change what a station accepts or what an assembly permits, and never grant another class's signature. |
| **Solo is a gate, not a mode** | Every rule is checked against one player. Where it costs a solo player, the doc names the knob. |
| **Telemetry from the first line** | Events into a no-op sink from step 2. The questions this prototype exists to answer are distributions over sessions, and sessions that never emitted are gone. |
| **A player is an identity, not a body** | Class, progression and discoveries live on the player state and behind a persistence seam, never on the character actor. A body is a thing the world lends you. |
| **Steps, not a roadmap** | Work is a ladder of small proofs. The next few steps are concrete; the rest are sketched and get detailed when reached. |
## How the work runs
[`Steps.md`](Steps.md) is a numbered ladder. Each step says what exists afterwards that did not before, links the
spec section that defines it, and states what proves it done: a test passes, a checklist is ticked, a person
performs an action. "Implemented" never closes a step. The first steps are written in full; later ones are
sketches that are detailed only when the step before them closes, because a plan written fifteen steps ahead is
a roadmap with a different name.
A step that turns out wrong in the building corrects its spec in the same change, under a "what was built, and
where it differs" heading, so the next reader is not misled by the sketch. Decisions go in the log the moment they
are made. The worklog gets one terse line per step closed or wall hit.
## What this is not, yet
Named so that scope drift has to be a decision rather than an accident.
- **Not a vertical slice.** There is no loop to prove. There are three feels to prove.
- **Not an economy.** No gold, no customers, no orders, no shop. Substances are spawned by a cheat.
- **Not a place.** One test level. No hall, no town, no generated dungeon.
- **Not a progression.** No upgrades, no reputation, no skill trees. Classes exist as kits with two abilities.
- **Not social infrastructure.** No lobbies, no invitations, no voice. Two clients and a server in the editor.
- **Not player versus player.** The damage funnel discards it. Players can inconvenience each other; they cannot
hurt each other.
Every one of these has a home in [`Ideas.md`](Ideas.md) with what it would need and what it must not break.
## Tone and look
Stylised, chunky, readable at a glance. The placeholder is the engine's mannequin in a greybox gym with a plain
white HUD; the two earlier projects each had a finished palette and neither is this game's, so an art direction
decides when there is one. Until then, saturated colour in the world means one of two things: a substance's
identity, or the thing you are meant to reach.
Comedy, when it happens, comes from physics and other players, never from writing. A thrown ingot skidding under
the anvil is the game working.
## Glossary
Every document uses these words with exactly these meanings.
| Term | Meaning |
| --- | --- |
| **Body** | The character actor a player or enemy currently occupies. Not the player. |
| **Player state** | The replicated per-player object that outlives bodies: identity, class, attributes, cooldowns, discoveries. |
| **Kit** | A class's abilities, in slot order. Fixed by class. |
| **Signature** | The one ability in a kit no gear or mod may grant to another class. |
| **Funnel** | The single path a kind of consequence takes: the damage execution, the interaction service, the activity result. |
| **Prop** | A thing in the world a player can act on through the interaction system. |
| **Carryable** | A thing a player can hold. Carrying is not an interaction. |
| **Downed** | At zero health, immobile, revivable, bleeding out. Not dead. |
| **Stat block** | The one set of numbers every body carries: health, speed, attack, armour, resistances, work speed. |
| **Effect** | The only way a number on a stat block changes. Timed, infinite or instant; from an ability, an area, a surface, an item or the world. |
| **Status** | A named kind of effect: slow, haste, poisoned. The same name from any source, so one counter stops all of them. |
| **Counter** | Immunity (blocks a status by tag), resistance (scales it), cleanse (removes it). Lives on the receiver. |
| **Family** | A kind of item and the tree of parts it has: sword, axe, bow. |
| **Part** | A position in an item: blade, guard, handle, pommel. |
| **Piece** | A crafted object filling one part. Has identity. |
| **Trait** | One of a piece's three layers: characteristic (shape), substance (what it is made of), enchantment (ornament). |
| **Substance** | The design word "material", renamed because the engine owns that word. Iron, oak, mithril. A substance object is one physical ingot or log. |
| **Coherence** | An item's quality: piece values plus a bonus for pieces that agree with each other. |
| **Station** | A prop where work happens: bench, anvil, forge. |
| **Activity** | Hands-on work at a station, on the one shared runtime. Skill raises the ceiling, never gates the floor. |
| **Domain** | Which station family works a thing: forge, wood, enchant. Gates the work, never the worker. |
| **Step** | One rung of the ladder, closed by a proof. |
| **The gym** | The test level made of movement problems. It never leaves the project. |