Skip to content

Proposal: define activity-specific XP contracts for combat disciplines #7

Description

@zoeyrose

Important

This issue is implemented in the fresh MIT-licensed Go server under the replacement program. Its gameplay and content-design decisions remain authoritative. C, CPython, classic packet, file-path, and enum details in the preserved specification are historical evidence only; do not copy, translate, or structurally port GPL implementation code.

Replacement implementation contract

Preserve every activity-evidence and anti-farming rule. Implement a Go settlement policy over immutable participation snapshots from the encounter ledger; never calculate rewards from mutable current-skill state.

The server remains authoritative, consumes versioned compiled content, and exposes bounded generated Game Protocol 1 messages. Pure rules may use a specifically approved typed CEL environment. Starlark is not part of this issue unless the separate residual-scripting decision explicitly approves it.

Required verification

  • Preserve every observable rule, balance decision, disclosure boundary, and anti-exploit invariant from the specification below.
  • Add deterministic Go unit/property tests and wrapper-managed scenario coverage at the appropriate integration boundary.
  • Add bounded malformed-input and persistence-failure cases where this feature accepts content, network, or stored data.
  • Add Go/Rust protocol conformance fixtures for every new cross-process field; the client must not reconstruct authoritative rules from prose.
  • Demonstrate that implementation and tests contain no copied GPL source/test material and execute no runtime Python.
Preserved product/design specification and historical implementation notes

Summary

Replace the assumption that every trainable combat skill is the same kill-XP bar with explicit, activity-specific progression contracts.

The immediate player-facing change should remain the consolidation already owned by #18:

  • Melee Combat replaces slash, cleave, pierce, and impact weapon XP;
  • Archery replaces bow, crossbow, and sling XP;
  • Unarmed and Throwing remain separate because their equipment and action loops are materially different.

This issue owns the complementary decision: what evidence earns XP for each broad discipline, when it is settled, and how all awards remain within one bounded encounter budget. It does not duplicate #18's skill/content migration or #27's weapon profiles and technique trees.

Why change this

The current seven-way split rewards committing to an item taxonomy, not learning meaningfully different play:

  • 114 authored weapon/launcher archetypes carry one-based numeric item_skill values: 105 melee weapons are divided across four damage-family skills and nine launchers across bow/crossbow/sling skills.
  • living_update_player() applies that one skill level directly to melee WC and damage; arrow_get_wc() and arrow_get_damage() do the equivalent for launchers.
  • skill_attack() changes chosen_skill from the equipped weapon, while attack_hit() records effective damage under that skill ID and award_kill_exp() settles proportional kill XP.
  • As a result, replacing a sword with an axe or a bow with a crossbow resets both accuracy/damage progression even though the core player action is unchanged.

Weapon identity should come from damage type, timing, ammunition, reach, shape, and the profiles/techniques in #27—not from making the player repeat the level curve.

Atrinik already has the beginnings of activity-specific progression: books award Literacy on a one-time meaningful read, traps award Find/Remove Traps on successful outcomes, FLAG_STAND_STILL excludes some skills from character XP, and trap XP contributes at a hard-coded 20%. The policy is simply implicit and scattered.

Proposed progression contracts

Every skill should declare or document all of the following:

  1. its authoritative action/source identity;
  2. the meaningful evidence it records;
  3. the terminal event that settles XP;
  4. eligibility, anti-repeat, and anti-farming rules;
  5. its contribution to overall character XP;
  6. which level-dependent mechanics it scales.

Initial contracts:

Discipline Meaningful evidence Settlement
Melee Combat Effective, post-mitigation, non-overkill HP damage caused by an equipped melee weapon Eligible encounter completion/kill
Archery The same damage caused by a bow, crossbow, or sling projectile, attributed to the firing action rather than mutable chosen_skill Eligible encounter completion/kill
Unarmed Effective damage from an unarmed action Eligible encounter completion/kill
Throwing Effective damage from a thrown-object action Eligible encounter completion/kill
Wizardry / Divine Magic Effective hostile damage for offensive spells; later, explicitly bounded support evidence for spells whose purpose is healing, cleansing, protection, or control Eligible encounter completion, never cast count
Magic Devices The meaningful result caused through the device action; do not also credit the embedded spell's casting discipline Eligible encounter completion or a one-shot validated device outcome
Literacy First meaningful read/identification of eligible knowledge Immediate one-shot success, as today
Find / Remove Traps A genuine first find or successful disarm against an eligible trap Immediate anti-reroll success, as today
Crafting skills A valid completed output, bounded by recipe/input identity and difficulty Successful completion, not attempts or elapsed time

Do not add a passive Defense skill to the current automatic block/absorb path. Per-block or per-damage-taken XP would reward standing in weak attacks, equipment swapping, and unattended play. If #27 later adds an intentional guard, parry, or interception action, record actual encounter-bound damage prevented and either credit its owning Melee/Unarmed discipline or justify a new discipline with an independent active loop.

Meditation likewise should not gain XP merely from elapsed idle time. Keep it fixed, milestone-trained, or redesign it around an active bounded decision before making it progressive.

Award and anti-farming rules

  • Record evidence during an encounter, but award only at an existing terminal success. Do not add per-hit, per-cast, per-block, or per-tick XP.
  • Start from one level-relative encounter award produced by calc_skill_exp() and divide that budget among eligible action sources. Mixed actions must never multiply the pool.
  • Preserve the current effective-damage rules: after protection/block/absorption, capped to remaining HP, with zero damage and overkill excluded.
  • Snapshot the initiating action source into projectiles and delayed effects. A later equipment or chosen_skill change must not redirect credit.
  • Grey/ineligible activity earns no XP and its share must not become bonus XP for another skill.
  • Support evidence, when implemented through Proposal: add a shared encounter participation and reward-attribution ledger #23, must be effective rather than attempted: no overhealing, redundant cleanse, repeated buff refresh, friendly/self-inflicted damage loops, passive proximity, or PvP trading. Cap support weight against hostile encounter output and the same total encounter budget.
  • Reset evidence on the encounter lifecycle owned by Proposal: add a shared encounter participation and reward-attribution ledger #23: death/completion, authoritative reset or full disengagement, destruction, and map teardown. Transformations and multipart actors must not duplicate it.
  • Continue to use party/range/ownership eligibility; being in the party alone is not evidence.

Implementation outline from the current codebase

1. Land the broad identities through #18

  • Replace the seven enum/table entries in server/src/include/skills.h and server/src/include/skillist.h with SK_MELEE_COMBAT and SK_ARCHERY.
  • Add the two skill archetypes under arch/intern/skills/; remove the seven superseded archetypes/icons rather than retaining aliases.
  • Point all 105 authored melee weapons and nine launchers at the appropriate new one-based item_skill.
  • Update SKILL_IS_MELEE, SKILL_IS_ARCHERY, bow_get_skill(), item filters/examination, tests, scripts, plugins, tools, tutorial text, and documentation.
  • Remove the unreachable two-hand/polearm enum entries unless a real progression loop is approved.

The legacy item packet already sends the referenced skill object's object ID, level, XP, and description rather than exposing item_skill as a wire enum. The basic consolidation therefore should not need a packet-version branch; later technique/tree UI remains owned by #27.

2. Generalize evidence and settlement

Current master already has a bounded combat_contribution_t list on the victim. attack_hit() records player generation, skill ID, and effective damage, and award_kill_exp() distributes the award across participating skills. Use this as the short-term seam and migrate it into #23's shared encounter ledger rather than adding a second tracker.

3. Make skill policy explicit

Move character-XP weighting and progression flags out of special cases in skill_exp_to_character_exp() where practical. A small validated progression-policy table keyed by skill ID is sufficient; action-specific evidence should stay in the owning gameplay subsystem rather than becoming scriptable client input.

Validate every nonzero item_skill before indexing skill_ptr. Current paths such as manual_apply() assume the numeric content reference resolves and directly dereference it; consolidation is a good point to turn malformed content into a startup/collection error rather than a runtime crash.

4. Choose an intentional development-save policy

Do not sum the old nonlinear XP totals: that would create a large Melee/Archery level and double-count overall character progression. Because Atrinik has no compatibility baseline to preserve, the simplest policy is to reject/reset affected development saves. If a one-time conversion is specifically required, use the maximum absolute XP among the four melee skills and among the three launcher skills, remove the superseded skill objects, and recompute character XP from surviving skills. Document and test whichever policy is selected.

Acceptance criteria

  • Define stable combat-discipline and spell-tradition identities #18's broad Melee Combat and Archery skills replace the seven weapon-family XP bars without erasing weapon behavior differences.
  • Every current skill has a documented meaningful-evidence, settlement, repeat-prevention, character-XP, and scaling contract.
  • Damage disciplines award only from effective encounter contribution and settle only on an eligible terminal event.
  • Mixing weapons/actions cannot increase the total encounter XP budget or make last-hit/equipment swapping optimal.
  • Projectile and delayed-effect credit retains the initiating action source.
  • Device use cannot double-credit Magic Devices and a casting discipline.
  • Support evidence cannot count overhealing, redundant effects, passive proximity, friendly/self-inflicted loops, or repeated refreshes.
  • Automatic blocking, absorption, damage taken, idle time, misses, attempts, and zero-effect actions do not generate XP.
  • Every authored item_skill resolves to a valid skill; malformed references fail validation safely.
  • Superseded skills are removed, and the selected development-save policy neither sums nonlinear family XP nor leaves duplicate skill objects.

Validation

  • Add focused server tests for same-discipline weapon swaps, mixed Melee/Archery damage, grey skills, caps/rounding, party allocation, action-source snapshots, devices, reset/teardown, transformations, and duplicate completion.
  • Add exploit tests for blocked/zero damage, overkill, hit-and-reset, overhealing, repeated cleanse/buff, self/friendly damage, idle meditation, and invalid item_skill values.
  • Collect/check all skill and weapon archetypes and assert complete skill-reference coverage.
  • Exercise skill inventory/item requirement UI with the two broad disciplines; add protocol tests only if later technique metadata changes packets.
  • Update progression tools, bots, tutorials, and player-facing descriptions together.
  • Run focused experience/attack tests, the server check target, and the normal GCC/Clang/MinGW build matrix.

Relationships

Delivered contribution baseline

atrinik/atrinik#148's effective-damage contribution and proportional combat-skill award behavior was delivered by atrinik/atrinik#172. Treat it as the implementation baseline; this issue owns the broader activity-specific evidence, settlement, and bounded-budget contracts, while #23 owns the generalized encounter lifecycle and participant ledger.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Fields

    Priority

    None yet

    Start date

    None yet

    Target date

    None yet

    Effort

    None yet

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions