Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Dark Dreams of Furiae - a new module for NWN:EE! Buy now
Attention, new and old users! Please read the new rules of conduct for the forums, and we hope you enjoy your stay!

Portraits utility for version 2.x - Updated for version 2.2

BillyYankBillyYank Member Posts: 2,769
edited May 2016 in General Modding
This is a utility that goes through a directory of portraits that start with "M" for male and "F" for female and produces the Lua code that will register these portraits so they show up in character creation under the correct gender.

EDIT: Version 2.2 introduced a new feature for modders that allows me to simplify this script greatly. You can see the details in another post by @Dee here: New Modding Feature. Now, instead of having to insert the portrait list directly into BGEE.lua, I can simply create a separate file and the game will read it directly from the override folder.

Original post
With the upgrade to 2.0 and 2.1 came a new way to add custom portraits to BG/SOD and BG2. You can still put them in the portraits folder and the appearance editor will cycle through them. Or you can put them in the override file and edit your BGEE.lua file to divide them into male and female portraits as detailed by @Dee here: On Portraits

Scroll down a little in that thread and you'll find a utility I wrote that would go through a directory full of portraits and create the LUA code to paste into your BGEE.lua for those of us who like to keep a lot of portraits around and who use a naming scheme where the files start with M or F to denote gender.

I was playing around with my portraits yesterday and decided I could go one step better on this. So here's my improved version of this utility. Instead of creating a text file that you can open and copy & paste the contents from. This version will insert the code directly into your BGEE.lua file for you. And, if you add or delete some portraits, just run it again and it will bring the BGEE.lua file up to date.

How to use

This is a PowerShell script, so it only works on Window 7 or later. If you have Windows XP, you can download PowerShell from Microsoft and install it.

If you've never run PowerShell scripts before you need to do this:
1. Find Windows PowerShell in your Start menu.
2. Right click on it and choose Run as Administrator.

3. At the command prompt type this:
PS C:\WINDOWS\system32> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
4. Type Y for Yes and hit enter.
PS C:\WINDOWS\system32> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to
the security risks described in the about_Execution_Policies help topic at Do
you want to change the execution policy?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): y
Close the PowerShell window. You only need to do this once and you'll be able to run scripts forever.

You can put your portraits in the override or portraits folder. Download the zip attached to this post and unzip the Register-Portraits.ps1 file into the folder with your portraits. The script assumes that it is in the same folder as the portraits.

Double-click on the Register-Portraits file to bring up the PowerShell ISE and click the green "Play" button on the toolbar.

This will produce a file named M_MyPort.lua. If you did this in the override folder you're done. If you did this in the portraits folder, move M_MyPort.lua to the override folder and you're done.

And that's it. Any time you need to update your portraits list, double-click the script, hit play, and move the Lua file to override if needed.

The script

$outfile = ".\M_MyPort.lua"

"function addPortrait(name, gender)" | Out-File -FilePath $outfile -Encoding ascii
"`ttable.insert(portraits, {name, gender})" | Out-File -FilePath $outfile -Append -Encoding ascii
"end" | Out-File -FilePath $outfile -Append -Encoding ascii

$females = Get-ChildItem | Where-Object Name -Like "F*L.bmp"
$males = Get-ChildItem | Where-Object Name -Like "M*L.bmp"

foreach ($lady in $females)
    $length = ($lady.BaseName).Length - 1
    $charname = ($lady.BaseName).SubString(0,$length)

    $outstring = "addPortrait('" + $charname + "', 2)"
    $outstring | Out-File -FilePath $outfile -Append -Encoding ascii

foreach ($dude in $males)
    $length = ($dude.BaseName).Length - 1
    $charname = ($dude.BaseName).SubString(0,$length)

    $outstring = "addPortrait('" + $charname + "', 1)"
    $outstring | Out-File -FilePath $outfile -Append -Encoding ascii


Line 1 has the filename of the output file M_MyPort.lua. You can change it in the script, or change the filename after running the script, but be aware that the file must be no longer than eight characters before the dot and the first two must be M_. So you only have six letters to play with in the file name.

Lines 7 & 8 of the script contain the file pattern for male and female:
$females = Get-ChildItem | Where-Object Name -Like "F*L.bmp"
$males = Get-ChildItem | Where-Object Name -Like "M*L.bmp"
If you use a different naming scheme you can change those lines. For example, if you use B & G for boy and girl instead of M & F, just edit those lines to:
$females = Get-ChildItem | Where-Object Name -Like "G*L.bmp"
$males = Get-ChildItem | Where-Object Name -Like "B*L.bmp"
If some of your portraits are M & F and some are B & G, then we can get a little more fancy and change to:
$females = Get-ChildItem | Where-Object {($_.Name -Like "F*L.bmp") -or ($_.Name -Like "G*L.bmp")}
$males = Get-ChildItem | Where-Object {($_.Name -Like "M*L.bmp") -or ($_.Name -Like "B*L.bmp")}
Try it out and let me know what you think. If anyone wants to translate it into a bash script for Mac or Linux, feel free.

Post edited by BillyYank on


  • TressetTresset Member, Moderator Posts: 8,205
    I moved this to the mod section. People usually look for things like this there.

  • BillyYankBillyYank Member Posts: 2,769
    I've figured out an easier way to run this script so you don't have to bother with the command line. Once you've got your portraits, bgee.lua and the script in your override folder, go to override and right-click on the script. Choose Open.

    This should pull up the PowerShell ISE, the script editor/debugger for Powershell. The top half of the window shows the script, the bottom half shows a command line already pointing to the override folder. Click the green Play button up top.

    That's it. No messing with changing directories or anything.

  • BillyYankBillyYank Member Posts: 2,769
    One thing @Dee mentioned in his post about the new feature is that those who produce portrait packs can create a M_* file and package it up with their portraits. So I'd thought I'd call in those who've made large portrait packs to take a look at this utility.


    I know there are more people out there with portrait packs, but the search on Vanilla forums truly sucks. If anyone remembers any other portrait pack makers, please give them a shout-out.

  • inethineth Member Posts: 623
    edited May 2016
    Where can I find details on this feature?

    I take it I would, for example, package a file called M_viking.lua together with my "Vikings" portrait pack - correct?
    And then users would simply extract it into their portraits folder together with the actual portrait files?
    (Or does it have to be the override folder?)
    (And I imagine the filename has to be 8 characters or less, as usual?)

  • BillyYankBillyYank Member Posts: 2,769
    Correct, the .lua file would need to be in override, but the portraits can be in override or portraits. The details are in the post made by Dee that I link in the OP. The same details are in the official release notes.
    Release Notes

  • smeagolheartsmeagolheart Member Posts: 7,963
    The game will only recognize one at a time right? If you make m_viking1 & m_Viking2 each with different portraits when you open the game you will only see one of those and nothing else including no vanilla portraits, right?

  • BillyYankBillyYank Member Posts: 2,769
    No, my utility uses "table.insert" to add the portraits to the existing table. In his example in the UI modding thread, Dee talks about using "portraits={ ..." which will create a new table called "portraits" that overwrites the original table.

    And you can't use m_viking1, because that's 9 letters.

  • DeeDee Member Posts: 10,447
    @BillyYank is correct. If you want to overwrite the default portrait list, you'll want a file with a modified portraits={} table in it. (Right now I've got one that just has the new player portraits from SoD, because I like them that much.)

  • DeeDee Member Posts: 10,447
    An additional note, from the programmers:

    If you're making a portrait pack (or installing one) with an M_ file containing (or modifying) the portraits table, you'll want to put it all in your override folder. If you're just using a custom portrait as an end-user, you'll want it in your portraits folder, following the appropriate naming convention (*L.bmp and *S.bmp).

  • smeagolheartsmeagolheart Member Posts: 7,963
    BillyYank said:

    No, my utility uses "table.insert" to add the portraits to the existing table. In his example in the UI modding thread, Dee talks about using "portraits={ ..." which will create a new table called "portraits" that overwrites the original table.

    And you can't use m_viking1, because that's 9 letters.

    The name was not meant literally, but as an example of a group of portraits.

    That is good that they can be added though that way without overwriting.

  • BillyYankBillyYank Member Posts: 2,769
    When choosing where to put the portraits, remember there's still a small bug with portraits placed in the portraits folder and registered in the table. In that case, using the left button to look through the portrait causes each one to be shown twice. So I keep my collection in the override.

  • JHatredJHatred Member Posts: 4
    Does this setup still work; with SoD perhaps? I've followed the directions to a T and tried using both the override folder and the portraits folder (the 2 different ways in the first post) and I am having no luck at all getting it to work.

  • BillyYankBillyYank Member Posts: 2,769
    What exactly isn't working? Is it producing the M_MyPort.lua file? Which override are you using, the one in Documents or the one in the game directory?

  • reznormsreznorms Member Posts: 2
    edited June 2019
    This perl script works on Linux (and I guess Mac too) where powershell isn't available. The only difference from the powershell script is that it outputs two files, one for males one for females portraits. Works on v2.5.
    #!/usr/bin/perl -w
    use strict;
    use warnings;
    my $mpdbfile = 'M_PortM.lua';
    my $fpdbfile = 'M_PortF.lua';
    my $m = "MP";
    my $f = "FP";
    open (my $mpdb, '>', $mpdbfile) or die 'Unable to write file: $';
    print {$mpdb} "function addPortrait(name, gender)" . "\n";
    print {$mpdb} "\t" . "table.insert(portraits, {name, gender})" . "\n";
    print {$mpdb} "end" . "\n";
    open (my $fpdb, '>', $fpdbfile) or die 'Unable to write file: $';
    print {$fpdb} "function addPortrait(name, gender)" . "\n";
    print {$fpdb} "\t" . "table.insert(portraits, {name, gender})" . "\n";
    print {$fpdb} "end" . "\n";
    my @files = sort(glob('*L.bmp'));
    foreach my $bmp (@files) {
        (my $portrait = $bmp) =~ s/L\.[^.]+$//;
        if (index($portrait, $m) != -1) {
            print {$mpdb} "addPortrait('" . $portrait . "', " . "1"  . ")\n";
        if (index($portrait, $f) != -1) {
            print {$fpdb} "addPortrait('" . $portrait . "', " . "2"  . ")\n";
    close $mpdb;
    close $fpdb;

    It will recognize "MP01L.bmp", "MP01M.bmp" and "MP01S.bmp" as "MP01" and register it as a male portrait. Same for females but they start with FP. Just change these two lines if you are using a different naming scheme.
    my $m = "MP";
    my $f = "FP";

    Then save it as "" or whatever you want in the same folder as your portraits and run it, move the two lua files in the override folder if you keep the portraits in their own folder.

  • reznormsreznorms Member Posts: 2
    ALIEN wrote: »

    Ah, didn't know that. Oh well, perl is already installed by default so no need to install more stuff.

Sign In or Register to comment.