lushen124 / Universal-FE-Randomizer

Properly universal this time.
MIT License
98 stars 28 forks source link

GBA Character Shuffling - Automatically collect / parse pallet from picture #426

Open Geeene opened 1 year ago

Geeene commented 1 year ago

Small improvement to the Character Shuffling logic to make the paletteString optional. Obviously we still need the palette, so there are two ways to get it:

  1. If it's an indexed PNG, then the colors can be parsed from the PLTE Chunk of the image. (Same thing could probably be done for other formats aswell)
  2. If it's not a PNG or not an indexed PNG, we can iterate trough the image and grab all the unique colors

Both solutions require that there is <16 colors in the image and will sort the background color to the front as GBAFE requires these two things.

There are actually some characters that have less than 16 colors in their portrait (Tethys for example), I made sure this works aswell, and provided a JUnit Test for this.

(FE6 pictures are re-exported using Usenti to make them into indexed pngs, which also has the benefit of cutting size by more than half for each)

Currently I have set it to only do something if the paletteString is not set, but could make sense to always use this and deprecate the paletteString field, as if someone has a wrong paletteString in an entry, this wouldn't really help

Rationale: Someone from reddit tried using the feature to import some custom characters into the game, and had some trouble with it. While helping it was obvious tha the palettes weren't correct, so I thought it could be convenient to add this functionality, so that a user creating custom files doesn't have to care for by hand finding the palette String for each portrait.

lushen124 commented 1 year ago

412 has an approach for handling battle palettes which is to make it explicit from the JSON. I think it's possible to pull from the portrait as well, since that's what I did manually, but how do you know which colors map to which part of the palette? I don't know if the order of colors are consistent in any portraits to let you infer which colors are hair colors vs primary/secondary colors.

Geeene commented 1 year ago

I don't know if colors are very consistent either, would have to check that, but even if not I do have an idea of how to have an educated guess what colors could be used for the Battle palettes:

Ofcourse there will be edge cases that don't work but the idea would be like this: Take this Syrene for example (she would be a more difficult case) grafik

we know from the configuration where here Mouth chunks are: grafik

What we could do for many cases is that we take each color in this chunk and ignore it (in the following temenostrated by making them the same color as the background):

grafik grafik grafik grafik grafik

After 5 replacements in this case, we have excluded anything that is not Armor / hair color

Additionally, if you go through the image top to bottom, left to right, pretty much always the first color that is not transparent you stumble on would be the outline color: grafik

Additionally ignore that one: grafik

Now it would be easy as to count all the colors, sort by amount used, each in the top half and bottom half. Using upto 3 most used colors in the top half for the hair color and top 3 in the bottom for armor using top 3 for Hair, and the colors in the bottom half upto 3 for Armor

Cases that probably or certainly mess with this logic: Hats 2023-10-17 19_43_27-Window

Beards 2023-10-17 19_35_56-Window

Bald grafik

Characters with Hair in the mouth frames (like Syrene too): grafik

In general manually chosen ones will be better, but having (something like) this as a default incase none are manually defined it could be worth while maybe?

Geeene commented 1 year ago

Alternatively, do it like this:

Grab the first non transparent color from the image, (this is again the border so we ignore it) Then grab the next 3-4 unique colors that appear for the first time and consider them the hair colors. Then do the same thing for the other colors except only with a limited number of chunks such as these: grafik

This could also have decent results while not running into some of the above issues (except hats)

lushen124 commented 8 months ago

It's an interesting idea, and could be used for a fallback if no colors are specified, but I feel it's best to allow the JSON to also carry colors in case the user wants to specifically set their colors. I feel heuristic approaches like this may not apply that consistently, especially in user-created portraits.

Geeene commented 8 months ago

It's an interesting idea, and could be used for a fallback if no colors are specified, but I feel it's best to allow the JSON to also carry colors in case the user wants to specifically set their colors. I feel heuristic approaches like this may not apply that consistently, especially in user-created portraits.

I fully agree, colors chosen by hand will obviously look better ^^ Was mainly an idea of how it could work, haven't actually tried it yet either