Skip to content

Modding support

Nikolai Wuttke edited this page May 11, 2022 · 19 revisions

Like the original DOS executable, Rigel Engine supports replacing individual files from the game's data pack file (NUKEM2.CMP) with external files. For example, when a file called L1.MNI is found next to the .CMP file, it will be used instead of the version found inside the .CMP. This makes it possible to use existing patches and mods, like the sunglasses patch.

On top of this, Rigel Engine features enhanced modding support (available as of v0.8.0): Sprites, tile sets, backdrops, sound effects, and music can be replaced with files in modern formats. The game looks for replacement files in a folder called asset_replacements next to the .CMP file. For each file that's found in that folder, the game will load that file instead of the version in the original game data.

I made a video demonstrating this, and explaining how to use it: https://youtu.be/bqF6EVP2qoA

Type Naming scheme Supported formats Notes
Tile sets tileset<N>.png PNG <N> must match the (hexadecimal) number of the tileset to be replaced. E.g. tileset2.png to replace CZONE2.MNI, tilesetA.png to replace CZONEA.MNI, etc.
Backdrops backdrop<N>.png PNG Just like with tile sets, backdrop1.png replaces DROP1.MNI etc.
Sprites actor<N>_frame<F>.png PNG <N> is the actor ID and <F> is the animation frame. For example, the blue guard enemy has ID 159. To replace all animation frames of that sprite, files named actor159_frame0.png up to actor159_frame12.png should be provided.
Sound effects sound<N>.wav Wave <N> is the sound effect number, starting at 1. See note below on intro movie sound effects.
Music see notes Ogg, Mp3, Flac, Opus, Wave, various module formats To replace music, the filename needs to match the name of the game's original music file, but with one of the supported formats' extensions instead of IMF. E.g. kickbuta.mp3 to replace KICKBUTA.IMF. A variety of file formats is supported, essentially any format supported by the SDL_mixer library. This includes tracker module formats supported by ModPlug.

Limitations

  • It's currently not possible to replace full screen images like the menu background or episode end screens, except by replacing with files in the original game's format.
  • It's not possible to replace the large menu font with a modern format.
  • Using any high-resolution graphics forces nearest neighbor scaling.
  • In-game text, like the tutorial messages when picking up items, can't be changed except by compiling a custom executable.

Intro movie sound effects

To replace the sound effects used in the intro movie (Duke at shooting range), use the following:

  • sound35.wav - gun shot sound
  • sound36.wav - gun shot sound (2)
  • sound37.wav - falling shells
  • sound38.wav - target moves
  • sound39.wav - target stops
  • sound40.wav - "I'm"
  • sound41.wav - "back"

This is different from the naming of these files in the original game data, and these numbers are not shown in editing tools. I just defined them this way for RigelEngine.

Notes on image size and aspect ratio

Replacement graphics have no restrictions w.r.t. color, the full RGB spectrum can be used. Files can contain an alpha channel, and will be rendered accordingly. Replacement graphics can either match the resolution of the original graphics, or be higher resolution.

The way this works is that the engine determines the on-screen area that should be occupied by a graphic like a sprite, and then stretches whatever graphic is used (replacement or original) to fill that area.

For example, Duke Nukem's idle pose is 32x40 pixels in the original art. When running the engine at, say, 1920x1080 resolution, this will be upscaled to 144x216 pixels. Now if a replacement sprite is used, it will also be displayed as 144x216, regardless of the actual size of the replacement.

One important point is that the scaling takes aspect ratio correction into account: The original game's 320x200 resolution is stretched vertically when playing on a period-appropriate CRT monitor with 4:3 aspect ratio (320x200 is actually 16:10 without the stretching). To faithfully recreate the look of the game, RigelEngine therefore replicates this vertical stretching.

Now this means that if you were to replace the aforementioned Duke sprite with a replacement that's twice the size, i.e. 64x80, it will also undergo the same vertical stretching. With a replacement that already matches the aspect ratio of the on-screen display this won't be the case. E.g. 72x108, 80x120. These example sizes have an aspect ratio of 2:3, which matches the on-screen display of the sprite (144x216 at 1080p), whereas the original art (32x40) has an aspect ratio of 4:5.

Now how do you figure out what size to use for replacements in order to avoid vertical stretching? The easiest is to use the original art's size scaled by a factor of 5 horizontally, and 6 vertically. These scaling factors transform images into their aspect-corrected equivalents without any artifacts, since the scaling is by integer multiples on both axes. For full-screen images (320x200), this gives us a resolution of 1600x1200. For the Duke sprite example, it gives us 160x240.

Alternatively, you can decide to target a certain resolution like 1080p or 4k, and then determine the scaling factors that the engine will use. In the example above, I mentioned that the Duke sprite will occupy 144x216 pixels on-screen after upscaling when running at 1080p, but how did I determine these numbers? With the following formula:

scale_x = screen_height * 4/3 / 320
scale_y = screen_height / 200

So for 1080p, we would calculate the horizontal scale as 1080 * 4/3 / 320 = 4.5, and the vertical scale as 1080 / 200 = 5.4. If we then apply these factors to the Duke sprite, we get the numbers we used: 32 * 4.5 = 144, 40 * 5.4 = 216.

With this method, it's possible to determine the ideal size for a replacement graphic to appear on screen without any scaling at all at a certain resolution. If someone plays the game at a different resolution than the one you targeted, there will still be scaling but the aspect ratio of your art will be preserved.

Backdrops

Backdrops are handled a little differently compared to other graphics, in order to allow for wide backgrounds. The vertical stretching mentioned above will only be applied if a replacement backdrop matches the original art size, i.e. 320x200. If the replacement is larger on any axis (i.e. 640x200, 320x240 etc.), the graphic will be scaled uniformly in order to have it fill the entire screen vertically.

For example if you have a backdrop that's 216 pixels high and you're playing at 1080p, then it will be scaled by a factor of 5 (1080/216 = 5) both vertically and horizontally, regardless of the horizontal size.

How to extract assets

To extract assets from the original game and convert them to modern formats, various tools can be used. I can recommend K1n9_Duk3's Enormous Tool: It's a level editor, but also allows browsing the game's various assets and exporting them. It's also a good source for figuring out the numbers of sound effects etc. Unfortunately, it only runs on Windows.

Some other tools that I'm aware of:

Clone this wiki locally