Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

非常有趣的mod和一些改进意见 #1

Open
tastynoob opened this issue Jun 4, 2024 · 17 comments
Open

非常有趣的mod和一些改进意见 #1

tastynoob opened this issue Jun 4, 2024 · 17 comments

Comments

@tastynoob
Copy link

1.优化汇编风格,实际上没必要参考真实机器的x86汇编,完全可以定制一套更加高效的汇编格式
2.替换掉javascript执行器,使用一种简单的定制语言,编译为汇编解释执行

@tastynoob
Copy link
Author

有群吗,我可以参与设计

@imengyu
Copy link
Owner

imengyu commented Jun 5, 2024

很好的想法但是很难设计

@tastynoob
Copy link
Author

很好的想法但是很难设计

我可以提供一些帮助,我本职就是CPU工程师,恰好又喜欢玩缺氧

@imengyu
Copy link
Owner

imengyu commented Jun 5, 2024

还是非常感谢您的支持。

但是我个人认为,这是一个用于游戏中的模组,没有生产力要求,换成更高效的语言并不会带来什么更好的收益。而且如果如你说的替换掉js,搞一个特殊的脚本语言、汇编语言,这样大家都不会,反而要学习,劝退。我选择js作为控制语言,也是因为它足够简单,语言热门,会的人最多,大家可以快速上手。

您的想法可以作为一个分支来开发,作为第三第四种,这样大家也有选择可以选喜欢的玩。

(PS。缺氧是使用C#语言开发的,目前这个模组运行js和汇编都是使用C#写的一个解释器来运行的,目前实现不了直接在游戏里运行汇编代码,更不要提编译这复杂的东西了)

@tastynoob
Copy link
Author

可能对我的意思理解有点出入

首先,C51汇编本身就很低效,编码和解释执行都很低效,考虑到性能,我觉得设计一种更简单的汇编格式较好
比如

add x1 x2 x3 表示 x1 = x2 + x3, x代表寄存器堆
add [x1] [x2] [x3] 表示 mem[x1] = mem[x2] + mem[x3], mem代表内存
loop:
b x2 < x3 loop 表示x2<x3的话就跳转到loop
j loop 直接跳转
call sleep(100) 调用内置函数

这样会更直观,上手会更容易,对于第一次接触的玩家,我想这种汇编会比C51更加容易学习

第二点,替换掉javascript也是因为效率比较低,并且容易把游戏搞崩,最佳方法应该是编译为上面说的自定义汇编代码,一帧只执行若干条指令,这样可以保证游戏不会卡顿或者卡死,塞个简单的编译器并不难

@tastynoob
Copy link
Author

我可以免费提供完整帮助

@tastynoob
Copy link
Author

这个mod要做得好玩的话建议限制CPU中的代码量,比如二级科技可以只给个4输入4输出的CPU,限制为64条汇编指令的ROM,给个128byte内存RAM,三级、四级科技的CPU则有更多的端口,ROM和RAM,同样也需要一些稀有金属,可以整个新建筑“编程器”,负责将用户写的代码转换为汇编代码

@imengyu
Copy link
Owner

imengyu commented Jun 5, 2024

  • 我使用的JS解释器项目是 https://github.com/nilproject/NiL.JS 。实测下来性能上并不会有太多问题,我觉得已经足够完美,不需要编译,编译了也不一定比解释快多少,除非像chrome v8引擎开JIT编译成字节码执行那会很快,但那得写多少代码,几万行,写一个编译器有这么简单吗。
  • 汇编的话我自己写了一个解释器 https://github.com/imengyu/ONICPU/blob/main/ONICPU/FCPUExecutorAssemblyCode.cs ,目前是每0.2s 执行8条指令,测试性能并不会太差。如果你觉得不满意可以开个分支自己开发,按照这个接口直接新建一个解释器类,重新写一款,我再将其合并到主分支里面。
    另外推荐一款异星工场的类似CPU模组 https://mods.factorio.com/mod/fcpu ,我也是受它的启发而做了这个模组的,它的指令也是和标准差不多。

感谢你的支持!我个人可能没有太多时间开发这个模组,主要是维护和修复bug,如果你想做,可以开个分支自己开发,我再将你的修改合并到主分支里面。

@tastynoob
Copy link
Author

正在重写汇编解释器,估计过几天就能写完

@tastynoob
Copy link
Author

https://github.com/tastynoob/FAST-PSASM
我设计了个更加简单的“伪汇编”格式和一个更加高效的伪汇编解释器
测试1s可执行200M左右条指令

@tastynoob
Copy link
Author

我可能需要你的一点帮助,我不是特别懂缺氧mod开发,很多API我并不知道用法,目前我已经将我的psasm移植上去了,但仍有不少问题

@tastynoob
Copy link
Author

我实现了一套保存恢复机制,可以将汇编解释器保存为二进制文件的形式,保存一个CPUContext仅需1.5K左右的存储,并且保存与恢复仅需5ms左右,这比json序列化更加高效快速,但是我不是特别懂缺氧存档的保存加载机制,这部分需要你的帮助

@imengyu
Copy link
Owner

imengyu commented Jun 9, 2024

@tastynoob 接入到cpu模组里面的这一块代码我帮你写就可以了,我需要一些时间来修改

@tastynoob
Copy link
Author

tastynoob commented Jun 9, 2024

这是我的修改ONICPU-PSASM,目前做了如下改动:
将C51汇编解释器改为psAsm解释器,现在能够在游戏存档保存加载时完整恢复,而不用手动启动
javascript解释器目前已经被我改坏了,处于不可用的状态
目前还有个bug,触发条件是:保存存档后立即退出到主页面,然后立即加载,点开CPU的编辑界面
会在这里触发“nullreference”异常
但是如果你保存存档后退出到桌面,再重新启动游戏,则不会有如上bug
然后下面是我个人修改建议:
1.考虑到兼容性,可以单独开一个插件叫“KCPU”,删除javascript解释器,只保留psasm解释器,因为javascript解释器目前还无法做到完整恢复,并且有安全隐患(如果有人写了个死循环,并且此时存档刚好保存,那么可能会出现一加载存档即卡死的问题,这会导致存档崩溃)
2.将线组改为原来的4bit位宽,将输入端口合并成一个32bit值,同理对输出端口也一样,可简化编程,这样最多可达32个输入,32个输出,已经完全够用。
3.将CPU区分为二、三、四级科技,二级科技CPU仅保留4个输入,4个输出,拥有较小的rom和ram,三级科技CPU可拥有8到16个输入、输出,四级科技CPU可拥有32个输入输出
4.添加reset端口,为1时重置CPU
5.8位显示器使用2个线组端口,16位显示器使用4个线组端口,32位显示器实际上可以去掉

@imengyu
Copy link
Owner

imengyu commented Jun 9, 2024

我给你整理一个干净的分支出来好了,没有javascript,只有汇编的一个空类,然后你在这上面开发可以吗

@tastynoob
Copy link
Author

可以,我把代码迁移过去

@tastynoob
Copy link
Author

我现在已经给psasm设计了一种简易编程语言pslang和它的编译器,目前已经能够正常的编译简单语句
再开发开发就可以迁移到mod上了
后几天因为要出差,暂时停止开发,详细可以看这里

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants