Skip to content

Generalize tool-based harvesting and crafting from Sam's saw quest #35

Description

@mamoru

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 below are historical evidence only; do not copy, translate, or structurally port GPL implementation code.

Replacement implementation contract

Implement the generic Go activity/transaction engine and compiled definitions. CEL may express bounded pure prerequisites; Sam's saw must be the first scenario and require neither Starlark nor custom runtime scripting.

The server remains authoritative, consumes versioned compiled content, and exposes bounded generated Game Protocol 1 messages. Pure rules may use an approved typed CEL environment; Starlark is not required.

Required verification

  • Preserve every observable rule and exclusion in the specification.
  • Add deterministic Go unit/property tests and wrapper-managed scenarios.
  • Add bounded content/protocol/persistence failure cases.
  • Demonstrate zero runtime Python and no copied GPL source or tests.
Preserved product/design specification and historical implementation notes

Summary

Turn the working Sam Goodberry saw interaction into a reusable, data-driven tool/activity system, then use branch harvesting and campfire construction as the first two vertical slices.

The original quest enhancement is genuine, but its first scenario has since been implemented as a one-off. The remaining work is to replace the item-specific script and display-name matching with infrastructure that content authors can reuse safely.

What exists today

  • Sam's saw is an artifact based on arch/items/tools/saw.arc.
  • The underlying saw is a MISC_OBJECT (type 79), so there is no first-class tool behavior.
  • maps/python/items/sam_goodberry_saw.py handles Apply, scans adjacent wall-layer objects, and recognizes a target by the display name "thick branch tree".
  • One success creates all ten deserted_island_branch items and the quest's item requirement advances normally.
  • The quest removes the saw after the branches are returned.
  • The general EVENT_APPLY path already lets scripts override an item's behavior, and QuestManager already tracks stable quest/part UIDs and item objectives.

This is a sound content prototype, but it cannot describe tool compatibility, targets, yields, durability, work time, interruption, or reusable recipes without another bespoke script.

Proposed end state

First-class tools and activities

Introduce a TOOL object type with a small data-driven activity contract. A tool definition should declare:

  • stable tool/action ID, such as cut_wood or ignite;
  • supported target/resource tags;
  • reach and whether the target is marked, adjacent, or underfoot;
  • required skill/discipline and minimum tier where applicable;
  • wind-up/work duration and interruption policy;
  • durability/condition cost and failure behavior;
  • optional animation, sound, message, and effect IDs.

Do not encode gameplay rules in display names, faces, or arbitrary subtype numbers. Integrate action timing with #25 rather than adding blocking sleeps or private cooldown fields.

Authored resource nodes and recipes

Give harvest targets stable resource/activity metadata:

  • resource-node ID and compatible actions;
  • bounded yield table with stable item IDs and quantities;
  • depletion/respawn or one-shot policy;
  • skill/quest prerequisites;
  • whether the source object changes face/state or is consumed.

Campfire construction should be a recipe/activity that consumes an explicit branch quantity and an ignition tool, validates terrain/occupancy, and creates a bounded temporary campfire object. The recipe system from #27 and the content-identity catalog in atrinik/content#19 should own stable activity, recipe, and reward IDs.

Server and plugin seam

Add a central tool-apply path that:

  1. resolves the intended target deterministically;
  2. validates ownership, reach, map/terrain, target tags, prerequisites, resources, and capacity;
  3. starts or completes a server-authoritative activity;
  4. emits one structured tool/activity event containing activator, tool, target, recipe/resource ID, outcome, and produced/consumed quantities;
  5. commits consumption, condition loss, yield, quest/metric hooks, animation, and messages atomically.

Scripts may customize an authored activity, but the core must own validation and transactional item changes. A failed insertion or interrupted action must not consume inputs, duplicate yield, or partially advance a quest.

Migrate Sam's saw

Convert the thick branch trees and Sam's saw to the new metadata:

  • recognize the tree by stable resource tag, never the English name;
  • produce a configurable bounded number of branches per completed action;
  • prevent excess quest-only harvesting once the requirement is met;
  • keep clear feedback when no compatible target is in reach;
  • preserve removal/return of the quest saw;
  • decide explicitly whether the tutorial uses one ten-branch action or several smaller actions.

The quest should continue to progress from authoritative inventory/objective changes. It must not contain special knowledge of the generic tool engine.

Authoring and validation

Update object/archetype documentation, Python bindings, editor type metadata, collection, and map checking together. Validate unknown action/resource/recipe IDs, incompatible target/tool pairs, impossible yields, invalid item references, negative costs/times, and resource nodes with no usable tool.

Delivery plan

  1. Specify tool, resource-node, and activity/recipe schemas.
  2. Add TOOL object methods and the transactional activity helper.
  3. Add plugin/Python event access and focused unit tests.
  4. Migrate Sam's saw and thick branch trees without changing quest outcome.
  5. Add campfire construction as the second independent content slice.
  6. Add authoring/checker support and remove the one-off saw script when no current consumer needs it.

Acceptance criteria

  • Tools and targets match through stable authored IDs/tags, never display text.
  • Apply resolves marked/adjacent/underfoot targets deterministically and reports ambiguity.
  • Work timing, interruption, costs, durability, yields, and messages are data-driven and bounded.
  • Input consumption, output insertion, condition loss, and quest/activity events commit atomically.
  • Sam's branch quest behaves correctly before/after completion, at full inventory, after interruption, and with nearby incompatible trees.
  • A separate tinderbox/branch recipe can create a temporary campfire without Sam-specific code.
  • Tools, resource nodes, recipes, and referenced items validate during collection/map checking.
  • Existing ordinary MISC_OBJECT apply behavior is unaffected and the one-off saw script is removed after migration.

Validation

Add server tests for target resolution, reach, compatibility, timing, interruption, durability, skill/quest gates, inventory-full rollback, exact quantities, duplicate apply, and resource reset. Add Python/plugin tests for the activity event and content tests for dangling IDs. Run collection/map checks and runtime-test both the complete Deserted Island quest and campfire construction.

Historical request: use a saw to gather the branches required by Sam and extend the mechanic to campfires.

Related: #27, #25, atrinik/content#19.

Content-schema dependency

This issue is a registered consumer of atrinik/content#15's authoritative schema/field metadata and atrinik/content#8's authored-source migration. Its new fields, registries, reference rules, editor descriptions, loader/compiler tables, Python exposure, documentation, and checker rules must be generated or consumed from that shared source of truth rather than added as a second hand-maintained catalog. If a temporary legacy adapter is required before migration completes, it must be generated from the atrinik/content#15-owned metadata and removed by atrinik/content#8.

Metadata

Metadata

Assignees

No one assigned

    Fields

    Priority

    None yet

    Start date

    None yet

    Target date

    None yet

    Effort

    None yet

    Projects

    Status
    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions