# Thành tích cho game PlayDrop

Khai báo thành tích thường và thành tích tích lũy kèm biểu tượng trong catalogue.json, mở khóa và báo tiến trình bằng sdk.achievements.

Source: https://www.playdrop.ai/vi/create/learn/achievements

Thành tích đánh dấu các mục tiêu trong game của bạn, kèm một biểu tượng và một mô tả mà người chơi thấy trên PlayDrop. Thành tích hoạt động cho cả khách lẫn người chơi đã đăng nhập.

## Khai báo thành tích

```json
{
  "achievements": [
    { "key": "first-win", "displayName": "First flag", "description": "Reach the flag once",
      "kind": "STANDARD", "icon": "achievements/first-win.png" },
    { "key": "collector", "displayName": "Collector", "description": "Collect 100 stars",
      "kind": "INCREMENTAL", "maxProgress": 100, "icon": "achievements/collector.png" },
    { "key": "secret-room", "displayName": "Secret room", "description": "Find the hidden room",
      "kind": "STANDARD", "hidden": true, "icon": "achievements/secret-room.png" }
  ]
}
```

- `key` theo cùng định dạng với khóa của [bảng xếp hạng](https://www.playdrop.ai/vi/create/learn/leaderboards).
- `kind` là `STANDARD` (mở khóa một lần) hoặc `INCREMENTAL` (mở khóa khi tiến trình đạt `maxProgress`, một số nguyên dương).
- `icon` là một tệp PNG trong gói. Hãy dùng một ảnh vuông rõ ràng, vẫn dễ nhìn ở kích thước nhỏ.
- `hidden: true` giữ bí mật tên và mô tả cho đến khi được mở khóa.

Không thể xóa các khóa đã xuất bản, và không thể đổi `kind`, `maxProgress` hay `hidden`. Hãy ngừng dùng một thành tích bằng `"status": "RETIRED"`.

## Mở khóa và báo tiến trình

```js
await sdk.achievements.unlock("first-win");
await sdk.achievements.setProgressAtLeast("collector", starsCollected);

const { achievements } = await sdk.achievements.list();
const { achievement } = await sdk.achievements.get("collector");
```

- `setProgressAtLeast` nhận tổng đến hiện tại, không bao giờ là lượng tăng. Tiến trình chỉ tăng, bị giới hạn ở `maxProgress` và mở khóa thành tích tại đó.
- Cả hai lệnh gọi đều trả về `{ accepted, changed, unlocked, progress, unlockedAt, achievement }`; `changed` là false khi không có gì mới xảy ra, nhờ đó bạn có thể chỉ hiện thông báo riêng của mình một lần.
- `list({ includeHiddenDefinitions: true, includeRetired: true })` bao gồm cả các định nghĩa ẩn và đã ngừng dùng.

Chỉ mở khóa trong lúc chơi thật, không bao giờ trong bản xem trước hay khi ghi hình. Khi hoàn toàn không có phiên người chơi, các lệnh gọi vẫn hoàn tất nhưng không được lưu.

## Thành tích hay

Hãy kết hợp những thành tích đầu game giúp người chơi làm quen với trò chơi cùng các mục tiêu dài hạn. Hãy gọi tên hành động, không phải phần thưởng: “Thắng mà không bị mất máu” nói rõ cần làm gì. Một tá thành tích được nghĩ kỹ tốt hơn cả trăm thành tích tầm thường.

## Hướng dẫn liên quan

- [Bảng xếp hạng](https://www.playdrop.ai/vi/create/learn/leaderboards): Khai báo bảng xếp hạng trong catalogue.json, gửi điểm bằng sdk.leaderboards, hiển thị hạng đầu và người chơi xung quanh. Loại điểm, giới hạn và quy tắc cập nhật.
- [Lưu đám mây](https://www.playdrop.ai/vi/create/learn/cloud-saves): Lưu và tải tiến trình người chơi bằng sdk.me.appData và updateAppData, cho khách và người chơi đã đăng nhập, kèm quy tắc ghi, xem trước và chơi ngoại tuyến.
- [catalogue.json](https://www.playdrop.ai/vi/create/learn/catalogue-json): Các trường catalogue.json game PlayDrop dùng: định danh, trang giới thiệu, chế độ chơi, màn hình, đăng nhập, Instant, tải trước, media, bản dịch, điểm và máy chủ.
