Lần Đầu Làm Game Server

Học Lập Trình /lan-dau-lam-game-server #java #Godot #Sqlite

Lần đầu mình chạm vào lập trình game: hóa ra “game” cũng là backend, database và thuật toán

Trước đây mình nghĩ lập trình game chủ yếu là vẽ nhân vật, xử lý phím bấm, va chạm, thắng thua. Nhưng khi làm bài midterm này, mình mới hiểu: phần “chơi được” chỉ là một nửa.

Nửa còn lại là hệ thống dữ liệu phía sau: đăng nhập, lưu điểm, bảng xếp hạng, inventory, giao dịch… và mọi thứ đều cần đúng, nhanh, và khó bị gian lận.

Mình xem bài này như một bước “backend-first” cho game: gameplay chạy mượt trên client, còn server là nơi giữ sự thật dữ liệu. Nói cách khác: client có thể hiển thị mọi thứ, nhưng dữ liệu quan trọng phải được server quyết định và lưu.

1. Kiến trúc tổng quan: Client Godot + Server Java + SQLite

Client Godot xử lý:

  • UI/Scene: Login → Lobby → Mode chơi Classic/Adventure → Leaderboard/Inventory

  • Gameplay loop: di chuyển, spawn food, tính điểm, game over

  • Gửi request JSON lên server

Server Java xử lý:

  • HTTP API: /api/auth, /api/score, /api/adventure, /api/inventory, /api/trade

  • Xác thực đăng nhập/đăng ký

  • Lưu điểm, trả leaderboard

  • Quản lý inventory và trade bằng transaction

Database SQLite lưu:

  • users

  • scores

  • login_history

  • login_attempts

  • adventure_logs

  • inventory

Điểm “backend-first” ở đây là: mình nhìn game như một hệ thống có request/response, có schema, có luật dữ liệu, và có hiệu năng.

2. Khoảnh khắc “wow”: bấm Login trong game = gửi JSON như làm web backend

Ở Godot, khi bấm Login/Register, client gửi JSON lên server:

gdscript

var data = {
  "cmd": command,
  "user": username,
  "pass": password
}

http_request.request(
  AUTH_URL,
  ["Content-Type: application/json"],
  HTTPClient.METHOD_POST,
  JSON.stringify(data)
)

Server Java nhận JSON, đọc cmd, rồi xử lý đăng ký/đăng nhập:

java

String cmd = json.get("cmd").getAsString();

if (cmd.equalsIgnoreCase("register")) {
    // xử lý đăng ký
} else if (cmd.equalsIgnoreCase("login")) {
    // xử lý đăng nhập
}

Từ đây mình hiểu: làm game có tài khoản người chơi thực chất là làm client-server giống web/app, chỉ khác là client là game engine.

3. Database không chỉ “lưu”: nó dạy mình tư duy đúng/sai và an toàn dữ liệu

3.1. Schema và ràng buộc constraints

Database tạo bảng và ràng buộc như:

  • username UNIQUE NOT NULL để không trùng tài khoản

  • FOREIGN KEY để dữ liệu liên kết hợp lý

  • UNIQUE(username, item_type) để mỗi user chỉ có 1 dòng cho 1 loại item trong inventory

Ý nghĩa theo first principles:

  • Database tồn tại để mình không phải tin vào trí nhớ của chương trình.

  • Constraints tồn tại để mình không phải tin vào sự “tự giác” của code.

3.2. UPSERT cho inventory

Khi nhặt đồ, server dùng UPSERT để cộng dồn số lượng:

sql

INSERT INTO inventory(username, item_type, quantity)
VALUES (?, ?, ?)
ON CONFLICT(username, item_type)
DO UPDATE SET quantity = quantity + ?;

Tại sao hay:

  • Không cần “check có tồn tại chưa” bằng 2 query.

  • Ít bug cạnh tranh race condition hơn cách tự viết logic if/else.

3.3. Transaction cho trade

Trade “bán Táo Vàng lấy điểm” dùng transaction:

  • Trừ item trong inventory

  • Tính điểm mới

  • Cập nhật scores

  • Nếu lỗi giữa chừng: rollback

Tư duy cần học:

Transaction là “bảo toàn dữ liệu”: hoặc thành công hết, hoặc quay lại trạng thái cũ.

4. Algorithm/Data Structures: game loop và leaderboard là bài thuật toán sống

4.1. Game loop và cấu trúc dữ liệu cho snake

Trong AdventureGame, thân rắn là mảng đóng vai trò hàng đợi:

  • insert(0, new_head) giống push front

  • pop_back() giống pop back

Đây là bài học thuật toán rất thật: chọn cấu trúc dữ liệu giúp code rõ ràng và chạy ổn.

4.2. Leaderboard: sort + giới hạn top N + cache RAM

Server load top điểm lên RAM bằng danh sách topList, trả cực nhanh mà không query DB mỗi lần:

  • Khi có điểm mới: cập nhật DB

  • Cập nhật RAM

  • Collections.sort(topList)

  • Nếu quá 10: remove(10)

Tại sao làm vậy:

  • Database mạnh ở lưu trữ, nhưng không nên bị gọi liên tục cho cùng một dữ liệu top 10.

  • RAM cache giúp phản hồi nhanh.

  • Đây là lúc mình bắt đầu hiểu bài toán hiệu năng.

4.3. Anti-cheat mindset

Nếu tin điểm từ client hoàn toàn, người chơi có thể sửa RAM hoặc cheat.

Vì vậy, “server là sự thật” là tư duy nền tảng cho game có điểm và bảng xếp hạng.

5. Những thứ mình học được

Mình đã học được:

  • Cách một game client gửi request JSON và nhận response

  • Cách server chia API theo handler/endpoint

  • Cách thiết kế schema cơ bản cho user/score/inventory

  • UPSERT, ORDER BY, GROUP BY, LIMIT

  • Transaction và rollback để giữ dữ liệu nhất quán

  • Tư duy cache RAM cho leaderboard

  • Tư duy thuật toán từ game loop: queue, sort, top N

6. Roadmap học tiếp

Algorithm/Data Structures cần học thêm:

  • Big-O cơ bản, vì insert(0, array) và sort đều có chi phí

  • Queue/Deque, có thể cài bằng linked list hoặc circular buffer

  • Sorting và top-K

  • PriorityQueue heap để giữ top K hiệu quả hơn sort toàn bộ

  • HashMap/Dictionary: map username -> score để update nhanh

  • Random & probability cho spawn loot/gacha

Database cần học thêm:

  • Index là gì, khi nào cần index

  • Ví dụ: username, scores(username), inventory(username, item_type)

  • Normalization cơ bản: dữ liệu nên đặt ở bảng nào cho hợp lý

  • Transaction isolation ở mức cơ bản

  • SQL injection và chuẩn hóa input

  • PreparedStatement là một bước đúng

  • Migrations: quản lý thay đổi schema theo thời gian

Kết luận: bài này khiến mình nhìn “lập trình game” khác đi

Sau bài này, mình không còn nghĩ game chỉ là gameplay.

Game là một hệ thống:

  • Có vòng lặp thời gian thực: game loop

  • Có dữ liệu cần đúng: database

  • Có thuật toán để chạy nhanh: top K, cache

  • Có kiến trúc client-server như một sản phẩm thật

Nếu mình viết lại bài này cho “lần đầu chạm vào game dev”, thì đây chính là điều đáng nhớ nhất:

Lập trình game là lập trình hệ thống, chỉ khác ở chỗ client là một thế giới sống.

Reader response

Bình luận

0 comment

Bài viết này chưa có bình luận nào.

Giới hạn 60 ký tự cho tên và 1000 ký tự cho nội dung.

Tác giả

Duc Hoang

Golang Backend Developer

Toi dang xay dung blog ca nhan de ghi lai qua trinh hoc lap trinh va cac project thuc hanh.