OhMyGame
OhMyGame is the open-source studio for making games with AI. Design, build, playtest, and publish games in one app, with your own model keys.
Kỷ Nguyên Huyền Thoại — nhập vai cày cuốc, ép đồ, săn boss, Reset. Chơi ngay trên trình duyệt điện thoại và máy tính.
Translation pending
GamesJavaScript · HTMLGitHub @nguyentrunghieu01195OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Game nhập vai cày cuốc (kiểu MU) chạy trên trình duyệt PC và điện thoại. Viết bằng JavaScript thuần (ES Modules) + Canvas 2D, đóng gói bằng Vite.
npm install
cd server && npm install && cd .. # cài thư viện cho máy chủ
npm start # build game + chạy máy chủ tại http://localhost:8787 (chơi trực tuyến)
npm run dev # chạy thử tại http://localhost:5173 (tự tải lại khi sửa code)
npm run build # ra dist/index.html — game gói gọn 1 file
npm run build:design # ra dist-design/design.html — trang Design Sheet
npm test # test đơn vị (bang hội, Boss, đấu giá, công thành, thuế chợ…) — vài giây
npm run test:e2e # từ đầu đến cuối trên máy chủ thật (cần: cd server && npm install) — vài phút
npm run test:all # cả hai
node tests/run.mjs unit siege # chỉ chạy các file có tên chứa "siege"
Cần Node ≥ 18 (Dockerfile dùng Node 20). Test đơn vị giả lập thời gian để chạy cả vòng đời (đợt Boss, đấu giá, trận công thành theo tuần); test từ đầu đến cuối dựng máy chủ thật trên cổng riêng, dữ liệu tạm, đồng hồ máy chủ chỉnh bằng tests/helpers/timeshift.cjs. Thử tải công thành: node tools/load/siege-load.mjs 100 45.
config/ → core/ → systems/ → render/ → ui/ → main.js
(dữ liệu) (nền tảng) (luật chơi) (vẽ) (giao diện) (khởi động)
Tầng dưới không bao giờ gọi tầng trên. Riêng systems/ không chạm vào DOM hay canvas, nên sau này có thể chuyển nguyên khối lên server Node.js để làm bản nhiều người chơi.
| Thư mục | Vai trò | Ai thường sửa |
|---|---|---|
src/config/ | Dữ liệu tĩnh: class, bản đồ, quái, vật phẩm, mọi con số cân bằng (balance.js) | Game designer |
src/core/ | Trạng thái toàn cục G, event bus, lưu/tải game, hàm tiện ích | Lập trình viên lõi |
src/systems/ | Luật chơi: chỉ số, chiến đấu, rơi đồ, AI quái, ép đồ, reset, cửa hàng | Lập trình viên gameplay |
src/render/ | Toạ độ isometric, camera, ghép cảnh; render/art/<bộ>/ là các bộ đồ hoạ | Lập trình viên đồ hoạ / họa sĩ kỹ thuật |
src/ui/ | HUD, các bảng (mỗi bảng 1 file), điều khiển, màn hình bắt đầu | Lập trình viên UI |
src/design/ | Trang Design Sheet để duyệt đồ hoạ | Họa sĩ |
src/net/ | Kết nối máy chủ: hiện diện, chat, xếp hạng | Lập trình viên mạng |
server/ | Máy chủ Node.js (HTTP + WebSocket) | Lập trình viên backend |
core/state.js)G.S: dữ liệu nhân vật được lưu (cấp, chỉ số, đồ, ngọc…).G.P: chỉ số tính ra từ S bằng calcStats(), không lưu.G.R: thế giới đang chạy (quái, vật rơi, hiệu ứng). Được tạo lại khi vào bản đồ.systems/ phát sự kiện qua core/events.js (log, announce, levelUp, kill…), còn ui/hud.js lắng nghe và hiển thị. Nhờ vậy logic không biết gì về giao diện.
| Muốn… | Sửa ở đâu |
|---|---|
| Đổi tỉ lệ rơi đồ, EXP, giá, tỉ lệ ép | config/balance.js |
| Thêm bản đồ / quái | Thêm object vào config/maps.js |
| Thêm class nhân vật | config/classes.js (kèm STAT_FORMULA), thêm bộ kỹ năng trong config/skills.js (SKILL_LIST, CLASS_TIERS) + hàm trong systems/skills.js (SKILL_FN), cách vẽ trong render/art/*/hero.js |
| Thêm bảng giao diện | Tạo file trong ui/panels/ (gồm render() và actions), đăng ký trong ui/panels/index.js |
| Thêm bộ đồ hoạ mới | Tạo thư mục render/art/<tên>/ export đúng interface (xem render/art/index.js), rồi đăng ký vào ART_PACKS |
| Sửa nhiệm vụ, điểm danh, thưởng offline | config/quests.js (dữ liệu) và systems/quests.js, systems/offline.js (logic) |
| Sửa sự kiện (lịch, độ khó, thưởng, vé) | config/events.js (dữ liệu) và systems/events.js (luật chơi) |
| Sửa Tháp Vô Tận (cấp quái, thưởng, lượt/ngày, hiệu ứng tầng) | config/tower.js (dữ liệu) và systems/tower.js (luật chơi) |
| Thêm loại vũ khí / bộ giáp / hiệu ứng bộ | config/gear.js (dữ liệu), cách vẽ trong render/art/v2/gear.js |
| Thêm món thời trang | config/fashion.js (dữ liệu & điều kiện mở khóa), cách vẽ trong render/art/v2/gear.js |
| Sửa kỹ năng (sát thương, hồi chiêu, điều kiện học, chi phí nâng cấp) | config/skills.js |
| Đổi bộ đồ hoạ mặc định | CFG.ART_STYLE trong config/constants.js |
classic: phong cách bản thử nghiệm đầu tiên.v2 (mặc định): phong cách "Chibi Dark Fantasy", đã duyệt. Gồm kit.js (bút vẽ, tông màu), hero.js, monsters.js, environment.js, items.js (icon và đồ rơi), fx.js.Có thể chuyển qua lại giữa hai bộ ngay trong game: Cài đặt → Đồ hoạ.
Tiến độ nhiệm vụ được cập nhật bằng cách lắng nghe sự kiện (EV.KILL, EV.UPGRADE…), nên thêm loại mục tiêu mới chỉ cần phát thêm sự kiện từ hệ thống tương ứng.
| Sự kiện | Lịch mở cổng | Luật chơi |
|---|---|---|
| 🏰 Huyết Lâu | Phút :00 và :30 mỗi giờ, mở 5 phút | Hạ 30 quái để phá phép bảo hộ, phá Cổng Thành, rồi hạ Huyết Ma Vương trong 8 phút. Còn dư nhiều thời gian thì thưởng thêm. |
| 😈 Quảng Trường Quỷ | Phút :15 và :45 mỗi giờ, mở 5 phút | Sống sót qua 4 đợt quỷ trong 6 phút, đợt cuối có boss. Điểm càng cao thì thưởng càng lớn. |
makeRuntime trong systems/world.js) có giới hạn vùng đi lại (R.bounds).R.event có handler gồm update, onKill, onDeath, leave, hud). Có thể thêm loại khu vực mới theo cùng cách này.Máy chủ (server/) là Node.js + WebSocket. Nó phục vụ luôn file game nên chỉ cần 1 cổng: mở http://địa-chỉ:8787 là vào game và tự kết nối.
| Tính năng | Cách hoạt động |
|---|---|
| Tài khoản | Đăng ký / đăng nhập (tên đăng nhập + mật khẩu) ở màn hình bắt đầu. Không đăng nhập vẫn chơi được như khách (máy chủ cấp mã token lưu trong trình duyệt). Tên nhân vật trùng thì tự thêm số. |
| Thấy nhau trên bản đồ | Mỗi bản đồ là một phòng (m0…m9). Vị trí gửi 5 lần/giây, máy chủ gom và phát lại 10 lần/giây. Client nội suy để chuyển động mượt. Trong sự kiện hoặc Tháp thì không ai thấy ai. |
| Chat thế giới | Tối đa 120 ký tự, mỗi người cách nhau 1,5 giây. Lưu 50 tin gần nhất. |
| Thông báo hệ thống | Ép +9 trở lên, chế cánh cấp 2–3, hạ Boss, Reset, xong sự kiện, mỗi 5 tầng tháp. Client chỉ gửi loại thành tích, câu chữ do máy chủ soạn nên không chèn nội dung bậy được. |
| Bảng xếp hạng | Cấp & Reset, Tháp, Lực chiến; top 20, cập nhật mỗi 10 giây. Xem tại /api/rank. |
| Lưu dữ liệu | Hồ sơ lưu trong server/data/players.json (ghi nguyên tử, 2 giây/lần). Khi đông người thì thay server/src/store.js bằng PostgreSQL. |
Chống gian lận: người chơi có tài khoản chơi ở chế độ máy chủ quyết định (xem mục bên dưới) — chiến đấu, rơi đồ, ép đồ, Zen… đều do máy chủ tính. Người chơi khách vẫn chơi trên máy mình nên không được xếp hạng và không dùng được chợ.
Trên iPhone, file .html mở trong app Claude hoặc app Tệp không chạy được code, nên phải mở game qua một đường link web.
| Cách | Đăng nhập / lưu máy chủ | Chơi trực tuyến | Ghi chú |
|---|---|---|---|
| VPS + Docker (khuyên dùng) | ✔ | ✔ | Cần 1 VPS (~100–150k/tháng) và 1 tên miền. HTTPS tự động. |
| GitHub Pages | chỉ khi có máy chủ riêng | chỉ khi có máy chủ riêng | Miễn phí, chỉ chứa file game. Chơi khách, lưu trên máy. |
VPS + Docker (có HTTPS):
game.tenmien.com) về IP của VPS.DOMAIN và ADMIN_PASSWORD trong docker-compose.yml.docker compose up -d --build. Mở https://game.tenmien.com là vào game; dữ liệu tài khoản nằm trong volume kng-data (giữ nguyên khi cập nhật).docker compose up -d --build.Không có tên miền: docker build -t kynguyen . && docker run -d -p 80:8787 -v kng-data:/data --restart unless-stopped kynguyen rồi mở http://IP-máy-chủ
(chơi và đăng nhập được, nhưng không cài lên màn hình chính được vì thiếu HTTPS).
GitHub Pages: tạo repo Public → tải lên các file trong thư mục dist/ (index.html, manifest.webmanifest, sw.js, favicon.png, thư mục icons/) → Settings → Pages → Branch main → Save.
Muốn đăng nhập thì ở form đăng nhập nhập địa chỉ máy chủ (phải là https://, vì trang GitHub Pages là HTTPS).
npm ci && npm run build && cd server && npm ci && cd .. && PORT=8787 node server/src/index.js. Nên dùng pm2 để giữ tiến trình chạy, và Nginx/Caddy để có HTTPS. Có HTTPS thì client tự dùng wss://.PORT (mặc định 8787), DATA_DIR (thư mục lưu dữ liệu), DIST_DIR (thư mục chứa file game), ADMIN_PASSWORD (bật trang /admin), BACKUP_HOURS, BACKUP_KEEP.ws://địa-chỉ:8787/ws.10 loại vũ khí (config/gear.js → WEAPON_TYPES):
Mỗi loại có chỉ số riêng (sát thương, tốc đánh, tầm, sát thương kỹ năng, số mũi tên…). Món đồ lưu loại vũ khí ở trường wt.
12 bộ giáp (ARMOR_SETS): mỗi bậc có 2 dòng, món đồ lưu dòng ở trường line. Mặc 3 món cùng bộ kích hoạt hiệu ứng 1; đủ 5 món kích hoạt hiệu ứng 2 và hào quang màu bộ. Mỗi bộ có kiểu vai giáp, mào mũ và huy hiệu riêng.
Rèn lại (bảng Ép đồ): đổi loại vũ khí hoặc dòng bộ giáp, giữ nguyên bậc, cấp ép và dòng Hoàn Hảo. Phí tính theo bậc và cấp ép.
Thời trang (config/fashion.js): 6 trang phục, 4 mũ, 4 hào quang. Chỉ đổi ngoại hình, không cộng chỉ số. Mở khóa bằng điểm danh, Tháp, sự kiện, Reset, hoặc mua bằng Zen.
S.fashion = { owned, eq, show }.look.fa để người chơi khác nhìn thấy.Nhân vật V2 vẽ lại: mặt có lông mày, mắt có tròng và điểm sáng; tóc riêng theo class (Pháp Sư tóc dài, Xạ Thủ buộc đuôi ngựa). Tay và chân có khớp khuỷu, khớp gối; khi đánh có vệt chém; Kiếm Sĩ xoay người khi dùng Xoáy Kiếm.
config/skills.js → CLASS_TIERS, TIER_RESETS, S.tier): Bậc 1 khi mới tạo. Reset 1 / Reset 3 mở nhiệm vụ chuyển chức
(TIER_QUESTS, 5 bước: cấp độ, săn quái mạnh, boss, sự kiện/tháp, nộp lễ vật). Xong bước cuối mới lên bậc, nhận chỉ số vĩnh viễn TIER_BONUS.
Logic ở systems/quests.js (currentTierStep, claimTierStep), giao diện ở tab Chuyển chức của bảng Nhiệm vụ.
Kiếm Sĩ → Kiếm Vương → Kiếm Thánh · Pháp Sư → Đại Pháp Sư → Pháp Thần · Xạ Thủ → Thần Tiễn Thủ → Tiễn Thánh.SKILL_LIST): 4 chủ động, 1 tăng cường (buff), 1 nội tại. Mỗi kỹ năng cần cấp nhân vật + bậc để học, trả bằng Zen.rankLevelReq), Zen + ngọc (rankCost).
Cấp tối đa theo bậc: 5 / 8 / 10 (RANK_CAP), nên muốn max kỹ năng phải Reset.S.skills.bar): phím 1–4 (Space = ô 1), bình thuốc chuyển sang Q/W, K mở bảng Kỹ năng.
AUTO tự dùng các kỹ năng trên thanh: buff trước, chiêu hồi lâu trước; có thể tắt tự dùng từng kỹ năng.m.stun), làm chậm (m.slowT), hút (hố đen). Buff lưu ở G.R.p.buffs và được cộng trong calcStats.SKILL_LIST → nếu là chủ động thì thêm hàm cùng tên vào SKILL_FN (systems/skills.js),
icon sk_<id> trong render/art/v2/items.js, hiệu ứng (nếu cần) trong render/art/v2/fx.js.migrateSkills): giữ kỹ năng đầu tiên ở ô 1.config/maps.js, 72×72 → 96×96 ô): Đồng Cỏ Xanh, Rừng Bóng Tối, Đầm Lầy Độc, Hầm Mộ, Hẻm Núi Đá Đỏ, Băng Nguyên,
Bờ Biển San Hô, Sa Mạc, Núi Lửa Hỏa Ngục, Thiên Giới Đọa Lạc. Mỗi bản đồ có 4 loại quái + 1 boss.systems/world.js → generateMap): nhiễu giá trị tạo hồ/dung nham/vách đá, thị trấn ở giữa, đường mòn nối các bãi quái,
4 vùng cấp độ xa dần thị trấn (càng xa càng mạnh), hang boss ở rìa. Mặt đất vẽ theo khối 12×12 ô có cache nên bản đồ lớn vẫn mượt.systems/nav.js): lưới ô chặn, A* 8 hướng có làm mượt, đi trượt dọc vật cản. Người chơi, quái và AUTO đều dùng chung.ui/minimap.js): góc phải trên, hiện thị trấn, quái, tinh anh, boss, người chơi khác. Bấm ⤢ hoặc phím N mở bản đồ lớn:
chạm vào bất kỳ đâu để tự đi tới (AUTO tạm dừng tới khi đến nơi), có danh sách khu vực theo cấp.ui/startScreen.js, net/account.js, server/src/accounts.js): tên đăng nhập 3–20 ký tự (chữ không dấu, số, _, .), mật khẩu ≥ 6 ký tự,
băm bằng scrypt + muối riêng. Phiên đăng nhập là token ngẫu nhiên (máy chủ chỉ lưu bản băm SHA-256), hết hạn sau 90 ngày không dùng, tối đa 8 thiết bị.
Giới hạn thử: 20 lần/10 phút mỗi IP, 8 lần sai/10 phút mỗi tài khoản. Có đổi mật khẩu (đăng xuất mọi thiết bị khác).POST /api/register, POST /api/login, POST /api/logout, GET /api/me, GET/PUT/DELETE /api/save, POST /api/password (header Authorization: Bearer <token>, có CORS để chạy trang game ở tên miền khác).public/manifest.webmanifest, public/sw.js, src/pwa.js): cài lên màn hình chính (Android/PC có nút Cài game vào máy; iPhone: Safari → Chia sẻ → Thêm vào MH chính),
mở toàn màn hình, mở được khi mất mạng. Trang game lấy bản mới từ mạng trước nên cập nhật là có ngay; API tài khoản không bao giờ bị lưu đệm.ui/tutorial.js): 7 bước có vòng sáng chỉ đúng nút (đi lại, đánh quái, bật AUTO, cộng điểm, bản đồ khu vực, kỹ năng),
thưởng 30.000 Zen + 20 bình máu/mana. Bỏ qua được; xem lại trong Cài đặt → Hướng dẫn.ui/input.js): nút phản hồi ngay khi nhấc tay (không chờ sự kiện click), chạy được cả trong trình xem nhúng.Áp dụng cho mọi người chơi có tài khoản. Máy người chơi chỉ gửi lệnh và vẽ lại thế giới; máy chủ chạy luật chơi thật.
Máy người chơi Máy chủ (server/src/host.js)
chạm đất / chạm quái / bấm nút ──act──▶ kiểm tra tham số (src/net/actions.js) → chạy đúng hàm luật chơi
vẽ, nội suy, âm thanh, rung ◀─snap── thế giới quanh nhân vật 10 lần/giây (chỉ phần thay đổi)
bảng nhân vật, túi đồ… ◀──st─── phần bản lưu (G.S) bị đổi, 4 lần/giây
chữ sát thương, log, hiệu ứng ◀──ev─── sự kiện game (giết quái, lên cấp, ép đồ…)
src/systems/* (luật chơi không đụng DOM). Mỗi người chơi là 1 thế giới riêng; vì code dùng biến G toàn cục nên máy chủ
"đổi ngữ cảnh" (gán G.S/G.R/G.P của người đó → chạy → cất lại) trong vòng lặp 20 lần/giây.act(tên, ...tham số) (src/net/actions.js): ~35 hành động (đi, đánh, kỹ năng, bình thuốc, cộng điểm, trang bị, bán, ép đồ, rèn, chế cánh,
mua, nhận nhiệm vụ/điểm danh/thưởng vắng mặt, thời trang, dịch chuyển, sự kiện, tháp, Reset, tuỳ chọn, hướng dẫn). Mỗi hành động có bộ kiểm tra kiểu & giới hạn tham số
(vd. mua số âm, cộng điểm vào chỉ số không tồn tại → bị chặn). Chơi khách thì act() chạy ngay trên máy, chơi tài khoản thì gửi lên máy chủ.PUT /api/save bị từ chối; máy chủ tự ghi bản lưu mỗi 30 giây và khi thoát. Sửa Zen/cấp trên máy chỉ đổi số hiển thị, máy chủ không nhận.src/ (Dockerfile đã chép sẵn). Khi sửa luật chơi trong src/, phải khởi động lại máy chủ.Cần tài khoản và đang trong game. Mở bằng nút 🏰 bên phải màn hình.
GUILD_QUESTS trong config/guild.js, tiến độ theo dõi trong systems/quests.js). Mỗi nhiệm vụ +30 điểm cống hiến cho bang và Zen cho người làm, nhận đủ bộ thêm +40 điểm. Nhận thưởng qua máy chủ (POST /api/guild/quest).src/config/guild.js; luật & dữ liệu ở server/src/guilds.js (guilds.json, có trong sao lưu / khôi phục). Máy chủ gắn S.guild vào nhân vật khi vào game và mỗi lần bang thay đổi — không nhận từ máy người chơi. Buff tính trong systems/stats.js.Hằng ngày lúc 12:00 và 20:00 (giờ Việt Nam), cổng mở 15 phút. Vào bằng 🏰 Bang hội → tab 🐲 Boss (cần cấp 30 và đã vào bang).
server/src/arena.js): Boss đuổi người gần nhất, đánh thường, và định kỳ báo trước rồi đập đất trúng nhiều người cùng lúc. Sát thương Boss tính theo % máu người bị đánh nên người cấp thấp vẫn tham gia được; chết thì hồi sinh tại điểm xuất phát.relayEffects trong server/src/host.js). Hiệu ứng sao chép đánh dấu foreign nên không gây sát thương lần nữa. Hiệu ứng bám theo người (buff) và hiệu ứng của Boss không sao chép.GBOSS_REWARDS) thành các phiên đấu giá: 15 phút đầu chỉ người đã đánh Boss của bang đó được đặt giá (tiền thắng được chia đều cho những người đã đánh); không ai đặt → ra Đấu giá thế giới 30 phút, ai cũng đặt được (tiền không chia); vẫn không ai đặt → quà tặng người gây sát thương cao nhất bang. Mỗi lần trả giá phải cao hơn ≥ 5%; Zen bị giữ ngay khi đặt, bị vượt thì hoàn qua hộp thư và báo ngay cho người bị vượt. Chống đặt giá phút chót: đặt khi còn dưới 30 giây thì phiên được cộng thêm 30 giây (tối đa 10 phút; số ở AUCTION trong src/config/gboss.js). Mở bằng nút 🔨.DIY trong src/config/gboss.js): thời gian cày đủ đồ Hoàn Hảo + ngọc (số đo từ bot mô phỏng và bảng ép đồ có tính rớt cấp / vỡ đồ) × thu nhập cày 2M Zen/giờ, khởi điểm = 35% giá tự cày; đồ bậc cao × thêm. Mỗi phiên hiện dòng "Tự kiếm / tự ép ≈ …" để người chơi so sánh. Đổi zenPerHour / startFrac là cả bảng giá đổi theo.GBOSS.minActiveSec; mỗi giây có gây sát thương mới được tính, nên đứng yên không cộng giờ) mới được tính là tham gia — nhận thưởng tham gia, được chia tiền đấu giá và đặt giá trong bang. Tính theo thời gian chứ không theo % sát thương nên người yếu vẫn đạt được. Tiến độ hiện trong tab Boss (⚠ = chưa đủ) và trên HUD trong trận. Biến môi trường chỉ dùng để thử nghiệm.Hằng tuần Chủ nhật 20:00 (giờ VN), trận kéo dài 30 phút. Mở bằng 🏰 Bang hội → tab 🏯 Công thành (cấp 50 trở lên).
SIEGE.pvpCoef). Chết hồi sinh sau 6 giây tại điểm xuất phát của bang, bất tử 3 giây, không mất EXP. PvP chỉ có trong trận này.server/src/siegebrain.js) giữ máu cổng, ngai, giờ giữ. Người địch trong tầm (tối đa 30 gần nhất) được đặt vào thế giới của mỗi người dưới dạng mob đại diện (m.pvp) nên toàn bộ code đánh quái (kỹ năng, đạn, AUTO) dùng được để đánh người; sát thương được ghi lại và máy chủ trừ máu thật của người bị đánh (hitMob → siegeHit trong systems/combat.js). Hiệu ứng chiêu của đồng đội và địch hiện qua relayEffects.siege.json (chủ thành, đăng ký, lịch sử; có trong sao lưu / khôi phục). Số liệu ở ; luật trong trận ở .Cần đăng nhập tài khoản và có máy chủ. Mở bằng nút ⚖️ bên phải màn hình, hoặc Túi đồ → Bán ở chợ.
server/src/market.js): mọi thao tác gửi kèm bản lưu + rev, máy chủ kiểm tra đồ có thật rồi mới trừ, lưu lại và trả "delta" cho máy người chơi áp dụng.
Đồ đang bán / đang khoá nằm ở máy chủ (market.json, có trong bản sao lưu); máy chủ khởi động lại giữa lúc giao dịch thì đồ tự trả về hộp thư. Vật phẩm chuyển sang người khác được cấp id mới.Chợ và giao dịch thao tác thẳng trên nhân vật đang chạy ở máy chủ — không nhận dữ liệu nhân vật từ máy người chơi, nên không tạo được đồ/Zen giả để bán.
Dữ liệu nằm ở đâu (thư mục DATA_DIR, khi chạy Docker là volume kng-data):
| File | Nội dung |
|---|---|
accounts.json | Tài khoản: tên đăng nhập, mật khẩu đã băm, phiên đăng nhập, trạng thái khoá |
saves/<id>.json | Toàn bộ nhân vật của từng tài khoản |
players.json | Hồ sơ trực tuyến (tên hiển thị, cấp, tháp, lực chiến) cho bảng xếp hạng |
market.json | Hàng đang bán ở chợ, lịch sử bán, đồ đang khoá trong giao dịch |
(trong accounts.json) | Hộp thư của từng tài khoản |
backups/kng-YYYYMMDD-HHMMSS.json.gz | Bản sao lưu (gộp cả 3 thứ trên) |
Người chơi khách (không đăng nhập) chỉ được lưu trong trình duyệt của họ.
Sao lưu tự động (server/src/backup.js): mỗi BACKUP_HOURS giờ (mặc định 24), giữ BACKUP_KEEP bản (mặc định 14). Máy chủ vừa bật mà bản gần nhất đã cũ thì sao lưu ngay.
Bản sao lưu vẫn nằm trên cùng VPS → nên tải về máy định kỳ từ trang quản trị (hoặc dùng rclone/scp chép thư mục backups/ sang nơi khác).
Khôi phục: dừng máy chủ → node server/src/restore.js <file .json.gz> → bật lại. Dữ liệu đang có được chuyển sang before-restore-<thời gian>/ để quay lại được.
Với Docker: docker compose stop game → docker compose run --rm game node server/src/restore.js /data/backups/<file> → docker compose start game.
Trang quản trị https://tên-miền/admin — bật bằng biến môi trường ADMIN_PASSWORD (ít nhất 10 ký tự, không dùng mật khẩu mẫu; nếu yếu thì trang tự tắt):
Người bị khoá: không đăng nhập được, bị ngắt kết nối ngay, biến mất khỏi bảng xếp hạng. Đăng nhập quản trị giới hạn 10 lần thử/10 phút mỗi IP, phiên quản trị hết hạn sau 12 giờ.
node tools/sim/balance.mjs <knight|wizard|archer> [giờ tối đa] [số Reset] — bot tự chơi bằng đúng logic game (không vẽ, ~1 giây cho 1 giờ chơi),
in ra mốc cấp, Zen, ngọc, số lần chết, cấp kỹ năng, kỷ lục tháp sau mỗi Reset. Chạy lại sau mỗi lần sửa config/*.js để kiểm tra.
Kết quả hiện tại (EXP x3, bot chơi "chăm, không nạp", có chơi thử Huyết Lâu + Quảng Trường Quỷ ở cấp 50/150/250 và sau mỗi Reset):
| Kiếm Sĩ | Pháp Sư | Xạ Thủ | |
|---|---|---|---|
| Reset 1 | ~13.4h | ~12h | ~11h |
| Lên Bậc 2 | 15.6h | 13.8h | 13.9h |
| Lên Bậc 3 | 24.8h | 20.4h | 21.5h |
| Kỷ lục tháp sau Reset 3 | 59 | 79 | 47 |
| Sự kiện | Thắng hết | Thua Quảng Trường Quỷ ở cấp 50, còn lại thắng | Thua Quảng Trường Quỷ ở cấp 50, còn lại thắng |
Lưu ý: bot chơi tối ưu, không nghỉ; người chơi thật thường chậm hơn 1.5–2 lần. Kết quả dao động ~±1h mỗi lần chạy (ngẫu nhiên).
Các lượt chỉnh gần nhất: ngọc rơi giảm ~65%, quái bản đồ sau mạnh hơn tới +30%, EXP tháp tính theo cấp người chơi, máu quái tháp +3%/tầng,
chi phí kỹ năng theo cấp yêu cầu, lễ vật chuyển chức 15M / 30M Zen, Bậc 3 cần tháp tầng 40; Xạ Thủ: tốc đánh 1.1, sát thương /11,
Mưa Tên 4 mục tiêu hồi 2.6s; Pháp Sư: sát thương /3.6, HP cao hơn, Mưa Thiên Thạch hồi 2.6s; quái sự kiện −40% sát thương, cùng cấp người chơi,
bản đồ rộng: AUTO bỏ qua quái không với tới sau 4 giây, giới hạn cấp quái của AUTO không áp dụng trong Tháp/sự kiện; Quảng Trường Quỷ sinh 4 quái/lượt (tối đa 10 cùng lúc); AUTO ưu tiên nhặt đồ trong 4.5 ô khi không bị đánh.
Khi kết nối máy chủ: EXP tối đa x3 (onlineMaxExpRate) và tắt chế độ thử sự kiện.
render/juice.js: rung màn hình (EV.SHAKE, chí mạng, chiêu lớn, bị boss đập), chữ sát thương 4 kiểu (thường / kỹ năng / chí mạng nảy to / mất máu),
viền đỏ khi bị đánh mạnh hoặc HP < 30%, hào quang bậc nhân vật (Bậc 2 xanh bạc, Bậc 3 vàng + vầng sáng trên đầu — người chơi khác cũng thấy),
thời tiết theo bản đồ (hoa bay, mưa + sấm, đom đóm ma, tuyết, tàn lửa, lông vũ). Tắt được rung/thời tiết trong Cài đặt.MONSTER.bossSlam (config/balance.js).audio/audio.js: âm thanh tổng hợp bằng Web Audio (không cần file): ~35 hiệu ứng gắn vào event bus + nhạc nền thủ tục theo từng bản đồ,
nhạc dồn dập trong sự kiện/tháp. Âm lượng hiệu ứng & nhạc chỉnh riêng trong Cài đặt (lưu trên trình duyệt).design/Ky Nguyen Design System.html (xuất từ Claude Design).src/styles/theme.css (nạp sau main.css, chỉ ghi đè hình thức) + src/styles/fonts.css
(Philosopher 700 cho tiêu đề, Be Vietnam Pro 400/600/700/800 cho nội dung & số — nhúng sẵn, chạy offline).outdoor của design system (độ sáng +15%).design/Character Style Guide.html. Bản vẽ trong game: src/render/art/v2/chibi.js (renderer 3 class) + heroDraw.js (cầu nối drawHero, cache, cánh / thời trang). Xem trực tiếp: /characters.html (thêm #80 để mở sẵn cỡ 80px).part). Bộ Da khớp đúng bảng màu của guide.gear.js)
qua phép ánh xạ toạ độ đầu/thân (toHead, toTorso).hero.js (đổi import trong render/art/v2/index.js nếu cần so sánh).GBOSS_MIN_ACTIVE_SECGBOSS.participation). Chết trong đấu trường chỉ hồi sinh sau vài giây tại điểm xuất phát, không mất EXP. Dữ liệu ở gboss.json (có trong sao lưu / khôi phục). Số liệu ở src/config/gboss.js; luật trong trận ở src/systems/gboss.js.src/config/siege.jssrc/systems/siege.jsnode tools/load/siege-load.mjs 100 45, 100 bot AUTO cùng 1 trận, máy dev): tick máy chủ trung bình ~21 ms / 50 ms (đỉnh ~27 ms), mạng ~6 KB/giây mỗi người sau nén (~4.4 Mbit/s tổng). Máy chủ yếu hơn thì hạ SIEGE.maxPerGuild (hoặc maxProxies).SIEGE_TEST=1 để dùng POST /api/siege/_debug (bắt đầu trận ngay, bỏ qua lịch), SIEGE_MIN_ACTIVE_SEC để hạ thời gian chiến đấu tối thiểu.siegeAuto trong systems/siege.js, gắn qua HOOKS.auto).royal), icon bọc ánh vàng.battle đang diễn ra)./admin → tab Công thành: xem trạng thái, bang đã đăng ký (huỷ + hoàn phí), ép bắt đầu trận (bỏ qua lịch, cần ≥ 1 bang công), huỷ trận đang diễn ra (hoàn phí, không đổi chủ thành), đặt / gỡ chủ thành, xem bảng điểm trận và lịch sử.