onflow / sc-eng-gaming

Showcasing how a Rock Paper Scissors game could be made #onFlow
https://onflow.org
The Unlicense
10 stars 2 forks source link

Gaming Smart Contracts #3

Open alilloig opened 2 years ago

alilloig commented 2 years ago

Context

We need to create and documentate the basic contracts for supporting NFT based games on Cadence showcasing best practices for the most common use cases, including a MVP rock, paper, scissor style game.

Definition of Done

sisyphusSmiling commented 2 years ago

Following up on this morning's meeting with some notes on current state & next steps:

Current state: [X] Clarified approach and necessary components for MVP [X] MVP specs and initial component task allocation

Next steps [ ] Gaming NFT Metadata View - @alilloig [ ] Match NFT Escrow mechanism - @sisyphusSmiling

We will spend some time thinking about these components and regroup on 09/12 before meeting with the TEA team midweek.

joshuahannan commented 2 years ago

There might be a couple missing issues here. I don't see an issue for the NFT metadata win/loss view or an issue for creating the initial NFT contract. Can y'all create those issues too?

alilloig commented 2 years ago

There might be a couple missing issues here. I don't see an issue for the NFT metadata win/loss view or an issue for creating the initial NFT contract. Can y'all create those issues too?

I included the metadata as a part of this issue https://github.com/onflow/sc-eng-gaming/issues/6

Probably better to restructure and create separate issues for those?

joshuahannan commented 2 years ago

Maybe. Actually #6 is probably fine now that I think about it

alilloig commented 2 years ago

Maybe. Actually #6 is probably fine now that I think about it

Will specify about the NFT utility of the NFT as a win/loss record and that that should be the main focus of the view

sisyphusSmiling commented 2 years ago

As communicated to TEA team, here's our current thought process on the initial approach toward a Rock Paper Scissors MVP:

Based on our Monday convo, it sounds like shared priorities are defining the NFT, its attributes (mutable v. immutable), when and how those attributes are changed as well as custody during gameplay.

With that in mind, we’re thinking that the commit-reveal pattern should be our focus in the next iteration, focusing instead on a simpler, single user transaction UX.

TL;DR: Players submit a single transaction at the start of a match to deposit their Game Piece NFT into escrow. Throughout gameplay, the game client submits both players’ moves to the chain in a single transaction every round. The NFTs are then returned to each player after the game is over.

What that looks like is:

  1. Players tell game client they want to play a match
  2. Client calls to the game contract to init a match
  3. Client presents each player a transaction by which they submit their GamePiece NFT into escrow for the match
  4. Once the GameAdmin has received both NFTs, it initializes the initial game state and emits an event
  5. The game client sees this event and asks each user for their move (Rock, Paper, or Scissors)
  6. Once each user has submitted their moves to the client, the client submits a single transaction to the GameAdmin containing the move of each user
  7. The GameAdmin performs some logic to resolve the round, determining a winner and a loser, and altering NFT win/loss values as necessary
  8. With the single round match over, the GameAdmin finalizes the match state & win/loss data and emits an event that the match is over.
  9. The game client then submits another transaction, ensuring the Game Piece NFTs are returned to each players’ collection :rock:

Here’s a visual diagram in case that helps. Feel free to comment there as well.

Still working out the specifics of each component as well as which account each resource is stored, but we are thinking that the NFT and Escrow mechanism will be defined in one contract with the Game & GameAdmin defined in another. Álvaro will work on the former while I work on the latter.

joshuahannan commented 2 years ago

Great summary! I'm interested to hear how you think the escrow mechanism could be defined in the NFT contract. By defining that in the contract, do you just mean defining how contracts that escrow the NFTs can modify the NFTs metadata (as well as the associated views?) or defining the entire escrow mechanism?

alilloig commented 1 year ago

I just found this on my opened tabs, sorry for the delay! This will be a little more detailed on the design document, but we are talking about defining the entire escrow mechanism in the NFT contract. Why?

Because at least so far I haven't find another way of restricting the access of the owner of a resource to call a method in it rather than the method being access(contract) and having another resource (the escrow) that holds the NFT and has a method to call the mutate function. Can you think of any pattern that allows us to define the escrow mechanism outside of the NFT contract? We will have a call and talk about this and some other nuances as soon as I have all my ideas sorted.

pub resource NFT: NonFungibleToken.INFT {
        pub let id: UInt64
        pub var state: AnyStruct
        access(contract) fun mutate (newState: AnyStruct) {
            self.state = newState
        }
}