现在开始设置基础架构: 我想要参加solana的黑客松,要求是使用solana,构建项目,我打算做一个类似背包英雄的rogelike卡牌游戏,
我先帮你把这件事落成一个能开工的基础方案:确认目前 Solana 黑客松/开发栈的最新入口,然后给你一套适合“背包英雄式 roguelike 卡牌游戏”的链上/链下架构、仓库结构和第一阶段里程碑。
可以,先别急着上链太多逻辑。你这个方向很适合做成 “链下跑核心战斗,链上承载资产、赛季结果和可验证成就” 的 Solana 黑客松项目,这样最容易在时间内做出 能玩、能演示、能解释为什么必须用 Solana 的作品。Solana 官方现在仍把黑客松作为线上项目启动平台,项目需要明确“构建在 Solana 上”;官方开发文档也在持续推荐从现成模板、Anchor 和游戏示例入手。
项目一句话可以先定成:
Bag of Fate / Packrun
一个“背包管理 + roguelike 卡牌战斗”游戏:玩家在局内收集卡牌、遗物、背包物品,通过背包摆放关系影响战斗牌组、费用、触发和成长;局外把关键成果写到 Solana,形成资产、赛季榜和可交易/可组合的游戏身份。
这个定位好处是:
第一版最稳的架构是:
原因很现实:Solana 程序适合做 状态确认、资产归属、可组合性,但不适合把大量 roguelike 局内状态每一步都写链。Solana 官方开发资料也强调要关注计算消耗,并提供面向游戏的模板和 SDK。
先把玩法压到这几个模块:
这一版就已经足够做 demo 了。
你需要把“上链理由”讲得非常具体:
每次成功通关后,生成一个可验证战绩记录:
这些信息写到 Solana,形成:
遗物/称号/皮肤资产化
这样就能回答“为什么不是普通网页游戏”的问题。
可组合身份
玩家地址本身就是身份,后面可以扩展:
Solana 的游戏入口和生态页也在强调这种面向游戏的开发能力与生态工具支持。
最适合黑客松的是二选一:
适合你想快速做浏览器可玩 demo。
Solana 官方文档明确给了 Next.js/React + Anchor 的游戏路径,也提到 Phaser 模板适合浏览器游戏起步。
适合你更重视表现力,但黑客松里开发速度可能稍慢。Solana 文档列出了 Unity SDK 作为社区游戏 SDK 之一。
你的题材我更推荐 A。
原因:卡牌 + 背包格子 + 浏览器演示,更快。
Anchor 目前仍是 Solana 上最常见、最快进入生产开发的框架之一,官方和 Anchor 文档都把它放在 Quickstart / Basics 路径里。
packrun/
apps/
web/ # Next.js 前端 + 钱包接入 + 游戏 UI
game/ # Phaser 游戏核心(也可并入 web)
programs/
packrun_program/ # Anchor program
packages/
sdk/ # 前端调用 program 的 TS SDK
game-core/ # 纯 TS 战斗规则、背包计算、卡牌结算
shared/ # 类型、常量、schema
backend/
api/ # leaderboard / replay / anti-cheat helpers
assets/
cards/
relics/
enemies/
docs/
pitch.md
economy.md
architecture.md
先做最少 4 类 PDA:
seeds = ["player", player_pubkey]
fields:
- authority
- username / nickname
- total_runs
- best_score
- highest_floor
- unlocked_flags
seeds = ["run", player_pubkey, run_id]
fields:
- player
- run_id
- seed
- score
- floor_reached
- result
- deck_hash
- relic_hash
- created_at
seeds = ["season", season_id]
fields:
- season_id
- start_ts
- end_ts
- ruleset_hash
seeds = ["achievement", player_pubkey, achievement_id]
fields:
- player
- achievement_id
- unlocked_at
这已经够 demo 了。不要先做复杂经济系统。
你做成“背包英雄 + 卡牌 roguelike”,最好突出一个真正新鲜的核心机制:
背包布局直接改写牌组行为
比如:
这样你有三层策略:
这会比“普通卡牌 + 普通 NFT”更容易打动评委。
Demo 顺序建议:
这样 2~3 分钟就能讲明白“游戏好玩 + Solana 有必要”。
把第一版限制为:
先别碰 Anchor,先做:
只做:
init_playersubmit_rununlock_achievement就够了。
你可以先用这个版本:
我们正在构建一款运行在 Solana 生态上的 roguelike 卡牌游戏。玩家在 run 中通过管理背包布局、收集物品与构建牌组来完成战斗。与传统卡牌游戏不同,背包中的物品位置关系会直接影响战斗卡牌的费用、效果和连锁触发。Solana 在本项目中负责玩家身份、战绩记录、赛季排行榜与稀有成就资产,使游戏进度和高光时刻具备可验证、可拥有和可组合的特性。
这是个很好的黑客松题目。
因为它同时满足:
下一步最合适的是:我直接帮你把这项目拆成一份 “技术架构 + 模块清单 + 2 周开发排期”,再继续往下走。
关于链上交互,是做成每场小战斗都与链上交互,整场游戏完成后一起与链上交互,还是每次操作/每轮抽牌与链上交互
我先把这件事定成一个可落地的决策:比较 3 种链上交互粒度,然后给你一个最适合黑客松和真正能跑起来的方案。
结论先给你:
黑客松版本,最优方案是:整场 run 结束后,或在少数“关键节点”与链上交互。
不要做“每次操作/每轮抽牌都上链”,也通常不要做“每场小战斗都上链”。
原因不是“不能”,而是 产品体验、费用、失败率、开发复杂度 都会明显变差。Solana 虽然手续费低,但每笔交易依然有基础费;而且即使交易失败,费用通常也会被收取。官方也明确强调,程序应尽量减少计算消耗,并注意 compute budget 与优先级费用。
比如:
我不建议。
为什么:
适合它的只有一种情况:
你做的是“全链上博弈”本身,链上可验证过程就是作品卖点。
但你这个题材的卖点显然不是这个。
比如:
可以做,但不是最优默认。
优点:
缺点:
什么时候适合:
你要把“每一场战斗”作为比赛单位,比如:
对于你现在这个“背包英雄式 roguelike 卡牌游戏”首版,我觉得这不是最优起点。
比如:
这是我最推荐的默认方案。
优点:
init_playerstart_run(可选)submit_rununlock_achievement不是纯粹只在最后一次交互,而是:
可选做一个轻量 start_run
记录:
作用:
做 submit_run
记录:
只在非常少的高价值事件上链,比如:
这个结构比“只最后提交”更稳一点,但仍然不会破坏游玩体验。
因为它处在一个最尴尬的位置:
所以除非你的比赛单位天然就是“一场战斗”,否则不值得。
我建议你第一版链上数据结构只保留这些:
这套就足够黑客松 demo 了。
推荐架构:
链下完成整个 run 的战斗与数值结算,链上只做 run 开始承诺 + run 结束结果提交 + 成就/排行榜。
这是当前最平衡的选择:
下一步我可以直接给你画出这套 “游戏前端 + Anchor program + 提交流程”的时序图和账户结构。
如果使用全局上链,在安全方面,如果有人修改了战斗奖励中稀有卡牌掉落的概率,会难以检测吗,
我先把风险边界说清楚:如果“整局链下、最后才上链”,那么掉落概率这种核心判定一旦完全在客户端做,确实很难靠链本身发现。接下来我给你拆成“到底难在哪、哪些作弊最现实、黑客松阶段怎么补到够用”。
会,而且不是“有点难”,而是:
如果稀有卡牌掉落概率是在客户端本地算的,而你只在整局结束时把结果提交上链,那么玩家篡改掉落概率这类作弊,链本身通常看不出来。
因为 Solana 程序只会看到你最后提交的结果;程序本身是无状态代码,只有你显式传入和保存的状态才会参与验证。换句话说,链不会自动知道你这张稀有卡到底是按 1% 掉的,还是你把本地代码改成了 100% 掉。
你现在讨论的是一种典型问题:
“游戏过程在链下,结果在链上”
这类架构最大的安全弱点,不是交易伪造,而是 结果生成过程不可见。
如果以下事情都在客户端完成:
那攻击者只要改前端 JS、改本地内存、挂代理、改 API 返回,最后再提交一个“看起来合法”的结果就行。
链上只能验证:
但很难验证“这个掉落是不是按正确概率算出来的”。这也是为什么可验证随机数在链上游戏里会被单独当成一类基础设施来做。Switchboard 的文档就直接说明了:链上随机数很难,随机性通常需要由外部机制提供并把单一结果提交到链上,否则不同节点各自算随机会导致状态不一致。
如果有人把稀有卡掉率从 1% 改到 5%,他不需要每局都出神卡。
他只需要“略微提高”,长期看收益巨大,但单局数据看起来并不夸张。
这比“直接提交 99999 分”更难抓,因为后者很像异常值,前者更像运气好。
如果链上只存:
你没有:
那就几乎没法重演“这张稀有卡到底为何掉出来”。
如果回放日志也是客户端自己生成的,攻击者可以连日志一起伪造。
所以“我有 replay 文件”不自动等于“我能证明结果真实”。
它的正确理解应该是:
全局上链不是绝对不安全,而是你必须把“高价值结果的生成权”从客户端手里拿走。
对于你这个项目,最关键的不是“每轮抽牌上链”,而是:
这些必须至少做到下面三种中的一种。
这是黑客松最实用的。
流程:
非常适合。
这是更正统的链上公平方案。
Switchboard 的 Solana 随机数文档和教程就明确围绕 verifiable randomness 和 commit-reveal 模式展开,核心目标就是让结果不是客户端想改就能改。
流程可以是:
seed_commit 上链适合只用在“高价值掉落”上,不适合全覆盖。
比如:
普通白卡蓝卡就别上这个。
这是一种折中:
适合做第二阶段,不适合当首个安全底座。
那答案就是:
对,别人篡改稀有卡掉率会相当难检测。
不是完全检测不到,但通常只能靠:
这不够稳。
我建议你把奖励分级:
例如:
链下生成即可。
就算有人刷一点,也不至于破坏整个 demo。
例如:
不要让客户端直接决定。
至少用这两种之一:
例如:
必须由链上程序或可信结算服务控制发放条件。
全链下
链下算
由后端结算并签名
提交时附带:
这样别人就算把本地概率改了,也拿不到有效签名,因此无法把伪造的稀有奖励变成正式链上结果。
你可以在路演时这样讲:
普通战斗与构筑过程在链下完成,以保证 roguelike 的流畅体验;但所有高价值掉落、稀有奖励和赛季相关结果都通过受控结算流程生成,并在提交到 Solana 前经过签名校验或可验证随机机制确认,避免客户端篡改掉率带来的伪造资产问题。
这句话很像一个成熟项目会说的话。
“整局结束后才上链”本身不是问题;真正的问题是“谁决定高价值随机结果”。
如果答案是“客户端自己决定”,那确实很难检测作弊。
如果答案是“服务端签名”或“可验证随机数”,那就能把风险压到黑客松可接受范围内。
我可以下一条直接给你一版 “稀有掉落安全方案设计图”,包括:
1.我不希望加入后端这种过于中心化的机制 2.有没有可能做成类似杀戮尖塔的随机机制也就是你说的由seed控制整局游戏的掉落机制,这样链上只要验算就能确定是否作弊,这种有什么缺陷
你的这个方向是对的,而且是目前最“优雅”的去中心化方案之一:
用 seed 决定整局所有随机 → 游戏完全确定性 → 链上只验证结果
这本质上就是:
Deterministic Roguelike + Verifiable Replay / Proof
很多“类杀戮尖塔 + 公平竞技”的系统都会往这个方向走。
✅ 可以做,而且很适合你这种游戏类型
❗ 但它不是“没有缺陷”,而是有几个非常关键的坑:
最大问题不是“能不能验证”,而是:
👉 如何防止玩家“挑 seed / 试错 / 预知未来”
下面我给你完整拆清楚。
你想做的是:
seedrng = PRNG(seed)
提交:
验证方式:
👉 如果一致 → 合法
👉 如果不一致 → 作弊
因为:
你甚至可以说:
“所有 run 都是可重放、可验证的”
这在黑客松里是很加分的叙事
如果 seed 是玩家自己生成或可预测:
然后只提交“好的一局”
👉 这叫:
seed grinding / cherry picking
如果 seed 是:
seed = current_timestamp
玩家可以:
👉 你排行榜就废了
因为:
seed → 所有随机都确定
玩家可以:
👉 这叫:
perfect foresight(完全预知)
这会:
你说:
“链上验算就能确定是否作弊”
理论对,但现实是:
原因:
👉 所以:
链上通常不会真的 replay 整局
而是:
👉 只验证摘要(hash / signature / commitment)
你必须保证:
否则:
👉 重放结果不一致 → 误判作弊
流程:
commit = hash(secret_seed)
用:
seed = hash(secret_seed + run_id)
提交:
secret_seed
链上验证:
hash(secret_seed) == commit
👉 玩家不能中途改 seed
例如:
seed = hash(
player_pubkey +
slot +
recent_blockhash
)
👉 玩家无法控制 seed
但:
像《杀戮尖塔》:
👉 优点:
👉 强烈推荐你加这个模式
你有几个选择:
Slay the Spire 实际上也能被预测。
👉 玩家不太会真的去算
例如:
👉 更复杂,不建议黑客松做
不要让链上“重跑整局”
改成:
链上只验证:
👉 这才是现实可行路径
你必须:
👉 用于体验
👉 这是你最应该重点做的模式
👉 不需要后端
你的思路本质是:
把“随机性”变成“确定性”,再把“验证问题”变成“重放问题”
这是非常正确的。
但你必须解决:
👉 黑客松版本:
👉 你会得到:
如果你愿意,我可以下一步直接帮你设计:
👉 一套完整的 deterministic RNG + 掉落表 + seed 派生结构(含代码级设计)
这个会直接决定你整个游戏系统的“灵魂”。
关于链上验算部分,怎样实现使用seed验算整局,一局中可能包含数场战斗,数次选择时间,甚至每场战斗都有不同卡牌选择,有可能验算吗
我先把“能不能验”这个问题拆开:理论上能,但不应该在 Solana 链上把整局完整重放。我去确认一下官方关于计算预算和交易限制的最新表述,然后给你一个真正可实现的验证架构。
可以验,但要先把“验算”分成两种:
核心原因是,Solana 单笔交易的计算预算是有限的。官方文档目前写的是:默认每条非内置指令 200,000 CU,每笔交易上限 1,400,000 CU;而且优先费用按你请求的 CU 上限计,不是按实际使用量计。对一个包含多场战斗、很多奖励结算、路线选择、卡牌选择的 roguelike 来说,把整局完整 replay 塞进一次链上验证,基本会非常吃紧,甚至不现实。
可行的实现方式不是“链上重跑整局”,而是“链下可重放,链上只做轻验证”。
你可以把体系设计成:
这是能落地的。
只要你把整局游戏写成一个确定性状态机,就能验。
形式上类似这样:
state_0 = init(seed, ruleset, player_loadout)
state_1 = step(state_0, action_1)
state_2 = step(state_1, action_2)
...
state_n = step(state_{n-1}, action_n)
这里:
seed 决定所有随机源action_i 是玩家第 i 步操作step() 是纯函数seed + 同样的 action 序列,一定得到同样的最终结果这样一局里就算有:
只要这些都来自同一个确定性规则系统,就都能被重放验证。
不能混入任何本地随机,比如:
Math.random()你应该做成:
rng_master = PRNG(seed)
battle_seed_1 = hash(seed, "battle", 1)
reward_seed_1 = hash(seed, "reward", 1)
shop_seed_1 = hash(seed, "shop", 1)
也就是不用“全局一直 next() 到底”,而是按事件域分叉 seed。
这样好处很大:
这条最重要。
你必须避免:
最好统一成:
否则你会遇到一个很烦的问题:
不是玩家作弊,而是你自己 replay 不一致。
只提交:
这是不够的。
因为同一个 seed 下,玩家中间不同选择会走向不同结局。
所以你必须至少能拿到:
最简单的做法是把一局编码成一串动作日志:
[
choose_path(2),
reward_pick(1),
play_card(card_7, target_0),
end_turn,
play_card(card_3, target_1),
...
]
有了 seed + action log,链下就能完整重放。
否则你会遇到另一个问题:
那 replay 可能直接变掉。
所以每个 run 都要绑定:
ruleset_versioncontent_hashdrop_table_hash链上至少要记住这些摘要值之一。
因为你的一局可能包含上百步状态转移。
而 Solana 的交易费用和优先费用又和你请求的计算预算相关;官方明确写了优先费用取决于你请求的 CU limit,不是实际用了多少。也就是说,就算你勉强把 replay 塞进链上,成本、失败率和开发复杂度都不会好看。
更实际的问题是:
所以架构上应该避免“链上重放整局”。
这是我最推荐的。
提交一个 RunCommit:
本地保存:
提交:
由链下 verifier 做:
这叫“公开可验证”,但不是“链上逐步执行”。
如果你很想让链更强参与,可以把一局拆段:
每一段结束产出一个 segment_hash:
segment_1 = hash(seed_1, actions_1, state_end_1)
segment_2 = hash(seed_2, actions_2, state_end_2, segment_1)
...
最后链上只收:
这样比“整局一次性验”更稳,也更容易抽查。
你不该把目标写成:
在 Solana program 里重跑整局游戏
你该把目标写成:
给每一局生成一个任何人都能链下重放的证明包,链上只保存承诺和结果摘要
master_seed
map_seed = H(master_seed, "map")
battle_seed_i = H(master_seed, "battle", i)
reward_seed_i = H(master_seed, "reward", i)
shop_seed_i = H(master_seed, "shop", i)
RunProof {
run_id,
ruleset_hash,
master_seed_reveal, // 或 daily seed 引用
initial_loadout_hash,
actions[],
checkpoints[],
final_state_hash,
final_score
}
每场战斗结束记一个:
Checkpoint {
index,
phase_type, // battle / reward / shop / route
start_state_hash,
actions_hash,
end_state_hash
}
只存:
这就足够去中心化了。
链本身不会帮你把整局算完。
所以严格说,这是:
链上承诺 + 链下可验证
不是“纯链上执行”。
一整局动作很多,日志体积会上去。
解决方式通常是:
也就是前面说的确定性要求非常高。
这其实是最大工程挑战。
做这套:
这样你同时拥有:
这比试图“所有模式都链上严验”现实得多。
一局里包含数场战斗、数次选择、很多卡牌决策,并不妨碍验算;真正决定可不可验的,是你能不能把整局写成“seed 驱动 + 动作驱动 + 完全确定性”的状态机。
但在 Solana 上,最合理的实现不是“链上重放整局”,而是“链下重放整局,链上只验证承诺和摘要”。这也是更符合 Solana 计算预算与费用模型的做法。
我可以下一步直接给你画一版 RunProof 数据结构 + battle checkpoint 哈希链设计。
你的意思是链上只去验算seed,status这样的简单数字是否合法,玩家是否真的作弊通过链下可验证进行判断,这种方法构建的排行榜中我认为会出现很多作弊者,虽然链下可以验证出他作弊,但是怎样广播到链上,修改共识,改变排行榜呢
你抓到的是关键点:如果协议一开始没有把“申诉/挑战/回滚排行榜”的流程写进链上规则里,事后发现作弊,链本身不会自动改榜。 我先确认一下 Solana 官方关于程序、账户状态和交易执行的最新表述,再给你一个真正能落地的“可挑战排行榜”设计。
对,你理解得很准:
如果链上只验证“seed/格式/摘要是否自洽”,那它只能防“明显不合法的提交”,防不了“过程作假但摘要看起来合法”的提交。
而且更关键的是,一旦协议里没有预先设计“挑战—裁决—更新排行榜”的链上流程,事后就不能靠一句“他作弊了”去改共识。 在 Solana 里,程序本身无状态,所有可变状态都在数据账户里;账户数据只能由其 owner program 通过指令改写;交易又是原子执行的,所以排行榜是否能被修正,取决于你有没有在程序里提前写好可执行的修正规则。
所以答案不是“链下验出作弊后怎么广播到链上、让链自动改榜”,而是:
最实用的做法是把排行榜分成两层:
玩家提交 run 后,先进入 pending / provisional leaderboard。
这一步链上只检查:
这类检查适合链上做,因为只涉及少量账户和少量字段。Solana 交易和指令本来就是按“明确传入账户 + 明确指令数据”的方式执行的,不会替你自动读取一整局外部过程。
给每个 run 一个 challenge window,比如 1 小时、24 小时,或者“到每日赛结束前”。
在这个窗口内,任何人都可以对该 run 发起 challenge,提交:
如果窗口结束且无人成功挑战,该条目才从 provisional 进入 final leaderboard。
这不是“修改共识”,而是排行榜账户本来就处于“待终局”的协议状态,后续通过程序指令合法推进到 final。Solana 的状态就是账户数据,程序只要被调用、并且拿到了可写账户,就可以按你定义的规则更新这些状态。
这是两个完全不同的东西。
你不能指望:
因为 Solana 交易一旦执行成功,它本身不会被应用层随意撤销;应用层能做的是再发一笔新的合法交易,去更新你的排行榜账户、把某条成绩标记为 invalid、扣罚保证金、重排名次。交易是原子执行的,状态回滚只发生在当前交易失败时,不会因为后面“有人不同意”而自动回滚旧的应用状态。
我建议你直接做成下面这个结构。
submit_run()玩家提交:
run_idseed_commit 或 daily_seed_idresult_summaryscorefinal_state_hashaction_log_hashproof_uri 或 proof_rootbond链上做轻验证后:
RunRecord { status = Pending }challenge_deadlinechallenge_run()挑战者在时限内提交:
run_idchallenge_typeevidence_hash / proof payload链上把 run 状态改为:
UnderChallengeresolve_challenge()这里有两条路:
只处理那些链上能低成本验证的作弊,例如:
这类可以由程序直接判:
Invalid更复杂的作弊,如“中间某回合偷偷改了掉率”,通常不适合链上完整重放。
这时你需要协议里预留一个 裁决入口,例如:
他们链下跑 verifier,确认作弊后,再调用:
slash_run(run_id, signed_verdict)resolve_challenge(run_id, verdict)这样“广播到链上”的不是舆论,而是符合你协议格式的裁决指令。
你担心的是:
会不会榜上先挂满作弊者,虽然链下知道他们作弊,但链上没法改?
答案是:
如果你做“立即终局榜”,会。
如果你做“可挑战的乐观榜”,就不会成为致命问题。
因为在后者里:
PendingFinalSlashed/Invalidated那你必须接受一个现实:
最终裁决一定会存在“谁有权认定作弊”的问题。
因为仅靠“seed + 最终摘要”,不足以让链自动判断所有过程型作弊。
你至少要在三种取舍里选一种:
优点:
缺点:
优点:
缺点:
比如未来做:
优点:
缺点:
我建议你按模式分层。
不做强共识排行榜,只做:
这样哪怕有人作弊,也只是污染展示层,不影响资产安全。
这里做你真正的“严肃排行榜”:
action_log_hash只从 Final 榜单发:
这样你就把最难的问题,集中在少量高价值 run 上处理,而不是要求每一局都做到链上完美裁决。
RunRecordstatus: Pending | UnderChallenge | Final | Invalid
submitter: Pubkey
score: u64
seed_commit: [u8; 32]
action_log_hash: [u8; 32]
final_state_hash: [u8; 32]
proof_root_or_uri_hash: [u8; 32]
challenge_deadline: i64
bond: u64
ChallengeRecordrun_id: u64
challenger: Pubkey
reason_code: u8
evidence_hash: [u8; 32]
status: Open | ResolvedSuccess | ResolvedFail
bond: u64
LeaderboardEntry不要单独把名次写死。
更好的办法是:
Final 状态的 runPending/Invalid 不参与最终奖励结算这样你甚至不需要频繁“重排链上榜单数据结构”,前端或索引器根据状态计算最终榜单即可。
从应用设计上看,不是“修改共识”,而是:
通过新交易更新应用状态。
Solana 共识层负责:
你的程序负责:
所以这件事的本质是协议设计,不是链共识替你兜底。
如果你不想加中心化后端,又不想榜单被作弊者占满:
就不要做“即时最终排行榜”。
改做:
提交 -> Pending -> 挑战期 -> Final -> 发奖励
这是你这个项目里最关键的一条协议设计。
没有它,“链下可验证”基本只是一句口号;有了它,“链下可验证”才会变成能影响链上结果的机制。
下一步我可以直接给你一版 “可挑战排行榜协议” 的时序图 + Anchor 指令设计,把 submit_run / challenge_run / resolve_run / finalize_run 四个指令一次性定下来。
如果按照final榜单来的话,我有两个问题1.对于一个小型的黑客松项目,是否会有人充当验证者2.使用验证者机制,必定逃脱不了经济部分,从纯粹的game转向了gamefi,对于黑客松过于复杂。 关于经济部分,我目前的设想是,玩家开始游戏,花费gas,如果游戏成功,给予一张卡片的NFT,大概率普通,小概率稀有,几张普通可以随机成一张稀有,单出一个模式,使用这些NFT进行对战,胜者获取败者的一张NFT销毁败者其他NFT,当然还有之前的每日挑战模式,关于这些在线对战部分,暂时不在黑客松范围内,我想知道,这个机制是否合理
先直接说结论,然后我帮你把逻辑“收紧到黑客松可做版本”。
不会。至少在黑客松阶段,基本不会。
现实情况是:
👉 所以你这里有一个认知要纠正:
❌ “链下可验证” ≠ 自动有人帮你验证
✅ 它只是“如果需要,可以被验证”
是的,如果你做完整挑战/押金/仲裁机制,会明显偏 GameFi。
而且:
👉 所以你的直觉是对的:
不应该在黑客松阶段做完整验证经济系统
而是:
把“游戏体验 + 资产生成”当核心
排行榜只是“展示”,不是“价值结算基础”
你说的是:
- 玩家开始游戏 → 花 gas
- 成功 → 掉 NFT(普通/稀有)
- 普通可合成稀有
- 未来 PvP 用 NFT 对战
- 胜者拿对方 NFT
- 失败者 NFT 被销毁
我直接说:
你现在的逻辑是:
“成功 run → 掉 NFT”
如果掉落是:
那结果就是:
👉 玩家可以刷 NFT
比如:
最终结果:
你设计的是:
胜者拿对方一张 NFT + 销毁剩余 NFT
这个问题很大:
👉 这种机制叫:
Full Loot PvP(全损失 PvP)
通常只在:
才适用
👉 对于你这个偏策略卡牌 + roguelike:
不匹配
你现在有:
但缺:
👉 简单说:
还不算一个完整经济系统
我给你一版最适合黑客松的版本(很重要)
👉 只有“每日挑战模式”产出 NFT
为什么:
daily_seed + 玩家表现 → deterministic 掉落
例如:
👉 完全 deterministic,不用概率
普通 run:
👉 防止刷资产
不要一开始就做复杂战斗 NFT
先做:
稀有度 = f(score, seed,规则)
不是概率
你原来:
几张普通 → 随机稀有
改成:
👉 确定性合成
3 普通 + burn → 1 稀有(固定)
或者:
普通NFT属性组合 → 新NFT
👉 不要随机
你可以这样改:
👉 这样不会劝退
简单处理:
或者:
👉 只奖励 Top N(人工/软验证即可)
你解决了所有核心问题:
| 问题 | 解决 |
|---|---|
| 验证者没人做 | 不需要 |
| 掉率作弊 | 用 deterministic |
| seed 刷 | 用 daily seed |
| 经济崩 | 控制入口 |
| 游戏变 GameFi | 保持游戏优先 |
| 黑客松复杂度 | 降到可做 |
👉 不要试图让“所有 run 都公平可信”
👉 而是:
只让“每日挑战模式”成为唯一可信资产入口
这样你就:
👉 “每日挑战 + deterministic 掉落 + NFT mint 规则”完整公式设计
包括:
这个会直接决定你 demo 是否“看起来像一个真正产品”。
你设计的很不错,我的打算是在黑客松期间,做完单机模式,每日榜单,可以铸造NFT,只用于收藏,暂时不涉及PVP,关于每日榜单,1.你的意思就是不用管是否有人验证,只要出可以完整精确验证逻辑就可以吗?2.分数系统,分数计算是像杀戮尖塔,通过局内行为给分,但这又绕回到验证机制,因为现在杀戮尖塔的每日挑战榜单上前几名天天是挂,杀戮尖塔没有铸造NFT,但这个游戏NFT与榜单联系,验证机制可以完成责任吗
可以,但要把责任边界说清楚。
对黑客松来说,基本是这个意思,但要补一句:
你不是在做“强安全排行榜”,而是在做“有可验证能力的排行榜”。
这两者差很多。
你在黑客松阶段做到下面这件事,就已经很不错了:
这说明你的榜单不是黑箱,而是“可审计”的。
但这不等于:
所以你该把卖点表述成:
我们实现了一个可重放、可验证的每日挑战系统;黑客松版本提供公开验证能力,但不引入复杂的链上挑战经济或仲裁系统。
这就很诚实,也很合理。
如果 NFT 直接和“榜单名次”强绑定,那现在这套轻验证机制,不足以完成责任。
这是最关键的判断。
因为只要有下面这个映射:
那么你就进入了一个新阶段:
排行榜不再只是展示层,而是价值分配层。
一旦是价值分配层,你就不能只靠“理论上可验证”。
因为会出现:
这时候,验证机制必须能实际影响结果,而不只是“有人可以在本地指出你有问题”。
所以答案是:
这是我最推荐的黑客松方案。
例如:
这种设计里:
这样即便榜单前几名有挂,对 NFT 系统伤害也小很多。
因为 NFT 的发放依据是门槛,不是相对排名。
这就大幅降低了验证压力。
例如:
这个方案会把问题变得很难,因为你必须解决:
这已经明显超出黑客松舒适区了。
改做:
这是最稳的。
因为你把问题从:
谁是真正第 1 名?
变成了:
这个 run 有没有达到某个可解释的门槛?
前者需要强验证、争议处理、终局规则。
后者只需要:
复杂度差一个数量级。
即使是成熟游戏,只要:
前排被污染是很常见的。
但《杀戮尖塔》的问题之所以没那么致命,是因为:
你这里一旦把 NFT 绑上去,风险就放大了。
所以你不能照搬“普通游戏排行榜容忍少量挂”的思路到“资产发放”。
我建议你把它限定在这个范围:
这样,责任边界就合理了。
按达成条件发,不按排名发。
例如:
这样你仍然可以把 NFT 和 daily mode 绑定,而且非常好讲:
这很好。
你说得对,分数越依赖局内细节,越难验证。
所以黑客松版分数系统要遵守一条原则:
别做几十个隐性 bonus。
尽量让分数来自少数、清晰、可重放的变量。
比如只用:
而不要做太多:
越复杂,越容易让验证成本上升。
Score =
floor_reached * 100
+ boss_kill_bonus
+ hp_remaining * 10
- turn_count * 2
+ elite_kills * 50
+ challenge_modifier_bonus
特点:
可以完成“展示级和审计级责任”,不能完成“资产终局分配责任”。
翻成更直白的话:
所以你最好的产品策略是:
展示、社交、挑战感
纪念、收藏、成就证明
按榜单名次强绑定高价值资产
这样你整个系统会非常顺。
把每日 NFT 定义成:
Daily Challenge Achievement NFT
而不是:
Leaderboard Prize NFT
这两个名字背后的协议复杂度完全不同。
前者你现在就能做,而且合理。
后者需要一整套终局验证与争议处理,不适合黑客松。
如果你愿意,我下一条可以直接帮你定一版:
“每日挑战 NFT 发放规则 + 分数公式 + 元数据字段”
把黑客松可交付版本一次定死。
NFT部分,NFT与门槛绑定确实可以减少作弊者的影响,我在想,可不可以把seed,操作,status等数据写入mint的NFT元数据中,这样作弊者的NFT可以被轻易验证不合法失去价值,这样可行吗
我先确认一下 Solana 侧当前最常用的 NFT 元数据承载方式,再给你判断“把 seed / action / status 写进 NFT 元数据”这条路哪里可行、哪里不够。
可行,但要分清楚两件事:
1. 把 proof 数据写进 NFT 元数据,能大幅提升“可审计性”
2. 它不能自动让作弊 NFT 失效,也不能自动失去价值
这两个不要混在一起。
你完全可以把这些东西和 NFT 绑定:
daily_seed_id 或 seed_commitruleset_hashscorefinal_state_hashaction_log_hashproof_uri 或 replay_urirun_idminted_atverified_level这样 NFT 会变成一个 可验证的挑战成就凭证,而不是一张只有图片的卡。
Solana 现在常见的 NFT 元数据方式就是:链上 metadata 账户保存基础字段和一个 uri,再由这个 uri 指向链下 JSON;官方文档也明确说明了链上 metadata 通常只放名称、符号、URI 等,而扩展信息放在 URI 指向的 JSON 中。
如果作弊者也能 mint 出 NFT,那么:
score、假的 action_log_hash、假的 proof_uri 写进去所以真正的问题不是“能不能写进 metadata”,而是:
谁有权 mint,mint 前验证到什么程度,mint 后如何标记合法性。
这很适合你的黑客松定位。
你可以把 NFT 定义成:
Daily Challenge Achievement NFT
它的元数据不是只有:
还包含:
这样别人拿到这张 NFT,不只是“看图”,而是可以追溯它的来源。
比起只写原始数据,更好的做法是加一个字段:
{
"attributes": [
{"trait_type": "Daily Seed", "value": "2026-04-23"},
{"trait_type": "Score", "value": 2480},
{"trait_type": "Tier", "value": "Gold"},
{"trait_type": "Ruleset Hash", "value": "0x..."},
{"trait_type": "Action Log Hash", "value": "0x..."},
{"trait_type": "Final State Hash", "value": "0x..."},
{"trait_type": "Verification Status", "value": "Self-Reported"}
]
}
然后以后如果你有更强的验证器,可以把状态升级成:
Self-ReportedReplay-PublishedCommunity-VerifiedOfficially-VerifiedDisputed这会非常有用。
Solana / Metaplex 的常见元数据结构里,链上存的是:
详细的扩展属性通常在 uri 指向的链下 JSON 里。Solana 官方文档还特别建议把 JSON 存在可靠的持久存储上,比如 Arweave、IPFS 或稳定 CDN。
这意味着:
也就是说,metadata 可以帮助别人验证,但不会替你执行惩罚。
官方文档说明 metadata 是否可变,取决于 is_mutable / update authority 设计;如果账户可变,update authority 可以更新 metadata。
所以你会遇到一个取舍:
优点:
Verification Status 从 Pending 改成 Verified/Disputed缺点:
优点:
缺点:
你说“作弊者的 NFT 会轻易验证不合法,失去价值”,这句话只在一个前提下成立:
你的前端、社区和可能的交易场景,都认可某种验证标准。
否则链上只会看到:
链不会替你说“这张作废”。
所以更准确的说法是:
proof 写进 NFT metadata 可以让“合法 NFT 更容易被识别”,但不能保证“非法 NFT 自动失去价值”。
我建议你做成两层。
在 metadata JSON 里放:
run_idday_idseed_commitruleset_hashscoreaction_log_hashfinal_state_hashproof_uri这个状态不要只靠 NFT 自己说自己合法。
更稳的是由你的 game program 或一个独立 registry 账户维护:
mint -> Pendingmint -> Verifiedmint -> Disputedmint -> RevokedForRewards(如果你以后需要)这样:
Verified这就足够了。
这是最稳的。
daily_seed_idscoretieraction_log_hashproof_uriverification_status = "Unverified" 或 "Replay-Available"这样就很好了。
对于黑客松,这已经足够强。
如果你想再前进一步,可以保留 update authority,后续把 metadata 里的状态改成:
PendingVerifiedDisputed技术上是可行的,因为可变 metadata 可以被更新。
但我不建议你一开始就把这个做太重。
黑客松里更简单的做法是:
这是一个实现细节,但很重要。
原因:
链上或 metadata JSON 里只存:
action_log_hashproof_uri然后:
proof_uri 指向 IPFS/Arweave 上的 replay 文件这才是正常结构。
不是:
把数据写进 NFT,作弊者 NFT 就会自动失去价值
而是:
把每日挑战证明嵌入 NFT 元数据与可追溯 proof 中,让合法成绩具备公开可审计性;官方前端和社区工具可据此区分已验证与未验证成就 NFT。
这个表述更准确,也更专业。
day_idrun_idscoretierruleset_hashseed_commitaction_log_hashfinal_state_hashproof_uriverification_hintgame_versionReplay AvailableReplay Verified这样非常合理,而且黑客松内可实现。
可行,而且是好设计;但它提升的是“可验证性和可追溯性”,不是“自动惩罚性”。
要让作弊 NFT 真正“失去价值”,还需要你的前端、社区标准或后续验证注册表去承认哪些 NFT 是 Verified,哪些只是 Self-Reported。
我可以下一步直接帮你写一版 NFT metadata JSON schema,把这些字段一次性定出来。