Skip to main content

Command Palette

Search for a command to run...

EP 1: Game Item with SUI Object

สร้างไอเทมเกมส์สุดเท่ห์ด้วย Sui Object

Updated
3 min read
EP 1: Game Item with SUI Object

เปิดหัวมาแล้ว รอบนี้เตือนไว้ก่อนเลยว่าเฉพาะสาย Developer เท่านั้น !!! และแน่นอนไม่ได้จบในบทความเดียว พร้อมยัง เช็คสภาพเครื่องกันก่อน ใครยังไม่ได้ติดตั้งเครื่องมือในการพัฒนาไปดูจากที่นี้ได้นะ

https://github.com/Contribution-DAO/sui-move-intro-course-thai/blob/main/unit-one/lessons/1_set_up_environment.md

พร้อมแล้วก็ไปกันเลย

เริ่มต้นกันก่อน — ทำไม Sui Object ถึงเหมาะกับเกม?

ในโลกของ Sui นั้นทุกๆ อย่างคือ Object ไม่ใช่แค่ token เหมือน ERC-721 แต่เป็นวัตถุที่ มีชีวิต จริง!

ERC-721 คือ Non-Fungible Token Standard หรือก็คือ NFT ที่เราน่าจะคุ้นๆหรือเคยมีติดมือกันมาบ้างแล้วนั้นเเหละ ซึ่งเป็นที่นิยมใช้งานกันใน EVM Smart Contract

มาลองจินตนาการดูว่า

  • Item = ดาบในเกมของคุณ

  • Inventory = กระเป๋าเก็บของของผู้เล่น

  • Owner = ผู้เล่นคนนั้น (หรือแม้แต่ object อื่น)

ซึ่ง Sui Object มีหลังพิเศษเหล่านี้:

  • มี UID เป็นรหัสไม่ซ้ำ เหมือน DNA ของวัตถุ

  • มี Owner ที่เปลี่ยนมือได้ (หรือจะอยู่ใน object อื่นก็ยังได้!)

  • มี Versioning เวลามีการเปลี่ยนแปลง

  • มี Type Safety ด้วยภาษา Move ทำให้ bug ยากจะเกิด

ถึงตรงนี้เราจะไม่เกริ่นเรื่อง Sui Object แล้วนะ ใครไม่เข้าใจมีงอล เพราะเขียนไว้เเล้วที่นี้ https://onthemoveth.hashnode.dev/sui-object เพราะฉะนั้นพูดง่ายๆ คือ SUI Object คือ ไอเทมจริงๆ ที่คุณถืออยู่ในเกมส์


โครงสร้างของเกมส์ที่เราจะสร้างในตอนนี้

เราจะเริ่มจากพื้นฐานเเบบสุดๆกันก่อน

  • 🗡️ Item — NFT ไอเทม 1 ชิ้น

  • 🎒 Inventory — กระเป๋าเก็บของของผู้เล่น

จากนั้นผู้เล่นจะสามารถเสกของได้ (Mint) เเบบ GM นั้นเอง แล้วเราก็จะเอาของที่เสกขึ้นมาไปเก็บไว้ในกระเป๋า เหมือนตอนเล่นเกมส์จริงๆเลย

มาเขียนโค้ด Move กันเลย

สร้างโปรเจ็คกันก่อน ด้วยคำสั่งด้านล่างนี้ โครงสร้างของโปรเจ็คจะถูกสร้างขึ้นมาโดยอัตโนมัติ

sui move new my_item

แก้ไขไฟล์ Move.toml

ซึ่งตรงนี้เราจะไม่อธิบายแล้วนะ เพราะมีใน https://github.com/Contribution-DAO/sui-move-intro-course-thai/blob/main/unit-one/lessons/2_sui_project_structure.md แล้ว โดยเราจะเพิ่ม dependencies เข้าไป

[dependencies]
Sui = { override = true, git = "https://github.com/example/example.git", subdir = "crates/sui-framework/packages/sui-framework",rev = "testnet-v1.57.2" }

ไฟล์ sources/items.move

module my_items::items {
    use 0x2::object::{Self, UID};
    use 0x2::tx_context::{Self as tx, TxContext};
    use 0x2::transfer;
    use std::string::String;

    // Item: ดาบสุดแกร่งของเรา
    public struct Item has key, store {
        id: UID,
        name: String,
        class: String,
        power: u64,
        image_url: String,
    }

    // Inventory: กระเป๋าผู้เล่น
    public struct Inventory has key, store {
        id: UID,
        owner: address,
    }

    // Mint ไอเทมใหม่ให้ผู้เล่น
    public fun mint_to_sender(
        name: String,
        class: String,
        power: u64,
        image_url: String,
        ctx: &mut TxContext
    ) {
        let item = Item { id: object::new(ctx), name, class, power, image_url };
        transfer::public_transfer(item, tx::sender(ctx));
    }

    // สร้างกระเป๋าใหม่
    public fun create_inventory(ctx: &mut TxContext) {
        let inv = Inventory { id: object::new(ctx), owner: tx::sender(ctx) };
        transfer::public_transfer(inv, tx::sender(ctx));
    }

    // เอาไอเทมใส่กระเป๋า
    public fun put_into_inventory(inv: &Inventory, item: Item) {
        let inv_addr = inv.owner;
        transfer::transfer(item, inv_addr);
    }

    // เอาไอเทมออกจากกระเป๋า
    public fun take_out_from_inventory_to_sender(
        inv: &Inventory, item: Item, ctx: &mut TxContext
    ) {
        assert!(inv.owner == tx::sender(ctx), 1);
        transfer::public_transfer(item, tx::sender(ctx));
    }
}

Code พร้อม มาเริ่ม Deploy กัน

  1. เปลี่ยน environment
sui client switch --env testnet
  1. ขอเหรียญจาก faucet
sui client faucet
  1. Build และ Publish
sui move build
sui client publish --gas-budget 100000000

หลังจาก publish สำเร็จเราก็ได้

  • packageId (เหมือน ID ของโปรเจกต์)

  • UpgradeCap (กุญแจไว้ใช้ตอนอัปเกรดใน EP2)

ลองเอา packageId ไปเปิดบน Testnet Explorer ดูนะ

https://suiscan.xyz/testnet/object/{packageId}

ทดลองใช้งานจริง

สร้างกระเป๋าเอาไว้เก็บ Item (Inventory)

sui client call \
  --package $PACKAGE_ID \
  --module items \
  --function create_inventory \
  --gas-budget 50000000

Mint ดาบในตำนาน

sui client call \
  --package $PACKAGE_ID \
  --module items \
  --function mint_to_sender \
  --args "Excalibur" "Weapon" 9001 "ipfs://bafy..." \
  --gas-budget 50000000

เก็บดาบใส่กระเป๋าให้เรียบร้อย

sui client call \
  --package $PACKAGE_ID \
  --module items \
  --function put_into_inventory \
  --args $INVENTORY_ID $ITEM_ID \
  --gas-budget 50000000

และนี้คือตัวอย่าง transaction สุดท้ายของเรา

https://suiscan.xyz/testnet/object/0xb020131b5c1004b42a8f0d6ccf9f9c23b0f711ff14199538874fc0219b9f37d7/tx-blocks

ดาบถูกจัดเก็บลงในกระเป๋าละ

Diagram แสดงความสัมพันธ์

classDiagram
    class Inventory {
        +UID id
        +address owner
    }

    class Item {
        +UID id
        +String name
        +String class
        +u64 power
        +String image_url
    }

 Inventory "1" o-- "many" Item : holds

ตอนนี้เราได้สร้างระบบไอเทมในเกมส์ครบแล้ว
✅ สร้างได้
✅ เก็บในกระเป๋าได้
✅ โอนไปมาได้

แต่ถ้าอยากตีบวกดาบให้เทพขึ้นล่ะ? หรือถ้าอยากเพิ่ม rarity, durability? จะทำยังไง… ลองไปปรับเพิ่มกันดูนะครับ ก่อนที่เราจะมาเฉลยใน EP.2 :) เจอกัน

By GANG | ContributionDAO