EP 1: Game Item with SUI Object
สร้างไอเทมเกมส์สุดเท่ห์ด้วย Sui Object

เปิดหัวมาแล้ว รอบนี้เตือนไว้ก่อนเลยว่าเฉพาะสาย Developer เท่านั้น !!! และแน่นอนไม่ได้จบในบทความเดียว พร้อมยัง เช็คสภาพเครื่องกันก่อน ใครยังไม่ได้ติดตั้งเครื่องมือในการพัฒนาไปดูจากที่นี้ได้นะ
พร้อมแล้วก็ไปกันเลย
เริ่มต้นกันก่อน — ทำไม 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 กัน
- เปลี่ยน environment
sui client switch --env testnet
- ขอเหรียญจาก faucet
sui client faucet
- 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 สุดท้ายของเรา
ดาบถูกจัดเก็บลงในกระเป๋าละ
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





