Python在游戏中的热更新实现

目录
  • 介绍:
  • 原理:
    • 1.标准import
    • 2.reload函数
  • 实现:
  • 总结:

介绍:

热更新,就是在服务器不重启的的情况下,对游戏增加新的功能或者修复出现bug 的代码。游戏更新迭代速度快,催生了热更技术的需求,在我经历过的游戏项目中,无论是服务端还是客户端,版本的更新都是围绕着热更新,特别是现在游戏动辄几个G,每次让玩家下载完整的包不现实,随意游戏必须要支持热更。下面来谈一下客户端Python热更新的处理。

原理:

1.标准import

都知道Python提供了import可以导入一个标准的python模块,将模块载入内存,并加到sys.modules中。但是多次import同一模块只是将名称导入到当前的Local名字空间,也就是一个模块不会重复载入,所以想要热更靠这个特性是不行的。此路不通,请换个思路。

2.reload函数

reload()函数可以重新载入已经导入的模块,这样似乎就可以热更新Python的代码了。但是python原生的reload函数太过简单,不足以支撑游戏的热更新需求,主要原因有几个: reload重新加载的模块不会替换旧版本的模块,也就是已经引用的旧模块无法更新 同样因为不能旧对象的引用,使用from ... import ... 方式引用的模块同样不能更新 reloas(m)后,class及其派生class的实例对象,仍然使用旧的class定义。 同时加载模块失败时候,没有回滚机制,导致需要重新import该模块 因此,结合游戏的热更新需求,自定义合适的reload。新的自定义reload目的是为了达到在原程序不结束的情况下,让程序能动态加载改动后的代码。主要想达到下面两点: 提升开发效率 在游戏不重启的情况下修复紧急BUG

实现:

热更新最核心的需求就是让python解释器执行最新的代码,同时保证其他关联模块不会出现问题。对于刷新function,class内定义的method比较容易实现,但对于刷新module内定义的变量,class内定义的变量,还有新增加的成员变量,则需要有统一的约定。所以在实现热更新过程中,我们需要考虑好代码更新和数据更新这两点,下面罗列一下新的reload具备哪些特性:

1.更新代码定义(function/method/static_method/class_method) 不更新数据(除了代码定义外的类型都当作是数据) 在module中约定reload_module接口,class中约定reload_class接口,在这两个接口中手动处理数据的更新,还有更多的约定和接口待完成 替换函数对象的内容

# 用新的函数对象内容更新旧的函数对象中的内容,保持函数对象本身地址不变
def update_function(oldobj, newobj, depth=0):
    setattr(oldobj, "func_code", newobj.func_code)
    setattr(oldobj, "func_defaults", newobj.func_defaults)
    setattr(oldobj, "func_doc", newobj.func_doc)

2.替换类的内容

# 用新类内容更新旧类内容,保持旧类本身地址不变
def _update_new_style_class(oldobj, newobj, depth):
    handlers = get_valid_handlers()
    for k, v in newobj.__dict__.iteritems():
        # 如果新的key不在旧的class中,添加之
        if k not in oldobj.__dict__:
            setattr(oldobj, k, v)
            _log("[A] %s : %s"%(k, _S(v)), depth)
            continue
        oldv = oldobj.__dict__[k]  

        # 如果key对象类型在新旧class间不同,那留用旧class的对象
        if type(oldv) != type(v):
            _log("[RD] %s : %s"%(k, _S(oldv)), depth)
            continue  

        # 更新当前支持更新的对象
        v_type = type(v)
        handler = handlers.get(v_type)
        if handler:
            _log("[U] %s : %s"%(k, _S(v)), depth)
            handler(oldv, v, depth + 1)
            # 由于是直接改oldv的内容,所以不用再setattr了。
        else:
            _log("[RC] %s : %s : %s"%(k, type(oldv), _S(oldv)), depth)  

    # 调用约定的reload_class接口,处理类变量的替换逻辑
    object_list = gc.get_referrers(oldobj)
    for obj in object_list:
        # 只有类型相同的才是类的实例对象
        if obj.__class__.__name__ != oldobj.__name__:
            continue
        if hasattr(obj, "x_reload_class"):
            obj.x_reload_class()

3.staticmethod

def _update_staticmethod(oldobj, newobj, depth):
    # 一个staticmethod对象,它的 sm.__get__(object)便是那个function对象
    oldfunc = oldobj.__get__(object)
    newfunc = newobj.__get__(object)
    update_function(oldfunc, newfunc, depth)

4.classmethod

def _update_classmethod(oldobj, newobj, depth):
    oldfunc = oldobj.__get__(object).im_func
    newfunc = newobj.__get__(object).im_func
    update_function(oldfunc, newfunc, depth)

模块的更新也是相类似,就不一一粘贴了,只是在原来的reload基础上进行改良,对于模块热更新,还约定了一个reload_module接口,可以自定义数据的更新。 下面添加一些用例:

def x_reload_class(self):
    """ 热更新后,每个重新对象的实例都会执行这个函数
    由于新老对象的替换不会重新调用构造函数,因此有必要对热更新的类对象执行初始化逻辑
    处理新老变量的修复,函数执行环境的修复
    """
    self._new_var = 5000    # 新变量的初始化
    self.runLogic()      # 新修复的逻辑

总结:

只是在基础的reload模块上做了一些定制,让热更新更适合游戏的开发节奏,而不是简单暴力的reload模块

到此这篇关于Python在游戏中的热更新实现的文章就介绍到这了,更多相关Python 热更新内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解webpack的文件监听实现(热更新)

    前言 文件监听是在源码发生变化时,自动重新构建出新的输出文件. webpack 开启监听模式,有两种方式: 1.启动 webpack 命令时,带上 --watch 参数.  唯一缺点:需要手动刷新才能看到变化: 2.在配置 webpack.config.js 中设置 watch: true.  优点: (1) WDS 不刷新浏览器 (2) WDS 不输出文件,⽽是放在内存中 (3) 使⽤用 HotModuleReplacementPlugin 插件 1 第一种方式, --watch 1.1 配置

  • 详解Angular5/Angular6项目如何添加热更新(HMR)功能

    本文介绍了详解Angular5/Angular6项目如何添加热更新(HMR)功能,分享给大家,具体如下: A:什么是HMR? Q:HMR(热替换)用于在运行的应用程序中更新代码而不需要重建它.这将导致更快的更新和更少的全页重新加载. angular6-hmr 提供angular6以上HMR(热更新)功能 步骤 1.进入angular项目父级目录内 git clone https://github.com/staven630/angular6-hmr angular6-hmr目录与angular项

  • C#实现热更新服务器程序的具体过程

    目录 热更新有没有解决一些开发问题的痛点 热更新实现原理 具体的实现过程 总结 热更新有没有解决一些开发问题的痛点 其实首先探讨的一个问题就是,热更服务器程序到底有没有必要出现,或者说有没有适用场景,我个人觉得吧还是有的. 如果真的可以在不重启应用的情况下实现逻辑的更新,这未尝对于一些紧急的情况不是一个好消息,尤其是一些小团队.小创业公司刚起步的时候,技术测试流程和人力不会像成规模的企业那样完善,那么带来的问题就是上线后的应用.游戏可能会存在一些Bug,如果不严重还好,可以留到下一个迭代更新统一

  • 解决vuecli3.0热更新失效的问题

    webpack的热更新可以说极大地提高了前端的开发效率,以下就是本人遇到的针对vuecli热更新失效的解决方法: 1.检查控制台,编译的时候是否有警告,警告很可能导致热更新的失效 2.vueCli3.0及以上的版本,注意不要用cnpm安装依赖包,要用npm 以上这篇解决vuecli3.0热更新失效的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • React Native 实现热更新并自动签名打包功能

    项目背景:手动link的安卓App 1.下载 react-native-code-push npm install --save react-native-code-push 2.在android/settings.gradle文件下新增: include ':app', ':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../no

  • websocket4.0+typescript 实现热更新的方法

    最近搞了一个webpack4+typescript的开发环境,折腾了很久现在记录一下.... 本身环境比较好搞,但是热更新是个麻烦事儿 本环境是基于webpack-dev-server搭建的 output: { publicPath: '/dist', path: path.resolve(__dirname, 'dist'), filename: 'ljax.bundle.js', hotUpdateChunkFilename: 'hot/hot-update.js', hotUpdateMa

  • 详解如何热更新线上的Java服务器代码

    一.前言 1.热更新代码的场景 (1)当线上服务器出现问题时,有些时候现有的手段不足以发现问题所在,可能需要追加打印日志或者增加一些调试代码,如果我们去改代码重新部署,会破坏问题现场,可以通过热部署的手段来增加调试代码 (2)线上出现紧急bug,通过Review代码找到问题,修改好后打包部署的流程可能比较久,可以通过热部署代码及时解决问题 二.Arthas的使用 使用阿里巴巴开源的Java诊断工具---Arthas,他可以附着在我们的Java服务器进程上面,查看服务器状态,jvm状态等各种参数指

  • 浅谈VUE-CLI脚手架热更新太慢的原因和解决方法

    用vue-cli构建了项目之后在webstorm开发,用npm run dev跑本地服务,经常修改之后在浏览器刷新没反应,偶尔才会有刷新,需要重新跑一遍npm run dev才会更新,这是怎么回事呢? 解决方法 webstorm保存的时候会先保存到旧时文件中,其实并没有真正保存,要在setting->stystem settings下的"use save write"去掉 以上这篇浅谈VUE-CLI脚手架热更新太慢的原因和解决方法就是小编分享给大家的全部内容了,希望能给大家一个参

  • Python在游戏中的热更新实现

    目录 介绍: 原理: 1.标准import 2.reload函数 实现: 总结: 介绍: 热更新,就是在服务器不重启的的情况下,对游戏增加新的功能或者修复出现bug 的代码.游戏更新迭代速度快,催生了热更技术的需求,在我经历过的游戏项目中,无论是服务端还是客户端,版本的更新都是围绕着热更新,特别是现在游戏动辄几个G,每次让玩家下载完整的包不现实,随意游戏必须要支持热更.下面来谈一下客户端Python热更新的处理. 原理: 1.标准import 都知道Python提供了import可以导入一个标准

  • 详解Android中实现热更新的原理

    这篇文章就来介绍一下Android中实现热更新的原理. 一.ClassLoader 我们知道Java在运行时加载对应的类是通过ClassLoader来实现的,ClassLoader本身是一个抽象来,Android中使用PathClassLoader类作为Android的默认的类加载器,PathClassLoader其实实现的就是简单的从文件系统中加载类文件.PathClassLoade本身继承自BaseDexClassLoader,BaseDexClassLoader重写了findClass方法

  • python 动态导入模块实现模块热更新的方法

    最近有个部署需求,需要读取py文件格式的配置项,我的实现思路是把配置文件解析到内存中.主要使用两种方法: importlib.import_module types.ModuleType 方法1.使用 import_module 动态导包 先来看看import module使用方法. 主要有两个参数: package:包名 name:模块名 返回 module 对象 现在开始实现动态导包,成功读取到配置项. import importlib settings = importlib.import

  • python基于pygame实现响应游戏中事件的方法(附源码)

    本文实例讲述了python基于pygame实现响应游戏中事件的方法.分享给大家供大家参考,具体如下: 先看一下我做的demo效果: 当玩家按下键盘上的:上,下,左,右键的时候,后台会打印出玩家所按键的数字值,而图形会随之移动 这是客观上面存在的现象. 那么啥是事件呢? 你叫我做出定义,我不知道,我只能举个例子说明,例如接下来的代码中,列出来一些关于游戏中的事件 ''' 事件 产生途径 参数 QUIT 用户按下关闭按钮 none ATIVEEVENT Pygame被激活或者隐藏 gain, sta

  • Ubuntu下使用Python实现游戏制作中的切分图片功能

    本文实例讲述了Ubuntu下使用Python实现游戏制作中的切分图片功能.分享给大家供大家参考,具体如下: why 拿到一个人物行走的素材,要用TexturePacker打包.TexturePacker打包后,助于游戏加载图片效率,且比较好管理. 目前得到一张整图,无法直接导入到TexturePacker. what 切片:使用切片将源图像分成许多的功能区域. how 1 ubuntu下图片处理软件 GIMP: 画好参考线后, 点击 滤镜->WEB ->切片 2 python + PIL  (

  • 如何在Python 游戏中模拟引力

    学习如何使用 Python 的 Pygame 模块编程电脑游戏,并开始操作引力. 真实的世界充满了运动和生活.物理学使得真实的生活如此忙碌和动态.物理学是物质在空间中运动的方式.既然一个电脑游戏世界没有物质,它也就没有物理学规律,使用游戏程序员不得不模拟物理学. 从大多数电脑游戏来说,这里基本上仅有两个方面的物理学是重要的:引力和碰撞. 当你添加一个敌人到你的游戏中时,你实现了一些碰撞检测,但是这篇文章要添加更多的东西,因为引力需要碰撞检测.想想为什么引力可能涉及碰撞.如果你不能想到任何原因,不

  • python 实现数据库中数据添加、查询与更新的示例代码

    一.前言 最近做web网站的测试,遇到很多需要批量造数据的功能:比如某个页面展示数据条数需要达到10000条进行测试,此时手动构造数据肯定是不可能的,此时只能通过python脚本进行自动构造数据:本次构造数据主要涉及到在某个表里面批量添加数据.在关联的几个表中同步批量添加数据.批量查询某个表中符合条件的数据.批量更新某个表中符合条件的数据等. 二.数据添加 即批量添加数据到某个表中. insert_data.py import pymysql import random import time

  • php中Swoole的热更新实现代码实例

    使用swoole_http_server替代php-fpm后,由于php长驻内存,修改了代码不能实时调试,需要去手动去重启服务,很是不方便,决定使用inotify来监控文件状态的改变,来给swoole发送reload信号,来实现swoole的热更新. 如何安装inotify就不写了,安装之后可以建立一个脚本文件,如php_reload.sh: #!/bin/sh # src 需要监控的地址 src=/home/server/Project/test/app/ /usr/bin/inotifywa

  • python编程使用PyQt制作预览窗口游戏中的小地图

    目录 写作思路 1.简述实现原理 2.部分代码解析 ①方框的完整代码 ②编辑界面 ③预览窗口 3.位置同步解析 ①上下两屏位置同步.编辑屏位置保持不变 写作思路 1.简述实现原理 2.部分代码解析 3.位置同步解析(①上下两屏位置同步②编辑屏位置保持不变) 效果图如下: 版本1: 这就是我们常见的预览窗口,上面预览窗口移动/缩放小方框都会导致下面的编辑界面位置发生变化,同理,下面的编辑界面的移动/缩放也会导致上面的小方框变化,并且上面预览图是编辑窗口的同比例缩放 版本2: 在版本1的基础上,加入

  • python游戏测试工具自动化遍历游戏中所有关卡

    目录 场景 思路 实现细节 1.卡住的判定和处理 2.GAutomator 调用游戏内部的 GM 指令 unity 中: python 中: 3.最终输出的报告 详细代码 AutoBattleTest.py 用来实现核心逻辑 ExcelTool.py 用来读写表格 后记 场景 游戏里有很多关卡(可能有几百个了),理论上每次发布到外网前都要遍历各关卡看看会不会有异常,上次就有玩家在打某个关卡时卡住不动了,如果每个关卡要人工遍历这样做会非常的耗时,所以考虑用自动化的方式来实现. 思路 游戏的战斗是有

随机推荐