# 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](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](https://onthemoveth.hashnode.dev/sui-object) เพราะฉะนั้นพูดง่ายๆ คือ SUI Object คือ **ไอเทมจริงๆ ที่คุณถืออยู่ในเกมส์**

---

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

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

* 🗡️ **Item** — NFT ไอเทม 1 ชิ้น
    
* 🎒 **Inventory** — กระเป๋าเก็บของของผู้เล่น
    

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759669309998/88972491-b40d-464e-b260-28a837b7cd2f.png align="center")

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

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

```bash
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](https://github.com/Contribution-DAO/sui-move-intro-course-thai/blob/main/unit-one/lessons/2_sui_project_structure.md) แล้ว โดยเราจะเพิ่ม dependencies เข้าไป

```rust
[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

```rust
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
    

```bash
sui client switch --env testnet
```

2. ขอเหรียญจาก faucet
    

```bash
sui client faucet
```

3. Build และ Publish
    

```bash
sui move build
sui client publish --gas-budget 100000000
```

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

* packageId (เหมือน ID ของโปรเจกต์)
    
* UpgradeCap (กุญแจไว้ใช้ตอนอัปเกรดใน EP2)
    

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

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759708763888/a83b53c8-ea04-4753-89de-6cd0e8a72f38.png align="center")

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

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

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

Mint ดาบในตำนาน

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

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

```bash
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](https://suiscan.xyz/testnet/object/0xb020131b5c1004b42a8f0d6ccf9f9c23b0f711ff14199538874fc0219b9f37d7/tx-blocks)

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

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

```plaintext
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*
