Download
A battle in Gallean

Remaking Disciples 2 (Gallean)

Gallean is an open source Disciples 2 remake with all campaigns and scenarios, 4K assets and hotseat multiplayer.

12 min read

Hello, fellow Disciples fans!

Gallean is an open source and cross-platform remake of Disciples 2 that has 4K assets, all campaigns and scenarios, and a fully reworked interface. It covers every mechanic of the original that I know of, and has an AI that is a real pain to play against.

Why Gallean?

In the lore, Gallean married Death, was murdered by a Dwarven god, and abandoned his children. A solid choice for a game name.

Gallean 0.8 is the first public release. The only reason it’s not a 1.0 is because I may need to make incompatible1 changes for some of the features I still have planned for 1.0, such as remote multiplayer. If you are willing to play with friends, only hotseat multiplayer is supported for now.

I never did a complete end-to-end game project before, and this has been a vivid journey. I decided to build the remake as an enterprise app rather than a game, and kept some sanity to complete it that way.

Taking a look at the result, I am proud of keeping it all to a simple dotnet build/publish AOT-compatible toolchain and covering the engine with tons of tests.

I am not (yet) proud of the world AI that just continues to do dumb things like losing a complex 80+ turn scenario on turn 2 by feeding Drega Zul to a Kraken. Although it sometimes does pretty cool stuff in the campaign such as ambushing your green hero with a totally unexpected min-maxed 3× Berserkers stack.

If you are interested in the end result, it’s available here: https://gallean.org/download. The source code is on GitHub: GalleanDev/Gallean.

To run the remake, you need the assets, which can come in either of two forms: either you can find a community-provided .galleanpack, or, if you have the original game assets, you can run them through the asset pipeline. When you run the game for the first time, it will guide you further.

Also, if you want to skip my nostalgic stories, you can go straight to the technical content.

The decision to remake

So I decided to try remaking it myself. I had some experience to rely on:

  1. 3.5 grades of an art school

    I dropped out after failing an art history test where I mistook Jheronimus Bosch for some contemporary artist. I remember teachers saying my watercolor paintings were the dirtiest they ever saw.

  2. Some common software engineering knowledge

    Like how to structure apps that don’t fall on their toes.

  3. My dated university-level 3D graphics skills

    Back in the day, I wrote a 3D engine where I used the now really outdated Nvidia Cg shaders. It could draw water with wrong caustics and used geometry shaders to create land patches with holes.

With all that baggage, one clear thing was: the asset pipeline had to not rely on me painting anything.

There is a lot to say about the engine and the rest of the game, but let’s start with the part everyone probably remembers most: the battles.

The new battlefield

The battlefield is the business card of Disciples 2. You spend hours here planning moves, trying out compositions or just grinding through enemies. Like many games of its era, it is barely forgiving: one miss can ruin a 15-turn battle, and without a visible turn queue the enemy moves come as a surprise all the time.

Hoping to buy patience for the upcoming technical parts, I will start by showing pictures of the new battle frame anatomy in Gallean:

00/ 15 One frame

Battle frame

A battle frame combines the background, units, effects and interface.

01/ 15 Battlefield

Background color

The battlefield starts as a 5760×2400 painting of plain colors, with no light or shadow. It has extra room at the sides for wider screens.

02/ 15 Battlefield

Background depth

A depth map estimates how far away each part of the ground is. This helps nearby lights reach the right areas.

03/ 15 Battlefield

Background normals

A normal map estimates which way each part of the ground faces. This tells the renderer how light hits it.

04/ 15 Battlefield

Lighting

The sun, lava and fire light the ground. Here they are shown on a plain gray surface.

05/ 15 Battlefield

Lit background

The renderer lights the painting with the sun, lava and effects.

06/ 15 Lava and smoke

Lava and smoke

Lava and smoke play as animation loops over the background. They respond to the scene lights too.

07/ 15 Shadows

Shadows

Units keep their original isometric (but softened) shadows. Nearby effects can add another dynamic shadow.

08/ 15 Selection

Selection

A ground marker and a highlight show the selected unit. Ground markers disappear during action animations.

09/ 15 Units

Unit sprites

The original animations are restored at 4×.

10/ 15 Units

Unit normals

Each frame has a normal map. This lets a sprite with a baked light respond to dynamic light sources.

11/ 15 Units

Unit lighting

The same sun, lava and fire light the units, along with color from the surrounding battlefield.

12/ 15 Units

Lit units

The sprite colors and lighting combine to draw the units in the scene.

13/ 15 Effects

Effects

Attacks and spells use the original animations. Glowing effects also light the ground and units.

14/ 15 Interface

Interface

Unit cards, hit points, items and commands are drawn above the scene. The interface scales with the screen and DPI.

15/ 15 One frame

Final frame

All the layers come together. The game updates the lighting as it draws each frame.

What I started with

For a remake that relies on original assets, there actually isn’t too much to gather from. The original draws at 800×600, in 16-bit color space using prerendered animated unit sprites in three different closed-loop forms: idle, attack, hit. The sprites come in layers for bodies, auras and shadows that get composed at different depths when rendering.

A battle in the original game
The same battle shown with the original artwork.

All units are built from 3D models, with a good polygon budget for the time, but not all of them aged well. That’s especially visible on small units where the artists were clearly skipping details that would become a couple of pixels in the final render. Units use flat baked lights with the light source located slightly above them.

The battle backgrounds have a special upward-facing geometry and a non-standard isometric projection to compensate for different unit sizes and lack of real depth.

When I was doing the early planning, I decided the remake needs to:

  1. Look good in 4K

    That means supporting different scaling factors and aspect ratios up to 21:9, and playing in 4K even on an iGPU. Given that the original was working fine with 64 MB of RAM on 2000-era hardware, aiming for less seemed wrong spirited.

  2. Light everything dynamically

    I would be aiming for proper dynamic lighting for units, effects and the environment. I would not aim for a proper 3D unit reconstruction, so for lighting that means I would have to recover the normals information directly from unit sprites.

  3. Redo the backgrounds

    I would make new backgrounds from scratch instead of upscaling the old ones, possibly with real 3D geometry.

  4. Ship the asset pipeline

    The asset pipeline, which I decided to call Umbra, has to be a proper first-class part of the project, built on the same .NET stack. It has to be fully deterministic and work on common hardware3, so that end users can run it themselves.

Making the units larger

I realized it would probably take multiple separate steps to get to 4K, so I started with the simple task of making the units twice their original size. My strategy was: try to recover as much original information as possible in the early steps. And leave all steps that might transform that information until the end.

A subtle property of this approach is that if the first steps are low-quality, all that follows turns into garbage. I learned that the hard way, after I started from upscaling the unit data to 2× by feeding animations to ESRGAN4 models:

The unit before and after upscale
The original idle frame and one attempt at a 2× upscale with ESRGAN. The body details get smeared, and the animated version is inconsistent.

As it turns out, animations need spatial and temporal consistency that breaks when using simple upscale models pretrained on static anime images.

It took me a while and some experiments to understand that although the sprites are images with alpha, they need to be processed as a complete animation sequence. This follows the principle of grabbing as much source information as possible, because the animated sequences actually carry a lot of hidden data encoded between frames about the source. Video-based restoration models such as the BasicVSR++ I ended up with for the first step are able to exploit that information.

In simple terms, think of it as follows: you can have three consecutive frames, and only one of them has unblurred details. If the restoration model can use that clearer frame and keep its details in its temporal context, the better info propagates to the final result.

Why three frames? Because that’s what I tried and enlarging the window didn’t improve the results further.

Unfortunately, the restored 2× units still did not have the detail I wanted for a 4K display. For better fidelity, I had to get the missing details out of somewhere.

Making the units detailed

Even with a proper 2× upscale the result is still too small. For example, for a typical small unit the sprite size becomes just 200×200, nowhere near enough for 4K.

I couldn’t find any solution other than guided generative refinement. But then at least I constrained this process to only inventing new things for those parts of the artwork where the model has a low confidence level. I chose a relatively recent LTX model and guided it with Gemma4-encoded prompts.

After that I had to spend a lot of GPU pod time going through most of the small units’ faces, which weren’t too easy to get right, especially because the unit portraits don’t always match the actual sprite:

The Witch Hunter portrait next to a frame of his battle sprite
Every Witch Hunter may hide a surprise under his hat.

A neat trick I found is to display a heat map of the result that shows if the tokens encoded in the prompt have actually affected the result. In the example below, my prompt was explicitly encoding the wanted shape of the helmet, trident and hands, so those are the parts that light up:

A prompt heat map of a unit
A prompt heat map for a refined unit.

LTX works on RGB video, which brings the alpha problem: it does not produce a transparency channel. Because refining changes the details, simply putting the original alpha back would give mismatched edges. Essentially, we are discarding the alpha information and have to reconstruct it back from the final result.

At first I tried refining the input twice on different backgrounds and post-processing that with a filter. My idea was that we could take the common pixels from two runs and turn them into a clear alpha contour. However, that didn’t work because using different backgrounds shifts the model state, and apparently it’s not possible to get identical generations even when you feed them the same noise vectors. In the end, this approach resulted in a much more complex problem than it was before, because now I had to pick the alpha contour out of two diverging sets of pixels.

My current solution for the alpha problem is to manually add a chroma key before refining, and then remove it with another model, CorridorKey. As you will see below, this doesn’t remove 100% of the chroma key in complex situations involving small “inland” pixels. But the final rendered result looked good enough, so I decided to stop here.

Before you get bored, I will show the full pipeline with different unit examples. Pick a unit, and check out its idle and attack animations:

Unit pipeline

Refine4×

LTX

LTX adds detail and doubles the size again, guided by the animation and a text description of the unit.


Up next: how the units respond to light

So far, I have scratched some parts of the battle asset restoration and the pipeline. However, even ideally restored static sprites would still look flat and unalive if they do not react to lights. The pipeline infographic above gives a hint of how the current lighting works: by storing a separate normal layer and exploiting the fact that all original assets are prerendered with exactly the same baked-in light. I will continue the story about this in the next post.

In the upcoming posts, I hope to write about actually lighting the units, making the backgrounds with environmental effects, and about why Drega Zul just can’t miss the opportunity of being eaten by the Kraken.

Stay tuned, and thanks for your attention!

Footnotes

  1. A pinky promise not to break save compatibility. Unless I absolutely have to. ↩

  2. Maybe I should write this idea down. ↩

  3. The final pipeline needs at least 12 GB of VRAM and 24 GB of RAM. Does that count as common hardware nowadays? ↩

  4. ESRGAN is a popular neural network that makes a single image larger. People have trained many versions of it for game art and anime. ↩