FOUR SDK / V1.0.0

Relationships, inventory and achievements

ts
await fourBtd.relationships.update({
  characterId: mira.id,
  subjectId: 'traveler',
  trust: 0.8,
  affinity: 0.6,
  familiarity: 0.4,
  rivalry: 0,
  status: 'friend',
  sharedEvents: [event.id],
});

const ally = await fourBtd.characters.create({
  name: 'Taro',
  owner: 'player-two',
});

await fourBtd.inventory.grant({
  characterId: mira.id,
  itemId: 'potion',
  quantity: 2,
  sourceWorld: 'forest',
});

await fourBtd.inventory.transfer({
  characterId: mira.id,
  toCharacterId: ally.id,
  itemId: 'potion',
  quantity: 1,
});

const ownership = await fourBtd.inventory.verify({
  characterId: ally.id,
  itemId: 'potion',
});

await fourBtd.achievements.unlock({
  characterId: mira.id,
  key: 'generous',
  name: 'A Helping Hand',
});

Relationship scores are clamped to [0, 1] when finite. Omitted scores preserve their existing values, or default to 0 when creating a new relationship.

Shared-event patches replace the existing list and must reference events belonging to the character.

Inventory behavior:

  • Quantities must be positive safe integers.

  • Transfers are atomic and require distinct, active owners.

  • Transfers preserve item provenance.

  • Removing the entire quantity returns null.

  • Existing stacks require matching optional asset addresses.

  • Grants preserve the existing stack's metadata and source world.

  • verify checks recorded offchain ownership, not a Solana token account.

Achievement unlocks are intrinsically idempotent by characterId and key. After the first unlock, the original name, description, and metadata are retained.