用python对游戏《野蛮时代》进行数据分析

一、字段含义与业务理解

《野蛮时代》是一款SLG游戏与早年的《帝国时代》相似,为了更好的理解数据我有去体验一段时间,以下就是我对这款游戏的业务理解。

整体游戏的玩法是,你作为一个部落领袖要去建造升级自己部落的建筑如兵营、瞭望塔、要塞等,而这些建筑的升级需要木材与食物,同时还存在着一定依赖关系,比如你必须先升级要塞到7级才能升级兵营至7级。而这些建筑根据其用途可以分为这么几类:

1.战争类
兵营、士兵小屋、治疗小井、治疗之泉、瞭望塔、据点传送门,其作用分别是训练士兵、提供士兵居所、给受伤士兵提供居所、治疗受伤士兵、探测其它部落对我方发起的进攻、将士兵传送到我方据点。

2.联盟类
你作为一个部落的首领,并非形单影只还需要加入联盟,因此也需要一些联盟建筑,包括战争大厅、联盟货车、联盟大厅。其作用是分别是与联盟其它成员一起发动战争,给其它成员运送物资、给援军提供住所。

3.伙伴培养类
你不是一个人在战斗,你还可以选择召唤自己的1-5星伙伴和培养自己的巨龙。其包括的建筑有占卜台、祭坛、冒险传送门、天梯、龙秘境,作用分别是招募伙伴、强化伙伴、打怪升级、与其它玩家进行PK、培养孵化巨龙。

4.辅助类
包括的建筑有圣火、智慧神庙、幸运小屋、神秘水晶、魔法幸运树、工作间、仓库、折扣商店。其作用分别是点燃圣火增加资源生产速度、智慧神庙用来进行科技研发、幸运小屋给予每日登陆奖励、神秘水晶用来购买道具、魔法幸运物用来许愿免费获得资源、工作间用来完成每日任务和联盟任务、仓库用来保护资源和生产资源、折扣商店用来获取便宜道具。

以上就是各种建筑和其作用,但游戏本身肯定不是天天升级建筑,还需要一定给予玩家一定活动空间,而整体活动可以分为四类:

  1. 打野怪、打巨龙与资源采集,你需要派自己的部队到领土之外去击败野怪获取资源,或者是直接搜集现成资源。

  2. 进行侵略,攻击其它玩家营地来获取资源。

  3. 让自己召唤过来的伙伴进行冒险,提升伙伴星级、等级、铭文。

4.部落入侵、霜火大陆争夺战(不同服玩家进行战争),矿岛争夺战。

上面这些活动和建筑的升级与建设就形成了这个游戏的核心玩法。而游戏盈利点也从中而来,主要包括三点点:

  1. 建筑升级和训练士兵都需要时间,许多人不愿意等待,那么势必就需要付费充值,充值使我更强。

  2. 资源的获取,只有有了充足的木材、食物、魔法石等资源才能升级建筑和打造出更强的军队。

  3. 伙伴与巨龙的强化,要想获得5星伙伴,那你最好是充钱获得抽取机会。

有了以上对业务的理解,那我们再来看对应的数据就有了更深刻一些的体会,我们来从拥有的数据集中选取部分字段来进行分析,具体字段如下:

字段名 字段解释 数据时间
user_id 用户唯一标识 永久
register_time 玩家注册时间 永久
meat_reduce_value 肉消耗数量 前七日
wood_reduce_value 木材消耗数量 前七日
stone_reduce_value 石头消耗数量 前七日
ivory_reduce_value 象牙消耗数量 前七日
magic_reduce_value 魔法石消耗数量 前七日
infantry_add_value 勇士招募数量 前七日
infantry_reduce_value 勇士损失数量 前七日
wound_infantry_add_value 勇士伤兵产生数量 前七日
wound_infantry_reduce_value 勇士伤兵恢复数量 前七日
general_acceleration_reduce_value 通用加速消耗数量 前七日
building_acceleration_reduce_value 建筑加速消耗数量 前七日
reaserch_acceleration_reduce_value 科研加速消耗数量 前七日
training_acceleration_reduce_value 训练加速消耗数量 前七日
treatment_acceleration_reduce_value 治疗加速消耗数量 前七日
pvp_battle_count 玩家对玩家次数 前七日
pvp_lanch_count 主动发起PVP次数 前七日
pve_battle_count 玩家对机器次数 前七日
pvp_win_count PVP胜利次数 前七日
pve_win_count PVE胜利次数 前七日
avg_online_minutes 平均在线时间 前七日
pay_price 消费金额 前七日
pay_count 消费次数 前七日
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

#选取相应字段
select_columns=['user_id','register_time','stone_reduce_value','ivory_reduce_value','meat_reduce_value','magic_reduce_value',  \
                'infantry_add_value','infantry_reduce_value','wound_infantry_add_value','wound_infantry_reduce_value','general_acceleration_reduce_value' \
                ,'building_acceleration_reduce_value','reaserch_acceleration_reduce_value','training_acceleration_reduce_value','treatment_acceleration_reduce_value',  \
                'pvp_battle_count','pvp_lanch_count','pve_battle_count','pvp_win_count','pve_win_count','avg_online_minutes','pay_price','pay_count']
#数据读取
original_data=pd.read_csv(r'F:\the-craft-of-selfteaching\game_data\data.csv',usecols=select_columns)

#显示数据前五行
original_data.head()

以上代码输出如下:


image.png

二、数据清洗

  1. 查看空值
original_data.info()
image.png

我们能发现数据一共828934行,没有空值。

  1. 异常值处理
original_data.info()
image.png

我们能从图中发现没有异常值,但是有一个非常奇怪的事情就是超过25%的玩家没有进行木材和食品的消耗,没有消耗木材和食物进行建筑搭建,基于对业务的理解,这是一个极其奇怪的事情。这说明了一个问题,有极大比例用户没有完成注册与激活这一步。

  1. 重复值处理
#显示每一列唯一值个数
print(original_data.nunique())
image.png

我们能看到user_id唯一值个数与行数相等,说明没有重复值。

  1. 格式转换
    由于register_time这列以日期时间格式显示,我们要把后面的日期进行去除,也就是进行格式清理。
#去除时间
original_data['register_time']=original_data['register_time'].apply(lambda x : x[0:10])
original_data['register_time'].head(5)
image.png

三、问题提出与分析

  1. 根据AARRR模型,用户从注册到激活,激活到留存,留存到付费,转化率如何,不同注册时间用户对应各个指标表现如何?
#不同注册时间用户对应的注册用户数量
register_number_of_everyday=original_data['register_time'].value_counts().sort_index()
#不同注册时间用户对应的激活用户数量
active_user_number_of_everyday=original_data.loc[original_data['wood_reduce_value']!=0]['register_time'].value_counts().sort_index()
#不同注册时间用户对应的留存用户数量
retention_user_number_of_everyday=original_data.loc[(original_data['wound_infantry_add_value']!=0)|(original_data['pay_count']!=0)]['register_time'].value_counts().sort_index()
#不同注册时间用户对应的付费用户数量
pay_user_number_of_everyday=original_data.loc[original_data['pay_count']!=0]['register_time'].value_counts().sort_index()
#总注册用户数量
total_register_number=original_data.shape[0]
#总激活用户数量
total_active_user_number=original_data.loc[original_data['wood_reduce_value']!=0].shape[0]
#总留存用户数量
total_retention_user_number=original_data.loc[original_data['wound_infantry_add_value']!=0].shape[0]
#总付费用户数量
total_pay_user_number=original_data.loc[original_data['pay_count']!=0].shape[0]
print('总注册用户数为:',total_register_number)
print('总激活用户数为:',total_active_user_number)
print('总留存用户数为:',total_retention_user_number)
print('总付费用户数为:',total_pay_user_number)

结果如下:
总注册用户数为: 828934
总激活用户数为: 599557
总留存用户数为: 149929
总付费用户数为: 19549

在上面我们用不同指标筛选出对应用户,在这里进行相应说明。
注册用户是指:已经注册的用户
激活用户是指:那些有消耗木材进行建筑物建造的用户;
留存用户是指:那些跟其它玩家发生冲突以至于有勇士伤兵产生的用户或者是无伤兵产生但有付费的用户,
付费用户是指:付费玩家。

光看数据我们很难有直观体会,因此我们将相应数据进行可视化。

import seaborn as sns 
#我们将不同注册时间用户对应的数据进行合并
total_data_everyday=pd.concat([register_number_of_everyday,active_user_number_of_everyday,retention_user_number_of_everyday,pay_user_number_of_everyday],axis=1)
#修改列名
total_data_everyday.columns=['register','active','retention','pay']
total_data_everyday
image.png

然后我们再根据这个数据进行折线图绘制。

#构建折线图函数
def get_lineplot(title,data):
    plt.figure(figsize=(25,13))
    plt.xlabel('date')
    all_graph=sns.lineplot( data=data)
    plt.title(title,fontsize=20)
    plt.show()
#先获取注册用户和激活用户的情况,因为这两个数据量级相差不大,从图像中可以看出相应趋势
get_lineplot('The number of register and active user ',total_data_everyday[['register','active']])

注册用户和激活用户折线图:


image.png
#留存用户折线图
get_lineplot('The number of retention user ',total_data_everyday['retention'])

留存用户折线图:

image.png
#付费用户折线图
get_lineplot('The number of payment user ',total_data_everyday['pay'])

付费用户折线图:

image.png

我们能从图中看到,3月10号、3月13号、3月16号、3月21号这四天从注册数量到留存数量都呈“尖峰状”,我们推测是有搞一些运营活动。然而3月10号与3月13号这两天里的用户却在付费方面表现极差,而3月16号与3月21号的用户付费意向高。所以如果只是单单想要极大增加留存用户数就应该进行3月10日与3月16日的运营活动,如果既想要高留存又要高付费,那么后两者的运营活动更为适合。

看完了不同日期对应的指标分析,我们再来看看总体情况是什么样的,并画出相应漏斗图进行分析。

from pyecharts import options as opts  
from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
from pyecharts.render import make_snapshot
from pyecharts.charts import Funnel   
pyechart_data=[828934,599557,146013,19549] #不同阶段用户数量
labels = total_data_everyday.columns.to_list() #设置标签
def funnel_base() -> Funnel:
    c = (
        Funnel()
        .add("转化", [list(z) for z in zip(labels,pyechart_data )])
        .set_global_opts(title_opts=opts.TitleOpts(title="AARR漏斗图"))
    )
    return c
funnel_base().load_javascript()
funnel_base().render_notebook()
#请注意如果你跟我一样使用的是jupyter lab ,一定要将这些代码放到3个cell里分别运行,否则漏斗图显示不出来,呈现一片空白
print(f'从注册到激活转化率为: {round(599557/828934*100,2)}%')
print(f'从激活到留存转化率为: {round(149929/599557*100,2)}%')
print(f'从留存到付费转化率为: {round(19549/149929*100,2)}%')
print(f'用户付费率PR为: {round(19549/599557*100,2)}%')
loudou.png

从注册到激活转化率为: 72.33%
从激活到留存转化率为: 25.01%
从留存到付费转化率为: 13.04%
用户付费率PR为: 3.26%

这里的付费率是指付费用户占激活用户百分比。

游戏行业付费率

我们能发现用户付费率最终为3.26%,而根据上图TalkingData发布的18年5月移动游戏数据指标来看,模拟类游戏付费率在安卓端和苹果端仅为1.74%和2.25%,所以《野蛮时代》的付费率是相当高的。而我们从漏斗图中能看到激活用户到留存用户转化率只有25%,这回我们结合avg_online_minutes平均在线时长进行分析,看看留存下来的用户与未留存下来的用户,在在线时长方面有什么差异。

  1. 留存用户与未留存用户在在线时长上的差别探究
#留存用户在线时长
retention_user_avg_online_time=original_data.loc[original_data['wound_infantry_add_value']!=0]['avg_online_minutes']
#未留存用户在线时长
unretention_user_avg_online_time=original_data.loc[(original_data['wood_reduce_value']!=0)&(original_data['wound_infantry_add_value']==0)]['avg_online_minutes']
#对留存用户在线时长进行描述性统计分析
retention_user_avg_online_time.describe()
image.png
#对未留存用户在线时长进行描述性统计分析
unretention_user_avg_online_time.describe()
image.png

我们能通过对比发现一点百分之75%的未留存用户平均在线时长未超过6分钟,而留存用户中则相反超过75%的留存用户平均在线时长超过6分钟。所以显而易见的一件事情是,许多玩家在还未熟悉游戏玩法时,就直接退出,所以新用户引导设计还需要进一步优化。

具体往哪方面优化呢?我这里有一个建议,在体验过游戏后我发现前几分钟所有操作都是不停根据指令建造各种建筑,玩家体验并不好,或者说根本没有自主性,为什么不可以新玩家一进入游戏那些新建筑就已全部搭建好了呢?

举个例子,新玩家一进入游戏,1级兵营就已经建造好并且手底下还有一些士兵,然后你指引玩家对野外野怪进行攻击获取资源,这样自主操作空间就大了,不至于一开始就不停点点点搭建建筑。当然具体可行性,需要进行A/B测试来验证。

除此之外,我们在上面两张图发现了三个异常值。第一个异常是留存用户中竟然有在线时长为0的人,因为我们是用有伤兵产生或者有付费行为来定义留存,而有伤兵产生就意味着玩家一定有去操作,所以我们具体来看一下数据情况。

#留存用户但在线时间为0
original_data.loc[((original_data['wound_infantry_add_value']!=0)|(original_data['pay_count']!=0))&(original_data['avg_online_minutes']==0)]
image.png
image.png

从上面两张图,我们发现玩家主动发起6次pvp但在线时长是0,这说明后端系统有漏洞,导致数据异常,在工作中需要沟通,定位问题然后去解决。

第二个异常是未留存用户中也有在线时长为零的,我们猜测也是系统出现问题导致数据异常。

#在线时间为0的未留存用户
original_data.loc[(original_data['wood_reduce_value']!=0)&(original_data['wound_infantry_add_value']==0)&(original_data['pay_count']==0)&(original_data['avg_online_minutes']==0)]
image.png

一共有288条数据有木材消耗,但无在线时长,还是系统漏洞。

第三个异常是我们发现未留存用户中有存在在线时长超过1000分钟的,我们来找到具体数据看看是异常值,还是正常值。

#在线时间大于1000分钟的未留存用户
original_data.loc[(original_data['avg_online_minutes']>1000)&(original_data['wood_reduce_value']!=0)&(original_data['wound_infantry_add_value']==0)&(original_data['pay_count']==0)]
image.png

image.png

我们发现除了user_id为2619848的用户数据异常外(因为在线时长几十个小时,但木材消耗量却只有3700),其余皆为真实用户数据,只不过这些用户既不付费也没有因为与其它玩家交战造成士兵伤亡。

  1. 平均用户收入、平均每付费用户收入、一次性付费用户占比
pay_user=original_data.loc[original_data['pay_price']!=0].copy()
ARPU=round(pay_user['pay_price'].sum()/original_data.shape[0],2)
ARPPU=round(pay_user['pay_price'].sum()/total_pay_user_number,2)
one_pay_user_number_rate=round(pay_user.loc[pay_user['pay_count']==1].shape[0]/pay_user.shape[0],4)
one_pay_user_total_pay_price_rate=pay_user.loc[pay_user['pay_count']==1]['pay_price'].sum()/pay_user['pay_price'].sum()
print('ARPU平均每用户收入贡献: {}'.format(ARPU))
print('ARPPU平均每付费用户收入贡献: {}'.format(ARPPU))
print('一次付费用户人数占比: {}%'.format(one_pay_rate*100))
print('一次性付费用户收入贡献占比:{}%'.format(round(one_pay_user_total_pay_price_rate*100,2)))

ARPU平均每用户收入贡献: 0.67
ARPPU平均每付费用户收入贡献: 28.49
一次付费用户人数占比: 43.04%
一次性付费用户收入贡献占比:2.38%

我们通过分析发现了一个糟糕的现象,那就是一次性付费用户占比太大,提供的收入太小,这个时候我们就应该挤掉水分,算一算有效付费率。
在这里我们定义有效付费率=付费率*(1-一次性付费用户占比),最后得到有效付费率为1.86%,高于模拟类游戏行业平均水准,还是不错的。

4.鲸鱼用户收入贡献与画像分析

在游戏行业中将付费用户分为小鱼用户、海豚用户、鲸鱼用户,鲸鱼用户是游戏运营中的重头戏,甚至会专门分析鲸鱼用户的留存率,原因在于少量的鲸鱼用户往往为游戏贡献了超过80%的收入。接下来我们来看看鲸鱼用户对收入的贡献,然后对比留存非付费用户,看看两类群体在行为上有什么差异。

我们将付费金额排在前20%的当做鲸鱼用户也就是高价值用户

#我们将付费金额排在前20%的当做鲸鱼用户也就是高价值用户
high_value_pay_user=original_data.loc[original_data['pay_price']!=0].sort_values(by='pay_price',ascending=False).head(int(19549*0.2))
#鲸鱼用户对收入贡献率
high_value_user_payrate_of_total=high_value_pay_user['pay_price'].sum()/original_data.loc[original_data['pay_price']!=0]['pay_price'].sum()
#留存下来但却不付费的用户,我们当做活跃非付费用户
active_user_not_pay=original_data.loc[(original_data['wound_infantry_add_value']!=0)&(original_data['pay_price']==0)]
print('鲸鱼用户收入贡献为:{}%'.format(round(high_value_user_payrate_of_total*100,2)))

鲸鱼用户收入贡献为:89.71%

付费用户之所以会付费主要在于充钱使我更强,而这个游戏里要想直观体会到自己比其它玩家强,那就是建筑等级还有发起PVP直接进攻其它玩家,所以我们猜测付费玩家加速道具使用频率高,同时PVP、PVE之类的指标都要比活跃非付费用户高。

pd.set_option('display.max_columns', 40)
high_value_pay_user.describe()
高价值付费用户加速道具使用状况
active_user_not_pay.describe()
活跃非付费用户加速道具使用状况

上面两图每行数据的含义是数据行数、平均值、最小值、第一四分位数、中位数、第三四分位数、最大值。我们可以看到在所有加速道具的使用上高价值付费用户都全面领先。

高价值付费用户
活跃非付费用户
print(f'高价值付费玩家PVP平均胜率为:{round(34.021745/43.138654*100,2)}%')
print(f'高价值付费玩家PVE平均胜率为:{round(67.859043/74.298286*100,2)}%')
print(f'活跃非付费玩家PVP平均胜率为:{round(3.890129/9.531600*100,2)}%')
print(f'活跃非付费玩家PVE平均胜率为:{round(12.149110/13.559327*100,2)}%')

高价值付费玩家PVP平均胜率为:78.87%
高价值付费玩家PVE平均胜率为:91.33%
活跃非付费玩家PVP平均胜率为:40.81%
活跃非付费玩家PVE平均胜率为:89.6%

我们能发现两类用户在PVP、PVE数量上都有显著差距,在PVE胜率上差距不大在PVP胜率上有一定差距。

玩家付费从数据来看就是他的数据到达某个阈值,然后自然而然发生的事情。综合加速道具使用和PVP、PVE情况,我们可以在前期给予这些活跃非付费用户更多加速道具培养他们使用习惯,而我们也能看到活跃非付费玩家PVP胜率只有40.81%,我们可以适度给予非付费玩家一些战争道具如伪装术使自己部队数在对方侦查时翻倍或者是12小时防御加成,来使玩家体验得以提升。此外对于那些能够巧妙避开所有付费,但同时活跃度高的玩家,我们可以挖掘其社交属性,让他把这款游戏分享给别人时得到相应道具奖励,完成AARRR模型的最后一步。

结论

  1. 根据AARRR模型从获取到付费每个阶段的转化率分别为72.32%,25%,13.04%,整体付费率为3.26%,与行业平均付费率1.74%相比,要高接近两倍。
  2. 针对不同注册时间用户进行转化率分析,发现由于运营活动3月10号与3月13号这两天里的用户在激活、留存转化方面表现优异但在付费方面表现极差,而3月16号与3月21号的用户在激活、留存、转化方面表现良好并且付费意向也高。所以要想提高留存运营活动偏前者,要想提高付费运营偏后者。
  3. 根据留存用户与未留存用户在线时长分析,我们发现超过75%的未留存用户在线时长不超过6分钟,而留存用户则75%以上都超过6分钟。所以我们建议在新手引导方面做出相应改善,直接跳过1级建筑建设过程,引导用户进行更有操作性的伙伴抽取、打野怪等行动。
  4. 通过计算我们得到ARPU平均每用户收入贡献: 0.67,ARPPU平均每付费用户收入贡献: 28.49,一次付费用户人数占比: 43.04%,一次性付费用户收入贡献占比:2.38%,所以虽然整体付费率有3.26%,但一次性付费用户占比大收入贡献小,小鱼用户过多,导致整体付费率不能真正体现游戏的收入转化机制是否设计良好,所以我们改变算法,计算出有效付费率为1.86%,高于行业平均水准。
  5. 我们对比鲸鱼用户与活跃非付费用户数据,发现在加速道具使用、PVP次数、PVE次数、PVP胜率上,鲸鱼用户都远高于活跃非付费用户。所以我们建议在前期多提供一些道具,培养活跃非付费用户使用习惯,这样等后面没有那么多道具赠送时,他们就会忍不住购买。至于那些肝帝,则要发挥他们的社交影响力,让他们完成分享游戏的任务,发挥自己的余热。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容