View Full Version : Greek observations
A few observations from my KH campaign:
-The KH starts out allied to Baktria, although they don't even know where Baktria is.
-The three Spartan characters the KH has at the start of the game don't have agoge-related traits (I already mentioned this in another thread).
-Athens still has the homeland resource, i.e. you can institute the agoge there. This contradicts the old KH governement map.
-The Eleutheroi town of Halikarnassos is owned by the Trmmli. Looks like a typo, although it may be a Carian name for all I know.
-The KH bodyguard lacks both an officer (all other professional hoplite unit have both a flagbearer and an officer) and a voice (they don't say "Somatophylakes Strategou" when you click them).
A couple more questions:
-According to the recruitment viewer Thracian cavalry are in the KH factional MIC, while Thracian infantry are in the regional one. This looks like a mistake to me.
-The higher levels of ports still have more fleets than the game allows (a city cannot have more than three sea-trading partners).
Tellos Athenaios
11-11-2007, 13:56
The last one of post #1 is because there's still some updating to do regarding the Voicemod. You may have noticed that the Argyraspides still cry Argyraspidai for instance. ...
The being allied to Baktria probably is because the KH (and the likes) were the main source of Hellenistic Immigrants for Baktria...
Halikarnassos issue: definitely no typo at least the only other option would be Greek, and the Greek isn't even remotely similar AFAIK. And considering the Uazali are Karian too. Intended, I think.
Thanks for the answers. I am not convinced about the KH-Baktrian alliance though. For one thing, they simply wouldn't have had any serious contact, even if there was a steady flow of immigrants. For another, Baktria was still part of the Seleucid Empire, and the Seleucids are at war with the KH at the start of the game.
Oh, and another thing about the Somatophylakes Strategou: they haven't got the "hardy" trait, making them have less endurance than even the Hoplites Haploi.
Diamondj
11-11-2007, 21:26
Thanks for the answers. I am not convinced about the KH-Baktrian alliance though. For one thing, they simply wouldn't have had any serious contact, even if there was a steady flow of immigrants. For another, Baktria was still part of the Seleucid Empire, and the Seleucids are at war with the KH at the start of the game.
Oh, and another thing about the Somatophylakes Strategou: they haven't got the "hardy" trait, making them have less endurance than even the Hoplites Haploi.
I think that since Bactria gained its independence in 250 bc only 20 years after the campaign begins the creators of EB simply made the decision to include them as if it was 250 BC already.
The last one of post #1 is because there's still some updating to do regarding the Voicemod. You may have noticed that the Argyraspides still cry Argyraspidai for instance. ...
Making them say "somatophylakes strategou" should be easy though, since that voice is already in the mod for the cavalry variant. Unless there's some very important reason why cavalry and infantry would say it in different ways.
AngryAngelDD
11-13-2007, 00:50
-The higher levels of ports still have more fleets than the game allows (a city cannot have more than three sea-trading partners).
right, they can´t have more than 3 export partners....(or at least no more than 3 are shown)
but anyway this add to trade income.
perhaps the additional trade routes "encourages" other cities to create a trade route beyond their harbor capacities.
example might be the "Coastal Clearing"....it has no harbour value at all, but it can recieve a import trade route.
perhaps the wise men at EB hq will tell us how these things work.
Tellos Athenaios
11-13-2007, 01:17
@Sakkura: the somatophylakes issue is easily solved; but there are other things 'we' need to update as well.
Lysander13
11-13-2007, 05:18
Oh, and another thing about the Somatophylakes Strategou: they haven't got the "hardy" trait, making them have less endurance than even the Hoplites Haploi.
Thought i should mention that this is also true for the Spartiates ( ;326 ) & Epilektoi Hoplitai ( ;461 ).
I think that since Bactria gained its independence in 250 bc only 20 years after the campaign begins the creators of EB simply made the decision to include them as if it was 250 BC already.
Indeed. Hence my suprise that the Baktrians appear to have a different diplomatic agenda than their overlord.
Another thing: shouldn't Thracian Peltasts have a higher armour value than normal ones due to their greaves?
My KH faction heir (Akrokratos) once got besieged in Demetrias. His dad lifted the siege for him, but Akrokratos is still walking around with the "indifferent to siege" trait.
My KH faction heir (Akrokratos) once got besieged in Demetrias. His dad lifted the siege for him, but Akrokratos is still walking around with the "indifferent to siege" trait.
Isn't that the way it's supposed to be? That the guy has developed the ability to keep up the morale of his troops during a siege, maybe by telling them tall tales of "back when he was in 'Nam" (err, 'Metrias) and a siege turned into a big victory.
I've run into a strange CTD. I tried to investigate a Ghetai FM (Diales per Apulon) with one of my spies when the game crashed. I restarted Windows, reloaded the game and tried again with the same result. I tried investigating Diales with another spy (result: CTD), and using the original spy to investigate another character (result: no CTD). Not activating the script did not prevent the CTD, and neither did the trait file nerf.
I think the CTD occurs before the spy reaches Diales as I still see the green pathway-line, but because I always click to speed up the process I am not sure.
I have all permanent fixes installed, as well as the Pahlava fix and the apeleutheroi nerf. Furthermore I have made slight modifications to the EDU and use a formation mod.
Any idea what causes this?
Isn't that the way it's supposed to be? That the guy has developed the ability to keep up the morale of his troops during a siege, maybe by telling them tall tales of "back when he was in 'Nam" (err, 'Metrias) and a siege turned into a big victory.
Probably :beam: . He lost it a couple of turns later, though.
Sounds like a trait related crash when the spy gets something triggered by the investigation. Try the trait nerf.
Sounds like a trait related crash when the spy gets something triggered by the investigation. Try the trait nerf.
I did. It didn't make a difference. Anyway, it's not related to that particular spy as it always (that is, 5 out 5 times) occurred when he investigated Diales, but not when he investigated a nearby Epeirote general (2 times). When I investigated Diales with another spy, the CTD occurred again, so it seems related to Diales trait-sheet.
I haven't investigated Diales since that turn, because he retreated to Buridava and has been besieged by the Epeirotes since.
That could be some trait typo then, concerning the traits of that guy. The trait nerf only disables the triggers, so any existing traits could cause it. I've fixed a number of such typos, however it's unfeasible to port them back to 1.0 since I made such a lot of other changes too at the time, among them cutting away about 10% of the size of the trait descriptions file.
I suggest you abstain from investigating him and instead kill him somehow :beam:.
I suggest you abstain from investigating him and instead kill him somehow :beam:.
The Epeirotes did that for me :brood: .
Thanks for the answer. If you want, I can send you the save-game, but I doubt that's necessary.
No, it shouldn't be. I've created a tool to check for these typos now, so it should be the end of them :2thumbsup:.
Mouzafphaerre
01-06-2008, 14:43
.
You made a spell chequer? :clown:
.
More of a validation tool, but if you like, yes, a spell checker :beam:. Would you like to have it, perhaps? It should work with any mod.
Mouzafphaerre
01-07-2008, 06:16
.
Of course! :jumping:
Although I already have a spell chequer.I have a spell chequer
it came with my pea sea,
It plainly marquees four my revue
Miss steaks eye cannot sea
When I strike a quay or right
a word, I weight four it two say,
weather eye am wrong oar write,
It shows me strait a weigh
As soon as a mist ache is maid
It noes bee fore two late
and eye can put the error rite
Its rarely, rarely grate.
I've run this poem threw it
I'm shore your pleased to no
Its letter perfect in it's weigh
My chequer toiled me saw!
(Sauce unknown):clown:
.
Here's the code for the java class. You'll have to change the constants for the paths in the top, then compile and run. There's also quite a bit of fluff code from my very first bug hunting, searching for the source of the reinforcement CTD, and I'm sure it's not as efficient as it could be either. But it does the job :beam:.
package europabarbarorum;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Vector;
/**
* All sorts of stuff you can do with traits. Mostly validation and other bug hunting currently.
* @author Brigt Olav Vik, aka bovi
*/
public class Traits
{
private static final String ROOT_FOLDER = "../../../";
private static final String EDCT = "eb/data/export_descr_character_traits.txt";
private static final String EDA = "eb/data/export_descr_ancillaries.txt";
private static final String VNV = "eb/data/text/export_VnVs.txt";
public Traits()
{
}
public String[] validateAffects() throws Exception
{
Vector mismatches = new Vector();
Hashtable traits = new Hashtable();
HashSet affects = new HashSet();
Vector triggers = new Vector();
String line = null;
BufferedReader r = new BufferedReader(new FileReader(ROOT_FOLDER + EDCT));
while((line = r.readLine()) != null)
{
if(line.indexOf(";") == 0)
continue;
line = line.toLowerCase();
if(line.indexOf("trait") == 0)
{
line = line.substring(6).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" ")).trim();
traits.put(line, line);
}
else if(line.indexOf("trigger") == 0)
{
line = line.substring(line.indexOf("trigger") + 7).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
triggers.add(line);
}
else if(line.indexOf("affects") >= 0)
{
line = line.substring(line.indexOf("affects") + 7).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
affects.add(line);
}
}
r.close();
r = new BufferedReader(new FileReader(ROOT_FOLDER + EDA));
while((line = r.readLine()) != null)
{
if(line.indexOf(";") == 0)
continue;
line = line.toLowerCase();
if(line.indexOf("affects") >= 0)
{
line = line.substring(line.indexOf("affects") + 7).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
affects.add(line);
}
}
String[] affectsArray = new String[affects.size()];
String hasTrait = null;
affects.toArray(affectsArray);
for (int i = 0; i < affectsArray.length; i++)
{
hasTrait = (String)traits.get(affectsArray[i]);
if(hasTrait == null)
mismatches.add(affectsArray[i]);
}
String[] retur = new String[mismatches.size()];
mismatches.toArray(retur);
return retur;
}
public String[] validateDescriptions() throws Exception
{
Vector mismatches = new Vector();
Hashtable references = new Hashtable();
Hashtable descriptions = new Hashtable();
String line = null;
BufferedReader r = new BufferedReader(new FileReader(ROOT_FOLDER + EDCT));
while((line = r.readLine()) != null)
{
if(line.indexOf(";") == 0)
continue;
line = line.toLowerCase().trim();
if(line.indexOf("level") == 0)
{
line = line.substring(6).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" ")).trim();
references.put(line, "1");
}
else if(line.indexOf("description") == 0)
{
line = line.substring(12).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
references.put(line, "1");
}
else if(line.indexOf("effectsdescription") == 0)
{
line = line.substring(19).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
references.put(line, "1");
}
else if(line.indexOf("gainmessage") == 0)
{
line = line.substring(12).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
references.put(line, "1");
}
else if(line.indexOf("losemessage") == 0)
{
line = line.substring(12).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
references.put(line, "1");
}
else if(line.indexOf("epithet") == 0)
{
line = line.substring(8).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
references.put(line, "1");
}
}
r.close();
r = new BufferedReader(new FileReader(ROOT_FOLDER + VNV));
while((line = r.readLine()) != null)
{
line = new String(line.getBytes(), "UTF-16");
if(line.indexOf("¬") == 0)
continue;
line = line.toLowerCase().trim();
if(line.indexOf("{") == 0)
{
line = line.substring(1, line.indexOf("}")).trim();
if(line.indexOf(" ") >= 0)
line = line.substring(0, line.indexOf(" "));
descriptions.put(line, "1");
}
}
String[] referenceArray = new String[references.size()];
String hasDesc = null;
references.keySet().toArray(referenceArray);
for (int i = 0; i < referenceArray.length; i++)
{
hasDesc = (String)descriptions.get(referenceArray[i]);
if(hasDesc == null)
mismatches.add("Missing description: " + referenceArray[i]);
}
String[] descArray = new String[descriptions.size()];
String isReferenced = null;
descriptions.keySet().toArray(descArray);
for (int i = 0; i < descArray.length; i++)
{
isReferenced = (String)references.get(descArray[i]);
if(isReferenced == null)
mismatches.add("Superfluous description? " + descArray[i]);
}
String[] retur = new String[mismatches.size()];
mismatches.toArray(retur);
return retur;
}
public static void main(String[] args) throws Exception
{
Traits t = new Traits();
String[] affectMismatches = t.validateAffects();
System.out.println("Mismatching Affects:");
for (int i = 0; i < affectMismatches.length; i++)
{
System.out.println(affectMismatches[i]);
}
System.out.println("--------------------");
System.out.println("Description mismatches:");
String[] descMismatches = t.validateDescriptions();
for (int i = 0; i < descMismatches.length; i++)
{
System.out.println(descMismatches[i]);
}
System.out.println("--------------------");
}
public static String[] maxOutChance(String[] lines)
{
boolean isBattleTrigger = false;
int pos = 0;
for (int i = 0; i < lines.length; i++)
{
if (lines[i].toLowerCase().indexOf("whentotest") >= 0)
isBattleTrigger = lines[i].toLowerCase().indexOf("postbattle") >= 0;
if (isBattleTrigger && (pos = lines[i].toLowerCase().indexOf("chance")) >= 0)
lines[i] = lines[i].substring(0, pos) + "Chance 100";
}
return lines;
}
public static String[] commentBattleTriggers(String[] lines, int count)
{
boolean isBattleTrigger = false;
count++;
for (int i = 0; i < lines.length; i++)
{
if (lines[i].toLowerCase().indexOf("whentotest") >= 0)
{
isBattleTrigger = lines[i].toLowerCase().indexOf("postbattle") >= 0;
if(isBattleTrigger && !lines[i-1].startsWith("; "))
{
count--;
if(count == 0)
return lines;
lines[i-1] = "; " + lines[i-1];
}
}
if (isBattleTrigger &&
lines[i].toLowerCase().indexOf("trigger") < 0 &&
!lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[i] = "; " + lines[i];
}
return lines;
}
public static String[] uncommentBattleTriggers(String[] lines, int count)
{
boolean isBattleTrigger = false;
count++;
for (int i = 0; i < lines.length; i++)
{
if (lines[i].toLowerCase().indexOf("whentotest") >= 0)
{
isBattleTrigger = lines[i].toLowerCase().indexOf("postbattle") >= 0;
if(isBattleTrigger && lines[i].startsWith("; "))
{
count--;
if(count == 0)
return lines;
if(lines[i-1].startsWith("; "))
lines[i-1] = lines[i-1].substring(2);
}
}
if (isBattleTrigger &&
lines[i].startsWith("; ") &&
(lines[i].toLowerCase().indexOf("trigger")) < 0 &&
!isGenuineComment(lines[i]))
lines[i] = lines[i].substring(2);
if (isBattleTrigger &&
lines[i].startsWith(";") &&
(lines[i].toLowerCase().indexOf("trigger")) < 0 &&
!isGenuineComment(lines[i]))
lines[i] = lines[i].substring(1);
}
return lines;
}
public static String[] uncommentBattleTriggers(String[] lines, String triggerNamePattern)
{
boolean doUncomment = false;
for (int i = 0; i < lines.length; i++)
{
if (lines[i].toLowerCase().indexOf("trigger")>= 0)
doUncomment = false;
if (lines[i].toLowerCase().indexOf("trigger ") >= 0 &&
lines[i].toLowerCase().indexOf(triggerNamePattern.toLowerCase()) >= 0)
doUncomment = true;
if (doUncomment &&
lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[i] = lines[i].substring(2);
if (doUncomment &&
lines[i].startsWith("; ") &&
(lines[i].toLowerCase().indexOf("trigger")) < 0 &&
!isGenuineComment(lines[i]))
lines[i] = lines[i].substring(1);
}
return lines;
}
public static String[] commentBattleTriggers(String[] lines, String triggerNamePattern)
{
boolean doComment = false;
for (int i = 0; i < lines.length; i++)
{
if (lines[i].toLowerCase().indexOf("trigger")>= 0)
doComment = false;
if (lines[i].toLowerCase().indexOf("trigger ") >= 0 &&
lines[i].toLowerCase().indexOf(triggerNamePattern.toLowerCase()) >= 0)
doComment = true;
if (doComment &&
!lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[i] = "; " + lines[i];
}
return lines;
}
public static String[] uncommentBattleTriggersWithPattern(String[] lines, String pattern)
{
pattern = pattern.toLowerCase();
boolean isBattleTrigger = false;
boolean hasPattern = false;
for (int i = 0; i < lines.length; i++)
{
if(lines[i].startsWith(";"))
continue;
if (lines[i].toLowerCase().indexOf("trigger")>= 0)
{
hasPattern = false;
isBattleTrigger = false;
}
if (lines[i].toLowerCase().indexOf("whentotest") >= 0)
isBattleTrigger = lines[i].toLowerCase().indexOf("postbattle") >= 0;
if(lines[i].toLowerCase().indexOf(pattern) >= 0)
{
hasPattern = true;
if(isBattleTrigger)
{
for (int j = i; j > 1 && lines[j].toLowerCase().indexOf("trigger") < 0; j--)
{
if (lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[j-1] = lines[j-1].substring(2);
}
}
}
if (isBattleTrigger && hasPattern &&
lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[i] = lines[i].substring(2);
}
return lines;
}
public static String[] commentBattleTriggersWithPattern(String[] lines, String pattern)
{
pattern = pattern.toLowerCase();
boolean isBattleTrigger = false;
boolean hasPattern = false;
for (int i = 0; i < lines.length; i++)
{
if(lines[i].startsWith(";"))
continue;
if (lines[i].toLowerCase().indexOf("trigger")>= 0)
{
hasPattern = false;
isBattleTrigger = false;
}
if (lines[i].toLowerCase().indexOf("whentotest") >= 0)
isBattleTrigger = lines[i].toLowerCase().indexOf("postbattle") >= 0;
if(lines[i].toLowerCase().indexOf(pattern) >= 0)
{
hasPattern = true;
if(isBattleTrigger)
{
for (int j = i; j > 1 && lines[j].toLowerCase().indexOf("trigger") < 0; j--)
{
if (!lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[j-1] = "; " + lines[j-1];
}
}
}
if (isBattleTrigger && hasPattern &&
!lines[i].startsWith("; ") &&
!isGenuineComment(lines[i]))
lines[i] = "; " + lines[i];
}
return lines;
}
public static void printDistinctWhenToTests(String[] lines)
{
Vector retur = new Vector();
for (int i = 0; i < lines.length; i++)
{
if(lines[i].toLowerCase().indexOf("whentotest") >= 0 &&
!retur.contains(lines[i]))
retur.add(lines[i]);
}
for (int i = 0; i < retur.size(); i++)
{
System.out.println(retur.get(i));
}
}
/*
public static String replace(String org, String pattern, String replacement)
{
String retur = org;
int pos = 0;
while ((pos = retur.indexOf(pattern, pos)) >= 0)
{
retur = retur.substring(0, pos) + replacement + retur.substring(pos + pattern.length());
}
return retur;
}
*/
public static boolean isGenuineComment(String line)
{
return
line.toLowerCase().indexOf(":") >= 0 ||
line.toLowerCase().indexOf("-----") >= 0 ||
line.toLowerCase().indexOf("=====") >= 0 ||
line.toLowerCase().indexOf("%") >= 0 ||
line.toLowerCase().indexOf("section") >= 0 ||
line.toLowerCase().indexOf("gaining initial star easiest") >= 0 ||
line.toLowerCase().indexOf("o <") >= 0 ||
line.toLowerCase().indexOf("celts win big battle, twice the points") >= 0 ||
line.toLowerCase().indexOf("strategicskill shown by bringing bigger battalion") >= 0 ||
line.toLowerCase().indexOf("determine whether general learned") >= 0;
}
}
Mouzafphaerre
01-07-2008, 10:23
.
Will be my first Java compilation. :yes: Actually first compilation in more than a decade. :burnout:
.
Oh yeah, I forgot to say that you may have to twiddle the interpretation of the character encoding depending on how your files are coded. You can see how I did it with the UTF-16 encoding for the VNV (descriptions) file. The others use the default encoding for the OS, which is probably WIN1252 for most.
Chris A. T.
01-07-2008, 14:43
Quote:
Originally Posted by Ludens
Oh, and another thing about the Somatophylakes Strategou: they haven't got the "hardy" trait, making them have less endurance than even the Hoplites Haploi.
Thought i should mention that this is also true for the Spartiates ( ;326 ) & Epilektoi Hoplitai ( ;461 ).
You will quite often find that heavily armoured troops, especially infantry, have less stamina and/or speed than their less armoured variants.
I suppose all that armour is, in fact, sorta heavy or something..
;-)
A couple more questions:
-According to the recruitment viewer Thracian cavalry are in the KH factional MIC, while Thracian infantry are in the regional one. This looks like a mistake to me.
-The higher levels of ports still have more fleets than the game allows (a city cannot have more than three sea-trading partners).
I have wondered about this, too. And it goes not only for the KH; for the Getai, thracian peltasts, elite infantry and medium cavalry are factional troop types, while thracian light cavalry, light spearmen and triballi infantry are regionals!
The question might have any of a number of answers:
For the Getai and similar types, it might be because of the restricted max number of unit types, so that reasonably similar dacian, thracian, etc. cavalry types all get lumped together under "Thracian Medium Cavalry", f.ex.
In situations like the KH, it might be because of military traditions. Since the KH traditionally where strong infantry-wise, but not so when it came to cavalry, they might have relied a lot on mercenary thracian cavalry, who therefore would become incorporated into the military structure over time, in a way that the infantry simply didn't. Another example of this would be the Ptolemaic relation to some of the galatians vs. other celts.
That said, I would certainly also like to know the actual reason.
Lysander13
01-08-2008, 03:57
You will quite often find that heavily armoured troops, especially infantry, have less stamina and/or speed than their less armoured variants.
I suppose all that armour is, in fact, sorta heavy or something..
Fair enough. However the fact of the matter is that the RTW engine doesn't handle fatigue very well to start with; so not giving let's say a particular unit the hardy attribute while all other's in that same unit's classification more or less have it, puts the the unit without the attribute at a disadvantage. Specifically, if controlled by the AI. Of course if one plays with fatigue off it's a mute point.
vBulletin® v3.7.1, Copyright ©2000-2025, Jelsoft Enterprises Ltd.