Dom Pedro's Promotion Project

Impaler[WrG] said:
Dom: I was thinking about the implementation of your mod and realized that the addition of so many variables to the CvUnit class will result in a considerable incresse the the game memory consumption as units are instantiated many many times in the game. It probably wont be enough to cause any realy seriously deteterious effects, I'm thinking of minimizing long term memory bloat. I would recomend that you look into using reduced sizes on many of the variables, short int can be substituted for int in most locations and their are probably some situations when char will be safe to use. Just use the small variables in the object and cast everything within the get/set/change functions to isolate them from the rest of the program. Their are some examples of this in the CvPlot class as Firaxis did do a bit of optimization their (plots being the most numerous objects in the game). Avoid an signed/unsigned convertions as these are known to be unreliable on different processors. I've been thinking of doing a memory usage profile on Civ4 which could be used to track how much our mods are actualy incressing the size of the game memory footprint.

Thanks for the tips, and yes, this was a concern of mine as well. I've been trying to put checks in as many places as possible to keep the system from running through unnecessary processes.

Also, since unspecified integers default to signed anyway, I don't think it'll be an issue.
 
I whipped up a little function to check the total memmory alocated for a unit. I got 584 bytes for units in my CCCP mod, this should be slightly more then in vanilla due to the addition of things like the RogerBacon Flying Bolean. You can use the same code to track memmory footprint as well.

The additional function protoypes for CvUnit.h

void logMsg(char* format, ... );
int SizeOf();

First is the loging function which I got from Jdog5000

void CvUnit::logMsg(char* format, ... )
{
static char buf[1024];
_vsnprintf( buf, 1020, format, (char*)(&format+1) );
gDLL->logMsg("sdkDbg.log", buf);
}

And the size calculation, add any new Arrays you create here, direct member variables dont need to be included because their all grabed in the CvUnit size of operation.

int CvUnit::SizeOf()
{
int size = 0;

size += sizeof(m_aiExtraDomainModifier[0]) * NUM_DOMAIN_TYPES;
size += sizeof(m_pabHasPromotion[0]) * GC.getNumPromotionInfos();
size += sizeof(m_paiTerrainDoubleMoveCount[0]) * GC.getNumTerrainInfos();
size += sizeof(m_paiFeatureDoubleMoveCount[0]) * GC.getNumFeatureInfos();
size += sizeof(m_paiExtraTerrainDefensePercent[0]) * GC.getNumTerrainInfos();
size += sizeof(m_paiExtraFeatureDefensePercent[0]) * GC.getNumFeatureInfos();
size += sizeof(m_paiExtraUnitCombatModifier[0]) * GC.getNumUnitCombatInfos();

return size + sizeof(CvUnit);
}

Lastly include this line at the bottom of the CvUnit::reset function

logMsg("Unit Created, %i Bytes of Memory Alocated", SizeOf());

You will have a new log file to examine and can see the total bytes of memory consumed.
 
Hey, folks,

Bit of an update...

I hit a snag for a little while there and started working on something else. I find that when you've banged your head against a wall long enough, you need to work on something else that might help you address the problem from a new angle... and this was no different. My tinkering elsewhere helped me figure out the solutions I needed for this, so I'm back on track.

A few new things:

See Invisible Promotion Tag

I'm still figuring out exactly how I'm going to do all this since I'd like to make it so that units that become invisible on certain terrains and features will be one kind of invisible type and you'll be able to have a promotion that will let a unit see that kind of invisible type but not another... That's probably going to end up being not nearly as moddable as I'm sure people would want, but it will work.

So I personally am using this to create a new promotion called "Tracking" which will be given to Scouts... Scouts will also have another promotion that makes them invisible in Forests and Jungles, so you need a Scout to find a Scout.

But then I'll also have a promotion that will enable planes and ships to see submarines as well since that's a different invisible type. Thankfully, invisible types are already in the game, so I'm not going to have to run around tearing out the game's insides to make this work ;)

Tech Free Promotions & Obsolete Techs

The first part of this causes a tech, upon being discovered, to give a promotion automatically to all units that can acquire the promotion. Also, new units that have it as a free promotion will start getting it after being trained.

The second part causes a promotion to be removed from all units that have it when a particular tech is discovered. It also prevents new units from being able to acquire the promotion or get it for free on being trained.

I want to use this to have certain units get progressively better as new techs become available... so, for example, with the Musketman, he gets "Matchlock" promotion when trained... but upon discovering some new tech, the Matchlock is rendered obsolete and removed and the "Flintlock" takes its place... and then the Rifling tech comes along and makes the Musketman obsolete altogether.. but the Musketman, with his inferior flintlock musket, will still be somewhat better off against a Rifleman than a Musketman armed with a matchlock musket.


And those are positively the LAST things I'm changing before an initial release!! :p I want to get this baby out there and working and that's not going to happen if I keep adding new stuff. So anything else is coming in updates.
 
Well, another progress report...

Damned thing doesn't want to work.. keep getting an error message when I try to load it. Have to figure that out still. But at least, in the process of trying to fix this problem, I caught a number of boo boos I made that would've just given me headaches later on.

Also, I decided to get rid of the Civ-specific aspect of this... two reasons: 1) It was too hard :p , and 2) I realized that there's plenty of other ways to restrict promotions to certain civs without having to make an XML tag to do it. It's not like units or buildings which have classes that can be used to make unique things that a civ will be able to have IN PLACE of something else... promotion classes someday? Maybe... but I figure I should muddle my way through this catastrophe first ;)
 
DPII, you have my sympathies-trust me ;). For me, though, it is less about crashing and more about 'the bloody thing just doesn't WORK!!!' :mischief:

Aussie_Lurker.
 
Well, I got it to start working and was very happy until I saw that NOTHING I'd coded was working... it was like the game was ignoring it... after about an hour grumbling about that, I realized I put the DLL in the wrong folder :p

And once I did that, I was right back to crashing... which was fine because I'd much rather it be crashing that just doing absolutely nothing :)

*polishes his green horn*
 
Hey, you want *Green*? The other night I was trying to add a TradeModifier function to CvCommerceInfo but-everytime I tried to compile it-it came up with an error. Well I checked and checked for the source of the problem-only to find that the CvInfos.h file I was modifying was in a different folder to my CvInfos.cpp :mischief: :p . Again, that will teach me to attempt these things in the wee small hours of the morning.

Aussie_Lurker.
 
Yes, I'm going to put with it a number of demo promotions just to show how it all works (provided it all works ;) ) and there'll be plenty of explanation in the thread too.
 
Dom Pedro, with regards to the defenders withdrawing, why don't you have a disengage ability instead for both defenders and attackers and then completely remove the withdrawl ability all together.

The disengage ability would just stop the battle right there and then. A unit could disengage once its health dropped by a certain amount. This would occur regardless of whether it was attacking or defending. There could be several promotions like Disengage I, II and III which stack and disengage with less and less damage. Disengage I might cause the unit to disengage if its health dropped by 90%. Disengage II might cause the unit to disengage if its health dropped by 60% and Disengage III might cause the unit to disengage if its health dropped below 40% (thus allowing it to disengage twice before being defeated entirely).
 
Yeah, I'm really not sure about how to do the defending withdrawal... it's definitely possible to have units that break combat at a certain point, but the problem is: what if you don't want the unit to break combat when it does? With the current withdrawal system, the alternative is death... but with something that breaks the combat earlier, it might not be what the player wants...

The other factor is that Lord Olleus's morale feature actually has units abandoning battle if their morale is low enough... but this, of course, is not the best either because sometimes it's not about morale... it's about tactics... now, one of the things I'm planning on implementing is Formations and Tactics promotions that will be able to be switched at any point... so it could be possible to have a sort of "Hit and Run" tactic promotion that would do this...

To be honest though, it's still far too early on the development of this part of mod for me to really say what it is I'm going to end up doing.
 
While trying to get this thing working, I also decided to make a change (not an addition). One of the things I want for my mod is for the component promotions... the promotions representing a unit's hardware.. to have movement penalties/bonuses.

However, giving a -1 MP for Plate Armor to a melee unit would be ludicrous since it would drop it's movement to 0. I'm going to increase the movement of all infantry units to 2 and cavalry to 3. But even still, multiple promotions with movement penalties would bring us quickly back to zero.

So I've simply changed the <iMovesChange></iMovesChange> tag in the XML to a float (that is a number that can be a decimal). So a promotion might have a -0.3 movement change to it, which when rounded to the nearest integer for the base moves will have no effect... but several promotions with such penalties will remove 1 MP for that unit.

So, for example, let's say we have several possible promotions: Plate Armor (-0.4), Leather Armor (0), Saber (0), Claymore (-0.2)...

If the unit has Leather Armor and a Saber, it gets no movement penalty, but it's also going to be weaker... a unit with Plate Armor and a Saber won't get a penalty either, but a unit with a Claymore and Plate Armor will since it'll have a penalty of -0.6 which is rounded to -1. This is just a hastily thrown together example... I'm not actually intending to make all different types of swords (though there will be several options for armor), but for somebody doing an RPG-esque Civ mod/scenario, they may want these kinds of distinctions.

I've also thought about removing MP as integers in general and having those fractions of an MP not used at the end of one turn added to the base movement of a unit in the following turn, however, this then gets to be a bit unreliable since that'd mean a unit might only have 1 MP one turn then 2 the next and gamers really need something more stable than that, so I don't think I'll do anything like that unless there's a real demand for it.
 
Back
Top Bottom