大型的游戏项目包含许多错综复杂的业务逻辑,针对UE4游戏而言,如果纯粹采用C++编写的话,一方面会增加大量的劳动成本,影响效率,另一方面难以解决游戏热更的问题。lua作为胶水语言,能够与C/C++/C#等语言互通,简化业务逻辑编写,并且支持热更。针对UE4的游戏开发,UnLua以及sluaunreal都是采用lua编写逻辑的解决方案。
作为一个没有怎么接触过游戏开发技术栈的小白,本文主要上手UnLua的使用。
大型的游戏项目包含许多错综复杂的业务逻辑,针对UE4游戏而言,如果纯粹采用C++编写的话,一方面会增加大量的劳动成本,影响效率,另一方面难以解决游戏热更的问题。lua作为胶水语言,能够与C/C++/C#等语言互通,简化业务逻辑编写,并且支持热更。针对UE4的游戏开发,UnLua以及sluaunreal都是采用lua编写逻辑的解决方案。
作为一个没有怎么接触过游戏开发技术栈的小白,本文主要上手UnLua的使用。
手机投屏/录屏在测试领域的用途有很多,比如:
当前手机投屏/录屏的解决方案有两个:STF的minicap以及Genymobile的scrcpy。今天则稍微介绍一下scrcpy,能够兼容各类安卓手机,并且在投屏方面,低延迟与高清晰度兼具。
在研发代码覆盖率测试工具的时候,通常除了代码覆盖数据收集模块之外,一般还要研发前端展示的部分以展现代码覆盖分析报告,通常会为每一个文件增加行染色,类似于jacoco这种形式。
然而代码覆盖报告实际出来的行染色,会出现许多正常代码行没有着色的情况。这是因为编程语言认为的“行”和本身我们在文本编辑器打出的”行“是不一样的。编译出来的“行”实际上是一段操作,比如我们定义一个函数的时候,编译器认为我们执行的操作有包括function xxx那一行,于是就有一种情况——我们实际没有运行过这个函数,但由于定义被覆盖,因此出现function xxx染绿,而函数体染红的现象。从用户的角度而言,用户如果对代码编译这块并不熟悉的话,就会造成理解上的偏差。
因此考虑工作成本,如果有必要的话,需要对代码覆盖数据进行修改,从而展现更好的代码行染色效果。以lua为例,可以采用这样的方法:
在某些游戏研发or测试的需求中,需要在Unreal增加一个插件或者模块,里面启动一个服务器作为SDK,然后外部通过直连或者adb forward可以连接到客户端中,获取客户端实时的场景、actor信息等等。UE4本身除了socket server支持之外,也支持简单的HTTP Web Server。由于网上没有比较好的范例,因此这里给出一个例子。
本文以Unreal 4.24为例。搭建HTTP Server,需要在.Build.cs
中引入如下模块:
1 | PrivateDependencyModuleNames.AddRange( |
通过FHttpServerModule::Get()
方法,可以获得内置的HTTP Server模块的一个单例,该instance负责管理内置private的socket listeners。我们可以通过该单例获取HTTPRouter
,然后绑定路由跟handler,然后调用StartAllListeners
,就能够启动Web服务器。具体代码如下:
最近开始研究一些游戏自动化测试方面的内容。游戏自动化测试是游戏测试研究领域的难点之一,当前主流的方案有两种,一种是采用纯粹的UI识别方法进行,典型的例子是Airtest,另一种是直接嵌入到游戏引擎中获取节点树等元素从而对实体进行操作,典型的例子是GAutomator。由于笔者先前略微接触过Airtest方面的内容,因此本次决定上手GAutomator尝试游戏自动化。
本次上手过程具体则用GAutomator对Unreal4.24示例mobile项目中的元素进行操作,利用安卓手机进行调试。基本原理上,GAutomator会作为插件嵌入到Unreal项目中,自己包含一些获取World中信息的功能,而后listen一个端口,从而外部请求该插件可以获取World中的信息。通过adb进行搭桥,在外部,用户可以基于GAutomatorAndroid编写,从而不仅可以与GAutomator的Unreal插件打通,而且也可以通过预先集成的UIAutomator这样的工具直接模拟屏幕操作。
hugo是当前热门的个人博客框架之一,和hexo同样是markdown文件跟博客帖子一一对应。有些同学想利用hugo制作个人视频博客,但发现在hugo博客中不支持直接在markdown里输入iframe标签,从而没有办法将其它网站的视频(比如b站)嵌进来。这种情况下,我们可以采用hugo内置的shortcode机制完成这个需求。
我们参考的文章是create your own shortcodes,在这个文档中介绍了自定义shortcode从而快速渲染网页的方法,并且举了youtube以及vimeo的例子。照葫芦画瓢,我们也可以定义b站的shortcode。
我们首先在layouts/shortcodes
目录下创建bilibili.html
,然后填充内容如下:
本月,eclipse theia发布了1.0版本。作为一个云端/桌面IDE框架,并且顶着eclipse foundation的名声,theia在github上受到万众瞩目。因此笔者决定上手eclipse theia,提前品尝一下云端IDE的滋味。
笔者选择了gitpod而非本地docker作为theia的实验对象,这是因为gitpod本身就是theia的扩展版,并且支持github/gitlab上的项目导入,相当于云端github/gitlab项目的IDE,这样就可以实现在theia中启动一个theia项目,一探其中究竟。
登录gitpod,选择theia项目。项目的预设中会自动构建并在容器的3000端口启动theia。点击右侧的preview,就可以在gitpod的theia中打开原生的theia网页。当然也可以利用gitpod的open in browser方法,在自己浏览器的新标签页中打开原生的theia。
最近在项目组测试有开发一个导表检查的需求,大致是在策划提交表更新到svn之后,svn发送post-commit到策划表数据服务,而后策划表数据服务下载excel文件,更新数据之后,将导表检查下游服务所需的检查数据进行整合,然后post到导表检查服务。在这个过程中,由于做的仓促没有考虑设计,最后策划表数据服务的JVM发生了OOM问题。经过一番排查改进了设计,解决了这个问题。
JVM的内存结构跟GC流程是老生常谈的话题。Java8去掉了永久区的设定,更改为了Metaspace存储类的元信息、常量等内容,而剩下来依然是新区eden和老区old。当eden区空间满的时候触发young gc,将eden区根节点不可达的对象清除,存活的对象转到survivor区。survivor区的对象如果经历了某一个数(可配置,最高15)的young gc后仍然存活,就会转到old区。如果短时间内创建大量对象,且eden区放不下,young gc没有清除过多数据的情况下,多余的数据会转到old区。如果old区也放不下,就出现OOM(Out Of Memory)。一般业务层面导致OOM的原因基本上是一次产生大量对象,或者是内存泄露,没有及时清除不需要的数据引用。
策划表数据的业务逻辑上是下载数据->更新数据->进行导表检查的一个流程,其中下载、更新数据这一环节会产生大量的对象,而同样进行导表检查时为了发导表检查所需的数据,也会产生大对象——需要将数据序列化为json字符串。在这个流程里自己犯了几个错误导致OOM的问题,具体如下:
近期项目组准备做一个新的工具,因此自个儿做的start-fastapi框架正好能派上用场试试水。在起草需求搭建最初框架的时候也逐步发现原先的start-fastapi有一些不足的地方,因此做了一些针对性的优化。
首先必须重新介绍一下start-fastapi,其本身是轻量级web框架fastapi的延伸,但是由于fastapi给的例子过于简单,因此就基于此做了一个简单的web后端脚手架,借鉴了eggjs的目录组织模型,使得整个框架更加易于投产。如果稍微看过start-fastapi其中的代码的话就能够发现它并不是一个OOP的框架,这是因为一方面python本身不是向java一般与OO设计理念强耦合,且其module隔离与动态加载机制已经足够区分每一个功能模块了;另一方面轻量的HTTP Web Server本身作为无状态的服务,各个功能模块应该是静态式、单例式的存在。在start-fastapi上也可以继续扩展底层。从起草工具的效果来看,多人协同开发时,每个人负责的模块应当也不会有太大冲突的概率。
接下来是近期优化的一些点,首先是application目录下的优化。原先application分为了service、middleware、config等多个模块,但现在直接缩减为controller、logger跟router,这是因为service跟middleware里全局性的功能模块一般都是用户自定义的,而controller的response可以约定,logger factory也可以统一提供。而router作为后端app的固有功能,这块就必不可少了。
Vuetify是Vue的一套前端组件框架,基于Material Design设计,界面较为整洁。最近由于项目需要开始入手,但在写自定义v-autocomplete
组件的时候却踩了许多坑。因此本文果断记录一下踩坑的过程。
首先新上手vue的话肯定耳边都会萦绕着“双向绑定”一词,用的最多的属性就是v-model
了。但是我们参考官方文档可以发现v-model
只是语法糖,除了绑定默认组件的值(比如select
元素是value
,而checkbox
元素是checked
)之外,还会绑定监听用户输入事件(比如text
元素是input
,而radio
元素是change
)。因此要用v-model
的话需要关注相应的元素是否本身就支持语法糖。我们在v-autocomplete官方文档中可以发现,其扩展了v-select
组件,因此如果用自定义组件包一层的话,一般主要关心的是怎样传递最终选择的value,就可以了。
比如要做一个异步检索items的v-autocomplete
组件,我们可以用如下的方式自定义:
其中template如下: