Company of Heroes Patch 2.300 and Modding

If you've gone online with CoH in the past two days, you'll have been required to download the new 2.300 patch.

The good news: lots of balance fixes, team automatch, hopefully better RO server, other niceties
The bad news: "-dev" mode no longer works, making it difficult to develop and run mods and custom maps

Apparently, Relic are working on a fix for this, but in the meantime I have a temporary solution: Download COH2300dev.rar and extract it to your Company of Heroes folder (probably something like C:\Program Files\THQ\Company of Heroes). RelicCOH.exe has -dev permanently turned off in 2.300, and the RelicCOHUnblocked.exe you just placed in your folder has -dev permanently turned on. Set your shortcuts to use the unblocked EXE if you want dev mode. For convenience, the included batch file can be used to swap the two files over - simply double click RelicCOHSwap(.bat) to swap -dev mode between permanently off and permanently on. Before applying any future patches, remember to swap things back to how they were originally and then delete the custom EXE.

If you're interested in how the altered EXE is different, and why it works then read on. Otherwise be glad that there is a workaround for CoH 2.300. As always, donations via paypal are always appreciated:


Step 1: Load 2.300's RelicCOH.exe into a disassembler and have a poke around. I use IDA5 as my disassembler of choice. The free IDA4 is good as well, but lacks an integrated debugger, so you would have to augment it with OllyDbg or similar. Given that RelicCOH.exe is ~10mb, IDA takes a long time to analyse it fully.

Step 2: As the problem we're looking into is about (not) loading data archives and data folders, we want to find the code which does that loading. The actual code that does the loading for mods is going to be hard to find, but the code that does it for Engine\Data and Engine\Archives\Engine.sga will be easy to find, and should be roughly equivalent to the mod code. Use IDA to search for strings with Engine.sga in them and following the XRef on the string to find the loading code for Engine:

If you have a look over that section of code, you should see the logic followed for loading the Engine data folder:

IF ("-noarchive" option set)
OR ((g_pAppSettings[0xDC] != 0) AND ("-archiveonly" option not set)) THEN
  LOAD Engine\Data\
END

Step 3: So this g_pAppSettings[0xDC] field would seem to control the loading of data folders. Let's call it the isDevMode flag. We want to know where it is set - so open an XRef window for g_pAppSettings. You'll see lots of instances where g_pAppSettings is moved into a register, and one instance where a register is moved into g_pAppSettings. This last one is what we are interested in, as it is where this g_pAppSettings global is created rather than just used for something:

I've placed a breakpoint on the line where the isDevMode field is set, hence why it is marked in red. This piece of code looks like a constructor where every field is set to 0, rather than the actual code logic to set the isDevMode field to 0 or 1 depending on -dev, so we need to keep on searching.

Step 4: Launch RelicCOH.exe through IDA and wait for the aforementioned breakpoint to trip. We want to know when the isDevMode field is set properly, so setup a hardware breakpoint on memory write to the isDevMode field:

Resume RelicCOH.exe and wait for this memory write breakpoint to trip. This brings us to a new piece of code:

Here, the -dev switch is checked for, but the return value ignored as -sync_high is immediately checked after. Shortly after, the isDevMode field is set to 0. This "accidental modding block" must have removed the code which checks for -dev and then sets isDevMode accordingly with code that just sets it to 0 every time.

Step 5: If we were being efficient, then we would write some code to take the result of the -dev check and set isDevMode to 0/1 as such. I didn't feel like doing that, so I did the next best thing. Make a copy of RelicCOH.exe and open it in a hex editor (I use XVI32) and search for the instruction we just saw in IDA (C6 81 DC 00 00 00 00 - the move 0 into isDevMode). If the last 00 is changed to 01, then isDevMode will be set to 1 rather than 0. That's all the unblocked EXE is - a copy of RelicCOH.exe with one bit changed from a 0 to a 1 so that isDevMode is always on rather than always off.

Europe in Ruins Ingame UI?

Above: Company of Heroes: Opposing Fronts running with a prototype overlay rendered on top.

Download video of the overlay in action.

The Europe in Ruins mod for Company of Heroes always presents interesting challenges. At the moment, I'm prototyping an in-game UI for the mod, as administering your army inside the game should be alot more user friendly than doing it on a website. If you're interested in how it's done then carry on reading, otherwise be happy that EiR might one day use an in-game UI.

  1. Firstly, a special mod DLL is specify in the EiR.module file. This DLL behaves exactly like the default CoH mod DLL, except it replaces the Lua loadfile function with one that can load DLLs as well as files. This mod DLL is a minimal jailbreak; with it Lua/SCAR can load whatever DLLs they want to, without having to hack or patch any CoH code. The replacement it performs is very simple; the first 5 bytes of the original loadfile function are replaced with a jump to the custom loadfile function.
  2. A command typed into the console (dofile [[eir.lua]]) then loads a DLL containing the overlay code along with some auxiliary helper code written in Lua. The overlay DLL patches two things: the DirectXDevice9's EndScene function, and the PeekMessage function.
  3. For the EndScene function, it calls Spooge.dll to get a Spooge Device pointer, and then takes the DirectXDevice pointer from the Spooge Device, and then gets a pointer to the DirectXDevice's virtual function pointer table. In this table, it replaces the pointer to the EndScene function with a pointer to our own version of the function (after first recording the address of the original function).
  4. For the PeekMessage function, it finds where PeekMessage is called in Platform.dll and replaces those 5 bytes with a call to our own version of the function. The overlay DLL can now draw things on top of CoH by drawing in the custom EndScene function, and can intercept input events by filtering the output from PeekMessage. It exposes to Lua/SCAR simple constructs for drawing and for rendering.
  5. The aforementioned Lua auxiliary helper code abstracts the primitive constructs provided by the DLL into a simple API for creating/manipulating windows and other GUI elements like buttons, text boxes and dropdown lists (although only window and button are done at the moment).
Hopefully someday this will come together to allow a full in-game UI for EiR, but at the moment it is still very much in the prototyping stage. Stay tuned!

Edit: Some people have mentioned that it looks like the Steam in-game UI. As a clarification, this does not use or depend upon any part of Steam. I have been using the Steam UI as a look & feel to aim for (at least for my prototyping), but this just means that the 9 images that are used to stitch together a window graphic are the same colours and whatnot as Steam uses. Again, this will not need Steam, does not use Steam and is not associated with Steam.

Opposing Fronts

The Opposing Fronts expansion for Relic's WW2 RTS "Company of Heroes" contains a secret donkey unit:

Harvest Open Beta

"Harvest" is a cool little RTS game developed by the swedish indie company Oxeye. Download and play now from http://www.oxeyegames.com/harvest/

What level can you get to?

page: 20 21 22