Skip to content

Supporting a New Game

Gordon Guan edited this page Sep 12, 2018 · 3 revisions

Abstract

It is necessary to understand the general structure of twinject (Architecture) in order to understand this page.

Supporting a previously unsupported game with twinject is a multi-step process:

1. Determine compatibility of general hooks/code

Although the general purpose code should theoretically be compatible with all games, there are some minor inconsistencies in the game engine which may cause the assumptions made to break down.

Factors that affect compatibility of shared code include:

  • bugs in game engine implementation
  • radical changes to game engine implementation
  • faulty assumption in shared code

A real-world example is th11, which has a bug in DirectInput which causes it to fail to initialize properly (thus, the di8 hook does not work for controlling game input).

We want to minimize the amount of game-specific code, and maximize the usage of shared code. Thus, possible solutions to the factors above include (in order of decreasing preference):

  • patching the game (we do this with th11)
    As long as the patches are small, this is the preferred solution for fixing bugs in the game engine itself. It is important that the patches only affect twinject compatibility, and have no side effects that would affect the game.

  • modifying the shared code
    If this approach is taken, the shared code should be modified in an elegant manner, which hopefully adds compatibility for multiple games. There is no point to modifying the shared code to support a single game (no dynamic_cast), since we may as well have a new game-specific component.

We use this approach for every game before th10 in the d3d9_hook component, since those games require the d3dconverter patch. This changes the way the DLL is loaded (dynamic vs static), thus changing the way we need to hook D3D.

  • making a specific game-specific component
    Last resort method, should only be used for radically different game engines (th06).

TODO

2. Implement game-specific hooks/code

Most of the code regarding bullet/enemy/laser position, detection etc. is game-specific, since the game-engines change almost every game which makes them incompatible (besides games like th10/th11). Although the same hooking/polling structure can be used throughout all the games, the actual method for obtaining game information must be redesigned. This process is usually very involved, requiring reverse-engineering of the game.

TODO

Supporting a Non-Touhou Game

If you want to use twinject with another game that isn't from the Touhou Project, then almost all of the code I have written will be of no use to you since even the shared code is specific to Direct3D 9.0 + DirectInput 8.

If the game you want to support also uses these libraries, then twinject will work perfectly with them with the guidelines above. Otherwise, although the shared code is not useful, twinject still provides a useful framework with the following components:

  • DLL injection of hook DLL
  • Hooking framework
  • Patch framework
  • Drawing framework
  • Key proxying and processing framework

The components above an be reused no matter what the target game's game engine is.