美文网首页程序员
为游戏中的统计变量加入标签

为游戏中的统计变量加入标签

作者: maAya | 来源:发表于2018-11-14 14:58 被阅读0次

睿智的唯物主义者+40

1. 一个现实的需求

在某个游戏中,会根据每一局玩家遇到的内容决定游戏结束后的提示(tips)。例如:

  • 当玩家玩得很差时(这一般说明他是个新手),显示最基础的提示
  • 当玩家遇到了特定敌人时,显示这类敌人的提示
  • 当玩家获得了某些道具时,显示这些道具的提示
  • 当玩家使用了某些技能时,显示这些技能的提示
  • 当玩家因为某种原因死亡时,显示避免这种死亡的提示
  • 等等……

玩家结束一局时可能会满足多个提示的显示条件,这时就在可以显示的提示里随机选择一个。

选择的实现方式是给各种种类的提示做一个权重表。根据玩家行为的不同调整不同类型提示的权重,然后选择一个结果。比如说:

local tipsWeightList = {
    [TIP_GROUP.TYPE_1] = 10,
    [TIP_GROUP.TYPE_2] = 0,     -- 不可能出现
    [TIP_GROUP.TYPE_3] = 50,
    [TIP_GROUP.TYPE_4] = 1000,  -- 出现概率最高
    [TIP_GROUP.TYPE_5] = 10,
}

睿智的策划为权重的调整加入了很多条件,希望能给玩家更好的体验,例如:

  • 当玩家还处在新手阶段时,大幅提升基础类提示的权重
  • 当一局游戏中出现了很多类型的道具时,之前出现提示较少的道具类型获得更大的权重
  • 某些死亡方式和某些敌人的搭配会大幅影响提示的权重
  • 随着一部分提示的出现,还没有出现过的提示的权重会有所变化(例如一些提示只有当一定数量的提示解锁后才可能出现)
  • 等等……

我们需要根据各种规则反复修改之前的权重表。当规则多起来之后,我们在测试中遇到了问题:这个权重表的每一项到底对不对?如果不对是哪里不对了?

回想一下P社游戏会把大量影响因素罗列出来,非常便于分析:

《欧陆风云IV》中的数值细节

我们希望自己的游戏一局游戏结束后能够将权重表罗列成这样:

基础组 10
    基础  +10
敌人1组 160
    发现了敌人  +10
    敌人1组出现率<10% (0/6)  +150
敌人2组 0
道具1组 10
    发现道具  +10
道具2组 0
道具3组 110
    发现道具  +10
    内容组出现率<10% (0/6)  +100
后期组 0
    全体出现率 (10/100)  +0

这样我们可以容易地看出权重计算得对不对,以及以此估算可能出现的提示。

为了适应睿智的策划的需求,这个记录肯定要是动态的。

2. 先说一个简单的例子

游戏中玩家拥有的金币的数量,最简单的实现是直接放在一个全局的单例里:

PlayerData:getInstance().coin = 10

如果再讲究一点,可以稍微封装一下:

PlayerData:getInstance():addCoin(20)  -- 收入
PlayerData:getInstance():addCoin(-5)  -- 支出

这样在赋值的时候可以干更多的事,比如做个安全检查、发个事件什么的。

在某个时刻,我们发现玩家拥有的金币和我们期望的不一致——肯定是哪里出现bug了。然后我们失望地发现游戏中赚钱和花钱的途径有十几种。为了找到问题出在哪里,我们要么在每处打log,要么加断点然后反复尝试,即便这样也不一定能很快定位到问题所在。

如果我们能像查询银行账单一样查询这个值的修改历史该有多好啊!

所以我们真的来做一个类似日志的系统。实现非常简单:

coin_history = {}
function addCoin(value, tag)
    coin_history[#coin_history+1] = {value = value, tag = tag}
end
function getCoin()
    local coin = 0
    for k, v in pairs(coin_history) do
        coin = coin + v.value
    end
    return coin
end

用起来并没有更麻烦,但是我们现在可以很容易地获得操作历史了:

function listCoinLog()
    print("------ Coin ------")
    local coin = 0
    for k, v in pairs(coin_history) do
        coin = coin + v.value
        if v.value >= 0 then
            print(coin .. "(+" .. v.value .. ") Comment: " .. v.tag)
        else
            print(coin .. "(" .. v.value .. ")  Comment: " .. v.tag)
        end
    end
end

测试一下:

addCoin(10, "income 1")
addCoin(20, "income 2")
addCoin(-5, "expend 1")
listCoinLog()

输出:

------ Coin ------  
10(+10) Comment: income 1   
30(+20) Comment: income 2   
25(-5)  Comment: expend 1

就像查询银行账单。

这样做的一大好处是,我们可能在游戏开发的某一时刻突然有了对数据的统计需求,比如:

  • 今天有10个工人在工作,每个工人贡献了多少?
  • 今天生产了20种产品,每种产品创造了多少收入?

为了这种需求加记录和统计的代码太可怕了,但是我们可以把这些信息全都变成tag,然后在需要的时候统计这些tag。

3. 扩展这个系统

我们有很多事可以做。

  1. 我们可以把这个标记系统单独抽出来做一个类,然后每个数值型的用户数据都是它的实例。
  2. 我们在持久化数据时可以把这些标记一起序列化。这种做法:
    1. 简单
    2. 可以保持全部的原始数据(可以在下次运行时de上次的bug了)
    3. 可以让篡改数据变得稍微更困难些。
  3. 我们可以直接在原始数据的基础上分析数据,例如按照tag分类排序,或者统计单一tag的结果。
  4. 虽然现在只有一个tag字段,但可以扩充更多的信息,比如来自谁、时间戳等等。
  5. 当记录过多时,可以加一个merge方法,归并所有的记录,只保留一条归并后的结果。
  6. 如果比较讲究的话,可以在归并数据时把记录全都转移到另一个archived列表里。但我们毕竟是做游戏不是记账软件,这个有点过于讲究了。

4. 回到最初的问题

有了这个系统之后最开始的问题变得很平凡了。

比如有两个条件都会增加『敌人1组』tips的出现权重:

  • 发现这种敌人
  • 敌人1组总体出现率极低

那么当条件1触发时我们就记录:

{group = 1, value = 10, tag = "发现了敌人"}

条件2触发时记录:

{group = 1, value = 150, tag = "敌人1组出现率低"}

在游戏结束时我们就可以获得类似这样的输出:

敌人1组 160
    发现了敌人  +10
    敌人1组出现率低  +150

当睿智的策划增加新的条件时,我们就加入一小段条件判断,然后把权重的改变打上tag。例如一个降低『敌人1组』出现率的条件是敌人2出现,我们就可以在敌人2出现时加入记录:

{group = 1, value = -100, tag = "敌人2出现"}

在最后获得的结果是:

敌人1组 60
    发现了敌人  +10
    敌人1组出现率低  +150
    敌人2出现  -100

相关文章

  • 为游戏中的统计变量加入标签

    睿智的唯物主义者+40 1. 一个现实的需求 在某个游戏中,会根据每一局玩家遇到的内容决定游戏结束后的提示(tip...

  • 商务与经济统计第一章笔记

    数据与统计资料 1、数据的组成 个体:数据的实体,通常为列标签 变量:个体的特征 观测值:测量值集合,通常为行数据...

  • 《商务与经济统计》笔记(一)

    数据与统计资料 1、数据的组成 个体:数据的实体,通常为列标签 变量:个体的特征 观测值:测量值集合,通常为行数据...

  • 20-01-28JS基础语法1

    字面量,常量,变量 1. 在 标签中加入typ...

  • Django中的{%if%} 怎么用?

    {% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统...

  • Django中的{%if%} 怎么用?

    {% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统...

  • C#窗体移动

    Point mouseOff;//鼠标移动位置变量 bool leftFlag;//标签是否为左键 ...

  • 分类与回归的区别

    分类:classification回归:regression李航《统计学习方法》的解释为:输入变量与输出变量均为连...

  • 百度统计工具

    记录百度统计工具使用方法 在首页加入统计代码,其中,baiduId为公司百度统计账号 封装统计方法 调用统计方法 ...

  • HTML标签的相关操作判断

    统计HTML标签中以b开头的标签数量 统计HTML标签中出现次数最多的标签 判断DOM标签的合法性 如标签的闭合、...

网友评论

    本文标题:为游戏中的统计变量加入标签

    本文链接:https://www.haomeiwen.com/subject/poorfqtx.html