a few things i found while reading games i was modding.
rpg maker: the script it wouldn’t load
changed is an rpg maker vx game, so all of its scripts live in one encrypted archive, Game.rgss2a. i wanted to run my own script before the game starts. my first try was the obvious one: point Game.ini at a loose script file. the game just stops with “Failed to load script”.
it turns out rgss2 ignores that file for as long as the archive exists. i checked by renaming the archive, and then the loose file loaded fine. so what i do now is append one extra entry to the archive itself, and cut it off again when you uninstall.
while i was in there i extracted the whole archive. the format is rgssad v1, which uses a fixed key (0xDEADCAFE), so a short script is enough. it holds 99 script sections, and most of the game’s logic is readable in them.
source: packets from 127.0.0.1
for the entropy zero 2 co-op, the host runs a small program on the same machine as the game, and it passes packets between the game and a relay. nothing arrived. the game server was running, but a query sent to 127.0.0.1:27015 got no answer, while the same query sent to the machine’s lan address (192.168.x.x:27015) did.
source silently drops any udp packet whose source address is 127.0.0.1. the fix was to make the program send from the lan address. no log line says any of this. i only found it by sending the same packet from both addresses and seeing which one worked.
ultrakill: levels that don’t break
i wanted explosions in ultrakill to blow holes in the level. the levels are baked: when a level loads, the game replaces each static renderer’s mesh with one big merged mesh, so there is no separate wall or floor to remove.
decompiling the game showed how renderers map onto sub-meshes of the merged one, and that was enough to cut block-shaped holes into the mesh and into its colliders. the cutting code has its own unit test, which caught one bug: a surface lying exactly on the edge of the blast box never got cut, because it counted as outside. i added a 0.05 margin.
ultrakill: the shader
to make the blocks i added look like they belong in the level, i read the game’s shader out of its asset bundles with unitypy. the level shader is a single pass with vertex lighting, and about half of the game’s materials (1,177 of 2,144) use the same two keywords, so the new blocks use them too.