What you'll learn

  • The OASIS karma model — positive, negative and weighted categories
  • Award and remove karma from within your app
  • Query a user's karma score, history and Akashic Records
  • Community-voted weighting for karma categories
  • Build a karma-gated feature (e.g. unlock a reward at karma ≥ 500)

The Karma Model

Karma in OASIS is a persistent, platform-wide reputation score. Unlike in-app point systems that reset per game, OASIS karma accumulates across every OApp a user interacts with. A player who helps others in your game, contributes to open-source OASIS tools, and mentors new players in Our World all earn karma — and that karma is visible to every other OApp they use.

Karma comes in two flavours:

Each karma type has a weighting — a multiplier that the community can vote on to reflect how much a given action matters relative to others. The platform aggregates votes and applies the result automatically.

📜
The Akashic Records

Every karma event is written to the Akashic Records — an immutable, distributed audit log stored across multiple OASIS providers. Any app can query the full karma history for any avatar. Think of it as a permanent, transparent record of a user's contributions to the ecosystem.

Reading Karma

karma-read.js
import { oasis } from './oasis.js';

const { avatarId } = oasis.auth.getSession();

// Simple total karma score
const { result: karma } = await oasis.karma.getKarmaForAvatar({ avatarId });
console.log('Total karma:', karma);

// Detailed breakdown
const { result: stats } = await oasis.karma.getKarmaStats({ avatarId });
console.log(stats);
// → { total: 1240, positive: 1350, negative: 110, level: 'Champion' }

// Full karma history (every event)
const { result: history } = await oasis.karma.getKarmaHistory({ avatarId });
history.forEach(event => {
  console.log(`${event.date} | ${event.type} | +${event.amount} | ${event.reason}`);
});

// Akashic Records — immutable distributed log
const { result: akashic } = await oasis.karma.getKarmaAkashicRecordsForAvatar({ avatarId });
console.log('Akashic entries:', akashic.length);

Awarding Karma

Call oasis.karma.addKarmaToAvatar() when a user does something positive in your app. You specify the karma type — this determines the base weighting.

award-karma.js
// Award karma for a positive action
const result = await oasis.karma.addKarmaToAvatar({
  avatarId,
  karmaType:  'CompletingQuest',    // positive karma type
  karmaSource: 'MyAwesomeOApp',       // your app name (shown in Akashic Records)
  karmaSourceId: 'quest-001',         // optional ID of the triggering event
  karmaSourceTitle: 'The Lost Sword'  // human-readable label
});

console.log('Karma awarded:', result.result?.karmaAwarded);
console.log('New total:', result.result?.newTotal);

Positive karma types

KarmaTypeTypical use case
CompletingQuestPlayer finishes a quest or mission
HelpingOthersAssisting another player in-game
CreatingOAppPublishing a new OApp to the ecosystem
SharingKnowledgeContributing docs, tutorials or guides
BeingInspiringContent or action that others rate highly
EvolveAndGrowLevelling up, completing learning milestones
MeditateCompleting mindfulness or wellbeing activities
BeAGoodSamaritanHelping new users get started
DoingGoodDeedsReal-world charitable actions verified on-chain

Removing Karma

Use this sparingly and always log the reason — negative karma events are also written to the Akashic Records and are visible to other apps.

javascript
await oasis.karma.removeKarmaFromAvatar({
  avatarId,
  karmaType:        'Cheating',
  karmaSource:      'MyAwesomeOApp',
  karmaSourceId:    'cheat-detection-event-007',
  karmaSourceTitle: 'Speed-hack detected in Race Zone'
});

Karma Weighting & Community Voting

Each karma type has a weighting multiplier. The raw karma awarded for, say, CompletingQuest is multiplied by this weight. The community can vote to adjust weightings over time.

javascript
// Read current weighting for a positive type
const { result: w } = await oasis.karma.getPositiveKarmaWeighting({ karmaType: 'CompletingQuest' });
console.log('CompletingQuest weighting:', w);

// Vote to increase the weighting for a type (community governance)
await oasis.karma.voteForPositiveKarmaWeighting({
  karmaType: 'SharingKnowledge',
  weighting:  2.5    // your suggested multiplier
});
🌍
Real-world use case — karma-gated content

An educational platform built on OASIS locks advanced course modules behind a karma threshold of 500. Users who've helped others across any OASIS app — not just this platform — already have that karma and get immediate access. New users are motivated to contribute because the karma they earn unlocks value everywhere, not just here.

Building a Karma Gate

Here's a complete pattern for gating a feature behind a minimum karma score:

karma-gate.js
import { oasis } from './oasis.js';

const KARMA_THRESHOLD = 500;

async function canAccessPremiumFeature(avatarId) {
  const { result: karma, isError } = await oasis.karma.getKarmaForAvatar({ avatarId });
  if (isError) return false;
  return karma >= KARMA_THRESHOLD;
}

// In your app route / component:
const { avatarId } = oasis.auth.getSession();
const hasAccess = await canAccessPremiumFeature(avatarId);

if (hasAccess) {
  showPremiumContent();
} else {
  showKarmaPrompt(`You need ${KARMA_THRESHOLD} karma to unlock this. Keep contributing!`);
}

Building a Karma Leaderboard

leaderboard.js
import { oasis } from './oasis.js';

async function buildLeaderboard(avatarIds) {
  const entries = await Promise.all(
    avatarIds.map(async id => {
      const [avatarRes, karmaRes] = await Promise.all([
        oasis.avatar.getAvatarDetail({ id }),
        oasis.karma.getKarmaForAvatar({ avatarId: id })
      ]);
      return {
        username: avatarRes.result?.username,
        karma:    karmaRes.result ?? 0
      };
    })
  );
  return entries.sort((a, b) => b.karma - a.karma);
}

const board = await buildLeaderboard(myPlayerIds);
board.forEach((entry, i) =>
  console.log(`#${i+1} ${entry.username} — ${entry.karma} karma`)
);

Karma API Quick Reference