零基础开发 era 游戏 #3 开发环境配置
工欲善其事,必先利其器。
其实任何文本编辑器都可以,只要你最后写出来的符合语法就行,Emuera 并不在乎你是用什么写的。
理论上你用 Windows 自带的「记事本」/「写字板」也是遵循相同的语法、写类似的内容,一样能做出新的 era 游戏。
但是何必呢?折磨虽小,痛苦永存。
这里简单介绍两个我(最中意)用得最顺手的文本编辑器。
Sublime Text#
资源请自行准备。
其实破解 sublime 很简单,以二进制形式打开可执行文件(
sublime_text.exe
)改几个字节码就行了。但我不敢在写在这里(DMCA 警告)。
实在找不到可用资源又不想交那笔巨贵的保护费的话,建议使用免费的 VS Code。
VS Code 天下第一。
- Ctrl + Shift + P 打开命令面板。
- 输入
Install Package Control
后 Enter 安装包管理器「Package Control」。 - 安装完成后 Ctrl + Shift + P 打开命令面板。
- 输入
install
选择Package Control: Install Package
。 - Enter 进入「安装包输入界面」。
- 继续输入
erabasic
安装代码高亮插件。
Sublime Text 的优势在于轻量,启动速度和内存占用比起 VS Code 来说都优秀得多。
缺点在于过于轻量,缺少很多便捷功能,插件安装 / 使用起来也远远不如 VS Code 简便。
而且插件市场也没有 VS Code 丰富。VSC 的话,只要你能想到的功能,基本上都有现成。
所以总的来说还是推荐使用 VS Code。
Visual Studio Code#
都说谷歌 / 苹果的砍刀部砍了多少多少项目,微软砍的一点也不少好吧。
还好 VS Code 活下来了,希望微软现在在测的 Loop 也能活下来 🙏。
微软家的良心软件:
- 文(轻度使用)可当纯粹的文本编辑器
- 武(重度使用)可调教成 IDE(集成开发环境)
- 下载并安装完成后 Ctrl + Shift + P 打开命令面板。
- 输入
Preferences: Open User Settings (JSON)
打开自定义配置文件。 - 调成你顺手的设置,具体可以自行搜索「VSCode 配置」,此处不再赘述。
熟悉之后继续配置我们需要的、其他一些提升「era 游戏开发体验」的小细节:
- Ctrl + Shift + X 或点击图标按钮打开「扩展」侧边栏。
- 搜索
erabasic
扩展并安装。
这时候就已经有代码高亮、自动补全、函数跳转……等等非常实用的开发辅助功能了。 - 再次打开配置文件(具体步骤参考上文),为 era 开发特别配置:
|
|
Tips#
- Ctrl + F 在当前文件中搜索关键词。
- Ctrl + Shift + F 在整个项目的所有文本文件中搜索关键词。
一个关于自动删除多余空格的小坑#
最后的 "files.trimTrailingWhitespace": true
需要特别注意一下。
如果代码习惯不好,建议改成 false
。
什么叫代码习惯不好?比如
PRINT 你吃牛肉干
← 注意行尾的空格PRINT 嘛?
预期的显示应该是 你吃牛肉干 嘛?
;但如果开启「自动清除多余空格」功能就会变成
PRINT 你吃牛肉干
← 我空格呢?PRINT 嘛?
最后显示为 你吃牛肉干嘛?
。
玩家可能会懵逼「我吃牛肉关你什么事?牛跟你告状了?」造成误解。
代码习惯好的话不应该直接硬打空格强行排版,而是采用更为稳妥和优雅的写法(俗称提高项目
PRINTFORM % "你吃牛肉干", 20, LEFT %
← 随便它怎么修空格PRINT 嘛?
我暂时只想到这种可能稍微影响游戏体验的问题,实际开发中你可能会遇到更恶劣、更难以处理、甚至根本就无从下手让人摸不着头脑的 bug。
无尽的调试(debug)是开发中不可避免的一环,无法接受的话趁早退坑保平安。
调教完成,享受辅助功能拉满的偷税的开发过程吧。
乐观点说,这套应该是目前最舒适最优雅的 era 开发环境配置了。
在安卓手机上进行开发#
用手机写 era 游戏,乍一听,这像是某种玩笑话;但我非常郑重地告诉你,并不是。
它是一个客观且长期存在的需求。
众所周知,有相当
其中又有部分喜欢折腾的深度玩家,期望在手机上直接查看 / 修改 era 游戏的源代码。
我知道这个现象的存在(收到过数次反馈),但一直没有去尝试解决。
因为我自己是没有这个需求的(我甚至几乎不用手机玩 era 游戏),所以不怎么上心。
而且个人思维惯性是这样,比较前沿。一说「手机开发 era」,我脑子里直接蹦出来的方案是最新的技术栈:部署一个 在线版 VS Code,然后直接在手机上通过浏览器访问。
(这个折腾起来有点麻烦的,懒癌一犯就摸了。)
直到 2022 年 8 月初,我在查背景资料的时候,偶然间在 era 日文 Wiki 发现,这个页面竟然推荐了安卓端的编辑器:
Jota+ Text Editor
Android 用テキストエディタ。
有志の手によりシンタックスハイライト設定ファイルが配布されており、
これを適用すると ERB 構文が色分けされる。
Google Play
安装#
简单调研了一下,「Jota+」是安卓平台上一个代码(文本)编辑器,完成度还算不错。
当然,我看上的主要是内置编码转换 / 自定义代码高亮这两个功能。
它的前身是「Jota Text Editor」,最新版为「Jota+ β」。
不过「Jota+ β」需要购买 PRO 使用凭证,白嫖的话还是用免费的「Jota+」就好。
(有一说一,就这点东西,660 円确实有点小贵。)
点击直接下载 apk 文件
至于代码高亮,遗憾的是前人写好的配置文件已经在曾经的 旧储备库爆炸事件 中佚失了。
Jota+ Text Editor 用 シンタックスハイライト設定ファイル (リンク切れ)
但是没关系,我可以现写一个。
配置#
在手机存储空间新建文本文件 /sdcard/.jota/keyword/user/csv.erh.erb.erd.conf
:
#
# EraBasic keyword file for Jota Text Editor.
#
# This file is in the Public Domain and distributed on "AS IS" basis.
#
# https://lackb.fun/era/era-diy-tutorial-3-editor/
author=lackbfun
version=0.1.0
comment=\[SKIPSTART\].*?\[SKIPEND\]
weakcomment=^\s*(;[!#];)?\s*\[SKIPEND\]|^\s*(;[!#];)?\s*\[SKIPSTART\]
linecomment=(^\s*|[^!#]);(?![!#];)[^\r\n]*
string="(\\\"|.)*?"|%(\\%|.)*?%
type=@[^,\(\r\n]*
constant=\b(SAVEDATA|CHARADATA|GLOBAL|DYNAMIC|STATIC|CONST|REF)\b
statement=\[IF[^\r\n]+\]|\[ENDIF\]|\b(PRINTDATA[KD]?[LW]?|STRDATA|ENDDATA|DATALIST|ENDLIST|NOSKIP|ENDNOSKIP|S?IF|ELSE(IF)?|ENDIF|SELECTCASE|IS|TO|CASE|CASEELSE|CONTINUE|BREAK|REPEAT|REND|FOR|NEXT|WHILE|WEND|DO|LOOP|CATCH|ENDCATCH|TRYC(CALL|JUMP|GOTO)(FORM|LIST)?|ENDFUNCGOTO|FUNC|ENDUFNC)\b
number=\b[0-9.]*\b|\d+p\d+|\{(\\\}|.)*?\}
operator=(!|'?=|>|<|\+|-|\*|\/|%|&|\||\^|:)
green=
blue=\b(PRINT(FORM)?(V|S)?(K|D)?(L|W)?|PRINTSINGLE(FORM)?(V|S)?(K|D)?|PRINTBUTTON(C|LC)?|PRINT_ABL|PRINT_TALENT|PRINT_MARK|PRINT_EXP|PRINT_PALAM|PRINT_ITEM|PRINT_SHOPITEM|UPCHECK|DRAWLINE|CLEARLINE|PRINT_IMG|PRINT_RECT|PRINT_SPACE|SETCOLOR|SETCOLOR|RESETCOLOR|SETBGCOLOR|SETBGCOLOR|RESETBGCOLOR|GETCOLOR|GETDEFCOLOR|GETBGCOLOR|GETDEFBGCOLOR|GETFOCUSCOLOR|FONTBOLD|FONTITALIC|FONTREGULAR|FONTSTYLE|GETSTYLE|CHKFONT|SETFONT|GETFONT|FORCEKANA|ALIGNMENT|CURRENTALIGN|REDRAW|CURRENTREDRAW|PRINTCPERLINE|LINEISEMPTY|BARSTR|MONEYSTR|SKIPDISP|ISSKIP|MOUSESKIP|TOUPPER|TOLOWER|TOHALF|TOFULL|TOSTR|ISNUMERIC|TOINT|STRLENS|STRLENSU|SUBSTRING|SUBSTRINGU|CHARATU|STRFIND|STRFINDU|STRCOUNT|SPLIT|REPLACE|UNICODE|POWER|ABS|SIGN|SQRT|GETBIT|MAX|MIN|LIMIT|INRANGE|SETBIT|CLEARBIT|INVERTBIT|ADDCHARA|DELCHARA|SWAPCHARA|SORTCHARA|GETCHARA|ADDDEFCHARA|ADDVOIDCHARA|DELALLCHARA|PICKUPCHARA|EXISTCSV|FINDCHARA|FINDLASTCHARA|COPYCHARA|ADDCOPYCHARA|VARSIZE|RESETDATA|RESETGLOBAL|RESET_STAIN|SWAP|CSVNAME|CSVCALLNAME|CSVNICKNAME|CSVMASTERNAME|CSVBASE|CSVCSTR|CSVABL|CSVTALENT|CSVMARK|CSVEXP|CSVRELATION|CSVJUEL|CSVEQUIP|CSVCFLAG|GETNUM|GETPALAMLV|GETEXPLV|FINDELEMENT|FINDLASTELEMENT|VARSET|CVARSET|ARRAYSHIFT|ARRAYREMOVE|ARRAYSORT|ARRAYCOPY|CUPCHECK|SAVEDATA|LOADDATA|DELDATA|CHKDATA|SAVENOS|SAVEGLOBAL|LOADGLOBAL|OUTPUTLOG|SAVECHARA|LOADCHARA|CHKCHARADATA|FIND_CHARADATA|GETTIME|GETMILLISECOND|GETSECOND|FORCEWAIT|INPUT|TINPUT|TINPUTS|TWAIT|ONEINPUT|TONEINPUT|TONEINPUTS|WAITANYKEY|BREAK|CONTINUE|RANDOMIZE|DUMPRAND|INITRAND|BEGIN|CALLTRAIN|DOTRAIN|RETURN|RETURNF|DEBUGCLEAR|ASSERT|TOOLTIP_SETCOLOR|TOOLTIP_SETDELAY|HTML_PRINT|HTML_TAGSPLIT|CLEARTEXTBOX|STOPCALLTRAIN|TIMES|BAR|BARL|SAVEGAME|LOADGAME|WAIT|RESTART|QUIT|GETTIMES|RAND|CBRT|LOG|LOG10|EXPONENT|SUMARRAY|MATCH|MAXARRAY|MINARRAY|SUMCARRAY|CMATCH|MAXCARRAY|MINCARRAY|GROUPMATCH|NOSAMES|ALLSAMES|MESSKIP|CONVERT|COLOR_FROMNAME|COLOR_FROMRGB|INRANGEARRAY|INRANGECARRAY|GETLINESTR|PRINTCLENGTH|STRFORM|GETCONFIG|GETCONFIGS|HTML_POPPRINTINGSTR|HTML_GETPRINTEDSTR|HTML_ESCAPE|HTML_TOPLAINTEXT|TOOLTIP_SETDURATION|AWAIT|STRJOIN|GETKEY|GETKEYTRIGGERED|MOUSEX|MOUSEY|ISACTIVE|SAVETEXT|LOADTEXT|SPRITECREATED|SPRITEWIDTH|SPRITEHEIGHT|SPRITEPOSX|SPRITEPOSY|SPRITESETPOS|SPRITEMOVE|ARRAYMSORT|CLIENTWIDTH|CLIENTHEIGHT|GCREATED|GWIDTH|GHEIGHT|GGETCOLOR|GCREATE|GCREATEFROMFILE|GDISPOSE|GCLEAR|GFILLRECTANGLE|GDRAWSPRITE|GSETCOLOR|GDRAWG|GDRAWGWITHMASK|GSETBRUSH|GSETFONT|GSETPEN|GSAVE|GLOAD|SPRITECREATE|SPRITEANIMECREATE|SPRITEANIMEADDFRAME|SPRITEDISPOSE|SPRITEGETCOLOR|CBGSETG|CBGSETSPRITE|CBGCLEAR|CBGREMOVERANGE|CBGSETBUTTONSPRITE|CBGCLEARBUTTON|CBGSETBMAPG|CBGREMOVEBMAP|INPUTMOUSEKEY|SETANIMETIMER|HTML_STRINGLEN|HTML_SUBSTRING|REGEXPMATCH|ISDEFINED|EXISTVAR|ENUM(FUNC|VAR|MACRO)(BEGINS|ENDS)?WITH|GETVARS?|SETVAR|VARSETEX|ARRAYMSORTEX|QUIT_AND_RESTART|FORCE_QUIT|FORCE_QUIT_AND_RESTART|FORCE_BEGIN|EXISTFUNCTION|ENUMFILES|GDRAWTEXT|GGETFONT|GGETFONTSIZE|GGETFONTSTYLE|GGETTEXTSIZE|GDRAWGWITHROTATE|PLAYSOUND|STOPSOUND|PLAYBGM|STOPBGM|EXISTSOUND|SETSOUNDVOLUME|SETBGMVOLUME|XML_DOCUMENT|XML_RELEASE|XML_EXIST|XML_GET|XML_SET|XML_TOSTR|XML_ADDNODE|XML_REMOVENODE|XML_REPLACE|XML_ADDATTRIBUTE|XML_REMOVEATTRIBUTE|MAP_CREATE|MAP_EXIST|MAP_RELEASE|MAP_GET|MAP_HAS|MAP_SET|MAP_REMOVE|MAP_SIZE|MAP_CLEAR|MAP_GETKEYS|MAP_TOXML|MAP_FROMXML|EXISTFILE|UPDATECHECK|GETMEMORYUSAGE|CLEARMEMORY|PRINTSINGLEFORM(?:K|D)?|PRINTFORM(?:L?C)(?:K|D)?|PRINTFORM(?:K|D)?(?:L|W)?|DATAFORM|PRINTPLAINFORM|DRAWLINEFORM|REUSELASTLINE|STRLENFORMU?|ENCODETOUNI|INPUTS|ONEINPUTS|THROW|DEBUGPRINTFORM|DEBUGPRINTFORML|PUTFORM|RETURNF?|RETURNFORM)\b ?
red=\b(CALLF?|CALLFORMF|CALLEVENT|(TRY)?(CALL|JUMP|GOTO)(FORM)?|)\b
yellow=\b(DAY|MONEY|ITEM|FLAG|TFLAG|UP|PALAMLV|EXPLV|EJAC|DOWN|COUNT|TARGET|ASSI|MASTER|NOITEM|LOSEBASE|SELECTCOM|ASSIPLAY|PREVCOM|TIME|ITEMSALES|PLAYER|NEXTCOM|PBAND|BOUGHT|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|GLOBAL|RANDDATA|SAVESTR|TSTR|STR|GLOBALS|SAVEDATA_TEXT|ISASSI|NO|BASE|MAXBASE|ABL|TALENT|EXP|MARK|PALAM|SOURCE|EX|CFLAG|JUEL|RELATION|EQUIP|TEQUIP|STAIN|GOTJUEL|NOWEX|DOWNBASE|CUP|CDOWN|TCVAR|NAME|CALLNAME|NICKNAME|MASTERNAME|CSTR|CDFLAG|DITEMTYPE|DA|DB|DC|DD|DE|TA|TB|ITEMPRICE|ABLNAME|TALENTNAME|EXPNAME|MARKNAME|PALAMNAME|ITEMNAME|TRAINNAME|BASENAME|SOURCENAME|EXNAME|EQUIPNAME|TEQUIPNAME|FLAGNAME|TFLAGNAME|CFLAGNAME|TCVARNAME|CSTRNAME|STAINNAME|CDFLAGNAME1|CDFLAGNAME2|STRNAME|TSTRNAME|SAVESTRNAME|GLOBALNAME|GLOBALSNAME|GAMEBASE_AUTHER|GAMEBASE_AUTHOR|GAMEBASE_INFO|GAMEBASE_YEAR|GAMEBASE_TITLE|GAMEBASE_GAMECODE|GAMEBASE_VERSION|GAMEBASE_ALLOWVERSION|GAMEBASE_DEFAULTCHARA|GAMEBASE_NOITEM|RAND|CHARANUM|LASTLOAD_TEXT|LASTLOAD_VERSION|LASTLOAD_NO|LINECOUNT|ISTIMEOUT|__INT_MAX__|__INT_MIN__|EMUERA_VERSION|WINDOW_TITLE|MONEYLABEL|DRAWLINESTR|__FILE__|__FUNCTION__|__LINE__|RESULTS?|ARGS?|LOCALS?)\b
magenta=\s*#(DEFINE|DIMS?|FUNCTIONS?|LOCALS?SIZE|SINGLE|PRI|LATER|ONLY)\b
或者 直接下载 配置文件后放到对应位置。
测试#
ERB 测试用例 test_erb_highlight.erb
:
@SYSTEM_TITLE ; 单行注释 LOCAL = 777 LOCALS = 草草草 ;#; PRINTL 已开启调试模式 PRINTFORML LOCAL={LOCAL} LOCALS=%LOCALS% [SKIPSTART] 多行注释 第二行注释 [SKIPEND] CALL 一般函数, 111, 222 REPEAT 3 PRINTVL 行内函数(RESULT, "测试时间 " + GETTIMES()) REND QUIT @一般函数, 参数A, 参数B #LOCALSIZE 3 #DIM 参数A #DIM REF 参数B [IF_DEBUG] LOCAL += 100 * 20 / 2 % 2000 + 1 - 1 [ENDIF] LOCAL:1 = 参数A LOCAL:2 = 参数B RETURN LOCAL:0 + LOCAL:1 + LOCAL:2 @行内函数(arg1, arg2) #FUNCTIONS #LOCALSSIZE 1 #DIM arg1 #DIMS arg2 LOCALS '= @"arg1={arg1} arg2=%arg2%" RETURNF LOCALS
ERH 测试用例 test_erh_highlight.erh
:
#DEFINE FIVE 5 #DIM CONST BIT = 1p0, 1p1, 1p2, 1p3, 1p4, 1p5, 1p6, 1p7
CSV 测试用例 test_csv_highlight.csv
:
; 假装这里是 Base.csv 1,体力 2,精力 ; 你懂的
如果代码高亮有渲染错误 bug(我相信一定有)欢迎反馈,在 Discord 直接回报就行。
其实有相当一部分是囿于 Jota+ 自身的渲染引擎功能有限,理论上根本无法实现的。
但欢迎积极反馈任何问题,万一可以解决呢。