• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

[Dev] 0.1 "Babylon" Progress Thread

Re: Civ colors. Puppeteer is right that what he's seeing is (almost certainly) an index. The end-all-be-all-guide to civ colors, as far as I am aware, is at https://forums.civfanatics.com/threads/new-team-colours.85016/ . In post #14, Rhye has attached a tutorial that goes into further detail (Word format, IIRC).

One important detail that is not obvious if you've only used the civ color option in the Firaxis editor is that the indexed files (ntp##.pcx) have one pixel, but a whole palette of colors, and different colors in that palette are used at different places in game, e.g. the city nameplate on the map, the F4 foreign advisor/diplo scene, the F8 score charts, as well as to compose the unit graphics. Rhye has documented many of these (as far as I know, all of them he dug deep enough to determine with certainty), and I used that documentation when building the Civ Colors section of my editor (where you can modify those ntp##.pcx files for you mod, with Rhye's explanation of the indexed colors right beside them for reference).

That's one of those things where it's going to be a bit of a nuisance to get it working exactly as it does in Civ III, but getting all the colors just so is also something that reliably falls in the "polish" camp. As long as you can tell cities/units apart on the map, you can have multiple players without confusion. Thus, I'd advocate doing just enough to accomplish that goal initially, unless one of us gets really into civ colors.
 
One important detail that is not obvious if you've only used the civ color option in the Firaxis editor is that the indexed files (ntp##.pcx) have one pixel, but a whole palette of colors, and different colors in that palette are used at different places in game, e.g. the city nameplate on the map, the F4 foreign advisor/diplo scene, the F8 score charts, as well as to compose the unit graphics.

I seem to already be pulling colors from those files as seen in the link below. I had just forgotten about it.

https://github.com/C7-Game/Prototyp...ffa7ce/ConvertCiv3Media/Civ3UnitSprite.cs#L79

That's some ugly code, though. A lot of the media code was "f around and find out," and apparently I haven't gone back to polish much of it after getting it working.

In fact I think I see a problem with it already: It may break for units not in vanilla Civ3 as I can't see it independently looking for the ntp path.

On the bright side, I just discovered that Mono is case-insensitive for file names, regardless of whether the OS filesystem is case sensitive. Flintlock changed the capitalization that mismatches my MacOS filesystem, and it works. TIL: https://www.mono-project.com/docs/advanced/iomap/

Edit: Random thoughts: The current "Animate()" and "Move()" methods don't really meet our current needs. We probably want a "MoveTo()", a default idle state that occasionally fidgets, and...I guess in-game-action-based methods. So, a class that tracks its own state and can clear its own state and return to default/idle loop after completing an action. Actually it's more complex than that (fortify, improvement activity, disappear if it's not the "top" unit...), but I guess it's a start.

Edit 2: That unit code might predate the Civ3MediaPath() function which is probably why it doesn't use it when it should.
 
Last edited:
I've been working on "Place Cities" lately, since that was part of our reveal plans. The changes are in the "citiesOnMap" branch for now.

Superficially, it kind of looks like it does in-game now:

upload_2021-11-27_9-23-35.png


But there are a bunch of issues to iron out, most notably that the width isn't dynamic, and the extra area on the right always shows up whether it's a capital or not (although for now, with only one city, it is by default). But those are (maybe) straightforward; the other questions I have are:

- Zoom. I set my local to default to 100%, and it looks great! But it doesn't look so good at most other zooms. I think we should probably make 100% the default, but perhaps more importantly, make it easy for the player to set it to 100%. 200% might also be a good special case.
- Font. I followed the OldLegacyMap/LegacyMap examples to figure out how to load the .ttf (thanks Puppeteer!), and the city pop size is in font 18, rather than the 12/24 I'd been using previously. The city name is 12, but is slightly too large, so I'll bump that down. But do we want to use LSANS if it's available? I'm thinking we should, if for no other reason than it'll match the game feel. Noto is generally pretty alright, but that "1" without a foot feels out of place. And typing this, I realize the reason is that while most of Civ III uses Lucida Sans (Serif), the city pop is rendered using a serif font. That might not be true, I may have been doing funny things with my Civ font. It seems weird that all the "1"s in game are serifed, whereas when I open LSANS.ttf in Windows, it's clearly sans-serif.

It's also worth noting that the greys and transparency are ballpark estimates, not exact matches.

Civ III city screenshot. Note the feet on the 1's:

upload_2021-11-27_9-34-6.png


Everyone sees those serifs in Civ3, right?

C7 with LSANS.ttf for the pop counter (the rest is still Noto):

upload_2021-11-27_9-39-38.png


I'll have to dive into my registry and see if I changed Civ's font to something other than the default.

Edit: Nope, doesn't look like I have any funny stuff going on for Civ's fonts (some guy wrote up a guide on how to change the fonts a few years ago). Still would appreciate confirmation that the 1's in Civ 3 are serifed on other people's boxes, just to be sure.
 
Last edited:
That said, I do recall common issues with the built-in font. Like maybe it doesn't work, or it loads wrong, or something. But if I open up LSANS.TTF directly in Windows, the 1 is not serifed and looks just like my screenshot.
 
Thanks for the answer! Yeah, the Windows font viewer shows it like it is in your screenshot. I'm not sure how I wound up with a serif font then. But that demystifies how to get it looking similar in C7.
 
Huh. I just Googled the font issue, and it was an error preventing playing. Solution To The Code 28/lsans Font Error . The solution is to delete or rename Conquests/LSANS.fot . I went to see if I have that file; I do, but what's weird is that the modified date is this morning when I fired up my game to take the screenshot of the font in-game. Weird.

I opened the fot file in Notepad++. It's mostly binary/nulls, but some text shows up including my local path to LSANS.TTF (on the F: drive in Steamapps), some random stuff, and, amusingly, "Windows! Windows! Windows!" Somebody was excited about Windows I guess.

As far as using that font in C7, I think it's doable without redistributing the font file ourselves. I created the Noto Sans font resources manually in the Godot UI if I recall, and there were actually two different font files for different sizes. Which confuses me because I thought TrueType and Adobe fonts scaled well, but whatever. There is almost certainly an in-code way to load LSANS as a resource at runtime and optionally use it. (Although I recall it being quite difficult to get Godot to read a media file from outside of its root res:// .) I recall that Noto Sans is pretty darn close to LSANS, though...I went through a bunch of Google redistributable fonts, and I recall Noto Sans being the closest. Although the number 1 is rather prominent in Civ3. But "a"s, "g"s, "q"s in particular vary a lot between otherwise similar sans-serif fonts. And slashed 0s vs non-slashed.
 
Last edited:
I set my local to default to 100%, and it looks great! But it doesn't look so good at most other zooms. I think we should probably make 100% the default, but perhaps more importantly, make it easy for the player to set it to 100%. 200% might also be a good special case.

The problem with a default zoom right now is that we don't center the map based on context, be it home starting location or an active unit. We're very close to being able to load arbitrary Civ3 saves directly. So I'd hope we would have a contextual way to center somewhere interesting before setting a 1:1 zoom. Also might be nice to have a minimap, or if not a minimap then at least a rectangle in a rectangle to show where we're zoomed in to.

In Civ3 the Z key toggles between 1:1 zoom and a zoomed-out view. I see no reason not to ape that behavior as soon as now, even if we toggle between 100% and 200% or 3 preset zooms.
 
As far as using that font in C7, I think it's doable without redistributing the font file ourselves. I created the Noto Sans font resources manually in the Godot UI if I recall, and there were actually two different font files for different sizes. Which confuses me because I thought TrueType and Adobe fonts scaled well, but whatever. There is almost certainly an in-code way to load LSANS as a resource at runtime and optionally use it. (Although I recall it being quite difficult to get Godot to read a media file from outside of its root res:// .) I recall that Noto Sans is pretty darn close to LSANS, though...I went through a bunch of Google redistributable fonts, and I recall Noto Sans being the closest. Although the number 1 is rather prominent in Civ3. But "a"s, "g"s, "q"s in particular vary a lot between otherwise similar sans-serif fonts. And slashed 0s vs non-slashed.

I figured out how to scale it today:

Code:
DynamicFont midSizedFont = new DynamicFont();
            midSizedFont.FontData = ResourceLoader.Load(Util.Civ3MediaPath("LSANS.TTF")) as DynamicFontData;
            midSizedFont.Size = 18;

And TempTiles is using it with LSANS:

Code:
string FontPath = Util.GetCiv3Path() + @"/LSANS.TTF";
MapFont = new DynamicFont();
MapFont.FontData = ResourceLoader.Load(FontPath) as DynamicFontData;

My LSANS.fot also is modified this morning :hmm:. But its contents are as you describe, pointing to LSANS.ttf and being very excited about Windows! But I'm not getting Error 28. One of my tasks for the next couple days is fixing the screen on my old XP laptop; if I do that I'll see what its fonts look like for another point of reference.

In-Civ, the C keys centers (and does Home center on your capital? Or is that Civ4?). We'd need a way to do the centering, as you say, but in theory it doesn't sound super difficult. (Cue impossible task) At least, it sounds easier than a minimap to me. Although now that I think about the latter, maybe the "right" way to make a minimap is to make a mini version of the map (say 5x5 pixels diagonally) and then scale it down, rather than trying to figure out how to draw a map in such a small area. Still sounds a bit tricky, though.

I like the "Z" idea. Might play around with that after I polish up city labels a bit more, though if you want to grab that piece of functionality first, go for it.
 
And TempTiles is using it with LSANS:

:lol: I have no memory of that. The older I get the more I realize I used to be smarter than I am now, apparently.

I like the "Z" idea. Might play around with that after I polish up city labels a bit more, though if you want to grab that piece of functionality first, go for it.

Not me. I want to get the map overhaul to a point where I feel good (enough) about merging it, and then I have several other ideas of things to mess with.

Actually, that just made up my mind on something: I now know how to "get it done" with the map overhaul merge without resetting anyone else's progress.
 
The city drawing code has reached an area that I think is good enough for now, which means good enough until we have more of the game built out. Here's how it looks:

upload_2021-11-28_17-42-20.png


The placement of the population number, and the centering of the city name and what it's producing, is all dynamic, using the GetStringSize method in Godot to calculate the offset. It also works correctly for both capital and non-capital cities (with/without the not-perfectly-centered star icon).

I've also moved our dummy units so they are back on land for the time being (though they can still walk on water if they so choose).

Putting this together has me thinking about game mechanics. Babylon objective "Place cities" is ready in the singular, if not the plural. Combat is not until "Carthage" (prototype) or "Dutch" (full). "Dutch" includes "Prototype cities", and "Egypt" includes most city-related tasks. So it's probably a bit early to dive into that. What I'm thinking might make sense for now is to have the cities always do a couple tasks forever, which the player can't change until later milestones:

- Grow. Ten turns, the pop number increases. Doesn't cause any other effects, but shows that there's something going on behind the scenes.
- Produce Warriors, and maybe Settlers. Again, shows mechanics, and also gives the player more units to play with, which will be helpful if they want to interact with the barbarians. I'm thinking give the cities Warrior/Warrior/Settler in their queue, and 5/5/15 turn production times.

These would all be placeholder, but the "calculate city effects at the end of a turn" would be a long-term item, and they should be fairly easy. I think it's also important to make the world a little bit richer for the first couple shared builds, to encourage audience participation and bolster hopes that we might make it farther than prior attempts, and possibly even to a playable game.

Edit: I'm also thinking of adding mountains to the map. I'm guessing it's already in the permanent map, just not being displayed. I've done that once before (in my editor) and that also seems like a good step to make the world more alive. That also falls in better with the "Babylon" "World Map" feature.
 
I'm also thinking of adding mountains to the map. I'm guessing it's already in the permanent map, just not being displayed.

Eh, sort of. The mountain tile type is 6 in type QueryCiv3.MapTile.OverlayTerrain, but since c7 has no overlay terrain yet, it's not in the C7 json save. It can be; just make a spot for it and set it in C7GameData.ImportCiv3.ImportSav in the foreach tile loop.

To refresh the json save when the format updates, so far I've been using /_Console/BuildDevSave , but as you can see all it does anymore is run ImportCiv3 and C7SaveFormat.Save .

I'll attach the save I made for this here, but it doesn't especially matter which save we use once our units and cities can avoid being on water when the map changes. Also, the save is seed 1234567, small size middle options on terrain and barbs.

Edit: Also, I don't yet know the image selection bytes for overlay terrain...I think I'm very close, but I haven't looked at it lately. Then again if all the mountains look the same for now that's not a blocker to adding the tile selection later.
 

Attachments

Random thoughts from a tired and active mind...

Here is my favorite reference for tile values. It's from one of my HTML/js civ3 maps. I have the info elsewhere, but this one is easy for me to find and refer to:

PHP:
    baseTerrainCss = {
        '0': 'desert',
        '1': 'plains',
        '2': 'grassland',
        '3': 'tundra',
        'b': 'coast',
        'c': 'sea',
        'd': 'ocean'
    }
    overlayTerrain = {
        '4': 'fp',
        '5': 'hill',
        '6': '⛰️',
        '7': 'forest',
        '8': 'jungle',
        '9': 'marsh',
        'a': 'volcano'
    }

Also, terrain is one byte with two nybbles for base and overlay in the original Civ3, so a mountain is 0x62 (or 0x26, I forget) as they're always on grass. A tile without overlay just repeats the base, so grassland is 0x22. But I have the overlay and base broken out separately as ints in the getters in QueryCiv3.

To add new map info to C7, make a public field (or public getter & setter) for it in C7GameData.Tile , and then assign it in the ImportCiv3.ImportSav foreach tile loop with c7Tile.YourNewProperty = tile.OverlayTerrain or a value derived from it or depending on it being 6.

For the logic side. I haven't really looked at how y'all are placing units and cities yet on the display side.

Edit: Aw, the forest, jungle and volcano unicode didn't make it through to the in-post code, so added the words.

Edit 2: Oh, yeah, you know how tiles work. Sorry. I guess I'm really tired this weekend.
 
Today I added a grid to the map. It's on by default and can be toggled with the I key. Ideally the toggle would be bound to CTRL+G for consistency with the original game but right now that key combination gets captured by the unit buttons. To make the toggle work I transformed LooseLayer from an interface to an abstract class so that way every map layer can have a "visible" field that controls whether or not it's drawn.

The grid revealed another problem: this whole time the terrain was being drawn misaligned. I never noticed before because I didn't know where the tile boundaries actually were. To get the terrain sprites to line up with the other layers I had to draw them centered 1 cell (= 32 pixels or half the sprite height) above the tile centers. But now this has created another little issue that the grid doesn't align with the edges of the terrain sprites. Everything is drawn properly when you're looking at the middle of the map since everything is now correctly aligned by tile, I made sure of this by generating the test map in the editor and comparing side-by-side, but when you scroll to the edges in C7 it's apparent that the grid lines run through the middle of the terrain sprites not along their edges. It's not a big deal but it doesn't look very good. FWIW, Firaxis' solution to this problem was ice caps for the top & bottom edges and restricting the camera from showing any empty tile slots on the left & right edges.
 
(Going to check my other alerts before commenting too much on the terrain. Though I like the idea of having side-by-side reference for base/overlay; I never did memorize those hex codes very well)

I thought the base terrain might be off when I was moving the chariot around this afternoon. Wanted to be sure of it though. A grid is addition for helping confirm the graphical accuracy. And you're absolutely right that the in-game, tile-aligned grid runs through the middle of the terrain graphics. What Firaxis did to help them reason with that when they were developing Civ3 is adding another grid (in red, below) that they could turn on, but which is not available in-game:

sotd99.jpg


The gray grid is what we're used to, the red corresponds to the tiles from the terrain graphics. I found this screenshot, Screenshot of the Day 99, to be a helpful when adding map features to my editor.

The description for the screenshot is:

SOTD 99/Thunderfall said:
An old pre-Civ3 release screenshot. It shows some debugging features (minimap river highlighting, excessive grids) and programmer art. There’s probably some old/placeholder art in there too.

This screenshot is dated July 21, 2001 and is submitted by Mike Breitkreutz of Firaxis. I am just glad Firaxis changed the font!
biggrin.gif
Thanks to MikeB for this special screenshot.

Thinking of minimaps, I realized while playing the COTM today that at least one person has implemented a third-party minimap; CivAssist II has one. Not sure how they did it, but that does mean there's at least some community expertise on it.

-----------

On the subject of keyboard shortcuts, that's interesting that Ctrl+G is being captured by Goto. Not entirely surprising; I knew that we'd have to handle modifier keys for shortcuts at some point, and hadn't looked into how they were being handled currently.
 
I've made some progress with mountains, although I haven't actually spent much time on it over the past 12 hours. Still, we can see some hilly terrain now:

upload_2021-11-30_2-50-22.png


So far I've just been focused on getting hills/mountains at the right tile and alignment; adding the proper graphics to form mountain chains is upcoming.

One of the things I have realized is that our 1234567 sample map does not contain a single volcano (although it does contain a good amount of marsh). Probably just luck of the draw, and it shouldn't block adding support for volcanoes. Just kind of interesting that we wound up without any. Maybe I'll see about hex editing in a volcano. I haven't yet determined whether we have any snow-capped mountains.

I've also realized that sooner rather than later, we should move away from the name of the terrain being what we compare against. That is because it won't work not only with non-English source files, but with any mods that use different names. But rather than use the plain numbers as Firaxis does, we can probably assign a "key" to each terrain, which may match the English name, while still allowing the actual name to be customized. (In my editor, I used enums that correspond to the ints, so it's readable but doesn't rely on the name being "Mountain", for example)

(This also presents longer-term questions about how to support adding more terrains. For now, I don't think we should let that derail us, and we should focus on supporting what's already out there. Longer-term, perhaps we should support defining which graphics are used for which terrains via some sort of JSON mapping file, and providing a default that works with the legacy scenarios?)

Playing a few turns of 1234567 in-Civ also has me hankering to add some resources, forests, etc. The world map seems like a great Babylon objective.
 
Well, we're going to need an analog to a BIC, and that is where the names and terrain type definitions are. The GameMap tile data should have a reference to that. It's of course a nybble in Civ3, but we can easily go to int or long (or unsigned anything).

WW was strongly wanting GUIDs for everything, although I'm not sure BIC references count, but I have yet been unable to imagine a sane way to use GUIDs for referencing what is in BICs. It just makes too much sense to have an int index to an array. Mountains are 6 which is their index in the BIC for terrain definitions.

Associative arrays/hash tables might work, but it's not clear to me what advantage that gives us.

we can probably assign a "key" to each terrain, which may match the English name, while still allowing the actual name to be customized. (In my editor, I used enums that correspond to the ints, so it's readable but doesn't rely on the name being "Mountain", for example)

Hmm. It would allow easier parsing, hand editing, and even user-created tools to better understand the json save. And it would avoid problems with reordering the array in the BIC analog. Ok, I'm in.

I'm trying to imagine situations where that breaks, but the contrived stuff I'm coming up with makes little sense.

adding the proper graphics to form mountain chains is upcoming.

I'm not sure where that data is yet, and QueryCiv3 doesn't yet know it. You might, though, having written more complete map code than mine.
 
WW was strongly wanting GUIDs for everything, although I'm not sure BIC references count, but I have yet been unable to imagine a sane way to use GUIDs for referencing what is in BICs. It just makes too much sense to have an int index to an array. Mountains are 6 which is their index in the BIC for terrain definitions.

Hmm. It would allow easier parsing, hand editing, and even user-created tools to better understand the json save. And it would avoid problems with reordering the array in the BIC analog. Ok, I'm in.

I'm trying to imagine situations where that breaks, but the contrived stuff I'm coming up with makes little sense.

It was looking at c7-static-map-save.json and seeing how nice it was that the terrain types were "Coast" or "Grassland" rather than "10" or "2" that gave me the idea. But I also wasn't thinking about guids. Thinking about it now, it's a balance of user-editability versus... uniqueness? For things like units on the map, where there isn't an obvious user-readable identifier (type doesn't work, there would be multiples and they could be upgraded; location doesn't work as it can change), guids make sense. But for things like terrain types, goods, etc., it's easier for the user if they don't have to look up that Ivory has guid 8174a-ef82c-1892bc-840cd to add Ivory to a tile.

I dunno, I'd be curious what @WildWeazel thinks. GUIDs made sense for everything when I first read about it, although I'm not sure exactly where that was now that I try to refresh myself on why it made sense at the time.

I'm not sure where that data is yet, and QueryCiv3 doesn't yet know it. You might, though, having written more complete map code than mine.

I have a nice method in my editor that handles that. Civ3 seems to have a little bit of randomness thrown in to make it not entirely predictable, but for mountains it matches pretty closely. And for the sake of sanity and expediency, I'd recommend going with the "choose the graphics based on the neighboring tiles" approach that is a 90% match rather than trying to figure out the exact algorithm.
 
I'd recommend going with the "choose the graphics based on the neighboring tiles" approach that is a 90% match rather than trying to figure out the exact algorithm.

My current theory is that there exists a file ID and image index for the overlay terrain like there is for base terrain. For reading premade maps, figuring that out is all we need, and I think I have it down to a handful of byte candidates.

Yeah, I'm not currently worried about generating those references based on tile type. Until you showed me how the base terrain was displayed I thought we *had* to figure out how it chooses tile graphic options, but now I believe that only happens at new map generation. (Although it must also happen during global warming events, but that doesn't really bring anything new to the table.)
 
Back
Top Bottom