• 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.

blackninja9939

Former Senior Programmer - Crusader Kings 3
99 Badges
Aug 28, 2013
2.414
8.570
  • BATTLETECH: Heavy Metal
  • Hearts of Iron IV: Death or Dishonor
  • Age of Wonders III
  • Cities: Skylines - Green Cities
  • Cities: Skylines - Mass Transit
  • Stellaris: Humanoids Species Pack
  • Stellaris: Digital Anniversary Edition
  • Surviving Mars: Digital Deluxe Edition
  • BATTLETECH - Digital Deluxe Edition
  • Cities: Skylines - Parklife
  • Cities: Skylines Industries
  • BATTLETECH: Flashpoint
  • Cities: Skylines - Snowfall
  • Cities: Skylines - Campus
  • BATTLETECH: Season pass
  • Age of Wonders: Planetfall Season pass
  • Age of Wonders: Planetfall - Revelations
  • Stellaris: Federations
  • Cities: Skylines Deluxe Edition
  • Hearts of Iron IV: No Step Back
  • Crusader Kings III
  • Hearts of Iron IV: By Blood Alone
  • Crusader Kings III: Royal Edition
  • Battle for Bosporus
  • Europa Universalis IV
  • Island Bound
  • Europa Universalis 4: Emperor
  • Empire of Sin
  • Stellaris: Necroids
  • Stellaris: Nemesis
  • Crusader Kings II
  • Crusader Kings II: Holy Fury
  • Imperator: Rome - Magna Graecia
  • Crusader Kings II: Charlemagne
  • Crusader Kings II: Rajas of India
  • Crusader Kings II: Sons of Abraham
  • Crusader Kings II: The Old Gods
  • Europa Universalis IV: Rights of Man
  • Europa Universalis IV: Cradle of Civilization
  • Stellaris: Synthetic Dawn
  • Surviving Mars
  • BATTLETECH
  • Europa Universalis IV: Mandate of Heaven
  • Crusader Kings II: Monks and Mystics
  • Tyranny: Archon Edition
  • Europa Universalis IV: Rule Britannia
  • Crusader Kings II: Reapers Due
  • Hearts of Iron IV: Colonel
  • Stellaris Sign-up
  • Hearts of Iron IV: Expansion Pass
So for those of you have no seen we held a game jam end of last year, you can see more in the Black Forge Jam thread for all of the projects.

I was part of the Medieval Menagerie team and was focused on adding support for showing dogs alongside humans in the game during those three days, since I am leaving the company soon I also got a bit of extra time to finish up the system itself so that we can add the mod support required for this even though we're not actually adding the Medieval Menagerie features into the game yet.

So in the next major patch, whatever the patch alongside Roads to Power gets called, you will have access to a new system for "portrait types" which allows you to do custom portrait models and genes for your own species.
The different portrait types will all work alongside each other, so you can have any number of portrait types and they'll be safe to render together without fully replacing each other. They can share a lot of things too so you do not need to re-script everything.

I'll say that again in big bold letters, the next patch will NOT contain animal portraits or any Medieval Menagerie features, just the systemic mod support to allow custom portraits.

So with that out of the way lets look at some dogs :D

1709891234909.png


The way I've set it up is that there are two new concepts, a portrait type and a portrait group, both of which are scripted in common/portrait_types.

A portrait group is something like "human", it controls what genes themselves are used for the portrait, color palettes, how to join the joints, and any other major changes that are not compatible with other setups.

Within a group there is multiple types, like male, female, boy and girl for the human group. These types are picked via age and sex, and they control more minor variations within a species and which head and torso entity to use.

So for the dogs I added during testing they are just one group with one type, if we later added bigger changes for puppies then maybe we add a second type for needing a different entity there.

By default things will be human, but you can change that via define.

We deal with the script in two ways, some types like the genes themselves define the portrait group they are for and then will be read into that group. For example here everything read into this morph_gene section will be for dogs.
eg:
Code:
morph_genes = {
    portrait_group = dog

    gene_age = {
        dog_aging_1 = {
            index = 0
            dog = {
            }
        }
    }
}
The other way we do it is by reaidng into either a list of groups or types, with the option to specify a default first. You can also copy from other entries too.
If you've seen the portrait script you'll have seen the spam of female = male, girl = male, boy = male for something that is shared across the types, now you can just specify one as "default" which has the added benefit of then working for any other portrait types too (as long as what it applies actually works still).

eg:
Code:
idle = {
    default = {
        default = { head = "idle_entry" torso = "idle_entry" }

        AI_honorable = {
            ... more script
        }
    }

    dog = {
        default = {  head = "idle" torso = "idle" }

        idle_1 = {
            animation = { head = "idle" torso = "idle" }
        }
        idle_2 = {
            animation = { head = "idle" torso = "idle_2" }
        }
        idle_3 = {
            animation = { head = "idle" torso = "idle_3" }
        }
    }
}

The barbershop and ruler designer will also work for customizing different portrait types, there is a another database to control customization rules here now in gfx/portraits/customization_rules.
This is basically moving the existing ruler designer and babrershop defines into being scripted per portrait group.
The database will error if you define rules for an unknown group or if you miss defining rules for a group.

So for humans it looks like:
Code:
human = {
    default_age = 25
    min_age_for_sexuality = 10

    modifier_overrides = {
        clothes = ruler_designer_clothes
        weight = ruler_designer_overweight
        weight = ruler_designer_underweight
        muscularity = muscular
    }

    accessories = {
        hairstyles = custom_hair
        beards = custom_beards
    }

    sex_only_genes = {
        female = { gene_bs_bust }
    }

    hidden_slider_genes = {
        gene_bs_body_type
    }

    gene_groups = {
        anatomy = {
            body = full_body
            head_neck = face
            ears = face
            face = face
            nose = face
            mouth = face
        }
        hair = {
            hairstyle = face
            beard = face
        }
    }

    color_genes = {
        hair = custom_hair
    }
    cloth_color = custom_clothes
}


The portrait editor now also lets you pick groups as well so you can see different gene impacts there.
1709892103716.png


Another change to support this is now every character stores the ethnicity their portrait was generated with, as ethnicities now define the portrait group.
When a child is born it will randomise between their parent ethnicities as the base, else it picks from a random one in the culture creating the character.
In old saves we randomise from your current culture, which is what the game effectively did before anyway, and from then we'll save it for new characters.

If you change ethnicity via effect to one with a different portrait group we randomise your new DNA. Ethnicity can be scripted for created characters via effect and in history too.

So with all of that said and done mods should now be able to add their own custom species with a lot less pain and without needing to juggle everything on one shared asset.
My parting gift to the modding community, have fun with it when it comes out :D:cool:
 
  • 34Love
  • 13Like
  • 3
  • 1Haha
Reactions:
This is insane.

Not only will it make the lifes of most fantasy TCs easier, it will allow whole new functionalities!
Hybrid cultures with varying lifespans assigned based on ethnicity....
Magic changing the ethnicity of a person - or turning them into animals....
Mixed species children with mixed features within a portrait_group, mixed species children without mixed features across portrait_groups...

This is such a major gift, thank you so much!
 
Last edited:
  • 10Like
  • 3
  • 2Love
Reactions:
Love it. Thank you a lot for all this fun these wonderful years full of strong code carrying the game like Atlas carries the world, sir!
 
  • 1Like
Reactions:
So for those of you have no seen we held a game jam end of last year, you can see more in the Black Forge Jam thread for all of the projects.

I was part of the Medieval Menagerie team and was focused on adding support for showing dogs alongside humans in the game during those three days, since I am leaving the company soon I also got a bit of extra time to finish up the system itself so that we can add the mod support required for this even though we're not actually adding the Medieval Menagerie features into the game yet.

So in the next major patch, whatever the patch alongside Roads to Power gets called, you will have access to a new system for "portrait types" which allows you to do custom portrait models and genes for your own species.
The different portrait types will all work alongside each other, so you can have any number of portrait types and they'll be safe to render together without fully replacing each other. They can share a lot of things too so you do not need to re-script everything.

I'll say that again in big bold letters, the next patch will NOT contain animal portraits or any Medieval Menagerie features, just the systemic mod support to allow custom portraits.

So with that out of the way lets look at some dogs :D

View attachment 1090837

The way I've set it up is that there are two new concepts, a portrait type and a portrait group, both of which are scripted in common/portrait_types.

A portrait group is something like "human", it controls what genes themselves are used for the portrait, color palettes, how to join the joints, and any other major changes that are not compatible with other setups.

Within a group there is multiple types, like male, female, boy and girl for the human group. These types are picked via age and sex, and they control more minor variations within a species and which head and torso entity to use.

So for the dogs I added during testing they are just one group with one type, if we later added bigger changes for puppies then maybe we add a second type for needing a different entity there.

By default things will be human, but you can change that via define.

We deal with the script in two ways, some types like the genes themselves define the portrait group they are for and then will be read into that group. For example here everything read into this morph_gene section will be for dogs.
eg:
Code:
morph_genes = {
    portrait_group = dog

    gene_age = {
        dog_aging_1 = {
            index = 0
            dog = {
            }
        }
    }
}
The other way we do it is by reaidng into either a list of groups or types, with the option to specify a default first. You can also copy from other entries too.
If you've seen the portrait script you'll have seen the spam of female = male, girl = male, boy = male for something that is shared across the types, now you can just specify one as "default" which has the added benefit of then working for any other portrait types too (as long as what it applies actually works still).

eg:
Code:
idle = {
    default = {
        default = { head = "idle_entry" torso = "idle_entry" }

        AI_honorable = {
            ... more script
        }
    }

    dog = {
        default = {  head = "idle" torso = "idle" }

        idle_1 = {
            animation = { head = "idle" torso = "idle" }
        }
        idle_2 = {
            animation = { head = "idle" torso = "idle_2" }
        }
        idle_3 = {
            animation = { head = "idle" torso = "idle_3" }
        }
    }
}

The barbershop and ruler designer will also work for customizing different portrait types, there is a another database to control customization rules here now in gfx/portraits/customization_rules.
This is basically moving the existing ruler designer and babrershop defines into being scripted per portrait group.
The database will error if you define rules for an unknown group or if you miss defining rules for a group.

So for humans it looks like:
Code:
human = {
    default_age = 25
    min_age_for_sexuality = 10

    modifier_overrides = {
        clothes = ruler_designer_clothes
        weight = ruler_designer_overweight
        weight = ruler_designer_underweight
        muscularity = muscular
    }

    accessories = {
        hairstyles = custom_hair
        beards = custom_beards
    }

    sex_only_genes = {
        female = { gene_bs_bust }
    }

    hidden_slider_genes = {
        gene_bs_body_type
    }

    gene_groups = {
        anatomy = {
            body = full_body
            head_neck = face
            ears = face
            face = face
            nose = face
            mouth = face
        }
        hair = {
            hairstyle = face
            beard = face
        }
    }

    color_genes = {
        hair = custom_hair
    }
    cloth_color = custom_clothes
}


The portrait editor now also lets you pick groups as well so you can see different gene impacts there.
View attachment 1090839

Another change to support this is now every character stores the ethnicity their portrait was generated with, as ethnicities now define the portrait group.
When a child is born it will randomise between their parent ethnicities as the base, else it picks from a random one in the culture creating the character.
In old saves we randomise from your current culture, which is what the game effectively did before anyway, and from then we'll save it for new characters.

If you change ethnicity via effect to one with a different portrait group we randomise your new DNA. Ethnicity can be scripted for created characters via effect and in history too.

So with all of that said and done mods should now be able to add their own custom species with a lot less pain and without needing to juggle everything on one shared asset.
My parting gift to the modding community, have fun with it when it comes out :D:cool:

Would it be possible for y'all to include the pet models that you made for the jam, even if they're not implemented into the game at all? Just like, in the game files somewhere. That way modders would be able to use those assets in their own mods.
 
Last edited:
  • 3
  • 1Like
  • 1
Reactions:
what do you meant NSFW ?! where is the nsfw part ?!
Mate it's just a joke, not all NSFW on the interweb thingy are actually not safe for work, some are just marked as a joke because it contains what we might consider sexy content in our particular context. I mean if you couldn't work that out for yourself then there's no point me answering really.

And if you're going to now ask me what interweb thingy means, don't bother, I won't answer,similarly don't bother telling me how you rate my joke :rolleyes:
 
Missed this at the time - only saw it after it was mentioned in a recent dev diary. Sounds brilliant. Does this have big implications for the Elder Kings 2 mod? Will they now be able to do cultural hybridisation across different species without either creating abominations or messing up the lifespan assignment?
 
Missed this at the time - only saw it after it was mentioned in a recent dev diary. Sounds brilliant. Does this have big implications for the Elder Kings 2 mod? Will they now be able to do cultural hybridisation across different species without either creating abominations or messing up the lifespan assignment?

We'll see.