下载 App

云变量和排行榜怎么接入 —— 从存分数到显示排行榜的完整指南

05/09140 浏览开发交流
做好了一个游戏,玩家打了高分,退出再进来就没了——这体验太差了。
更让人郁闷的是:玩家辛辛苦苦打了 9999 分,却没法看到自己在全服排第几。
云变量和排行榜就是解决这两个问题的:
云变量:把数据存到云端,下次打开游戏还在。金币、分数、等级、装备配置……什么都能存。
排行榜:基于云端数据自动排序,玩家可以看到自己在全服的排名。
引擎已经把最难的部分(网络通信、数据持久化、排序算法)全做好了。你只需要调几个 API,告诉嗒啦啦:"帮我存一下分数"、"帮我拉一下排行榜"。
难度:入门级,会写基础游戏代码就行
————————————————

第一章:先搞懂两个核心概念

云变量有两个"抽屉"来存数据:
【values —— 存"任意类型"数据】
用 Set() 方法写入。可以存字符串、表、布尔值……什么类型都行。
适合存游戏配置、装备列表、存档数据。
但是 values 里的数据不能排行榜排序。
【iscores —— 存"整数"数据】
用 SetInt() 或 Add() 方法写入。只能存整数。
适合存分数、金币、等级、击杀数。
重点:iscores 里的数据可以排行榜排序。
一句话记住:要排行榜 → 用 SetInt/Add 存到 iscores;不需要排行榜 → 用 Set 存到 values。
读的时候,回调函数会同时给你两个参数:第一个是 values,第二个是 iscores。
————————————————

第二章:存一个分数(最简单的用法)

游戏结束时把分数存到云端,用 clientCloud:SetInt() 方法。第一个参数是 key 名字(比如 "high_score"),第二个参数是分数值,第三个参数是回调。回调里 ok 表示成功,error 表示失败。
读出来用 clientCloud:Get() 方法。Get 的回调函数有两个参数,第一个是 values,第二个是 iscores。用 SetInt 写进去的数据在 iscores 里(第二个参数),用 Set 写的在 values 里(第一个参数)。
比如存分数:clientCloud:SetInt("high_score", 9999, { ok = function() ... end })
读分数:clientCloud:Get("high_score", { ok = function(values, iscores) local score = iscores.high_score or 0 end })
注意 iscores.high_score 后面加 or 0 做兜底,防止没存过的时候返回 nil。
————————————————

第三章:整数增量 —— 加金币、加经验

有些数据不是"覆盖"式的,而是"累加"式的。比如金币每局打完加 100,用 clientCloud:Add()。
clientCloud:Add("gold", 100) 加 100 金币,clientCloud:Add("gold", -50) 扣 50 金币(买道具)。
Add 是原子操作——多个请求同时到达也不会出错。
记住:设置固定值用 SetInt,累加用 Add。
————————————————

第四章:存复杂数据 —— 配置、装备、存档

存表、字符串等复杂数据用 clientCloud:Set()。比如 clientCloud:Set("game_config", { difficulty = "hard", music = true, sfx = true }),整个表结构会完整保存到云端。
读出来的时候,表结构会完整保留。在回调的第一个参数 values 里取:local config = values.game_config,然后就可以直接访问 config.difficulty、config.music 这些字段。
————————————————

第五章:批量操作 —— 一次存多个、读多个

一个一个调 API 太慢,用批量操作一次搞定。
【批量写入】
用 clientCloud:BatchSet() 开始,然后链式调用 :Set()、:SetInt()、:Add(),最后调 :Save() 提交。一次请求可以同时存任意类型数据、设整数、加整数。Save 的第一个参数是备注名(随便写),第二个参数是回调。
【批量读取】
用 clientCloud:BatchGet() 开始,链式调用 :Key("gold"):Key("exp"):Key("level") 列出要读的 key,最后调 :Fetch() 拉取。回调里一次拿到所有数据。
推荐:游戏启动时用 BatchGet 一次性加载,游戏结束时用 BatchSet 一次性保存。
————————————————

第六章:排行榜 —— 让玩家看到自己排第几

只要你用 SetInt 或 Add 存了整数数据,就可以直接拉排行榜——不需要额外配置。
【拉取排行榜前 10 名】
用 clientCloud:GetRankList("high_score", 0, 10, { ok = function(rankList) ... end })。
参数依次是:排序用的 key 名、起始位置(0 表示第一名)、取多少人、回调。
回调里的 rankList 是一个数组,用 ipairs 遍历。每个 item 里:
item.userId 是玩家 ID。
item.iscore.high_score 是该玩家的分数(SetInt/Add 存的整数数据)。
item.userId == clientCloud.userId 可以判断是不是自己。
默认降序(分数高的排前面)。想升序排(比如用时最短排前面),在回调参数前面加一个 true:clientCloud:GetRankList("best_time", 0, 10, true, { ok = function(rankList) ... end })。
【查我自己排第几】
用 clientCloud:GetUserRank(clientCloud.userId, "high_score", { ok = function(rank, scoreValue) ... end })。rank 是排名数字,nil 表示还没上榜。
【查总共多少人上榜】
用 clientCloud:GetRankTotal("high_score", { ok = function(total) ... end })。
【附加字段:排行榜里同时显示多个数据】
如果排行榜想同时显示分数和游戏场次,可以在 GetRankList 的回调参数后面追加 key 名。比如 clientCloud:GetRankList("high_score", 0, 10, { ok = function(rankList) ... end }, "play_count"),最后的 "play_count" 就是附加字段。
拿到之后用 item.iscore.play_count 读取。附加字段可以写多个,逗号隔开就行。
————————————————

第七章:排行榜显示昵称 —— 两种方案按需选

排行榜拉出来只有 userId,没有昵称。根据游戏类型不同,有两种方案:
方案 A:TapTap 平台昵称。适合休闲游戏、不需要改名的场景。昵称来自 TapTap 账号系统,零成本,不用自己存。
方案 B:游戏内自定义昵称。适合 RPG、社交游戏、需要改名的场景。昵称存到云变量里,玩家自由取名。
一句话判断:玩家需不需要自己起名字?不需要 → 方案 A;需要 → 方案 B。
—— 方案 A:使用 TapTap 平台昵称(推荐大多数游戏)——
玩家注册 TapTap 时已经有昵称了,用全局函数 GetUserNickname() 查询。
流程是这样的:先拉排行榜拿到 rankList,收集所有 item.userId 放到一个数组里。然后调用 GetUserNickname({ userIds = 那个数组, onSuccess = function(nicknames) ... end })。返回的 nicknames 数组里每个元素有 userId 和 nickname 两个字段。把它们做成一个 userId → nickname 的映射表,最后遍历排行榜的时候查这个映射表就能显示昵称了。
需要两次异步调用(先拉排行榜,再查昵称),但不需要自己存任何数据。
—— 方案 B:使用游戏内自定义昵称 ——
如果你的游戏有"输入昵称"环节(RPG 开局取名等),昵称需要自己存到云变量里。
第一步,玩家起名时存到云变量:clientCloud:Set("nickname", nickname)。
第二步,排行榜里通过附加字段直接带出来。调用 GetRankList 时在最后加上 "nickname":clientCloud:GetRankList("high_score", 0, 10, { ok = function(rankList) ... end }, "nickname")。
拿到之后用 item.score.nickname 读取(注意是 item.score 不是 item.iscore,因为 Set 存的数据在 score 里)。
方案 B 的好处:一次请求搞定排行榜加昵称,不用嵌套回调。
记得游戏启动时用 clientCloud:Get("nickname") 检查玩家有没有设过昵称,没设过就弹出取名界面。
两种方案也可以混用:排行榜附加字段先取自定义昵称,对于没取名的玩家再用 GetUserNickname() 查平台昵称兜底。跟嗒啦啦说"帮我做排行榜,优先显示游戏内自定义昵称,没有的回退到 TapTap 平台昵称"就行。
————————————————

第八章:一个完整的实战流程

把前面的串起来,做一个"启动加载 → 结算保存 → 排行榜"流程:
【启动加载】游戏启动时用 BatchGet 一次性读取 gold、high_score、play_count 三个 key。在回调里把数据存到本地变量,iscores 里取整数数据,values 里取配置数据。
【结算保存】游戏结束时用 BatchSet 一次性保存:Add("gold", 本局金币) 累加金币,Add("play_count", 1) 累加场次,SetInt("last_score", 本局分数) 覆盖最后一次分数。Save 之后在回调里再检查是否需要更新最高分。
【更新最高分】先 Get("high_score") 读出当前最高分,如果新分数更高就 SetInt("high_score", 新分数) 覆盖。
【显示排行榜】GetRankList 拉前 10 名,附加字段带上 play_count。拿到后收集所有 userId,调 GetUserNickname 查平台昵称。两个回调嵌套完成后,把排名、昵称、分数、场次拼在一起显示。
————————————————

第九章:回调结构和错误处理

所有 API 都用同样的回调结构:ok 表示成功,error 表示失败(有错误码和原因),timeout 表示超时(可选)。
建议至少加上 error,不然出了问题你都不知道。
常见错误码:-429 表示请求太频繁,超过限频(读写各 300 次/分钟)。
————————————————

常见坑

坑 1:用 Set 存分数,发现不能排行榜
排行榜只能基于 iscores 排序。要排行榜 → 必须用 SetInt() 或 Add()。
坑 2:昵称方案没选对
不需要自定义昵称 → 直接用 GetUserNickname() 查平台昵称。需要自定义昵称 → 用 clientCloud:Set("nickname", name) 存云变量,排行榜附加字段取出来。见第七章。
坑 3:回调里 values 和 iscores 搞反
Set() 存的 → values(第一个参数),SetInt()/Add() 存的 → iscores(第二个参数)。
坑 4:Get 只返回你请求的那个 key
想同时读多个 key → 用 BatchGet。
坑 5:排行榜 item 里找不到昵称
排行榜不返回昵称,需要额外查询。见第七章。
坑 6:Add 传了小数
Add 只能传整数。需要存小数用 Set(),但不能排行榜。
坑 7:每帧都读写导致限频
读写各 300 次/分钟。正确做法:开始时读一次,结束时写一次,中间在内存处理。
————————————————

提示词·直接复制给嗒啦啦

【模板 1:给游戏加云端存档】
「帮我给游戏加上云端存档功能:游戏启动时用 BatchGet 加载玩家数据(金币、最高分、游戏场次),游戏结束时用 BatchSet 批量保存(加金币、加场次、存本局分数),如果本局分数超过最高分就更新。加上 error 回调处理失败。」
【模板 2:加排行榜(平台昵称)】
「帮我做一个排行榜:显示 high_score 前 10 名,每行显示排名、玩家昵称、分数,高亮自己那一行,底部显示我的排名和总人数。昵称用 GetUserNickname 查询 TapTap 平台昵称。用 UI 组件做界面。」
【模板 3:加排行榜(自定义昵称)】
「帮我做排行榜,游戏支持自定义昵称。玩家首次进入弹出取名界面,昵称用 clientCloud:Set("nickname", name) 存云端。排行榜用附加字段同时获取 nickname 直接显示。」
————————————————

总结

云变量和排行榜的核心就三件事:
第一,搞清楚存哪儿。
数字想排行榜 → SetInt/Add 存到 iscores。复杂数据不排行榜 → Set 存到 values。
第二,批量操作更高效。
游戏开始用 BatchGet 一次性加载,游戏结束用 BatchSet 一次性保存。不要一个一个调。
第三,昵称看需求选方案。
不需要改名 → GetUserNickname() 查平台昵称,零成本。需要改名 → 云变量自己存,排行榜附加字段带出来。
最后一个建议:不要每帧读写云变量。开始时读一次,结束时写一次,中间在内存里处理。
云变量和排行榜虽然简单,但对玩家体验的提升是巨大的。有了云存档不怕数据丢失,有了排行榜有了竞争动力。试试看吧。
别再烧积分了!从每次 2000 到每次 50 的血泪经验截图
别再烧积分了!从每次 2000 到每次 50 的血泪经验
适用场景:所有在用 TapTap Code 开发游戏的小白 难度:★☆☆☆☆ 背景最近群里总有人"炫耀"一次操作花了几千积分,说实话这不是值得高兴的事——这是在告诉所有人你的开发方式有根本性问题。我也走过这条弯路,所以来说说怎么改。 积分消耗的本质是什么积分 = AI 处理的 token 数量 = 你发给 AI 的内容 + AI 回给你的内容所以烧积分的本质只有两种: 你让 AI 做了大量无效/重
精华
66 赞
20 回复
03:06
为了不被斩杀,我只能做到这些了截图
为了不被斩杀,我只能做到这些了
之前一直申请不到计划3,之前说太花哨,后面说体量完成度不足,在我一番小作文下,编辑终于给了我解答,什么原生质感,玩家开局体验啥的。 本来计划2也够用,准备以后再优化了,结果计划2赠送的积分要砍半了,学生党实在消费不起,于是只能再冲一波计划3了 从周六中午到现在一天半时间,优化了一遍角色卡,战斗卡,还有抽卡界面,优化了新手教程,该说不说确实比之前要舒服些。 前半部分为新版,后半部分为旧版。 明天再次
28 赞
6 回复
如何提升你游戏中的UI美术水平截图
如何提升你游戏中的UI美术水平
一、请为你的游戏挑选一款合适的字体 很多开发者没有注意到其实UI界面中最重要的元素是字体,一款合适的字体能给整个游戏的界面感官带来蜕变。 请看案例 那么如何挑选适合自己的字体呢? 我总结出了一些小经验可供参考: 黑体:通用 宋体:古风、武侠、修仙 楷体:古风、武侠、修仙 圆体:卡通、动漫、Q版 科技:科幻、未来、电子 顺手分享一个免费可商用字体网站: 当然 如果你不知道自己的游戏适合什么风格
精华
122 赞
44 回复
01:27
《大二暑假,我用AI做了一款属于自己的游戏》截图
《大二暑假,我用AI做了一款属于自己的游戏》
本人自制游戏现已加入taptap封闭测试(仅适配安卓机型)欢迎大家前来尝试(八月十号可以正式开始游玩) 如果有建议或者bug反馈可以加入qq群928501443 #发现好游戏 #游戏日常 #浅评一下 #今天游戏圈发生了啥
3 赞
永恒虚空持续开发日记1——关于游戏中的新名词:场频截图
永恒虚空持续开发日记1——关于游戏中的新名词:场频
写在前边:首先感谢TapTap制造版主大大@汪崽 对于作品潜力的肯定,给与了我积分计划二的权限[表情_不好意思]。这边也在加紧开发改进各种功能中,期望尽快给大家带来成熟的版本。[表情_猫咪举手] 大家好,我是永恒虚空的制作人黑猫不详,大家叫我黑猫就好。从今天开始我将以后置开发日记的形式给大家分享我在TapTap制造中制作的游戏永恒虚空的开发过程,新人希望大家多多关照! 今天先给大家介绍我作品中最重
投票
3 赞
游戏自荐《少女终焉契约》截图
游戏自荐《少女终焉契约》
之前玩放置类型的rpg游戏的时候我就在想,现在游戏的操作有的太过于繁琐了,有没有一款休闲一点的,想上线就上线,离线的时候角色能自动行动的游戏呢?感谢TapTap制造,我按照我的想法开发出了现在这款游戏。 一、故事背景和UI 游戏的故事背景是传统的异世界穿越故事,玩家被女神召唤到异世界,随后组建工会,招募美少女,打怪升级探索世界。所以我选择了更加二次元萌系画风的UI风格,主页为各个主要的功能,点开来
8 赞
3 回复
开发心得-界面布局心得截图
开发心得-界面布局心得
大家好,我正在用 TapTap 制造制作一款2D 治愈林间徒步旅行游戏《徒步荒野》。 我分享一下我的开发心得,希望能有用,下面是一些界面布局的心得。 第一步:定版式、操作 先确定游戏是横版还是竖版、需要哪些操作按钮,敲定整体玩法思路。 我的玩法灵感参考《边境之旅》,主打散步看风景、沿途触发随机事件。 原版是 3D,考虑到自己是新手,选择2D 横版街机式来做,制作更简单、好上手。 第二步:敲定全局美
6 赞
2 回复
关于制作出质量很高的横版战斗角色的方法截图
关于制作出质量很高的横版战斗角色的方法
其实全篇就一句话,角色为啥做起来这么好看,因为我一帧一帧K的。 在做角色之前,我们需要一个角色的设计稿,这个东西很简单,你把人设写好剩下的交给AI就行了,所有图片,序列帧都可以让AI绘制和处理,学会绘图是你要制作高质量游戏的第一课。 这里拿我在做的角色举例,他的参考图是这样: 当你拥有了一个角色以后,就要想办法让她动起来了。 那么如何让她动起来,答案是序列帧。 在此之前你需要知道,最容易出现一个误
40 赞
12 回复
AI 生成的 NPC 太假?那是你没给它注入“灵魂” | TapTap 制造截图
AI 生成的 NPC 太假?那是你没给它注入“灵魂” | TapTap 制造
在多人或竞技游戏中,如何让 AI 队友不呆板?如何在高延迟下实现丝滑的竞技体验?本期我们采访了《猛攻兄弟》与《飞驰登山拉力赛车》的作者,分享他们的经验之谈~ 2026/03/30 - 2026/4/6 本期核心看点: 数据概览:该周上架游戏中动作策略模拟类持续领跑优质分发榜,占比均达 43.08%。 重点关注:让 AI 像活人,让同步“零延迟” —— 多人竞技开发实战 避坑指南:人工测评准入与分
精华
26 赞
6 回复
2D 等轴测视角:完整理论截图
2D 等轴测视角:完整理论
2D 等轴测视角:完整理论 一、视角的本质 什么是等轴测 人站在高处斜着往下看地面,地面上的方格子不再是正方形,而变成了菱形。这就是等轴测的视觉本质。 俯视(正上方看下去): 等轴测(斜上方看下去): ┌──┬──┬──┐ ◇ ├──┼──┼──┤ ◇ ◇ ├──┼──┼──┤ ◇ ◇ ◇ └──┴──┴──┘ ◇ ◇ ◇ 正方形网格经过旋转 + 压缩,变成了菱形网格。 为什么是 2:1
6 赞