Post news Report RSS DevBlog #1: The development process

From this article you will know what methods are used to reach deep modification for Armies of Exigo.

Posted by on

There are typical methods for packaging resources (textures, static models, menu xml files, etc.) into *.ork game archives in order to game reads and uses the mod files instead of its own. This all applied, of course, but it's not that interesting. What is much more important is the deep modification and work with graphics.


♦ Using of ReShade ♦

Graphics of the original game are good. I mean, it is very bad technically and textures make all the beauty. That is why ReShade is definitely nessesary. This allows you to do such dirty things like DOF, AO and SSR aside of common color correction. Just look at screenshots taken with original graphic and reshaded one. Heaven and earth.

Vanilla graphics

Reshaded graphics


So, just adjust the picture for beauty? The problem is that light (day) and dark (underground or night) maps require different shader settings. And they should changed smoothly between these boundary states. There is a shader that simulates eye adaptation in the dark (and I use it as well), but in fact this is not a very flexible solution. In addition, different UI configuration requires a real-time adjusted UI mask. ReShade with addon support allows to do all that things.


♦ Deep modification ♦

And now the most interesting. In simple terms, deep game modification is achieved by injecting code into the game's address space and executing it. The game's exe loads a DLL containing my code, which manages the game's objects (functions, variables) directly in its memory. Also, ReShade parameters are controlled from the DLL code. In some cases, the original functions of the game engine are intercepted with my own in order to execute my code at right time or to read/write needed variables at that moment. Therefore, technically, adding almost any features to the engine comes down to the following scheme:

  1. Definition of a set of variables/functions that are used by the original engine, and which I need to read or change in order to implement feature.
  2. Determining addresses of desired set of variables/functions so I can work with them right in my DLL
  3. Changing variables from my DLL

By the way, cheats work and are developed according to the same principle ๐Ÿ˜‚.

To implement the first and second points, it is necessary to research assembler code of the game, using a debugger, etc. All these are typical examples of reverse engineering. In fact third point is engine shell over the original engine. Inside engine shell I work with the original engine API (that includes all researched functions during reverse engineering). So that lookes like as if I had part of source code of the original game engine. Below you can see part of engine API (screenshot from Visual Studio)

part of aoxapi


The larger and more functional engine shell, the easier it is to change some things in the game. You may seems the “moving against the wind” feature is a complicated thing, but it is implemented in just a few lines of code of engine shell:

float shiftedForce = 0.f;
if (m_weatherManager->windCurrentStrength > WEATHER_WIND_SPEEDADDPOINT) {
	shiftedForce = (m_weatherManager->windCurrentStrength - WEATHER_WIND_SPEEDADDPOINT) / (1.f - WEATHER_WIND_SPEEDADDPOINT);
}
AOX_Entity *pEnt = m_entityManager->GetFirstEntity();
while (1) {
	pEnt = m_entityManager->GetNextEntity(pEnt);
	if (!pEnt) {
		break;
	}
	if (pEnt->pMovement) {
		if (pEnt->pMovement->flags > 0) {
			auto movedir = m_entityManager->GetXYFromYAW(pEnt);
			pEnt->pMovement->speedRatio = 1.f + glm::dot(movedir, m_weatherManager->windCurrentGlobalDir) * WEATHER_WIND_SPEEDADDMAX * shiftedForce;
		}else {
			pEnt->pMovement->speedRatio = 1.f;
		}
	}
}

Scaling engine shell allows to make possible to add functionality that previously seemed impossible. For example, during research I discovered the function that recalculates lighting for terrain and static objects. It is executed only once during loading of map. Now I can invoke that every frame I change parameters of lights - so it's very easy to add dynamic lighting. Further - more: in the future, it will possible to bind light sources to spell effects.

So as you can see any feature is result of working with sets of variables/functions according to the above scheme. Therefore, when adding a feature, it is first evaluated how feasible it is. For example, I can't fix the implementation of shadows, because I need to disassemble render loop in the game, then work with shaders - all this leads to another big modification in terms of amount of work ๐Ÿ˜€. Thus, during the theoretical working on features, I see which sets of functions/variables I need to “look for” inside the game. For example, here is one of planned features (part of "features technical document"):

feature eng


As you can see from the description, to implement the feature, I need to find the function for spawning entity, to manage (move, update) light sources, to find a variable that affects on transparency of entity, to find the function for attaching effects to entity, to fly into space to search for alien life. At the time of planning this feature, I could only control the lights (theoretically, since this wasn't implemented in DLL), so it may seem that the task is too laborious for the not very important feature. This is only at first glance. In fact, all these things will be used to implement a bunch of other features. For example, at the moment, object transparency control is used for dust entities layer appearance during a hurricane. Therefore, by implementing this feature, I implement to some extent other features in the same way.

That's all, stay tuned for the further updates!

- INTERRUPTOR

Watch us on Youtube

Post comment Comments
Guest
Guest - - 689,936 comments

Nice. We are waiting for more articles ๐Ÿ˜๐Ÿ˜ How did you open .orc file?

Reply Good karma Bad karma0 votes
INTERRUPTOR Author
INTERRUPTOR - - 16 comments

I don't open *.orc files, I get access to *.orc data after its loaded during *.scn initialization.

Reply Good karma+1 vote
Guest
Guest - - 689,936 comments

Ahh what tool you use?

Reply Good karma Bad karma0 votes
INTERRUPTOR Author
INTERRUPTOR - - 16 comments

Visual Studio, IDA, Cheat Engine

Reply Good karma+1 vote
bak
bak - - 70 comments

.orc files are essentially series of concatenated encrypted .zip archives where the password to each individual zip is a text string containing the full internal path to the encrypted resource file... then thereโ€™s a CRC at the end of each whole .orc

Circa 2008, there was an extractor circulating around the web, and a separate tool that could pack the modified assets back. The tools were allegedly made by Siberian Gremlin from extractor.ru forums (sibgrem@rambler.ru, siberian-studio.ru)

P.S. Iโ€™ve used ReShade with a number of games and know what it is and how it works, in Aoะ• it looks like *** on wheels and IMO is totally redundant. AoE is just a different visual style from a different era.

Reply Good karma Bad karma+1 vote
INTERRUPTOR Author
INTERRUPTOR - - 16 comments

There are no tools for *.orc files. There are only for *.ork. Regarding Reshade. It would redundant without screen-space lights and global illumination with rt. Don't forget i use it with addon system. So it's not just color adjustment.

Reply Good karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: