Making a Clone of Civ II

Looks like you pretty much nailed it!
This is an earlier screenshot, notice how dithering is missing. Drawing an isometric grid like this with indexes of tiles shifted left and right depending on which column you're at was much more difficult than it would seem.
Anyway I managed to get city panels going and all the Advisor and World panes, importing of SAV files was practically done, also making of units/cities/civs etc. And a bunch of other panels. This is quite simple in winforms. I was actually doing unit moving and attack animations and attack logic when I stopped as my real-life work was tiring me.
I'm actually thinking of making it with Mono so it would work on Linux.
I was also thinking of moving the project to github but it's too amateurishly done.
 
This is an earlier screenshot, notice how dithering is missing. Drawing an isometric grid like this with indexes of tiles shifted left and right depending on which column you're at was much more difficult than it would seem.
Anyway I managed to get city panels going and all the Advisor and World panes, importing of SAV files was practically done, also making of units/cities/civs etc. And a bunch of other panels. This is quite simple in winforms. I was actually doing unit moving and attack animations and attack logic when I stopped as my real-life work was tiring me.
I'm actually thinking of making it with Mono so it would work on Linux.
I was also thinking of moving the project to github but it's too amateurishly done.

I really like the screenshot!

Oddly I just joined this forum as I was heading in this direction. I've started disassembling and looking at how various things work in ghidra/x64dbg. The isometric grid issue was a right pain in the backside for me too as it doesn't use the normal algorithm for generating an isometric map! grr..

I started by making a patch to play music via ogg files as I missed the soundtrack of the game.

My main ambition now though is to actually determine how civ2 actually performs some of its stuff mainly around AI. on the surface if you look at it it's not that much a complex game compared to modern standards. the executable also contains references to certain strings/files used in debugging which helps.

Please do move the project to git hub? even if just for posterity of your own code, I haven't got as far as you did in terms of graphics, I've solely been focused on reverse engineering the background logic, so for that I've written it in C/CPP as it provides a quick way to copy the memset/memcpy instructions from the decompiled code. I do have an asp.net map renderer though..

if ever you want to collab or to share code for something I'd be up for that.
 
Here's a quick perspective from a Civ4 modder: Why don't you guys just rip out the stuff you don't like (Civics, combat etc) from civ4 and then re-create civ2 with the civ4 engine?. The game logic is completely open source so you have full freedom to do what you want. You can even have the isometric perspective if you want (it's used by some mods like Afterworld). The downside would ofc be that you'd still be "chained" to the Civ4 exe (which is unlikely to be made open source any time soon)
 
Here's a quick perspective from a Civ4 modder: Why don't you guys just rip out the stuff you don't like (Civics, combat etc) from civ4 and then re-create civ2 with the civ4 engine?. The game logic is completely open source so you have full freedom to do what you want. You can even have the isometric perspective if you want (it's used by some mods like Afterworld). The downside would ofc be that you'd still be "chained" to the Civ4 exe (which is unlikely to be made open source any time soon)

I agree, that would probably be easier. Civ4's modding capabilities are quite incredible, I play the StarTrek mod quite a bit still to this day. I think for me it's a nostalgia thing and the prospect of porting it to other systems, however I do understand that freeciv is already out there.

I've not seen Afterworld before, it looks like an entirely new game, impressive!
 
So is there a link to the Github repo? Just curious. I'm thinking of working on a clone of CIV 2 that works on Linux distros (I haven't used Windows in years since I have no reason to use it).
 
Sorry, I've been cleaning the code for a month now.
Anyway the repo is here and it's WIP as you can see from images below. Sadly you need to test it on windows, I've been meaning to port it to Mono so it can be used beyond just Windows.
Currently you can load a SAV game and click around a map.
Lots of stuff broke when I moved from .net framework to core.


 
Thanks Blake for the promotion you-know-where!
Just to be clear, I don't expect this to be THE open-source Civ2 project. Most programmers prefer C/C++ with which the original was made, so it would be nice if someone (more experienced than me) started something similar where we could all contribute. One central project is better than several solo-ones.
Anyway got some advisor panels going:
adv1.gif adv2.gif adv3.gif
 
No worries, posted in some other places too. Might bring some helpers or at least some more support/fans lol.

Well being the only one who's got this far cloning civ2 probably makes yours THE project by default haha. ;)

Wow.. those look great.. you've got a great eye for accurately recreating the original layout and look. If the fonts weren't slightly different and you didn't have publicly available builds you'd have people accusing you of pulling a fast one on us with actual Civ2 screenshots hahaha.

Is there any AI work done yet? That's always the hard one. I've seen so many cool projects trying to rebuild Civilization, Master of Magic, Colonization, Dune, C&C etc and so many them got great engine and graphics work done but fell over when it came time to try and recreate the AI. But some of course prevailed eg MoM-IME, FreeCiv, C-Evo, FreeCol, OpenDune and OpenRA come to mind. Although in some cases their AI recreations behaved differently (for better or worse) to the originals. Bloody hard when you don't have the source files!
 
I still haven't figured out the fonts completely. I have to implement some sort of kerning. I tend to put to much attention to details, getting the size of fonts exactly right and having spacing in figures down to the pixel exact. This really drains me so I've started conforming to the rule - implement now, deal with details later.

Regarding AI - I haven't gotten that far yet. In Civ1 forum there have been guys really active over the years in deciphering the AI logic - either through reverse engineering or by disassembling the original exe with IDA or whatever. In recent months a guy has been publishing pseudo-code of AI logic here on the forums. Sadly there hasn't been a noticeable progress on CivONE is a couple of years.
 
Just to be clear, I don't expect this to be THE open-source Civ2 project. Most programmers prefer C/C++ with which the original was made, so it would be nice if someone (more experienced than me) started something similar where we could all contribute. One central project is better than several solo-ones.

The fact that you've actually started something is a great advantage, and could very well override any concerns or thoughts that I have here. I'll have to look into using C# to check this out. I am a bit concerned that C# can't use LUA, which would put in jeopardy the recent scenario innovations. Apparently (from 2 minute check) there is MoonSharp, but that implements lua 5.2, while TheNamelessOne implemented Lua 5.3.

Does C# (or, rather, the version that can be made cross platform with Mono) have automatic memory management? If not, I would suggest that as a reason to use something else, since I'm not sure that we have any professional programmers around, and I don't think performance is so critical that it is worth the trouble of finding memory leaks.

Using Love2d (or some other similar project) and Lua would, as I see it, have a couple advantages. 1. Lua is easier to program in than C or C++, and probably C# as well, and we already have a Civ related "learning area" in the form of making scenarios for the existing TOTPP. 2. Once we have something working, I'm pretty sure it could be converted incrementally to C/C++, if we want better performance or whatever.

Again, I'll have to look at what you already have. With OTR finally wrapping up, I will hopefully have time to look into this stuff again. Even if I decide to try implementing in Lua, your code might still prove extremely helpful as a model.
 
.NET and Mono both have garbage collectors (here).
Making this in C or C++ would be more feasible on the long run, at least in terms of recruiting support. Quick look at os game clones site tells me such projects outnumber those in C# by at least a factor of 8.
 
Last edited:
One must have: an option to disable bribing cities. Above all else, that's the thing that made me stop playing the game back in the days.
 
Wow I am genuinely amazed at how far you have got in recreating this!

I've been trying to tie up a wrapper to SDL and other cpp functions to get a clone of this going. Almost seems like you've done all of the work already!

I also find it easier to write in c# as almost a prototype language then go to cpp, though on a project of that scale its going to be quite complex. Stuff like reflection and not having to overly worry about memory management means you can cobble things together alot faster, also LINQ queries are very useful.

My main focus before I went down that path was deconstructing the AI and map generation systems using ghidra.

To be honest I kind of want to reverse engineer the pre MGE AI such as the one used in FW.

What you've done most definitely has started the ball rolling in terms of a modern civ2 clone, congratulations. :hatsoff:
 
Thanks. BTW drawing a map is a mess right now. I don't like how it's done, it's not in line with how the original does it so I'm redoing all of this right now. Also there are some memory issues, I plan on tackling them, but overall the GC does its job.
Regarding map drawing - the original does some simplifications zoomed out, like no drawing of coastlines which I implemented (right pic is mine). I'm doing everything with 32bpp bitmaps, the originals were 8bpp but it's a hassle working with them, also why limit ourselves to a 256 palette...
Clipboard02.gif Clipboard04.gif
 
Last edited:
Thanks. BTW drawing a map is a mess right now. I don't like how it's done, it's not in line with how the original does it so I'm redoing all of this right now. Also there are some memory issues, I plan on tackling them, but overall the GC does its job.
Regarding map drawing - the original does some simplifications zoomed out, like no drawing of coastlines which I implemented (right pic is mine). I'm doing everything with 32bpp bitmaps, the originals were 8bpp but it's a hassle working with them, also why limit ourselves to a 256 palette...
View attachment 580189 View attachment 580190
Can confirm I just loaded an old game I had somewhere and it appears to work quite well ( I did fork it and made a few changes to get it to build, not sure if it was my clone from git).

I really like the coastline and road stuff! I know that can't have been easy to do. nice

Not sure if you'd considered (and I may be teaching to suck eggs..) but it may be easier to have zoom done by using a camera style system so a:
PointF to represent the worldPos (in the window)
and another float to represent the mapScale

this is from memory but I think its right, making the coords of a tile would be:
stdTileWidth:= 32;
stdTileHeight:= 16;

tileWidth = (int)(stdTileWidth * mapScale);
tileHeight = (int)(stdTileHeight * mapScale);

drawTileAtX = (int)((tileX + worldPos.X) * tileWidth);
drawTileAtY = (int)((tileY + worldPos.Y) * tileHeight);

You could then adjust the zoom by *= 0.05 or whatever to get an incremental zoom using the mouse wheel and get smooth scrolling.. I'm not sure if that'd help or make things more complicated :/

Also I know there's various issues in regards to the draw string methods, TextRenderer vs Drawstring yields different results depending on the context in which it's used..
 
Can confirm I just loaded an old game I had somewhere and it appears to work quite well ( I did fork it and made a few changes to get it to build, not sure if it was my clone from git).

I really like the coastline and road stuff! I know that can't have been easy to do. nice

Not sure if you'd considered (and I may be teaching to suck eggs..) but it may be easier to have zoom done by using a camera style system so a:
PointF to represent the worldPos (in the window)
and another float to represent the mapScale

this is from memory but I think its right, making the coords of a tile would be:
stdTileWidth:= 32;
stdTileHeight:= 16;

tileWidth = (int)(stdTileWidth * mapScale);
tileHeight = (int)(stdTileHeight * mapScale);

drawTileAtX = (int)((tileX + worldPos.X) * tileWidth);
drawTileAtY = (int)((tileY + worldPos.Y) * tileHeight);

You could then adjust the zoom by *= 0.05 or whatever to get an incremental zoom using the mouse wheel and get smooth scrolling.. I'm not sure if that'd help or make things more complicated :/

Also I know there's various issues in regards to the draw string methods, TextRenderer vs Drawstring yields different results depending on the context in which it's used..

The way you wrote it sounds about right, the worldPos is the center of the window.
The only difference is I don't draw tiles one by one on the panel but instead make a bitmap of the part of map to be shown and than plop the bitmap on the panel (this is causing some memory leaks but I'll try to deal with it, it won't melt your comp).
I resize and draw the individual tiles more or less the way you wrote it. The formulas may be different but the concept is the same.
The scaling in x is 8 * (8 + zoom) and in y 4 * (8 + zoom) for tiles.
The game actually implements 16 zooms, from -8 (max zoom out) to +7 (max zoom in). Zoom=0 is normal zoom.
At zoom= -8/-7/-6 (the pic I shared in the other post) Reynolds avoided dithering and drawing of coastlines.

At every zoom you have to:
1) resize a tile and draw it
2) implement dithering
3) resize a unit shield and draw it
4) resize a unit and draw it
5) resize a city and draw it

Do this in two for loops (1st loop are rows, 2nd are columns) for each tile using your drawTileAtXY coords.

Once all this is done you draw strings - city Names. These overlap everything. I use drawString.

Anyways I'm redoing some of the map drawing stuff on my local repo, I'll push it hopefully soon, it's driving me mad.
 
Top Bottom