Sub Bug Fix and other Adventures in EXE Modding Release 9

EXE mod featuring stack bombard, bug fixes, and more

  1. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    Update Mar 7 '21: Mod is now called "C3X" and includes stack bombard, disorder warnings, and several bug fixes (in addition to the sub bug). Latest version is here: https://forums.civfanatics.com/resources/c3x.28759/



    For the past month or so I've been working at reverse engineering Civ 3. So far I've tackled and solved the submarine bug, and I might look into other bugs like the broken science age, but what I'd really like to do is implement some new features to make the game less tedious.

    For the sub bug fix, it's implemented as a C script that compiles itself, launches Civ 3, then patches the code in memory. More specifically it only changes one bit, a boolean argument to a function. For some background on the sub bug, see https://forums.civfanatics.com/threads/submarine-bug-investigation.526635/. My patch changes the boolean argument in a call to the function Antal1987 named f_Get_Tile_OccupantID. I'm not 100% confident in my fix as I haven't fully understood the code that I'm patching, instead I took a more empirical approach. But I have verified the patch works in a few different scenarios so I'm pretty confident in it.

    To launch Civ 3 with the patch applied, extract sub_bug_fix to the Conquests folder and run "RUNME.bat". Unlike other EXE mods floating around, this one doesn't replace or even make any permanent changes to the EXE. This has some advantages like no installation and no copyright infringement but also has the big disadvantage that you have to launch Civ through the script instead of through Steam or a shortcut. Maybe later versions will alter the EXE on disk instead of in memory. The only supported versions of Civ 3 are the Steam and GOG versions of Complete, although other versions might work if they use the same executable as GOG. Lastly this mod is open source, so check out "ep.c" if you're curious.

    For my next trick, I intend to implement stack bombard. I've already implemented a system to compile and inject C code into the executable (shipping the mod as a C script is neat but the real reason to have TCC handy is to make this possible) and used it to make a prototype. What's left to do is make stack bombard behave smarter, make sure it doesn't break at the edges, add a button to the interface, and port the whole thing to the Steam executable.

    After that there's one more feature I definitely want to implement, a warning that pops up when you try to end the turn with cities that will fall into disorder, and a few more I have in mind like:
    - AIs propose he most favorable trade they'll accept instead of making the player work for it
    - Cash rush costs are pre-exploited, i.e., you only pay double for shields up to the cost of the cheapest thing you could rush
    - Cities do not unassign citizens from polluted tiles (arguably not convenient since you're potentially losing the specialist yield)
    I am open to suggestions! Based on what I've read, a lot of people are playing with the NoRaze mod so I'll look into integrating that at some point (and if someone could tell me exactly what it patches that would save me a lot of time re-implementing it). Also I've seen many requests for an increase to the 31 civ limit. This would be maybe not an impossible task but at least a herculean one since the limit is baked so deeply into the program. I doubt I'll ever manage to do it, but that fact that it's so difficult makes it tempting.

    Long Live Civ 3!
     
    Last edited: Mar 7, 2021
    Damo13579, miggi03, Inexist and 7 others like this.
  2. tjs282

    tjs282 Stone \ Cold / Fish

    Joined:
    May 19, 2009
    Messages:
    3,871
    Gender:
    Male
    Location:
    Planet Earth. Possibly.
    If you're already looking at Antal's code, then he actually fixed this as well, IIRC.

    Unfortunately, (also IIRC) he packaged that fix into his later patches, which also did things like allow 2 directly adjacent cities (v.4?), or "eliminate" the 512-city limit and expand the FatCross (v.5 to v.8?) — the latter 2 functions apparently rarely or never worked properly for anyone else.
    This would be really useful to me — provided it would stop once all the units in the targeted tile are redlined (giving me an opportunity at that point to decide what I want to do with any unfired guns/ undropped bombs).

    Also, I like going for the Space VC, so I prefer to capture towns while I can still get something out of them — rather than bombarding them down to Pop1 (i.e. no citizens available to turn into Workers(Foreign)), and with all improvements destroyed (and thus unavailable to sell).

    Conquering/Dominating warmongers may well disagree, though!
    Civ Assist II already provides an alert for this at the beginning of a new turn, e.g. for towns that have grown, or acquired additional War-Weariness, over the preceding interturn. Just sayin'...
    I like the idea of the first one. Firaxis really dropped the ball on that: requiring the player to manually enter (and delete) gold- or GPT-offers until an optimum acceptable offer is reached is really tedious. A mousewheel-operated scroll-bar in the "Gold-amount" pop-up box would have been far preferable.

    I assume the second is for cash-rushing from zero shields, i.e. you automatically pay 80g for the 10-shield Worker, but then only 4x the gold for any remaining shields? Would also be helpful, but I don't think it would avoid a significant amount of tedium.

    That last would also be useful: the Specialist assigned by the Governator isn't always the one the player would have chosen, so the potential loss of their output is not necessarily a bad thing. But having to go into the town to reassign the citizen (or worse, going into a neighbouring town to reclaim a now-clean tile, then going to the town you want to use it) is an inconvenience I could do without.

    And if you could teach the .exe to automatically assign an appropriately round number of auto-mopping Workers to clean up Pollution (rather than, say, 5, or 11...), that would also be very useful (and while I'm dreaming, I'd like a pony)... ;)
     
  3. Civinator

    Civinator Blue Lion Supporter

    Joined:
    May 5, 2005
    Messages:
    7,253
    Gender:
    Male
    Flintlock, this is great news! :bounce:

    Can your find be added to the Antal4 exe that is used in CCM2 by hexediting ?
    Another interesting fix could be to change the unlimited railmovement to an adjustable movement factor.
     
  4. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    I've looked at Antal's GitHub page and found a bit of code for the science age bug but I didn't see where & why it's inserted into the EXE so it's not of much use to me unfortunately. I've thought about tackling the city limit but haven't yet looked into what it would require. According to Antal, at least one of the problems is that there is a statically allocated matrix only big enough for 512 cities. Making it larger would require moving it, which is possible in theory but difficult, maybe very difficult.
    This is the kind of thing I was thinking of when I said I still have to make stack bombard behave smarter. My plan is that if you stack bombard a tile with any units it will continue until all the units are killed or redlined but if you send it after an empty city it will continue until the city is completely destroyed.
    Interesting, Civ Assist works by reading save files, right? I've never used it myself.
    Yeah, cash rushing from zero shields is what I meant. Thinking about this some more, I wonder if city production is calculated before or after the pollution appears, because if it's calculated before you might not actually lose any yield to pollution as long as it's cleaned up immediately. Another work around would be to add a yield of 1 commerce to polluted tiles, which is about what you would have gotten from the specialist (ignoring corruption).
    This is a good idea. It might be hard to implement, though, since it requires adding state as well as code to the program.
    I think Antal's EXEs were all based on the CD version of Conquests. I checked just now and his executable is different from both the GOG and Steam versions of Complete so it's not something I could trivially layer my changes onto. Actually right now I can't layer my changes permanently onto any EXE but that's something I'll iomplement eventually for the convenience of others.

    For changing road or railroad movement, I'll keep it in mind. I can't say how feasible this would be implement without looking into it but I can already think of some challenges, for example the engine prices unit movement in road-moves, so assumes there's only one kind of road.
     
    tjs282 likes this.
  5. Nathiri

    Nathiri Commander

    Joined:
    Oct 7, 2014
    Messages:
    777
    Gender:
    Male
    Location:
    Georgia, US
    Finally someone else willing to tackle this one :).

    While more civs are always nice, I don't care too much about having more than 31 civs playable on a map as 31 is already taxing. More than 31 selectable would be cool of course, but I'm more interested in new game settings.

    My dream for civ3 has always been at some point to try and export data from the exe into an editable text file that can be added to a scenario folder much like existing firaxis text files: labels.txt, script.txt etc. This way, a scenario maker can make minor alterations to a bunch of game settings that could be small or big changes. For example, instead of the city screen generating boxes for the shield box, you could have it put a number. Something thats more easily distinguished from a glance rather than having to count the boxes yourself. You could activate or deactivate this from the text file. A text file gives more freedom as I never liked Antal's 1 tile city changes, though there was certainly a use for it. If I was able to specify a limit that was farther like 3-4 tiles, I would have been able to make more use of this addition.

    Could you add popups that come on specific turns or activated by doing a task? I wouldnt think this would require changing limits. You would just have to add a check for when the activator happens. The game already keeps track of dates and when a building is built or a tech is researched. There is already code when a tech is researched for a popup to appear, but this is disabled for scenarios.

    A harder ask I think would be, add new interface windows like a Religious Advisor. A religious advisor would be a new mechanic so I imagine that requires adding many checks throughout the game to track.

    I've also always wanted to be able to play around with the interface more than what the game gives. Like change the coordinates of buttons. Currently, we have to use graphical tricks in the pcx images, but there are certain button areas that are hard coded that would be nice to change. Like moving the advisor buttons to the top part of the screen, rather than the left. Coming from this, also, auto resolution fixes. Using KeepRes, it zooms everything out the bigger your computer resolution. If we could adjust the size proportions that would be awesome.
     
    Last edited: Jan 30, 2021
  6. Virote_Considon

    Virote_Considon The Great Dictator

    Joined:
    Jul 7, 2004
    Messages:
    9,378
    Location:
    Skaville UK Reputation: 1
    FWIW, I currently have the GOG version of Civ3 Complete, and the various no-raze patches that I managed to transfer over from my old HDD all work for it.
     
  7. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    Even adding selectable civs is difficult because the limit affects so many aspects of the code. For example, the UnitType object's layout assumes there are no more than 32 civs. This corresponds to the "Available To" settings in the units tab in the editor. Internally, there are only 32 bits set aside to hold that info (31 civs + barbs), so to add more civs you'd either have to enlarge that field, which would entail moving it and enlarging the object, or somehow compress more data into those 32 bits. Either option would require patching the executable in multiple locations, which is tricky since I can't even say for sure where every location is, and even that wouldn't fix the 31 civ limit, just one tiny piece of it.
    I've been thinking about this sort of thing too, in the context of the NoRaze patch. I'm guessing people want NoRaze for scenarios with pre-placed cities but not for regular games on random maps. It would be nice if it were possible to make NoRaze specific to certain scenarios. The best way to do this is probably what you suggest, a file with the same name as the scenario that the patched EXE could read to load in additional settings. That should totally be possible, it's just something I'd have to get around to implementing.
    Adding new popups should be easy. I can't say for sure until I've done it, but the code to throw up player prompts looks clean, modular, adaptible. Can you be more specific about what sort of events you'd like notifications for? I wasn't aware that there were no popups for research in scenarios (I only ever play the epic game) but it'd probably be easy to re-enable those.
    I haven't looked into the UI code in depth yet. The advisor screens look nicely modular, though, so adding another would hopefully be easy. Adding a religion system itself would probably be difficult, or maybe not, depending on how complex it is to be.
    Those are all replacement executables, right? As far as I know, all non-Steam executables should be interchangeable. The problem with the Steam EXE is that it has its own special labels.txt.



    In other news, I had a look at the capture_city function to see how hard it would be to re-implement the NoRaze patch. One half of it is easy, in fact I already threw together a patch in like 15 minutes, and the other half is messy. The easy half is disabling autoraze and razing by AI players. The messy half is disabling razing by the human player since the interface is not described in the EXE itself, instead it's read from scripts.txt. The natural way to disable human razing would be to delete the second option from the #WE_CAPTURE_CITY_GOLD and #SEIZE_CITY_WITH_WONDER entries in that file. Disabling it from within the EXE would require adding a weird special case for that prompt, unless I can think of some better way to do it. I haven't yet looked into removing the option to abandon cities.
     
  8. Nathiri

    Nathiri Commander

    Joined:
    Oct 7, 2014
    Messages:
    777
    Gender:
    Male
    Location:
    Georgia, US
    Well, in scenarios, we sometimes implement various "events" and have exact timing for situations we want to happen. Usually this involves auto-production in some way. It would be cool if, for example, I would have a pre-placed wonder auto-produce a wave of units at a certain time, to have a popoup window come up just before that happens to notify the player that such and such is coming "get ready", rather than relying on the civilopedia, and the player reminding themselves to prepare. Since its pre-placed, all I would need to do is have the popup set to come on a specific turn. If it's not pre-placed, maybe 2 ifs could be added and add the need for the wonder to be built before the X turns later req comes in.

    Or in another case, with Quintillus' editor he has a .SAV mechanic to patch game settings mid-game. If there was a popup for when the requirements are met, to notify to reload the save file for new settings.
     
  9. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    That sort of thing should be pretty easy. Getting the advisor to pop up with a message is literally one function call, the current turn number is just a global variable that I already know the location of, checking if a wonder is about to produce a unit should be easy though I haven't looked at the code yet.
     
  10. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    Presenting: stack bombard! Soon you'll be wondering how you ever played Civ 3 without it. To activate in game, press 'B' or click the button to bombard normally then hold control while clicking the target tile. The feature is not yet finished, but it's already very useful, just missing some edge cases and its own UI button. I've also added my reimplementation of NoRaze into this release, disabled by default (see config.txt to enable). Also I've renamed the mod to "C3X" since it's now more than a fix for the sub bug, it's not a great name but I couldn't think of anything better.

    Here's the read-me:
    Spoiler :
    C3X: Executable Mod for Civ 3 Complete
    Release 1

    INCLUDES:
    Fix for submarine bug
    Stack bombard (beta version)
    NoRaze (disabled by default)

    USAGE:
    No installation necessary, the mod makes no changes outside of its folder. Just copy the C3X_R1 folder into the
    Conquests folder (the one containing "Civ3Conquests.exe", not the scenarios) and run "RUNME.bat" to start Civ 3 instead
    of the normal shortcut or through Steam, etc. See below for how to activate stack bombard in game.

    STACK BOMBARD:
    To activate, have a siege unit selected, press B then CTRL+click the target tile. The selected unit will bombard the
    tile, then all other units of the same type on the same tile will automatically bombard the target as well. Stack
    bombard is not yet perfect but it's not stupid either. If you attack a tile with enemy units it will bombard until
    they're all dead or redlined without lethal bombard, if you attack a city w/o units it will stop once the city is
    reduced to size 1, and if you attack a tile it will stop once all destructible improvements have been destroyed. It's
    not perfect because there are still various edge cases it doesn't handle, for example, you might know that land
    artillery can't damage aircraft, but did you know that naval artillery can not only damage but kill aircraft on land? I
    didn't know that until I was experimenting to develop this feature.

    NO-RAZE:
    NoRaze has been re-implemented inside C3X but is not enabled by default. To enable it, edit "config.txt" according to
    the instructions inside. Eventually, I'd like to add the option to prevent human players from razing cities but for now
    the only options are to disable autorazing and razing by AI players.

    HOW IT WORKS:
    Some parts of the mod (sub bug fix, no-raze) are really just hex edits that are applied to the Civ process in memory
    immediately after it's launched. The real secret sauce is a system to compile and inject arbitrary C code into the
    process which makes it practical to implement new features in the game. The heart of the system is TCC (Tiny C Compiler)
    and much tedious work figuring out the functions and structs inside the executable (and thanks to Antal1987 for figuring
    out most of the structs years before I came along).

    The injected code, along with the rest of the mod, is fully open source. If you're curious how stack bombard was
    implemented, check out "patch_Main_Screen_Form_perform_action_on_tile" in "stack_bombard.c", I assure you the code is
    quite readable.

    COMPATIBILITY:
    The mod is only officially compatible with the GOG and Steam versions of Civ 3 Complete. It may be compatible with other
    versions if they use the same executable as one of those two.

    SPECIAL THANKS to Antal1987 for his work reverse engineering Civ3. See: https://github.com/Antal1987/C3CPatchFramework
     

    Attached Files:

    Civinator, Nathiri, Puppeteer and 2 others like this.
  11. tjs282

    tjs282 Stone \ Cold / Fish

    Joined:
    May 19, 2009
    Messages:
    3,871
    Gender:
    Male
    Location:
    Planet Earth. Possibly.
    Pollution definitely happens before production is calculated, although I'm not sure exactly how long before. Maybe around the same time that the current Worker-jobs are calculated (which would be very close to the beginning of the interturn)?

    If you haven't seen it already, you might find this interesting:

    https://forums.civfanatics.com/threads/interturn-mechanics.443195/
     
  12. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    I hadn't seen that before, thanks for the link. It says gold and science is calculated globally before the cities are processed individually, so it looks like if pollution turns a pop into a tax collector or researcher, that yield wouldn't be counted anyway. That's good because it means if you keep the citizen on the tile you don't lose anything other than the tile yield that you would have lost anyway. I also took some time to look at the code, the pollution spawning function is in the middle of some city update function. It comes after processing culture flips, unit spawns from buildings, and (I think) resistance, and before disease, meltdowns, disorder, WLTKD, and some more stuff I didn't bother to decipher. I'm guessing that function is a pre-production city update.
     
  13. Ares de Borg

    Ares de Borg Norman Knight

    Joined:
    Sep 19, 2004
    Messages:
    5,133
    Location:
    Heart Of Europe
    If you somehow could take out the city limit as in other patches, that would be great. :)
     
  14. Civinator

    Civinator Blue Lion Supporter

    Joined:
    May 5, 2005
    Messages:
    7,253
    Gender:
    Male
    Ares, great that you are back again at CFC. :)

    Unfortunately these 'other patches' never worked well in their NCL (No City Limits) components. Please read this post and the following posts in that thread:
    https://forums.civfanatics.com/threads/city-limits.327919/page-10#post-15710174
     
  15. Ares de Borg

    Ares de Borg Norman Knight

    Joined:
    Sep 19, 2004
    Messages:
    5,133
    Location:
    Heart Of Europe
    Thank you, old friend. I am aware of this issue, though. My hope was that someone might solve the problem. :)
     
  16. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    I've thought about doing a proper NCL patch but haven't looked into the details yet to see if it's actually possible. Based on what Antal1987 said in the thread I linked in the OP, the problem, or at least one problem, is that the game maintains a table of connections between cities which is not large enough. The table is 512x512 in size, enough for one entry for each pair of cities. Founding more than 512 cities causes the program to write beyond the bounds of the table, corrupting whatever other data already exists there. Since the table is statically allocated, solving the problem is not as simple as enlarging it, it's necessary to create a new table. Which then means that all references to the old table must be patched to point instead to the new one. If there aren't too many such references and this table is the only thing preventing the NCL from working, a proper patch would be doable.
     
  17. Civinator

    Civinator Blue Lion Supporter

    Joined:
    May 5, 2005
    Messages:
    7,253
    Gender:
    Male
    Flintlock, here are some details, posted by Tsubasanut, about the NCL problem: https://forums.civfanatics.com/threads/ccm2-epic-mod.625812/page-32#post-15755612

    Even more than a fix of the NCL-problem I would like a fix of the stealth attack-problem. At present stealth attack is only working, if at least two units, which are asigned targets for a stealth attack, are in the attacked stack. In my eyes stealth attack should also work, if there is only one asigned stealth attack target in the attacked stack. In my eyes, the micromanagement of cities on a 512-city-map is really more than enough, but an anti-tank gun should be able to attack a tank in a hostile stack, even if it is the only tank in that stack.
     
  18. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    Alright, I'll add that one to the list.
     
  19. MeteorPunch

    MeteorPunch #WINNING

    Joined:
    Jan 19, 2005
    Messages:
    4,834
    Location:
    TN-USA
    If you've managed to get stack Bombard to work, it would be really nice if you can get stack Re-base to work as well.
     
  20. Flintlock

    Flintlock King

    Joined:
    Sep 25, 2004
    Messages:
    783
    I would, except Firaxis beat me to it. Already in the game you can use the stack move commands to move aircraft between cities.



    Progress report, in case anyone's interested: Implementing a button for stack bombard took a lot longer than I thought it would. Getting the button to appear wasn't the issue, there I was able to make use of some nicely organized game code including a function to load PCX files, another to slice them up into sprites, and another to set up the unit buttons on the screen. The problem was making the button work, that code is rather convoluted and I didn't see any neat way to add a new mode action (mode actions are like bombard mode, go-to mode, etc). So I had to add an awkward side channel to make the button work, but it does work now, so that's what matters. For some better news, I also had a look at the science age bug. It turns out that one's easy. It's actually similar to the submarine bug in that one part of the code implements a switch then another part doesn't flick the switch how it's supposed to. Though unlike the sub bug where the problem was buried in the middle of several inscrutable functions, this one was plainly visible. I'll include the fix in the next release, which will be later this week. I still have the tedious task of porting the new things to the Steam executable.
     

Share This Page