Skip to content

Influence and Moonstream: Bringing On-chain Missions to Discord

Moonstream + Influence

Influence, a fully on-chain space strategy MMO on Starknet, is turning in-game events on the blockchain into missions for their community to complete. 

The missions are broken down into two forms: Solo Missions and Community Missions. Solo Missions are specific tasks that can be completed by one player’s crew. On the other hand, Community Missions must be completed by the entire player community in the game. The goal: players learn the game through missions while getting token rewards for completing them.

Influence had the specific challenge of bringing those on-chain missions to Discord for the player community to be able to seamlessly collaborate or compete with one another to complete missions. Moonstream helped them accomplish this by creating a Discord bot that can show players available missions and their completion status.

Bringing this vision to life

To bring this vision to life, Moonstream modified its Leaderboard tool that aggregates events emitted from smart contracts and applies a scoring logic to assign scores to players. 

We added functionality in seer, a tool for generating a CLI to any smart contract, to generate crawlers for Starknet events data. Any project can use this for their Starknet contracts, it is free software.

We used seer to generate a tool called influence-eth. Any Influence player can use it to build a dataset of Influence data – currently, it takes only 5 seconds to crawl the entire history of the game’s events.

We added functionality mapping events to mission scores in the influence-eth tool and we pushed it to the Leaderboard API.

What makes this Leaderboard tool more powerful is the API that allows users to display the leaderboard data as they choose or create new applications based on the data.

We took the data from the Leaderboard API and used it to power a Discord bot. By integrating mission status checks directly into Discord, the Discord bot allows players to engage more where they convene and collaborate.

So, how did Moonstream do it? Let’s look at two example missions to see how the leaderboard works.

Solo Mission: Construct at least one ship

In this example, Moonstream checks for the event ShipAssemblyFinished as seen in the JSON below, counts how many times the event has been emitted on-chain for the specific crew in caller_crew, and applies a scoring logic, in this case, 1 point for each event.

"ShipAssemblyFinished": {

    "type": "event",
    "name": "ShipAssemblyFinished",
    "kind": "struct",
    "members": [
      {
        "name": "ship",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "dry_dock",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "dry_dock_slot",
        "type": "core::integer::u64",
        "kind": "data"
      },
      {
        "name": "destination",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "finish_time",
        "type": "core::integer::u64",
        "kind": "data"
      },
      {
        "name": "caller_crew",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "caller",
        "type": "core::starknet::contract_address::ContractAddress",
        "kind": "data"
      }
    ]
  },

Community Mission: Construct a Spaceport, Marketplace, or Habitat anywhere in the Belt

Moonstream checks for the event ConstructionFinished to confirm that a building is finished. In this case, the logic ignores the crew since this applies to the entire Influence community.

"ConstructionFinished": {
    "type": "event",
    "name": "ConstructionFinished",
    "kind": "struct",
    "members": [
      {
        "name": "building",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "caller_crew",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "caller",
        "type": "core::starknet::contract_address::ContractAddress",
        "kind": "data"
      }
    ]
  },

However, we need to know what building type was constructed and where, and the ConstructionFinished does not provide that information. So it checks the ConstructionPlanned event to confirm the building and its location by mapping the building in both events and getting the building_type and asteroid.

"ConstructionPlanned": {
    "type": "event",
    "name": "ConstructionPlanned",
    "kind": "struct",
    "members": [
      {
        "name": "building",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "building_type",
        "type": "core::integer::u64",
        "kind": "data"
      },
      {
        "name": "asteroid",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "lot",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "grace_period_end",
        "type": "core::integer::u64",
        "kind": "data"
      },
      {
        "name": "caller_crew",
        "type": "influence::common::types::entity::Entity",
        "kind": "data"
      },
      {
        "name": "caller",
        "type": "core::starknet::contract_address::ContractAddress",
        "kind": "data"
      }
    ]
  },

Displaying Missions in Discord

Players can look up the list of available missions with a /mission bot command. They can also query their mission statuses in real-time with /status

Leaderboard bot

Leaderboard bot

With the bot, players can also link their in-game accounts or assets with their Discord account. That way they don’t need to enter their NFTs’ name each time they want to look up their mission status. Instead, they just choose a saved Identity from a list.

On the Moonstream API side, we store the Discord server configuration and saved player identification for quick access.

To sum up, Moonstream Leaderboards can be used to:

  1. Gather information about players’ on-chain actions
  2. Link those actions to specific scores
  3. Display player ranks based on those scores on Moonstream’s or the game’s website
  4. Connect the Leaderboard Discord bot to any Discord server
  5. Display and query player scores and ranks in Discord via the Leaderboard bot

The scores can be linked to players’ wallets as well as players’ NFTs. If you want to know more about the technology behind Leaderboards, you can reach out to Moonstream on Discord. The Discord bot is part of our LiveOps platform, something that we are piloting with Influence and making available to other web3 projects, as well.

Start playing Influence. Play with friends or compete with other players. Earn rewards. The sooner you start the stronger you get. Pre-release early access starts February 21st, with public access on February 27th.