makrohn / Universal-LPC-spritesheet

An attempt to merge most character assets generated by the Liberated Pixel Cup into a single .xcf, where they can be mixed and matched.
330 stars 171 forks source link

Make All Hairstyles Work for Both Genders #53

Closed jrconway3 closed 8 years ago

jrconway3 commented 10 years ago

As mentioned in this issue in the Character Generator: https://github.com/Gaurav0/Universal-LPC-Spritesheet-Character-Generator/issues/5

Technically the issue doesn't apply to the generator, though, it applies to the Universal Spritesheet. I agree with the poster of the other issue; this is a problem and hairstyles don't need to be split between gender, but there are slight differences in positioning between the male and female sprites (in fact, this may be the problem; why is there such a significant difference is the position of the male and female sprites?)

Just posting this here for now as a future issue to work on. Once I clear up some time I will be getting back to working on some updates on this later.

makrohn commented 10 years ago

If I recall correctly, the major challenge is that if you line up all the heads across genders, then none of the feet line up, and vice-versa. The tack I would take would be the same as I took towards the helmets. They're exactly the same for each gender, but aligned differently for head positioning.

jrconway3 commented 10 years ago

If the heads and feet do not both line up for certain tiles, there's not much we can do about it, so the only option is to reposition them. One option I may have to do is find a more efficient way of creating recolors quickly, otherwise minor changes to certain things will take a long time to do all the recolors for. Adding the palette XCF files certainly helped quite a bit.

Anyway, thanks for the notification. Again, not planning on doing this yet, just wanted to archive this for when I can get around to it.

cwebber commented 10 years ago

Heya! I'm one of the lead organizers of the original LPC (and the one who kicked the whole thing off).

Just chiming in to say that I'm happy to see this being seriously considered; full gender equality amongst characters is something I've always wanted to see in Liberated Pixel Cup assets, and that's something I've been really happy to see the Universal LPC Spritesheet working on.

I wonder if a nice way to do it might to be to have some script that "generates" the offsets from one gender to the other? if it's just a matter of top/bottom positioning, maybe having a script that takes certain marked assets and does some sort of movement up or down to have them fit(?). (I think that would maybe work, and is maybe the easiest solution other than maybe changing both bases to line up a bit better... I suspect that would require such major refactoring that it isn't likely to happen, but I think it would be the ideal route in a sense, because it wouldn't require reconfiguring things so much after the fact.)

By the way, it's a bit off topic, but Aeva, who participated in the other bug, was also one of the organizers of the Liberated Pixel Cup. Something we always wanted to see but never happened would be to have a more androgynously gendered option as well. (Actually, I think the two of us would have preferred a gender neutral base and build gendering on top of that base in the assets and etc, but we were kind of voted out there.) That's neither here nor there I guess.

Thanks for all your hard work on the Universal LPC Spritesheet! I really admire the project!

jrconway3 commented 10 years ago

An androgynous base is something I was thinking of too, I have a male character that has a very thin build, so the default male sprites just would not work for this. I'm not sure how well I could pull it off, though.

UPDATE:

To further clarify, I'm going to look into the possibility of doing an automatic recolor script first. I'm not sure how easy it would be to automatically offset the sprites, though. I think that would be far more difficult than simply doing an auto recolor script based on specific colors and just manually do the gender offsets.

My thought is, a basic command-line operation that checks a palette.json file I create, runs through all the default files, checks if the exact palette exists in each folder and simply runs through and saves each one into the folder per hairstyle. If I can do something like this, that would save a load of time. It would also give me an excuse to start working with a programming language I haven't tried yet but want to get into (or just use Java, which I know but barely use).

Until I get some work off my plate, though, I can't do anything. So this would have to wait a bit. I got the idea from a script in RPG Maker XP for a Fire Emblem game that does palette swaps based on set values (it actually uses a series of individual pixel palettes on the sprites, though). I'd just need to do a bit of research on scripts that can select colors in an image and replace them.

This is something I'll look into when I can.

Aeva commented 10 years ago

I'm a little confused - is this a bug where all of the female sprites have their head positioned a fixed number of pixels lower than the male counterparts, or is it a situation in which sometimes they line up and some times they don't?

Somewhat off topic: Part of my interest in this is that over the last week I wrote a javascript parser for a file format that facilitates sprite animation (you define the crop coordinates etc within the sprite sheet, and keyframes, and it lets you swap out the sprite sheets and it builds the animations automatically). You can see the results in action (granted with proprietary sprites because this format comes from a game I used to play) http://pirateradiotheater.org/files/m.grl/demos/03_animations/

I'm interested in building a set of these animation files for LPC assets, but if the offsets are different per gender, this isn't going to be usable at all :/

Also, I'm not sure what good having an androgynous base now would do. It would have been a better starting point so as to avoid this entire problem of having incompatible assets, instead of having to do a ton of book keeping.

jrconway3 commented 10 years ago

Its not a bug at all, its just the way the original spriteset was. The male sprites are bulkier than the female ones (gender stereotype :P). This is all based on the original LPC spritesheet and additional enhancements added to it; the Universal LPC Spritesheet is a way to put all of the sprites from the LPC into one full set that can easily be used.

Personally, I like the idea of have one androgynous set myself, but this is what we've got. I'd prefer the current "male" set to be an androgynous "heavyweight" character instead, because its a bit too bulky for my tastes, personally. I'd only have a few characters that'd be bulky, both male and female.

Here, I exported the male and female sprites so they overlap with one another and you can see the differences:

lpc-male-female

At the top and for most of the down-facing sprites, they match up perfectly. But there's a few differences in the swing and walk animations. According to Makrohn, the feet are all lined up fine, and I certainly don't see anything wrong with the feet. But the rest start to get out of line.

As for making an androgynous set now, I think it'd be very useful. It could be based entirely on the female set so any female sprites line up with the androgynous one. We could keep the male sprites as an extra "bulky" sprite instead of simply making it male.

Might be a bit of work, unfortunately... but it'd be easier than creating a new set from scratch.

Off topic: In regards to your link, aren't those based on Graal Online? Which, in turn, if you look at them, they're clearly ripped and edited directly out of A Link to the Past. They changed the base sprites enough to not exactly resemble Link, but its quite obvious if you look at the animations and everything that Graal Online's sprites and assets are from A Link to the Past. I know next-to-nothing about Graal Online, I just found it once on my iPhone and started playing it briefly before quitting.

Aeva commented 10 years ago

Well, it IS a bug, just its a bug in the original sprite sheets, and I guess is just as much my fault as anybody else who was involved in putting together the base assets. In the demo game, I was lazy about how I programmed the character rendering, and didn't notice :P

That overlay is helpful for illustrating the problem. I think what I'm going to do for producing the gani files is edit the heads out of the body sprites and put them on their own sprite sheet, which will also fix the offsetting problem. I'm concerned about the hands, however, since they also don't line up. I guess a similar approach to the head is probably what I'll have to do if I want to use LPC sprites, but I think that will make one of the gender's posture look odd :P I'll probably end up doing this for my project - the female positions for things are going to be the base for generating the ganis, and the male sprites may have some funky posture as a result, but I'm fine with that :)

I think I agree with what you're proposing about the sprite sheets for an androgynous base, and I really appreciate the proposal of building off the female base (I think its better drawn than the male base, personally). I think before making more bodies, there needs to be a template that is probably just a bitmask showing the canonical positions of the head and the hands, of which accessories can assume the contours thereof. I think you and I are working in similar directions with our respective projects.

Note on the assets in the linked animation demo - those are totally from Graal. Graal started actually as Zelda Online, some time back in the 90's, and they used game assets directly ripped from the rom. They got a cease and desist order at some point, and had to remove all of the copyrighted materials. I suspect someone probably just drew the bodies with a mouse in mspaint or something cheesy like that in a hurry, and then the placeholder probably just stuck. The sprite sheets for various things are still laid out in the same order.

The project was to write a javascript module that could read and render .gani files from graal - for now I just have the game data plugged into the demo for debugging, but I want to remove them as soon as possible, and replace it with LPC assets.

joewhite commented 10 years ago

I've put together a script that will generate spritesheets for male and female versions of all the hairstyles. You give it a few input images -- at least four (one for each direction), plus optional overrides for individual frames (typically used for the "hurt" animation) -- and it automatically generates male and female spritesheets. It knows the position of the head in each frame and positions the hair images accordingly. It also automatically applies cutouts as needed, for things like the bow arm reaching in front of the hair, and for hair that's slung over the shoulder (and therefore behind the torso, but in front of the far arm in east- and west-facing poses).

This started out as a proof of concept, but since I've got it generating all the hairstyles for both male and female, I think I've successfully proven the concept. It's not ready for a pull request yet -- right now it's just generating the base-color (white/purple) image, and I plan to have it generate all the recolors too, as well as the hair shadows -- but if anyone wants to take a look and offer feedback, it's at https://github.com/joewhite/Universal-LPC-spritesheet/tree/universal-hair. Feel free to open issues over on my fork. I've tested the script on Windows but not on anything Unix-like, but the way I'm doing things I think it'll still work. I've done a lot of spot-checking of the spritesheets it generates, but feel free to review the resulting spritesheets and open issues for anything that looks off.

There's no documentation yet (I'll work on that), but if you want to run the script, you'll need Ruby, and you'll need the ImageMagick command-line tools to be available on your path. You also need the Rake rubygem (gem install rake). Then you can just type rake and it will build any hair spritesheets that are out of date. The source images are under _build/hair.

jrconway3 commented 10 years ago

Alright, I'll install rake. I was planning on doing my own hair recolor script... well, I was planning to do it for a while now, I've just been really busy. Now I'm finally starting to clear up my schedule, so I was going to do some research on the subject and see if I could do it in Python (I'm sure there's a way) so that I could get some experience working with Python.

Basically, the idea behind a recolor script is that you have a json file or something similar, the script checks the json, recolors the base color sprites into the new color scheme from a preset palette, then saves all the files (named the color of said palette). The reason for JSON is to auto-update it.

The recolor script would then also be usable on pretty much any other type of sprite as well, just use a different JSON file with separate data entered in. This sounds pretty good, though. I really did want to do it myself just so I could get experience in a different programming language, but I've been having trouble getting other things taken care of.

So yeah, this sounds very useful and helpful. If my time clears up I may be able to help as well. I still think we should have a separate recolor script, though, because there are other things that could use quick auto-recolors other than just hair.

joewhite commented 10 years ago

Recolors are pretty straightforward using the ImageMagick command line, once you know its quirks. I just summed it up in a blog post, including the trick to leave out the embedded timestamp (important when you'll check the generated file into version control).

I had been thinking of using a bunch of 6x1 image files to represent the palettes -- that way it's visual, easy to see, easy to edit in any image editor. But I like your idea of JSON; it would be much simpler to implement. And easy to reuse in something like a JavaScript canvas script, if it came to that.

I agree that a general recolor script would be useful, but I think hair might have a wrinkle or two that might merit some customization. For one, hair has one semitransparent color (#9C59919C) that needs to be explicitly specified on the ImageMagick command line, but it will always have the same replacement as #9C5991 (apart from the alpha), so it would make sense to specify it once in the JSON and then special-case the command line to repeat it with the alpha. For another, some hairstyles have shadows, which get output as a separate set of files based on body-color palettes instead of hair-color palettes. I'd love to be able to put a shadow color in the same input files used for the rest of the hair, and then have the script automatically generate the shadow files as well as the hair files. This would really need to be special-cased so it only generated the shadow files if the shadow color was present in the input files.

Anyway. I'm definitely open to seeing any or all of this ported to Python, if you want. I used Ruby because Rake has built-in dependency tracking, so when you modify some input files, it will only regenerate the output files that need it. But there's no reason the scripts couldn't be Python. I'd prefer to stick with one language so users don't have to install all kinds of crap just to add new hairstyles, but I'd be fine with that language being Python -- I could stand to learn it a little better. I'll probably stick with Ruby for now, but feel free to try to port the stuff in _build (I've got a couple of helper scripts in there as well, to help take existing spritesheets and extract individual frames out of them), and let me know if you have any questions or if you come up with something good.

Gaurav0 commented 10 years ago

Hi all,

This is pretty awesome.

I don't know any Ruby, and I'm really a JavaScript expert. If you really want everything in one language, my vote would be to use JavaScript and grunt. :)

That said, I'm okay with learning some Ruby.

Also, if anyone has any ideas on how to go about autogenerating index.html in the online character generator, let me know.

Gaurav

jrconway3 commented 10 years ago

The only reason I even considered using Python is so I could learn Python. I had also considered Ruby and Javascript, too.

Joe,

I think its fine to include the recolors with the hairstyles. I'm not sure how you can auto do the shadows, though. Also, we should still create a separate recolor script as well for other features. Again, I can't work on anything just yet, but I've almost cleaned off my plate and can start getting to work on some things this weekend.

As for using JSON vs. an image, why not both? Have an option for JSON if desired, otherwise use an image palette? Overall I do think that JSON would be easier in general, though.

Guarav,

Not sure about how to autogen index.html at this time. Also, Ruby is incredibly easy, if you know Javascript you should be able to pick up Ruby as well. I haven't done much raw Ruby, but I have worked on Ruby in RPG Maker XP so I know all the syntaxes and everything.

In fact, that's one of the things I need to do first before I can get to working on a recolor script; I need to start developing a website in Ruby on Rails so I can get some Rails experience. I planned to do that this past weekend, then it got pushed to mid-week this week, so the recolor script naturally got pushed back as well. :P

Once the recolor script is done, that'll make it ten times easier to create new hairstyles, and if this script to auto-position hairstyles works well, that'll make it even easier. My only concern is potential hairstyles that may extend further up on the character sheet than traditional ones that are just above the top of the head (about 1 pixel above the head if I remember right).

Jaidyn

pennomi commented 10 years ago

Any chance this same work could be used to get the LPC Character Expressions on all animations as well?

jrconway3 commented 10 years ago

Hmm... perhaps... I'm not sure, I didn't even know there were LPC Character Expressions so thanks for pointing that out. There's a number of existing sprite extensions still in the XCF file that still need to be added as well. Although, not all of those "expressions" appear to actually be expressions, some are facial changes, but its still great and is definitely useful.

EDIT: Oh, I see, those LPC Character Expressions ARE the ones in the XCF. I've been slowly working on lining up a lot of those things in the file. Does that also include the pointed ears? Because ever since I lined up the pointed ears I've been getting credited for creating the pointed ears even though I just repositioned them in the file. -_-

EDIT 2: For further clarification, positioning all the individual elements isn't the hard part. The hard part is doing the recolors. Once again, if I can get a quick recolor script created then I can easily line up all the items and recolor them to all variants. If I have to do the recolors manually each extension (in this case the expressions) takes a couple of hours. Although the ability to auto-position them would also be helpful, too.

pennomi commented 10 years ago

Yeah, I think I was mostly referring to the auto-positioning. There will still be additional tweaks that need to be made of course, but that might be the majority of the battle.

If we can get a good process for doing stuff like that I'd be tempted to make a lot more... right now those facial changes are somewhat limited.

jrconway3 commented 10 years ago

That's my theory in hairstyles. If there's one fairly good thing I think I've done sprite-wise in the past, I'd say its designing decent hairstyles. If I can get a nice way of easily recoloring and perhaps positioning, that would make things way, way easier to handle. Then I can just created one four-way directional hairstyle, run the process and it automatically adds the hair to all directions.

Once I get some time I'll look into seeing if I can do anything more with Joe White's script. If I can figure out how it works (shouldn't be difficult) I could make new sets for positioning for other things such as facial expressions, body changes (ears, nose), and accessories; things which don't change from frame to frame (obviously that would not work for clothes; clothes would be next-to-impossible to auto).

joewhite commented 10 years ago

Re hairstyles that extend farther upward: no problem; I already had to deal with that for the existing hairstyles. What I settled on was making the input images 128x128, where pixel (64, 64) corresponds to the crown of the head (the leftmost pixel out of the first row of pixels at the top of the head). Then I extract the appropriate 64x64 chunk for each animation frame. That should allow plenty of room for mohawks or spiky "hero hair" (except in the last frame of the "hurt" animation, where the crown of the head is pretty close to the bottom of the frame). It should also extend gracefully to anything you would position relative to the head.

I think facial expressions would work great with this, both for positioning and (once it's in place) recoloring for all the different skin tones. The current, relative-to-the-crown-of-the-head positioning would be perfect for all the frames where the eyes are in the same place relative to the crown, which probably means everything except frames 2-5 of the "hurt" animation (and you can provide override images for those frames). For expressions that involve the eyes, you might also want to override individual frames for the "spellcast" eye-closing animation. You can override multiple frames with a single image file (e.g. s-spellcast1-spellcast4.png would override both the eyes-half-closed frames).

jrconway3 commented 10 years ago

I'm really dying right now. Dying to get back into working on doing game dev, anyway. So I'm going to try and pull your branch over to my fork (if I can figure out how) and start working on that recolor script tonight. ^^

I also need to figure out how to get Tiled working with RPG-JS... :P

joewhite commented 10 years ago

I've realized that I screwed up earlier in my branch. I started out by making all the original images use a consistent palette; the male hair colors were just slightly different than the female, and I wanted them all to be the same so they could use the same color maps. Some of the female images had #FFFFFF as a light color, and I thought those were mistakes and changed them to #FAF8F9; the visual distinction wasn't even noticeable. Then I got to the recolors and realized that that extra color did matter; in some of the recolors (especially the darker ones) it's a big contrast from the next darker color. So I've been making notes on how to go back and fix that mistake.

I'm planning to rebase my branch, to fix the commits that originally flattened the colors. But that would rewrite history, which could be an issue if you're working in a fork. Are you planning to modify any of the existing image and/or code files, or just add new files? If you're adding new (and probably even if you're editing code files), then it shouldn't be a problem for you to interactive rebase onto my new history. I'll at least plan to make it a new branch, and we can figure it out from there.

As far as recoloring goes, I've already got a script that will extract the palettes from the original images and generate something that's easily editable into JSON. Once I've fixed my original mistake with the colors, it should be easy to generate all the color mappings. Then it's a simple matter of using ImageMagick to search-and-replace colors.

Gaurav0 commented 10 years ago

I personally never, ever, rewrite history. Just make new commits fixing your mistakes.

Gaurav

On Friday, March 21, 2014 8:22 AM, Joe White notifications@github.com wrote:

I've realized that I screwed up earlier in my branch. I started out by making all the original images use a consistent palette; the male hair colors were just slightly different than the female, and I wanted them all to be the same so they could use the same color maps. Some of the female images had #FFFFFF as a light color, and I thought those were mistakes and changed them to #FAF8F9; the visual distinction wasn't even noticeable. Then I got to the recolors and realized that that extra color did matter; in some of the recolors (especially the darker ones) it's a big contrast from the next darker color. So I've been making notes on how to go back and fix that mistake. I'm planning to rebase my branch, to fix the commits that originally flattened the colors. But that would rewrite history, which could be an issue if you're working in a fork. Are you planning to modify any of the existing image and/or code files, or just add new files? If you're adding new (and probably even if you're editing code files), then it shouldn't be a problem for you to interactive rebase onto my new history. I'll at least plan to make it a new branch, and we can figure it out from there. As far as recoloring goes, I've already got a script that will extract the palettes from the original images and generate something that's easily editable into JSON. Once I've fixed my original mistake with the colors, it should be easy to generate all the color mappings. Then it's a simple matter of using ImageMagick to search-and-replace colors. — Reply to this email directly or view it on GitHub.

jrconway3 commented 10 years ago

I only rewrite history if I haven't committed anything yet or I have so many issues with a conflict so I just go and delete a branch I have created and recreate the branch, but that's few and far between.

Yeah, I figured it'd be easy to search-and-replace colors. Do you have that part committed? What I could do is take what you've got and just work on tweaking the settings slightly, then run it a few times to see how it looks on its own. Ideally of course we'd also want to import it during the process to auto position hairstyles and after doing the auto position, run the recolor on top of it.

I won't be able to start working on it until tonight probably (will be driving most of the afternoon). Could you create an entirely new Github repo just for these scripts so I could access it and fork that instead? I do think that this should be a separate repo anyway simply because this script could be applicable in more circumstances, and even then, this repo is specifically for the images themselves and it'd be more beneficial to have the script as a separate repo.

jrconway3 commented 10 years ago

Oh, and Joe, don't feel obligated to rush out and get that code out there. It'd be nice if I could help out on it, but if you find it easier to do it yourself, that's fine, too. I can just wait for you to finish before getting back to work on this project.

jrconway3 commented 10 years ago

Joe,

I pulled your repo now anyway and I think I see what you mean. One thing I noticed a while back is -that there's a "very" light color on some hairstyles... but unfortunately, its not on all of them. For the base hairstyle, its #FFFFFF. The SECOND lightest color is #FAF8F9.

This is a major issue I noticed before, I think I'm going to jump through the various sprites and see if I can find which ones have the lightest color and fix it on the ones that are messed up. I'm not sure if you've started doing this or not, but if you haven't, I'm going to work on fixing the female ones first.

Since you've got an auto-position script, thankfully, I only have to worry about one set at this time. I'll then try running your script after that and see how it works. I'll probably only manage to fix this lightest color tonight, but if I can fix it up I'll go and push it up to my repo and create a pull request on yours (in the universal-hair branch of course).

EDIT: I'm separating all the unique hairstyles into "base" files so I can review all of them together but just each individual part. It appears to me that the problem is actually that the lightest two colors are both #FAF8F9, but they're supposed to be #FAF8F9 (lightest) and #E8CFE4 (second lightest). Ponytail2 helped me to figure this one out; this one appears to be the correct one.

drinfernoo commented 8 years ago

Is this still a thing?

jrconway3 commented 8 years ago

I think it was basically done. It may not have gotten merged, though. I was working heavily on managing sprites a couple years ago, but then I just realized I wasn't ready for the sprite portion, I still had tons of planning to do for my own projects, and I also got extremely busy with other work that I was actually getting paid for, so everything got put on the backburner.

It might even be updated over in my fork. I'll look things over and get back to you, but I can't guarantee I'll have it done right away, I'm still extremely busy.

jrconway3 commented 8 years ago

Yeah, this was implemented and is actually live. I don't know if its in the generator yet, but there is a new generator created by someone over at OGA. This issue should've been closed but never did.