Thunderbrd
C2C War Dog
Now I have even seen a case where the quality promo does nothing but reset the exp counter. Unfortunately, I don't have a save game.
Interesting...
Now I have even seen a case where the quality promo does nothing but reset the exp counter. Unfortunately, I don't have a save game.
I have CTDs because of air units. I had several CTDs during my game. But when I deleted city, which built air unit, I played normally then. Now again I have CTD and can't find solution (but I think, it air unit spawned somewhere). I use C2C svn with space colonization modmod and with manually enabled Atompunk tech (I enabled it by myself in XML).
Here is the save and minidump. Crash after pushing "end of turn" button.
I deleted city which built early air unit (Blimp, I think). And then I have no ctds until now.
But now I don't know what causing CTD. I think, it is air unit somewhere. But I can't find it via world builder.
as advised i'm posting my problem here ...
the game crashes after ending the turn without any comment, no memory message, no entry in the logging files... nothing
version, latest svn
no special map
Resolved. Not PERFECTLY as I'd hoped, but I tracked it to the source as far as I could at least. Apparently, a unit had somehow taken on a duplicate ID in its plot list so when it was killed, the duplicate remained but the unit did not so the next loop through the units on that plot caused a crash when they found an ID that didn't have a unit attached to it. I suspect the jumptovalidplot function BUT that's only due to the unit being an exile and they always start off right away that way - but to defy that suspicion, there were many other exiles killed on that plot this round, not just this one. So more likely I simply don't have a clue how the problem initiates really, just that I've made it so that it cannot cause an issue nor persist if it ever does take place. Unfortunately, this MIGHT mean a slight slowdown in end turns but I don't think it should be noticeable.
Now that was a fascinating thread! I may comment on this bug there. You should take a look at the rather simple change that this debug required. The thread you posted suggests that this may be an issue elsewhere throughout all vanilla based mods and when I found the issue I was left to wonder about that because the 'fix' was made in a function I do not suspect we've ever modified.Newer versions of Windows are less forgiving about certain programming errors. Take a look at this thread that CTD took place in an similar scenario.
if (pLoopUnit == NULL)
{
// Koshling - this really isn't a valid condition I think but it's been seen
// and until we can understand the underlying cause, mitigate by ignoring the
// invalid unit
continue;
}
void CvPlot::removeUnit(CvUnit* pUnit, bool bUpdate)
{
CLLNode<IDInfo>* pUnitNode;
pUnitNode = headUnitNode();
while (pUnitNode != NULL)
{
if (::getUnit(pUnitNode->m_data) == pUnit)
{
FAssertMsg(::getUnit(pUnitNode->m_data)->at(getX_INLINE(), getY_INLINE()), "The current unit instance is expected to be at getX_INLINE and getY_INLINE");
m_units.deleteNode(pUnitNode);
template <class tVARTYPE>
inline CLLNode<tVARTYPE>* CLinkList<tVARTYPE>::deleteNode(CLLNode<tVARTYPE>* pNode)
{
CLLNode<tVARTYPE>* pPrevNode;
CLLNode<tVARTYPE>* pNextNode;
FAssert(pNode != NULL);
pPrevNode = pNode->m_pPrev;
pNextNode = pNode->m_pNext;
if ((pPrevNode != NULL) && (pNextNode != NULL))
{
pPrevNode->m_pNext = pNextNode;
pNextNode->m_pPrev = pPrevNode;
}
while (pUnitNode != NULL)
{
if (::getUnit(pUnitNode->m_data) == pUnit)
{
FAssertMsg(::getUnit(pUnitNode->m_data)->at(getX_INLINE(), getY_INLINE()), "The current unit instance is expected to be at getX_INLINE and getY_INLINE");
m_units.deleteNode(pUnitNode);
/*break;*///TBDebug: It has been found possible that a node may have somehow duplicated itself and thus the plot may have more than 1 of the node. If these duplicates aren't destroyed, we get a crash as well. Best case would be to somehow catch how this gets setup but in the debugging case that discovered this, it likely happened long beforehand. Jumptonearestvalidplot is the suspected culprit as it was an exile that showed the issue.
}
//else
//{
pUnitNode = nextUnitNode(pUnitNode);
//}
}
Ok, yeah, that makes total sense based on how the math works. You may want to post that in the tips and tricks section somewhere.Now I know how to avoid (at least in most cases) the bug with super-big strength of units after adjusting their stats in WB (it exists in Size Matters, I am not sure if it exists without it).
If you enter WB and adjust unit properties, duplicate it etc., after the first promotion (or chosing a new promo after old one is obsolete) you end with a super-strong unit. The problem is that by default the field "Base strength" shows actual strength of the unit (after effects of Quality Up and promotions increasing strength) multiplied by 100. This way e.g. an Ambusher (Str 3) with three +Str (+1, +2, +2 IIRC, so +5 base Strength) and one Quality Up (Base Str * 1.5, HP * 1.5) has 12 Strength and 150 HP. If you enter WB and look at the unit's properties, you will see Base Strength 1200. If you leave it, at the next promotion (and changing base Strength causes the unit to lose +Strength promotions, so it may happen immediately after leaving WB) you get an unit with 1200 base Strength - if you include Quality Up, you get 1800 Strength!
To avoid this, it is enough to put correct number in the "Base strength" field - in this case this is 3. I checked that and it works. I am not sure if it works for weakened units which start with e.g. 0.67 Strength - maybe one would need to put 1 instead.
S.
Even eliminating a unit mid-loop should still not allow such a problem since the 'next' pointer is re-established properly during the removal process. removeunit not being run while the unit is otherwise deleted would cause this problem. Most of these reasons would be painfully obvious immediately upon being incorrectly programmed.
That was exactly the mistake because the pUnitNode pointer is invalid as soon as the unit with the id that pointer is pointing to is removed from that plot for whatever reason during the loop. The memory segment that pointer points to is deallocated then the unit gets removed from the plot. From that point on that memory segment can be overwritten with other data and the pointer points to something else.
But this problem only became visible in newer windows versions because they have more aggressive memory handling to reduce the memory usage.
The fix that i posted in that thread works around the problem in that function. But there can be lots of other possible issues and duplicates can be possible too.
while (pUnitNode != NULL)
{
pLoopUnit = ::getUnit(pUnitNode->m_data);
pUnitNode = nextUnitNode(pUnitNode);
For awhile now, in Python, we have been coding to cover for the call to be for a NULL whatever. We check at the start of each function that all the parameters we are going to be working with are not NULL before we do anything. If any are we do nothing and return.
edit naturally we are only doing that in new versions of modules or ones we edit. Old ones are probably still coded assuming that all objects are not NULL.
Theory:
Given that the node list is readjusted properly when a unit is removed from the list, the problem is not so much that a unit was removed mid-loop, but that the loop was programmed incorrectly, which you proved with your adjustment. However, you did a very interesting trick to proxy the loop to get around it. But could it be as simple as this...
The original loop code started in this manner:
By putting this line : pUnitNode = nextUnitNode(pUnitNode);Code:while (pUnitNode != NULL) { pLoopUnit = ::getUnit(pUnitNode->m_data); pUnitNode = nextUnitNode(pUnitNode);
immediately after : pLoopUnit = ::getUnit(pUnitNode->m_data);
we've already switched pUnitNode over to the NEXT node before the actual processing in the loop takes place.
So could their error have been more simply addressed by placing 'pUnitNode = nextUnitNode(pUnitNode);' at the END of the While brackets, AFTER the processing has already taken place?
I'm almost sure I've had to make this change a time or two already to fix some previous crashes and while it made sense at the time, I didn't bring it up in the forums because I would have assumed it was a pretty basic issue.
Perhaps if I see another crash like that I'll try to address it in that way before freaking out over it otherwise.
Sorry if i ask a dumb question. I already searched the description...
I re-installed C2C. I installed the SVN Program. I downloaded the files and get a file with a green symbol. I exported the files there to another diretcory and then copied it to my C2C - but then i get only errors for missing files. What did i do wrong?
Thanks
Would that not just come up with a NULL response and thus break the While loop rather than trying to call to unit data on a NULL pointer thereafter?Removing the current unit is a problem if the nextUnitNode call is at the end of the loop
@T-brd,
The EoT wait after turn 200 on any GS is getting Bad. at turn 200 it's already over 1min 15 sec. But by turn 260 it's over 3+ mins, almost triple the EoT wait in 60 turns! This is getting bad.
I reduced the Num City Pipeline Multithread value from 4 down to 2 (Afforess A_New_DawnGlobalDefines) and it jumped to over 5+ min for EoT wait. I put it back to 4 asap! I've not see it this bad since last year's Ren Era game when the seige rams were exploding everywhere.
Save game attached so you can load it up and see what I mean.
JosEPh
Would that not just come up with a NULL response and thus break the While loop rather than trying to call to unit data on a NULL pointer thereafter?
BTW, I ask this as a question to help myself understand but otherwise, I have to say how impressed I am by the depth of your solution overall. It's extremely innovative. It also begs the question if in-general, we should be applying that sort of loop setup in all linked list unit loops throughout the code? I suppose it's not necessary unless the list can change due to the processing IN the loop...
My deepest apologies but I cannot fix this crash since the save has been made incompatible with the current assets at some point and cannot be loaded without crashing as a result. The source of that crash is not a bug but a change that breaks compatibility. I COULD try to back up my assets to that revision and try to fix it from there but I serve the mod's needs, and spending those kinds of hours on an out of date issue is not going to be an efficient use of my time towards that primary goal.First of all, English is not my first language, I defend myself more bad than good, with the help of google translate
I can't load my savegame from yesterday. Any attempt ends with a CTD after 10-15 minutes of loading.
Last night I stopped playing and Save My game without any problem. Although the last days the game crash to the desktop from time to time
A summary of the game options would be:
- C2C_PerfectWorld2df
- Gigantic Map
- Eternity Speed
- Turn 2100, approximately.
- About 15 AI players, maybe more, beacuse the barbarians transform into civs.
PC specs:
- CPU: i5 2500k (no OC)
- AMD 7970
- 8GB RAM
- Windows 10 x64
I post here but the game version is V36 SVN 9230 from this thread:
http://forums.civfanatics.com/showthread.php?t=559944
The minidump file say "The thread tried to read from or write to a virtual address for which it does not have the appropriate access".
Perhaps the map is too large and the game has reached the limit of the mod?
Apart from that I have seen in the previous thread there's a new version (9265).
Maybe the only option is to start with a less ambitious size and the new version?... But the game has taken me some time and I do not like to lose it.
If there is a trick you can do in Windows 10 (I upgraded recently) that can solve this problem, it is very welcome.
I upload the savegame to dropbox:
https://www.dropbox.com/s/j5h3kxeh8llmesz/Bas_Imm_Gig_C2C_Ete_Pre_4760-BC_Tem_Low_Aug-02-2016_01-18-28.CivBeyondSwordSave?dl=0