twinject icon indicating copy to clipboard operation
twinject copied to clipboard

Using `twinject` to tweak bullet and player movement speed?

Open vittorioromeo opened this issue 3 years ago • 6 comments

Hello,

I have an idea in mind for a project. I'd like players to enjoy Touhou at higher refresh rates without changing the actual gameplay speed.

At the moment, increasing or decreasing the FPS in Touhou games also affects the speed of the simulation. So I thought: what is we increase the FPS to, say, 144, and then give the game's update loop a fake time delta that would keep the simulation speed similar to the original one?

For example, assume that the normal time delta in Touhou is 1 for 60FPS. If we raise the FPS to 144, I'd like the time delta to become 0.416 (60 / 144). The game engine currently doesn't do this, and the time delta is always 1 regardless of the FPS.

Do you think twinject could be used to detect and change these values? I'm an experienced C++ developer but I have almost no experience in reverse engineering.

vittorioromeo avatar Apr 22 '21 14:04 vittorioromeo

Hey,

I think that's actually a pretty great idea. It's certainly possible to do this with twinject, with the difficulty depending on how the specific game is implemented. I think most Touhou games do their physics on a frame-by-frame basis, which is useful for keeping replays in sync since they don't run at the frame rate at when they are originally recorded. This means that the physics of the game might be tied to the framerate in mysterious ways, and that they don't necessarily seperate physics from rendering by using a time delta.

You can see an example with Shuusou Gyoku (Seihou Project), which is open-source and shares some similarities with early Touhou Project games. The game routines use frame counting based on the primary game loop keeping frame times of 16 ms. The game's internal compiled language for controlling enemies (ECL) also has an interrupt-based timer which is tied to frame count.

With these considerations in mind, raising the frame rate might require also modifying the stage scripts with proportionally reduced bullet velocities, increasing the time between stages etc. to keep the original gameplay speed.

Netdex avatar Apr 22 '21 18:04 Netdex

Thanks for the quick and detailed reply!


I think most Touhou games do their physics on a frame-by-frame basis [...] they don't necessarily seperate physics from rendering by using a time delta

That's what I assumed, and I have no plans of changing that. My idea was quick and dirty -- force the game to run at 144FPS, and decrease velocities/accelerations while increasing spell delays and stuff like that.


The game routines use frame counting based on the primary game loop keeping frame times of 16 ms. The game's internal compiled language for controlling enemies (ECL) also has an interrupt-based timer which is tied to frame count.

That's honestly pretty discouraging. I was hoping for some sort of global bullet speed multiplier, or some constant time delta which never changes... but it seems that, at least in that project, everything is pretty hard coded. Even with full access to the source it wouldn't be trivial to support 144FPS, and I shudder at the idea of having to do that while reverse engineering.


It's certainly possible to do this with twinject

Could you please share any pointer on where to start? Never hacked on a Touhou game before and I'm pretty lost :)

vittorioromeo avatar Apr 23 '21 01:04 vittorioromeo

OK, I have somewhat good news. I did some research on some Touhou Discord servers and it turns out someone made a 120FPS patch for EOSD: https://joec.moe/touhou/touhou.html

I managed to find the author of the patch and talked to them. They mentioned there is a value in memory which is basically the time delta, a floating point value always set to 1. This can be altered to change the speed of the simulation. Therefore, changing the value to 0.5 with Cheat Engine and increasing FPS to 120 with vpatch results in a somewhat consistent gameplay experience.

However, for some reason not everything uses the time delta value. I have found this value myself in TH12 (address: th12.exe+B2ED0, realaddress: 004B2ED0) and changed it to 0.4166 to enable 144FPS. Most things seem to be affected, including:

  • Player speed
  • Bullet speed
  • Simulation speed (e.g. delays between attacks, menu speed)
  • Timers (e.g. spell card timers)

Unfortunately, some other thing completely ignore this value:

  • Enemy speed/accelleration (I suspect ZUN coded velocity += accel rather than velocity += accel * dt)
  • Player attacks (Sanae B's attack is completely screwed up)

I discussed with the author of the TH06 patch and they mentioned that they had to tweak some other values manually by using IDA to disassemble the executable. So, in short:

  • Touhou games do have a time delta value that can be changed
  • Changing the time delta value brings us 80% of the way there
  • There are things that need to be manually fixed by disassembling and patching the executable

vittorioromeo avatar Apr 23 '21 15:04 vittorioromeo

That's pretty convenient, good find! My best guess is that this time delta value might have been used for some spellcards that manipulate time, like Youmu's slash attack in th07. It was probably a value that could have been manipulated using the stage script. This might also explain why enemy speed/acceleration is ignored, since there usually aren't any enemies during boss spell cards, and the boss movements are scripted anyways. I don't think anything in th12 uses this mechanic too, which is probably why Sanae B's attack wasn't validated for it. All of this is just a theory though of course.

This definitely makes this project tractable though, if those are the only two things that aren't affected by the time delta value. For example, it would be possible to locate the code that does enemy movement physics and hook/patch it to incorporate the time delta value as well.

Netdex avatar Apr 23 '21 16:04 Netdex

Please tell me this is still a thing. I'm dying to be able to play Touhou at a true 120 Hz refreshrate one day...

Deus-nsf avatar Jul 09 '22 12:07 Deus-nsf

Maybe 144 FPS at correct speed is a bit too ambitious and it would possibly lead to too many rounding errors and problems, however 120 FPS, since it's an even multiplier (x2, or rather /2 speed) seems much safer.

Deus-nsf avatar Jul 09 '22 13:07 Deus-nsf