SheerSt / pokewilds

PokeWilds - A Gen 2 Game/Engine using libGDX
2.65k stars 204 forks source link

Ripping attack animations #9

Open 1iminal opened 2 years ago

1iminal commented 2 years ago

Hi, first of all thank you for working on this project. In readme you mentioned that ripping attack animations is top priority task and that you will reveal the procedure if corresponding issue is created. I'd like to learn the details and see what I can do.

// UPD

List of moves |Hex|Move|Player|Enemy| |---|---|---|---| |47|Absorb|+|+| |33|Acid|+|+| |97|Acid Armor||| |B1|Aeroblast||| |85|Amnesia|+|+| |F6|Ancientpower|+|+| |D5|Attract|+|+| |3E|Aurora Beam|+|+| |8C|Barrage|+|+| |70|Barrier|+|+| |E2|Baton Pass||| |FB|Beat Up||| |BB|Belly Drum||| |75|Bide||| |14|Bind||| |2C|Bite|+|+| |3B|Blizzard|+|+| |22|Body Slam|+|+| |7D|Bone Club|+|+| |C6|Bone Rush||| |9B|Bonemerang||| |91|Bubble|+|+| |3D|Bubblebeam|+|+| |CC|Charm|+|+| |80|Clamp|+|+| |D2|Comet Chop||| |04|Comet Punch||| |6D|Confuse Ray|+|+| |5D|Constrict||| |A0|Conversion||| |B0|Conversion 2||| |B2|Cotton Spore||| |44|Counter||| |98|Crabhammer||| |EE|Cross Chop|+|+| |F2|Crunch|+|+| |AE|Curse|+|+| |0F|Cut|+|+| |B6|Defend||| |6F|Defense Curl|+|+| |C2|Destiny Bond||| |C5|Detect||| |5B|Dig|+|+| |32|Disable|+|+| |92|Dizzy Punch||| |26|Double Edge|+|+| |18|Double Kick|+|+| |03|Double Slap|+|+| |68|Double Team|+|+| |52|Dragon Rage|+|+| |E1|DragonBreath|+|+| |8A|Dream Eater||| |41|Drill Peck|+|+| |DF|Dynamic Punch|+|+| |59|Earthquake|+|+| |79|Egg Bomb|+|+| |34|Ember|+|+| |E3|Encore||| |CB|Endure||| |99|Explosion||| |F5|Extreme Speed|+|+| |B9|Faint Attack|+|+| |CE|False Swipe|+|+| |7E|Fire Blast|+|+| |07|Fire Punch|+|+| |53|Fire Spin|+|+| |5A|Fissure||| |AF|Flail||| |AC|Flame Wheel|+|+| |35|Flamethrower|+|+| |94|Flash|+|+| |13|Fly|+|+| |74|Focus Energy||| |C1|Foresight||| |DA|Frustration||| |1F|Fury Attack||| |9A|Fury Swipes|+|+| |F8|Future Sight||| |CA|Giga Drain|+|+| |89|Glare|+|+| |2D|Growl|+|+| |4A|Growth||| |0C|Guillotine||| |10|Gust|+|+| |6A|Harden|+|+| |72|Haze||| |1D|Headbutt|+|+| |D7|Heal Bell||| |88|Hi Jump Kick||| |ED|Hidden Power||| |1E|Horn Attack|+|+| |20|Horn Drill||| |38|Hydro Pump|+|+| |3F|Hyper Beam|+|+| |9E|Hyper Fang|+|+| |5F|Hypnosis|+|+| |3A|Ice Beam|+|+| |08|Ice Punch|+|+| |C4|Icy Wind||| |E7|Iron Tail||| |1A|Jump Kick||| |02|Karate Chop|+|+| |86|Kinesis||| |8D|Leech Life|+|+| |49|Leech Seed||| |2B|Leer|+|+| |7A|Lick|+|+| |71|Light Screen|+|+| |C7|Lock On||| |8E|Lovely Kiss|+|+| |43|Low Kick|+|+| |B7|Mach Punch||| |DE|Magnitude||| |D4|Mean Look|+|+| |60|Meditate||| |48|Mega Drain|+|+| |E0|Megahorn|+|+| |19|Mega Kick||| |05|Mega Punch|+|+| |E8|Metal Claw||| |76|Metronome|+|+| |D0|Milk Drink|+|+| |66|Mimic||| |AA|Mind Reader||| |6B|Minimize||| |F3|Mirror Coat||| |77|Mirror Move||| |36|Mist||| |EC|Moonlight||| |EA|Morning Sun||| |BD|Mud Slap||| |65|Night Shade||| |AB|Nightmare||| |BE|Octazooka||| |C8|Outrage||| |DC|Pain Split||| |06|Payday||| |40|Peck|+|+| |C3|Perish Song||| |50|Petal Dance||| |2A|Pin Missile||| |8B|Poison Gas|+|+| |4D|Poison Powder|+|+| |28|Poison Sting|+|+| |01|Pound|+|+| |B5|Powder Snow|+|+| |D9|Present||| |3C|Psybeam|+|+| |F4|Psych Up||| |5E|Psychic|+|+| |95|Psywave||| |E4|Pursuit||| |62|Quick Attack|+|+| |63|Rage||| |F0|Rain Dance|+|+| |E5|Rapid Spin|+|+| |4B|Razor Leaf|+|+| |0D|Razor Wind|+|+| |69|Recover|+|+| |73|Reflect|+|+| |9C|Rest||| |D8|Return|+|+| |B3|Reversal||| |2E|Roar|+|+| |9D|Rock Slide|+|+| |F9|Rock Smash|+|+| |58|Rock Throw|+|+| |1B|Rolling Kick|+|+| |CD|Rollout|+|+| |DD|Sacred Fire|+|+| |DB|Safeguard|+|+| |1C|Sand Attack|+|+| |C9|Sandstorm|+|+| |B8|Scary Face|+|+| |0A|Scratch|+|+| |67|Screech|+|+| |45|Seismic Toss|+|+| |78|Selfdestruct||| |F7|Shadow Ball|+|+| |9F|Sharpen||| |2F|Sing|+|+| |A6|Sketch||| |82|Skull Bash||| |8F|Sky Attack|+|+| |15|Slam|+|+| |A3|Slash|+|+| |4F|Sleep Powder|+|+| |D6|Sleep Talk||| |7C|Sludge|+|+| |BC|Sludge Bomb|+|+| |7B|Smog|+|+| |6C|Smokescreen|+|+| |AD|Snore||| |87|Softboiled||| |4C|Solar Beam|+|+| |31|Sonicboom|+|+| |D1|Spark||| |A9|Spider Web|+|+| |83|Spike Cannon|+|+| |BF|Spikes|+|+| |B4|Spite||| |96|Splash|+|+| |93|Spore|+|+| |D3|Steel Wing|+|+| |17|Stomp|+|+| |46|Strength|+|+| |51|String Shot|+|+| |A5|Struggle|+|+| |4E|Stun Spore|+|+| |42|Submission||| |A4|Substitute||| |F1|Sunny Day|+|+| |A2|Super Fang||| |30|Supersonic|+|+| |39|Surf|+|+| |CF|Swagger||| |BA|Sweet Kiss|+|+| |E6|Sweet Scent|+|+| |81|Swift|+|+| |0E|Swords Dance|+|+| |EB|Synthesis|+|+| |21|Tackle|+|+| |27|Tail Whip|+|+| |24|Take Down|+|+| |64|Teleport|+|+| |A8|Thief||| |25|Thrash||| |57|Thunder|+|+| |09|Thunder Punch|+|+| |55|Thunderbolt|+|+| |54|Thundershock|+|+| |56|Thunderwave|+|+| |5C|Toxic|+|+| |90|Transform||| |A1|Tri Attack|+|+| |A7|Triple Kick||| |29|Twineedle|+|+| |EF|Twister|+|+| |0B|Vice Grip|+|+| |16|Vine Whip|+|+| |E9|Vital Throw||| |37|Water Gun|+|+| |7F|Waterfall|+|+| |FA|Whirlpool|+|+| |12|Whirlwind|+|+| |11|Wing Attack|+|+| |6E|Withdraw|+|+| |23|Wrap|+|+| |C0|Zap Cannon|

Pokemon Gold custom ROM for ripping move anims: https://files.catbox.moe/dhr78b.gbc - ROM with transparent Pokemon sprites (good for ripping visual effects seamlessly and with minimal editing) https://files.catbox.moe/7yxc03.gbc - ROM with Pokemon sprites replaced with red squares (good for building metadata for moves with screen/sprite translations)

SheerSt commented 2 years ago

Hi there! Thanks for wanting to help :) I wrote the Contributing section a long time ago, I need to update it with better info. Rips of attack animations are complicated and difficult to do. It may be better to pursue something different as a first issue. Are you interested in doing code stuff?

If you still want to pursue the attack animations route, I can provide you with the script I use as well as an instructional video and you can see what you think.

Imo a good first step might be to get the game to build on your computer.

I am on discord if you would like to DM me there, whatever works best for you :)

1iminal commented 2 years ago

Are you interested in doing code stuff?

Maybe, eventually. Right now I feel like working with assets is more up my alley.

I can provide you with the script I use as well as an instructional video

Please do. I'd also like to see the build instructions.

I'd like to avoid using discord unless it's absolutely necessary. Digging chats for specific information there is a pain, and other people might find their answers here more easily, saving you from having to answer the same questions over and over again.

SheerSt commented 2 years ago

I've invited you to the pokemon-wilds-core repo which has the game's code. If you're interested in building the game you will need either Android Studio or Eclipse installed. Here are some steps to get Pokemon Wilds to build:

Lmk if you run into issues, not many people have done this so I'm sure there will be some.

More info on importing libGDX projects can be found here: https://libgdx.com/dev/import-and-running/

Regarding attack animations. I have a partially complete guide I made a while back. I don't have time to complete the full guide right now, unfortunately: https://youtu.be/gWUYm6CYR14

That way you can at least see what's involved with ripping attack animations. I have attached two python scripts which I use in the animation ripping process. The scripts require the ffmpeg and PIL libraries to be installed. I apologize as the scripts are very hacky, again something I need to improve when I have time.

Please feel free to ask me any Qs. If you respond on here I will do my best to respond quickly. github-scripts.zip

1iminal commented 2 years ago

I've managed to build and run it just fine using Android Studio, except for one error - when I try to open ITEM menu from the START menu in the overworld it throws an exception: Caused by: com.badlogic.gdx.utils.GdxRuntimeException: File not found: bag-reference1.png (Internal) There's no such file in both pokemon-wilds-core and pokemon-wilds repos.

Some tips for people trying to get it to build with IntelliJ IDEA/Android Studio:

I'll try the scripts in a bit, looking forward for the rest of the guide.

SheerSt commented 2 years ago

I pushed to pokemon-wilds-core to remove references bag-reference1.png. Let me know if you hit any other issues running.

1iminal commented 2 years ago

I've added a table of all moves to the opening post for the ease of tracking of moves that require rips. I've also built a custom Pokemon Gold ROM using pokegold disassembly (https://github.com/pret/pokegold). In this ROM Johto wild battle music is replaced with silence, because turning channels on and off manually to prevent music bleeding into move SFX is a pain.

1iminal commented 2 years ago

After playing around with python scripts I think I now have the basic idea behind the process. Still waiting for the rest of the guide and tips on how to turn output into assets ready to be included in the game (what should be output .ogg settings, etc).

razor_leaf_enemy_gsc (example) ![razor-leaf](https://user-images.githubusercontent.com/11787992/137580608-53a7546e-fbf7-4206-a378-1337c95a0c3e.png)
SheerSt commented 2 years ago

Thank you for your persistence with this.

I've also built a custom Pokemon Gold ROM using pokegold disassembly (https://github.com/pret/pokegold)

Very good idea, I didn't think of disabling the music. Something related, I've noticed sometimes sprites will be the same color as the background. For example, Shadow Ball, the edges of the 'ball' sprite match the background color making the attack rip inaccurate. I haven't had time to look into this but I've wondered in the past if it would be possible to change the background color in the battle screen to get around this issue. I tried modifying the palette in visualboyadvance and that didn't work.

Another attack with this issue is 'Harden'. There is a white 'reflection' sprite in the animation that is the same color as the background. Somehow changing the background color would make it possible to rip the Harden animation.

I will work on the rest of the guide video today.

SheerSt commented 2 years ago

I have uploaded a video showcasing the rest of the animation ripping process here: https://youtu.be/Bv_wdiTvOXc

Another thing that came to mind. If there was a way for both the player and enemy Pokemon's sprites fully transparent, that would also reduce the number of times that ripped frames needed to be repaired or edited manually (while keeping things simple).

Please let me know if you encounter any issues with the video.

EDIT: noticed a small issue, uploaded a fixed video

1iminal commented 2 years ago
  1. I've upated the link in the opening post with an improved ROM. In this ROM battle screen is set to pure green (RGB 0, 255, 0), all starter Pokemon now have transparent back sprites and all Pokemon that appear on Route 29 now have transparent front sprites to aid moves ripping. Along with the scripts this produces pretty good results.
    Example

frame-116

  1. When using the ROM I mentioned above, it's impossible to identify the last animation frame by enemy sprite disappearing effect (status moves don't cause this effect anyway), I think player/enemy HP bar REappearing is a better mark, frame identified by this event also happens to match the frame identified by method explained in the guide.
  2. Any reason you use -c:v ffv1 parameter when running ffmpeg command to cut the video? This makes ffmpeg output compressed results that may contain artifacts that will carry over to the extracted frames. To produce uncompressed output, one should use -c copy parameter instead, making the command look like the following:
    ffmpeg -ss [start_frame_number/60] -i source-old.AVI -c copy source.AVI
  3. If you use the ROM provided above, there's no need to boot up any audio editing software, ffpmeg can extract sound from source avi just fine. The command is ffmpeg -t 00:00:0X -i source.AVI -vn -f ogg sound.ogg, where X is duration of sound in seconds (from the beginning). Sound file produced by ffmpeg may be too loud compared to already existing sounds. To compare sound volume of two files using ffmpeg, one can use ffmpeg -i [filename] -filter:a volumedetect -f null /dev/null with both files. The command to lower/raise the volume is ffmpeg -i sound-old.ogg -filter:a "volume=0.2" sound.ogg (0.2 is what worked for me).
  4. Regarding the contents of metadata.out file - for some reason it randomly omits large numbers of frames (for example, it may go from 1 go 25 and then suddenly the next one will be 63 and up), are we supposed to fill the gaps manually when this happens so every frame has a corresponding line in metadata.out? This is what I did and everything works just fine in the game, but I'm asking just in case.
  5. In rip-attack-from-frames.py line 126 sets a limit that prevents anything within the area 8<x<=88 from being captured when exporting animation frames from raw frames. This causes effects of some moves (for example, Razor Leaf when used by an enemy Pokemon) to be cut off, in these cases the script should be edited accordingly.
  6. I've finished adding a move animation, should I just commit to master or a dev branch? Or should I make a pull request? Are there any rules regarding commit messages?
    Results

razor-leaf2

SheerSt commented 2 years ago

1 - that's perfect. I'd be interested to see how you did that sometime in the decompile (I've only done stuff like simple mods before.)

2 - unfortunately I've seen that that's not a good metric. There are a lot of attacks where the health bar will reappear and there will be a long frame delay before the hit animation plays (the tri-attack animation, for example). Not sure if this is possible but maybe the Pokemon sprite(s) could be changed again so that at least it is not using black/white colors, which tend to conflict with the attack animation sprites. (I apologize for not thinking of that)

3 - Its been over a year since I looked into ffmpeg, I dont remember. I haven't noticed any compression or artifacts in the resulting frames. I have noticed some compression with the audio so perhaps the new command will fix that.

4 - that's strange about the volume issue, I've never had to tweak the volume in audacity.

5 - in my experience various things can interfere with the script detecting if the healthbar is transparent. It's possible an enhancement could be made to the script. Currently the script just checks a pixel on screen to determine whether or not the health bar is visible. I always verify the contents of metadata.out to check (and fill in missing data).

6 - again an enhancement could probably be made. I remember hitting something like that in the past.

7 - The process currently is to push changes to a separate branch and open a pull request. There's only been a couple of other contributors and we haven't established any rules regarding commit messages or branch name conventions, etc.

I realize this process, the script etc is messy, thanks for your patience. Any improvements to the process are definitely appreciated. Nobody has been willing to look at attack animations yet, and I've been working on Wilds for over a year and a half now. The work you're doing is really valuable.

1iminal commented 2 years ago

One thing I realized is that player and enemy animations use identical sounds and the current folder structure encourages including the same sound file in the project twice. If package size is a concern, we should consider changing the folder structure (and hardcoded load paths) to something like this:

attacks\
    tackle_gsc\
        enemy\
            output\
            metadata.out
        player\
            output\
            metadata.out
        sound.ogg
1iminal commented 2 years ago

I've added ROM where Pokemon sprites are replaced with red squares. This one gives the benefit of using the same values in rip-attack-anim-from-frames.py because all Pokemon (on Route 29) now have the same sprite, and RGB 255, 0, 0 red color doesn't interfere with visual effects of moves.

SheerSt commented 2 years ago

One thing I realized is that player and enemy animations use identical sounds and the current folder structure encourages including the same sound file in the project twice. If package size is a concern, we should consider changing the folder structure (and hardcoded load paths) to something like this:

I agree that would be a good adjustment to help reduce the size of the game. I remember investigating this and there is a very slight time offset between the sound files. The perfectionist in me would like to somehow see if there's a consistent offset, so that code could be added to the game to offset the start of the sounds accordingly. Maybe that's a little much though.

1iminal commented 2 years ago

From what I've seen so far the offset is inconsistent between moves, some have a noticeable one (e.g. Rollout), some none at all (Struggle, Gust). Maybe a special metadata tag could help set this offset individually for cases when it matters.

SheerSt commented 2 years ago

Any thoughts on Quick Attack/Extremespeed?

I received an email with this question from you however I don't see it anywhere in the PRs or in this issue, hope I didn't miss something.

1iminal commented 2 years ago

I've just realized there's already enough functionality for these and deleted the comment. The actual hard ones would beTransform, Minimize, Substitute and others where sprite changes are persistent between turns, but I feel like I'm not ready to work on these yet.

SheerSt commented 2 years ago

I see, no problem. A metadata tag may need to be added to the game in order to signify when the Pokemon's sprite changes for those attacks. And you're right, code may need to be added to facilitate making the sprite changes persist between turns.

As for the animation itself for those attacks you mentioned, I have no code currently to rip that data and no metadata tag. It looks like it will operate by copying all pixels left or right per row. Those attacks would function okay without animations for now so maybe that can be looked at down the road.