• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.

Vent_Gala

Captain
35 Badges
Mar 19, 2005
450
6
  • Hearts of Iron IV: Cadet
  • 500k Club
  • Cities: Skylines
  • Crusader Kings II: Holy Knight (pre-order)
  • Pillars of Eternity
  • Cities: Skylines - After Dark
  • Cities: Skylines - Snowfall
  • Stellaris
  • Hearts of Iron IV Sign-up
  • War of the Roses
  • Hearts of Iron IV: Together for Victory
  • Cities: Skylines - Mass Transit
  • Hearts of Iron IV: Death or Dishonor
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: Expansion Pass
  • Prison Architect
  • Hearts of Iron IV: La Resistance
  • Heir to the Throne
  • Crusader Kings II: Legacy of Rome
  • Crusader Kings II: Sword of Islam
  • Europa Universalis III
  • Europa Universalis III Complete
  • Europa Universalis IV
  • For the Motherland
  • Hearts of Iron III
  • Hearts of Iron III: Their Finest Hour
  • Crusader Kings II
  • Impire
  • Europa Universalis III Complete
  • Lead and Gold
  • Europa Universalis III Complete
  • Rome Gold
  • Semper Fi
  • Rome: Vae Victis
Introduction

This thread is meant as a guide for those who want to edit the portraits of characters, custom or vanilla. I created this guide because although there are several threads on the subject already, they are spread far apart and the information is often presented as guesswork.
Through many hours of trial and error I've been able to compile a list of stuff that I now KNOW how to use properly, along with a list of stuff that is either still unclear or simply confirmed as not working. My findings will be presented in the posts below.

Disclaimer

Please keep in mind that I am in no way an experienced coder, but using simple logic, a dedicated mod directory for testing and hundreds of restarts can take you a long way. There is room for error in my findings, but I absolutely think that this is (so far) still the most complete set of instructions and conclusions regarding CK2's use of DNA.

The building blocks of a portrait

All portraits, be they male or female, consists of the same basic elements, and all those elements are layered to create the final character portrait. First there is a background image suitable for the character and his/her current situation. Then there is a generic head, either young, middle aged or old. Upon this head the game then add everything else by layering images with built in transparency, this includes unique facial features such as cheeks, hair and a nose, as well as things like clothes and headgear.

Note that the basic head contains facial features of it's own, but those are overwritten by the layers above it, it is merely there to provide a foundation that includes age apropriate features such as wrinkles.

The only exceptions are portraits of children, which are created using a single file per type of child (western male, western female, muslim male and muslim female). This is the reason all kids look alike in CK2.

How the game generates portraits

The game generates portraits using three sources; hard-coded information that we can't change, and information from the files portraits.gfx and portrait_properties.txt that can be modded. Both files can be opened using notepad and are found in the crusader kings ii/interface folder.

CK2 have portraits divided into 8 different categories (12 if you count children), and each category uses it's own set of building blocks as defined by portraits.gfx. The categories seem to be hard-coded, you could potentially add a new category in the file, but since the game has no way of knowing what kind of characters fall into that category it would either be ignored or crash the game.
The categories are:

Northern European Male
Northern European Female
Southern European Male
Italian Female (as far as I can tell, it's the female counterpart to Southern European Male)
Byzantine Male
Byzantine Female
Muslim Male
Muslim Female


Each category has it's own listing in portraits.gfx that defines what image files the game should use as building blocks, and where those files are located. The game then ties each image file to either a DNA slot or a Property slot. Unless a character has his/her DNA and/or Property sequence specified (as described below), the game will generate the portrait from a set of hard-coded rules as well as rules defined in portrait_properties.txt, using the files apropriate for the characters portrait category.

The listings in portraits.gfx are similar for all categories, but I will use Western European Male as an example. First of all, all files that are to be used are listed and given a code-name, seen here:

Code:
[COLOR="#00FFFF"]	### WESTERN MALE ####
	spriteType = {
		name = "GFX_character_imprisoned"
		texturefile = "gfx\\characters\\shared\\imprisoned.dds"
		noOfFrames = 2
		norefcount = yes
	}

	spriteType = {
		name = "GFX_character_reddots"
		texturefile = "gfx\\characters\\shared\\red_dots.dds"
		noOfFrames = 2
		norefcount = yes
	}

	spriteType = {
		name = "GFX_character_boils"
		texturefile = "gfx\\characters\\shared\\boils.dds"
		noOfFrames = 2
		norefcount = yes
	}

	spriteType = {
		name = "GFX_character_scars"
		texturefile = "gfx\\characters\\shared\\scars.dds"
		noOfFrames = 5
		norefcount = yes
	}

	spriteType = {
		name = "GFX_character_background"
		texturefile = "gfx\\characters\\shared\\backgrounds.dds"
		noOfFrames = 21
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_clothes_behind"
		texturefile = "gfx\\characters\\western_male\\western_male_clothes_behind.dds"
		noOfFrames = 15
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_headgear_behind"
		texturefile = "gfx\\characters\\western_male\\western_male_headgear_behind.dds"
		noOfFrames = 15
		norefcount = yes
	}


	spriteType = {
		name = "GFX_western_male_hair_behind"
		texturefile = "gfx\\characters\\western_male\\western_male_hair_behind_1.dds"
		noOfFrames = 14
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_hair_behind_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_hair_behind_2.dds"
		noOfFrames = 14
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_hair_behind_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_hair_behind_3.dds"
		noOfFrames = 14
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_beard_behind"
		texturefile = "gfx\\characters\\western_male\\western_male_beard_behind_1.dds"
		noOfFrames = 8
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_beard_behind_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_beard_behind_2.dds"
		noOfFrames = 8
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_beard_behind_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_beard_behind_3.dds"
		noOfFrames = 8
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_base"
		texturefile = "gfx\\characters\\western_male\\western_male_base_1.dds"
		noOfFrames = 1
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_base_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_base_2.dds"
		noOfFrames = 1
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_base_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_base_3.dds"
		noOfFrames = 1
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_neck"
		texturefile = "gfx\\characters\\western_male\\western_male_neck_1.dds"
		noOfFrames = 4
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_neck_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_neck_2.dds"
		noOfFrames = 4
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_neck_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_neck_3.dds"
		noOfFrames = 4
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_cheeks"
		texturefile = "gfx\\characters\\western_male\\western_male_cheeks_1.dds"
		noOfFrames = 11
		norefcount = yes
	}
	
	spriteType = {
		name = "GFX_western_male_cheeks_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_cheeks_2.dds"
		noOfFrames = 11
		norefcount = yes
	}
	
	spriteType = {
		name = "GFX_western_male_cheeks_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_cheeks_3.dds"
		noOfFrames = 11
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_chin"
		texturefile = "gfx\\characters\\western_male\\western_male_chin_1.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_chin_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_chin_2.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_chin_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_chin_3.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_mouth"
		texturefile = "gfx\\characters\\western_male\\western_male_mouth_1.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_mouth_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_mouth_2.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_mouth_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_mouth_3.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_nose"
		texturefile = "gfx\\characters\\western_male\\western_male_nose_1.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_nose_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_nose_2.dds"
		noOfFrames = 13
		norefcount = yes
	}
	
	spriteType = {
		name = "GFX_western_male_nose_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_nose_3.dds"
		noOfFrames = 13
		norefcount = yes
	}

#	spriteType = {
#		name = "GFX_western_male_head"
#		texturefile = "gfx\\characters\\western_male\\western_male_head_1.dds"
#		noOfFrames = 3
#		norefcount = yes
#	}

	spriteType = {
		name = "GFX_western_male_eyes"
		texturefile = "gfx\\characters\\western_male\\western_male_eyes_1.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_eyes_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_eyes_2.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_eyes_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_eyes_3.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_eyes2"
		texturefile = "gfx\\characters\\western_male\\western_male_eyes2.dds"
		noOfFrames = 13
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_clothes"
		texturefile = "gfx\\characters\\western_male\\western_male_clothes.dds"
		noOfFrames = 15
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_headgear_mid"
		texturefile = "gfx\\characters\\western_male\\western_male_headgear_mid.dds"
		noOfFrames = 15
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_ear"
		texturefile = "gfx\\characters\\western_male\\western_male_ear_1.dds"
		noOfFrames = 10
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_ear_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_ear_2.dds"
		noOfFrames = 10
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_ear_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_ear_3.dds"
		noOfFrames = 10
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_beard"
		texturefile = "gfx\\characters\\western_male\\western_male_beard_1.dds"
		noOfFrames = 8
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_beard_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_beard_2.dds"
		noOfFrames = 8
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_beard_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_beard_3.dds"
		noOfFrames = 8
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_hair"
		texturefile = "gfx\\characters\\western_male\\western_male_hair_1.dds"
		noOfFrames = 14
		norefcount = yes
	}

		spriteType = {
		name = "GFX_western_male_hair_midage"
		texturefile = "gfx\\characters\\western_male\\western_male_hair_2.dds"
		noOfFrames = 14
		norefcount = yes
	}
	
	spriteType = {
		name = "GFX_western_male_hair_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_hair_3.dds"
		noOfFrames = 14
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_clothes_infront"
		texturefile = "gfx\\characters\\western_male\\western_male_clothes_infront.dds"
		noOfFrames = 15
		norefcount = yes
	}

	spriteType = {
		name = "GFX_western_male_headgear"
		texturefile = "gfx\\characters\\western_male\\western_male_headgear.dds"
		noOfFrames = 15
		norefcount = yes
	}[/COLOR]

After that the files are assigned to either a DNA slot or a Property slot using the code-names defined above and hair/eye color is defined and also assigned to DNA slots This is what it looks like:

Code:
[COLOR="#00FFFF"]	# Northern European Male
	
	portraitType = {
		name = "PORTRAIT_westerngfx_male"
		effectFile = "gfx/FX/portrait.lua"
		layer = { # GFX_TYPE:[d|p]INDEX:COLOR_LINK
			"GFX_character_background:p0"
			"GFX_western_male_clothes_behind:p3"
			"GFX_western_male_headgear_behind:p5"
			"GFX_western_male_hair_behind:p1:h"
			"GFX_western_male_beard_behind:p4:h"
			"GFX_western_male_base:p2"
			"GFX_western_male_neck:d0"
			"GFX_western_male_cheeks:d4"
			"GFX_western_male_chin:d1"
			"GFX_western_male_mouth:d2"
			"GFX_western_male_nose:d3"
			#"GFX_western_male_head:d5"
			"GFX_western_male_eyes:d6"
			"GFX_western_male_eyes2:d6:e"
			"GFX_western_male_clothes:p3"
			"GFX_western_male_headgear_mid:p5"
			"GFX_western_male_ear:d7"			
			"GFX_western_male_beard:p4:h"
		   	 "GFX_western_male_hair:p1:h"
			"GFX_western_male_clothes_infront:p3"
			"GFX_character_scars:p7"
			"GFX_character_reddots:p8"
			"GFX_character_boils:p9"
			"GFX_western_male_headgear:p5"
			"GFX_character_imprisoned:p6"
		}

		hair_color_index = 8
		hair_color = { # dark, base, highlight
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 15 8 0 } { 176 155 108 } { 255 255 255 }
			{ 10 10 10 } { 125 85 56 } { 255 255 255 }
			{ 30 22 18 } { 150 90 55 } { 255 255 255 }
			{ 30 22 18 } { 178 80 41 } { 255 255 255 }
			{ 20 12 8 } { 78 54 37 } { 255 255 255 }
		}

		eye_color_index = 9
		eye_color = {
			{ 58 109 193}
			{ 120 74 46 }
			{ 34 103 36 }
		}
	}[/COLOR]

there are 10 DNA slots and 10 Property slots and they are labeled d0-d9 and p0-p9, where p0 would be the first DNA slot, p1 the second and so on. You will not be modding all slots, but I will explain why in a little while.

How you can create custom portraits

In order to create a custom portrait for a character, you really only have to edit a single file, namely the .txt file containing the character you want to edit, found in the crusader kings ii/history/characters folder. Vanilla characters are located in the file named after their culture, custom characters are located in whatever file you chose to create them in.

Once you have located your characters code, you need to add two lines:

dna="0000000000"
properties="00000"


As far as I can tell, it doesn't matter exactly where you add the lines as long as you add them within the body of code defining the character, but to be safe I like to add them below the dynasty entry since that is how it's done on the few vanilla characters that include these lines. Using my custom character Count Test Dummy of Skåne, the code should look like this:

Code:
[COLOR="#00FFFF"]9000000 = {
	name="Test"
	dynasty=8000000
	dna="0000000000" 
	properties="00000"
 	martial=5
	diplomacy=5
	intrigue=5
	stewardship=5
	religion="catholic"
	culture="swedish"
	add_trait="patient"
	add_trait="content"
	1031.11.14 = {
		birth="1031.11.14"
	}
	1101.6.22 = {
		death="1101.6.22"
	}
}[/COLOR]

Once you've added those two lines, you can start messing around with the sequences to create your custom portrait. I will explain how in the paragraph below, and to avoid confusion I will define the slots the same way the game defines them; d0-d9 and p0-p9. For example, whenever I mention the DNA slot d6, I am referring to the 7th DNA slot from the left.

How the sequences work

Remember how I told you you wouldn't need to include all slots? That's because some of them are hard-coded, to be precise, one DNA slot and all but two Property slots. These hard-coded slots wont change anything no matter what you do, the only reason to include them is if there are non hard-coded slot ahead of it. For example, p0 is the background for the portrait and it is hard-coded (only kings/emperors can have the throne room background for example), but since p1 is not hard-coded and it defines the hair, you have to include p0 as well. You can't just include one Property slot and expect the game to understand that you want it to be p1, as far as the game knows, p1 is simply the second Property slot from the left.

All said and done, I have found that the optimum number of slots one needs to include is 10 for DNA and 5 for Properties. Granted, the 10th DNA slot is currently unused, but I recommend that you include it anyway because I have not done enough testing to be absolutely sure that everything works as intended without it in case there is something I've missed. But again, everything should work without it.

So, how do you tell the game what facial features you want it to use? By using the slots to define what part of each image file it should use, but this is where it gets complicated. Let me explain:

The image files used in the portraits all have frames, and since each DNA/Property slot is tied to a specific image file, you can use that slot to tell the game what frame to use, and to do this you use letters, not numbers. For example, the image file used for noses on middle aged european males looks like this:

western_male_nose_2.jpg


The complicated part is how they are numbered. Slots can be defined as either 0 (zero) or any letter. The letter “a” refers to the second frame from the left, “b” is the third, “c” is the fourth and so forth. “Right” I can hear you say, “So zero is the first then? Easy enough”. Well... NO! Zero is in fact not used to define the first frame of an image file, instead it is used to tell the game to go right ahead and use it's hard-coded and pre-defined rules for randomly generating portraits for that particular slot. To select the first frame, you need to make use of the fact that the letters can loop. So if an image file has 3 frames, “a” selects the second, “b” selects the third and “c” loops back to the beginning and selects the first frame. Using the nose file from above, the letters defining each frame would look like this:

nose.jpg


Phew, complicated.

So, what slot controls what part of the portrait? Well, to find out you have to look it up in portraits.gfx as mentioned above. But since I'm a nice guy, I went ahead and did that for you, and I found that all portrait categories use the same system. It goes like this:

d0 = Neck
d1 = Chin
d2 = Mouth
d3 = Nose
d4 = Cheeks
d5 = Unused
d6 = Eyes
d7 = Ear
d8 = Hair Color/Eye color
d9 = Claimed to be Eye Color, but is in fact unused

p0 = Background
p1 = Hair
p2 = Base Head
p3 = Clothes
p4 = Beard
p5 = Headgear
p6 = Imprisoned
p7 = Scars
p8 = Red Dots
p9 = Boils


As I mentioned earlier, some of these are hard-coded and that's why you don't have to include all of them. The hard-coded ones will not change no matter what frame you tell the game to use, and they are:

Properties

Only hair and beards can be changed, meaning p1 and p4. Because of this, there is absolutely no need to include any slots beyond p4. So that's 5 Property slots in total for you to mod.

DNA

Eye color is supposed to be defined by d9, but it isn't. Instead, it is also defined by d8, just like hair color. This was brought to my attention by Cabezaestufa, and I'll let a direct quote from him explain it in more detail:

I have found that d9 doesn't actually do anything. Eye color is also defined by d8; hair and eye colors come in pairs. If there's the same number of hair and eye colors (or one is a multiple of the other) these pairs will always be the same, but if not, as the index increases all kinds of combinations can be produced. For example, if there are 5 hair colors and 3 eye colors, a=hair(2), eye(2), but c=hair(4), eye(1), etc.

This way, you can either make it so that black-haired people always have brown eyes and blondes always have blue eyes, or allow all kinds of combinations.
In theory, this means that you don't have to include d9, and indeed not including it has worked just fine for me. it also means (again, in theory) that d9 is currently unused, meaning the slot could be modded to use a custom image file, just like d5.

Number of frames per image file

To find out how many frames an image file has, you could open it up using a software that can open .dds files and have a look. But a much simpler way is to look in portraits.gfx since it lists the number of frames as it defines what image files to use for each portrait category. In the example below we can see that the image file used for mouths on old european males has 13 frames:

Code:
[COLOR="#00FFFF"]	spriteType = {
		name = "GFX_western_male_mouth_oldage"
		texturefile = "gfx\\characters\\western_male\\western_male_mouth_3.dds"
		noOfFrames = 13
		norefcount = yes
	}[/COLOR]

This way you can determine what letter to use in order to select frame one.

Hair and Eye color

Hair and eye color does not use image files, instead, they are defined by a set of RGB values in portrait.gfx as seen here:

Code:
[COLOR="#00FFFF"]		hair_color_index = 8
		hair_color = { # dark, base, highlight
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 15 8 0 } { 176 155 108 } { 255 255 255 }
			{ 10 10 10 } { 125 85 56 } { 255 255 255 }
			{ 30 22 18 } { 150 90 55 } { 255 255 255 }
			{ 30 22 18 } { 178 80 41 } { 255 255 255 }
			{ 20 12 8 } { 78 54 37 } { 255 255 255 }
		}

		eye_color_index = 9
		eye_color = {
			{ 58 109 193}
			{ 120 74 46 }
			{ 34 103 36 }[/COLOR]

They are numbered (or should I say lettered?) the same way as frames, only from top to bottom instead of left to right. So the letter “b” would select the third color from the top. Both hair and eye color uses d8, even though the code suggests eye color uses d9. To be clear, it doesn't, but it still has it's own colors defined as you can see in the code above.

As you can see, for hair the game uses three RGB values. The first is applied to the roots of the hair, the second is the main color and the third (which is always white) is used as a highlight.

Possible glitches

During my testing I have come across some glitches. These are not confirmed in any way, but I've noticed them often enough to feel that I should mention them.

-Setting a predefined (hard-coded) Property to any value other than zero can in rare cases cause artifacts in the portrait. I suggest using only zeros in those slots just to be sure. You can't edit those slots anyway, so why not, right?

-Setting any DNA slot that the game uses (all except d5 and d9) to a value of zero can in some cases cause either artifacts or even cause all DNA slots to be treated as if they had a value of zero. I suggest avoiding zeros in the DNA sequence just to be sure.


Example of a custom portrait

To recap, I'll once again use Count Test Dummy to illustrate a correctly coded custom portrait:

Code:
[COLOR="#00FFFF"]9000000 = {
	name="Test"
	dynasty=8000000
	dna="aaeaamaada" 
	properties="0b00h"
 	martial=5
	diplomacy=5
	intrigue=5
	stewardship=5
	religion="catholic"
	culture="swedish"
	add_trait="patient"
	add_trait="content"
	1031.11.14 = {
		birth="1031.11.14"
	}
	1101.6.22 = {
		death="1101.6.22"
	}
}[/COLOR]

This will create a portrait where all facial features uses the second frame, except for the mouth that will use frame 6, the eyes that will use frame 1 and the 5th hair color will be used, providing us with a ginger. In the Properties line we can see that hair frame 3 will be used along with beard frame 1, meaning he will be newly shaved man with a very silly haircut. And here he is in all his glory:

example.jpg
 
Last edited:
  • 2
Reactions:
REFERENCE MATERIAL


In this section you will find various lists, images and color samples meant to be used as a handy reference material collection while modding custom portraits. I will add to the section when and if I have the time.


Portrait categories


As mentioned earlier, there are 8 categories of portraits with their own body of code in portraits.gfx, however, the image files used are only divided into 4 categories, each with it's own subfolder in the crusader kings ii/gfx/characters folder. The reason for this is that while code is needed to, for example, provide Italians and Swedes with different sets of hair color, they are still closely related enough to use the same facial features. The four categories for portrait image files are:


Western Male (WM)
Western Female (WF)
Muslim Male (MM)
Muslim Female (MF)



Below is a list of the image files used by each category, along with the number of frames contained within each file and the letter needed to select frame one. I have not included the base file (the one containing the base head upon which all other layers are placed) since it only contains a single frame.

WM
WF
MM
MF
Background
21/u
21/u
21/u
21/u
Clothes
15/o
15/o
15/o
15/o
Headgear
15/o
14/n
14/n
11/k
Hair
14/n
13/m
13/m
11/k
Beard
8/h
-
7/g
-
Neck
4/d
4/d
4/d
4/d
Cheeks
11/k
11/k
11/k
11/k
Chin
13/m
13/m
13/m
13/m
Mouth
13/m
13/m
13/m
13/m
Nose
13/m
13/m
13/m
13/m
Eyes
13/m
13/m
13/m
13/m
Ear
10/j
13/m
11/k
6/f

And here is a link to a set of reference images for western males and females, provided by enderbr. A big thank you from all of us!

Hair and Eye color

Below are the hair and eye colors for Northern Europeans, along with the correct d8 lettering for custom portraits. All other culture groups use black hair and dark eyes, except for southern europeans that, although they only have dark hair, still use the full range of eye colors. However, there are plenty of modding to be done with hair/eye color, but I'll explain more about that in a later section. The colors shown are used by both male and female Northern europeans, and they apply to young and middle aged characters. Old characters have the same number of hair colors, but it's merely different shades of grey. Below the reference image I have included the RGB values for the hair and eye colors, hair uses three values (dark, base, highlights) while eyes use a single value. Note that there are six hair colors but only three eye colors, but since letters can loop and d8 governs both hair and eye color, the same eye color will be paired with both hair color 1 and 4 and so on...

hairColorGuide01.jpg


hair_color = { # dark, base, highlight
{ 10 10 10 } { 50 50 50 } { 255 255 255 }
{ 15 8 0 } { 176 155 108 } { 255 255 255 }
{ 10 10 10 } { 125 85 56 } { 255 255 255 }
{ 30 22 18 } { 150 90 55 } { 255 255 255 }
{ 30 22 18 } { 178 80 41 } { 255 255 255 }
{ 20 12 8 } { 78 54 37 } { 255 255 255 }

eye_color = {
{ 58 109 193}
{ 120 74 46 }
{ 34 103 36 }
 
Last edited:
FURTHER MODDING

In this section I'll discuss the various modding possibilties allowed by the portrait mechanics. I'll add to it whenever I have the time

Hair and Eye colors

It is possible to both edit the vanilla hair/eye colors AND to add completely new colors. Any new colors that are added will be used by the game, this is tested and confirmed, so even vanilla characters that does not have DNA/Properties sequences in their code could end up with one of the new colors. However, no matter how many colors you add or edit, one fact remains constant; hair and eye color are both governed by d8. This means that (since letters can loop) depending on the difference between the number of hair colors and the number of eye colors, it can be possible to get very specific about the hair/eye combination you want for a custom portrait.

For example, if you have 6 hair colors and 3 eye colors as in the example image below, the letter "A" in d8 would give you the 2nd hair color and the 2nd eye color, but the letter "J" would give you the 5th hair color and the 1st eye color.
HairEyePairing.jpg


As mentioned earlier, the code for hair/eye color is found in portraits.gfx in the crusader kings ii/interface folder. Colors are listed three times for each portrait category, once per age. So middle aged northern european males will have a separate color listing from old northern european males for example. Hair color uses three RGB values, one for the dark areas of the hair, one for the base color and one for highlights. eye colors only use a single RGB value per color. The code looks like this (hair/eye color code is in white):

Code:
[COLOR=#00ffff]    # old age
    portraitType = {
        name = "PORTRAIT_westerngfx_male2"
        effectFile = "gfx/FX/portrait.lua"
        layer = { # GFX_TYPE:[d|p]INDEX:COLOR_LINK
            "GFX_character_background:p0"
            "GFX_western_male_clothes_behind:p3"
            "GFX_western_male_headgear_behind:p5"
            "GFX_western_male_hair_behind_oldage:p1:h"
            "GFX_western_male_beard_behind_oldage:p4:h"
            "GFX_western_male_base_oldage:p2"
            "GFX_western_male_neck_oldage:d0"
            "GFX_western_male_cheeks_oldage:d4"
            "GFX_western_male_chin_oldage:d1"
            "GFX_western_male_mouth_oldage:d2"
            "GFX_western_male_nose_oldage:d3"
            #"GFX_western_male_head:d5"
            "GFX_western_male_eyes_oldage:d6"
            "GFX_western_male_eyes2:d6:e"            
            "GFX_western_male_clothes:p3"
            "GFX_western_male_headgear_mid:p5"
            "GFX_western_male_ear_oldage:d7"
            "GFX_western_male_beard_oldage:p4:h"
            "GFX_western_male_hair_oldage:p1:h"
            "GFX_western_male_clothes_infront:p3"
            "GFX_character_scars:p7"
            "GFX_character_reddots:p8"
            "GFX_character_boils:p9"
            "GFX_western_male_headgear:p5"
            "GFX_character_imprisoned:p6"
        }

[COLOR=#ffffff]        hair_color_index = 8
        hair_color = { # dark, base, highlight
            { 10 10 10 } {  200 200 200 } { 255 255 255 }
            { 15 8 0 } { 214 210 195 } { 255 255 255 }
            { 10 10 10 } { 143 134 127 } { 255 255 255 }
            { 30 22 18 } { 174 161 151 } { 255 255 255 }
            { 30 22 18 } { 180 170 151 } { 255 255 255 }
            { 30 22 18 } { 180 170 151 } { 255 255 255 }[/COLOR]
        }

[COLOR=#ffffff]        eye_color_index = 9
        eye_color = {
            { 58 109 193}
            { 120 74 46 }
            { 34 103 36 }[/COLOR]
        }
    }[/COLOR]

To edit a color, simple change the RGB value. To add a new color, simple add a new line with the RGB value you want. Remember that the age groups and genders within each portrait category have separate code, so (for example) if you want a new color to be used by both young and middle aged characters from a certain culture group, and by both genders, you need to add it in four different places. Here is an example where I added several extreme hair colors to middle aged northern european males:

Code:
[COLOR="#00FFFF"]	# middle age
	portraitType = {
		name = "PORTRAIT_westerngfx_male1"
		effectFile = "gfx/FX/portrait.lua"
		layer = { # GFX_TYPE:[d|p]INDEX:COLOR_LINK
			"GFX_character_background:p0"
			"GFX_western_male_clothes_behind:p3"
			"GFX_western_male_headgear_behind:p5"
			"GFX_western_male_hair_behind_midage:p1:h"
			"GFX_western_male_beard_behind_midage:p4:h"
			"GFX_western_male_base_midage:p2"
			"GFX_western_male_neck_midage:d0"
			"GFX_western_male_cheeks_midage:d4"
			"GFX_western_male_chin_midage:d1"
			"GFX_western_male_mouth_midage:d2"
			"GFX_western_male_nose_midage:d3"
			#"GFX_western_male_head:d5"
			"GFX_western_male_eyes_midage:d6"
			"GFX_western_male_eyes2:d6:e"
			"GFX_western_male_clothes:p3"
			"GFX_western_male_headgear_mid:p5"
			"GFX_western_male_ear_midage:d7"
			"GFX_western_male_beard_midage:p4:h"
			"GFX_western_male_hair_midage:p1:h"
			"GFX_western_male_clothes_infront:p3"
			"GFX_character_scars:p7"
			"GFX_character_reddots:p8"
			"GFX_character_boils:p9"
			"GFX_western_male_headgear:p5"
			"GFX_character_imprisoned:p6"
		}

		hair_color_index = 8
		hair_color = { # dark, base, highlight
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 15 8 0 } { 176 155 108 } { 255 255 255 }
			{ 10 10 10 } { 125 85 56 } { 255 255 255 }
			{ 30 22 18 } { 150 90 55 } { 255 255 255 }
			{ 30 22 18 } { 178 80 41 } { 255 255 255 }
			{ 20 12 8 } { 78 54 37 } { 255 255 255 }
[COLOR="#FFFFFF"]			{ 20 0 0 } { 150 0 0 } { 255 255 255 }
			{ 0 20 0 } { 0 150 0 } { 255 255 255 }
			{ 0 0 20 } { 0 0 150 } { 255 255 255 }
			{ 40 0 0 } { 255 0 0 } { 255 255 255 }
			{ 0 40 0 } { 0 255 0 } { 255 255 255 }
			{ 0 0 40 } { 0 0 255 } { 255 255 255 }[/COLOR]
		}

		eye_color_index = 9
		eye_color = {
			{ 58 109 193}
			{ 120 74 46 }
			{ 34 103 36 }
		}
	}[/COLOR]

And here I merely changed the first hair color from black to purple, and the third eye color from a natural green to an extreme red, but I did not add any new colors:

Code:
[COLOR="#00FFFF"]	# Southern European Male
	portraitType = {
		name = "PORTRAIT_italiangfx_male"
		effectFile = "gfx/FX/portrait.lua"
		layer = { # GFX_TYPE:[d|p]INDEX:COLOR_LINK
			"GFX_character_background:p0"
			"GFX_western_male_clothes_behind:p3"
			"GFX_western_male_headgear_behind:p5"
			"GFX_western_male_hair_behind:p1:h"
			"GFX_western_male_beard_behind:p4:h"
			"GFX_western_male_base:p2"
			"GFX_western_male_neck:d0"
			"GFX_western_male_cheeks:d4"
			"GFX_western_male_chin:d1"
			"GFX_western_male_mouth:d2"
			"GFX_western_male_nose:d3"
			#"GFX_western_male_head:d5"
			"GFX_western_male_eyes:d6"
			"GFX_western_male_eyes2:d6:e"
			"GFX_western_male_clothes:p3"
			"GFX_western_male_headgear_mid:p5"
			"GFX_western_male_ear:d7"			
			"GFX_western_male_beard:p4:h"
		   	 "GFX_western_male_hair:p1:h"
			"GFX_western_male_clothes_infront:p3"
			"GFX_character_scars:p7"
			"GFX_character_reddots:p8"
			"GFX_character_boils:p9"
			"GFX_western_male_headgear:p5"
			"GFX_character_imprisoned:p6"
		}

		hair_color_index = 8
		hair_color = { # dark, base, highlight
			[COLOR="#FFFFFF"]{ 20 0 20 } {  175 0 175 } { 255 255 255 }[/COLOR]
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
			{ 10 10 10 } {  50 50 50 } { 255 255 255 }
		}

		eye_color_index = 9
		eye_color = {
			{ 58 109 193}
			{ 120 74 46 }
			{[COLOR="#FFFFFF"] 255 0 0 }[/COLOR]
		}
	}[/COLOR]
 
Last edited:
  • 2
Reactions:
Here I intend to go into further findings not covered by the first part. I'll explain the purpose of the portrait_properties.txt file and further explore the weird world of zeros among other things.
 
Last edited:
Great guide! Just one minor correction: I have found that d9 doesn't actually do anything. Eye color is also defined by d8; hair and eye colors come in pairs. If there's the same number of hair and eye colors (or one is a multiple of the other) these pairs will always be the same, but if not, as the index increases all kinds of combinations can be produced. For example, if there are 5 hair colors and 3 eye colors, a=hair(2), eye(2), but c=hair(4), eye(1), etc.

This way, you can either make it so that black-haired people always have brown eyes and blondes always have blue eyes, or allow all kinds of combinations.

I also found out that the game doesn't mind if you have dna strings longer than 11 characters (or shorter), which might imply that we can add more features. I still haven't tested it, though.
 
Great guide! Just one minor correction: I have found that d9 doesn't actually do anything. Eye color is also defined by d8; hair and eye colors come in pairs. If there's the same number of hair and eye colors (or one is a multiple of the other) these pairs will always be the same, but if not, as the index increases all kinds of combinations can be produced. For example, if there are 5 hair colors and 3 eye colors, a=hair(2), eye(2), but c=hair(4), eye(1), etc.

This way, you can either make it so that black-haired people always have brown eyes and blondes always have blue eyes, or allow all kinds of combinations.

I also found out that the game doesn't mind if you have dna strings longer than 11 characters (or shorter), which might imply that we can add more features. I still haven't tested it, though.

Great find! I'll edit my guide to use this information. As I said, I knew that d9 was not in fact used for eye color, but my guess was that eye color was governed by hair color by some hard-coded rules, I hadn't even considered the much more logical solution you just presented.

As for the rest of your post, I have noticed the same thing. I plan to adress this in my future post regarding further modding possibilities. Indeed the game works just fine with more DNA slots added, but adding code to define those slots causes the game to crash. I suspect that the game can't handle double digit nominators for these strings, which is sort of supported by the fact that there are exactly 10 (0-9) defined nominators for each string. It would also explain why they chose to make hair and beard part of the Properties; they simply ran out of DNA slots. It's just my best guess though, I need to test it further.
 
Last edited:
Have you looked into the Mongol faces DLC? They have a whole new set of portraits for Horde characters.

No, I don't have that DLC and I'm not sure I'll buy it to be honest. I'd imagine it uses the same basic mechanics though.

By the way you should be careful to preserve correct length of dna because short dna can lead to corrupt save games and to the game crash.

Yes, I've had multiple crashes as well as corrupt saves while testing, due to short DNA sequences, that's why I've included a warning regarding not including d9. I have yet to experience any bugs due to not including d9, but again, I simply haven't tested it enough to feel secure about actually telling people to go ahead and skip it.

However, I have never had any problems when using 10 DNA slots and 5 Property slots, and that particular setup I have tested rather thoroughly. It appears obvious to me that the DNA sequence of 11 slots that has been suggested in multiple threads, is simply not needed. I can find no mention of a d10 slot anywhere in the game files, and I have included it in multiple tests, set to a large number of values without any sort of change in the portrait.
 
Started a reference material section here, and added a list containing the number of frames contained within the image files used by portraits, along with the letter needed to select the first frame. Hope it proves useful to someone...
 
No, I don't have that DLC and I'm not sure I'll buy it to be honest. I'd imagine it uses the same basic mechanics though.

Pretty much, yeah. It does so, however, in a portraits_mongol.gfx. I haven't seen any reference to it in any other files. It might be hardcoded. I was wondering, however, if it's linked to the culture name. I will test it later on.
 
The Orthodox beards mod seems to have died so I may have to take up doing my own modding. Thanks for this.
 
If you cold give me some tips on how to:

A) Remove Robert Guiscard's (Duke of Apulia) Mustache

B) Swap the portraits of William the Bastard and Harold Godwinson

They would be much appreciated.
 
If you cold give me some tips on how to:

A) Remove Robert Guiscard's (Duke of Apulia) Mustache

B) Swap the portraits of William the Bastard and Harold Godwinson

They would be much appreciated.

Do you have the character IDs at hand?

At any rate, if I may assume that none of them have specified DNA/Propereties strings (very few vanilla characters do), then their portraits are generated by the game's internal and hard-coded set of portrait parameters. It's clear that even characters without DNA strings specified have the same portrait each time you start the game, and that means that the game MUST be using a set of rules for how such portraits should be generated. I would assume that it takes things like stats, titles and culture into consideration.

So what you would need to do is to take a screenshot of each character and then open all the portrait files and cross reference them to find out exactly what frames each facial feature uses. Then you would be able to create DNA/Properties sequences using the same frames and use those to switch portraits between William and Harold. For Robert you would do the same, only with a DNA/Properties sequence matching his "randomly" generated portrait minus the noseshrub.

If they DO have DNA/Propereties sequences defined, you just have to find their character entries and copy/paste those lines between William and Harold, and for Robert you'd simply change p4 to a value of "h", thereby selecting the first frame in the beard file, which is blank (no beard).

EDIT:

Found them! (Thank god for notepad++)

Code:
[COLOR="#FFFFFF"]1128 = {
	name="Robert" #Guiscard
	# AKA: Robert 'Guiscard'
	dynasty=678
	properties="ch00e0"
	martial=9
	diplomacy=4
	intrigue=6
	stewardship=6
	religion="catholic"
	culture="norman"
	add_trait="deceitful"
	add_trait="envious"
	add_trait="patient"
	add_trait="brilliant_strategist"
	father=1120
	mother=10008
	1015.1.1 = {
		birth="1015.1.1"
	}
	1051.1.1 = {
		add_spouse = 10003
	}
	1057.1.1 = {
		remove_spouse = 10003
	}
	1058.1.1 = {
		add_spouse = 1123
	}
	1085.7.17 = {
		death="1085.7.17"
	}
}

140 = {
	name="William"
	# AKA: William 'the Conqueror'
	dynasty=752
	dna="medjejoeacc" 
	properties="ae00e0"
	martial=7
	diplomacy=7
	intrigue=10
	stewardship=6
	religion="catholic"
	culture="norman"
	add_trait="ambitious"
	add_trait="diligent"
	add_trait="just"
	add_trait="proud"
	add_trait="cynical"
	add_trait="brave"
	add_trait="temperate"
	add_trait="patient"
	add_trait="legit_bastard"
	add_trait="brilliant_strategist"
	father=252
	mother=41001
	1027.1.15 = {
		birth="1027.1.15"
	}
	1035.7.3 = {
		give_nickname = nick_the_bastard
	}
	1053.1.1 = {
		add_spouse=367 # Mathilda of Flanders
	}
	1066.1.5 = {
		add_claim = k_england
	}
	1066.9.14 = {
		wealth = 1000
		raise_levies = {
			#location = 25 # Sussex
			location = 97 # Rouen
			force_mult = 6.7
		}
	}
	1066.10.14 = {
		raise_levies = {
			dismiss = yes
			location = 97 # Rouen
			force_mult = 6.7
		}
	}
	1066.12.26  = {
		give_nickname = nick_the_conqueror
	}
	1087.9.9 = {
		death="1087.9.9"
	}
}

122 = {
	name="Harold" # Godwineson, king of England
	dynasty=756
	dna="epdbiohgmkk"
	properties="ae0000"
	martial=8
	diplomacy=6
	intrigue=5
	stewardship=6
	religion="catholic"
	culture="saxon"
	add_trait="arbitrary"
	add_trait="proud"
	add_trait="skilled_tactician"
	father=120
	mother=101534
	1025.1.2={
		birth="1025.1.2"
	}
	1048.1.1={
		add_spouse=131 #Ealdgyth 'Swanneck'
	}
	1064.1.1={
		remove_spouse = 131
	}
	1065.6.6={
		add_spouse=123 #Ealdgyth of Mercia
	}
	1066.9.14 = {
		raise_levies = {
			location = 62 # Leicester
			force_mult = 2.5
		}
	}
	1066.10.14={
		raise_levies = {
			dismiss = yes
			location = 62 # Leicester
			force_mult = 2.5
		}
		death="1066.10.14"
	}
}[/COLOR]

Willam and Robert are located in crusader kings ii/history/characters/norman.txt and Harold is located in crusader kings ii/history/characters/saxon.txt.

Just switch places with William and Harold's dna and properties lines and for Robert just replace his properties line with the following to remove his stasche:

properties="ch00h0"

That should work.
 
Last edited:
This is awsome, going to read it thrue tomorow when I have some time over. And finaly be able to putt myself in the game proper with looks and not just by traits/name/stats etc.