Jump to content

RicePigeon

Administrator
  • Posts

    3,952
  • Joined

Everything posted by RicePigeon

  1. Flandre Scarlet updated 3y: Is no longer air blockable. Now counts as a grounded melee attack. 3y: Blockstun increased by 2f. Starbow Break [X ver]: Startup after hitting wall decreased by 2f, now projectile invulnerable while on wall. Starbow Break [X ver]: Horizontal velocity increased. Starbow Break [X ver]: Recoil velocity & recovery decreased, now -7/-8 on block. "Laevatein": Now only hits once, damage values increased to compensate. Velocity increased. "Weapon of Mass Destruction": Explosion hitbox size drastically increased.
  2. Utsuho and Marisa were updated during MFFA's downtime. Slight adjustments to dashing behaviors. Corrections to guarding behavior regarding crossups. Adjustments to invincibility on Guard Cancel. Adjustments to reset behaviors. Rocket Dive: Fixed incorrect visual effects when fully charged. "Yatagarasu Dive": Dive portion damage increased (80xN->82xN). 6z: Is now air blockable. Witching Blaster: No longer whiffs against certain opponents in the corner. Witching Blaster [Air ver]: Recoil velocity slightly increased. "Sungrazer": Adjustments to startup invulnerability, can no longer be knocked out of attack on successful hit.
  3. Byakuren updated Adjusted dash cancel timings. Corrected guarding behavior in regards to crossups. Adjustments to reset behavior. Adjustments to invulnerability on Guard Cancel. j2y: No longer autocorrects.
  4. Ichirin updated Adjustments to dash behavior. Corrected guarding behavior in regards to crossups. Corrected invuln timing on Guard Cancel. Adjustments to reset behavior. Knockdowns will no longer cause Unzan to deactivate. 5y (Unzan): Hitstun & Blockstun decreased by 2f. 5y (Unzan): Active frames decreased by 2f, startup increased by 2f. Hurtboxes adjusted. 6z (Unzan): Corrected faulty juggle flag. 2y (Unzan): Recovery increased by 4f. Hanging Cloud's Iron Hammer: Hitbox size drastically reduced, recovery time increased by 3f. North Mountain Wind of Mercy: Damage decreased (100/120/140->90/110/130).
  5. You do realize the character was an April Fool's joke, yes? An april fools character from over four years ago, I might add...
  6. Damage Proration System Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN Proration, also known as Damage Dampening, is a system implemented in many fighting games that prevent combos from becoming too overpowered by decreasing the amount of damage dealt by each successive hit in a combo. The exact method of how proration is achieved differs by game; most Capcom games such as the Street Fighter and Marvel vs Capcom games use a linear proration system based on the number of hits in a combo, while most games by Arc System Works tend to use a scalar method where each hit of an attack applies its own scaling value. This tutorial will deal with the latter method, which gives you greater control over how damage is scaled. First, you'll need two floating point variables for this to work; we'll be using fvar(10) and fvar(11). We'll be dealing with fvar(11) as our final dampener later on, but for now, start with the following in your -2 state: [State -2, Reset var when the opponent recovers] type = Varset trigger1 = numenemy trigger1 = (enemynear,movetype!=H) trigger2 = !numenemy fvar(10) = 1.0 [State -2, Final Dampen] type = null trigger1 = (fvar(11) := ifelse(0.1>fvar(10),0.1,fvar(10)) || 1 ignorehitpause = 1 [State -2, Dampener itself] type = Attackmulset trigger1 = 1 value = fvar(11) ignorehitpause = 1 The first state controller will initialize our character's proration to 100% damage (the default), as well as reset our proration value whenever the opponent is not being comboed. The second state controller is optional, but is handy to have if you want there to be a minimum proration value, as many games that use this system tend to have one. In our above example, our minimum proration is set to 0.1 or 10%, so our damage scaling will never go below 10% of an attack's base damage. You can also further modify fvar(11) for any other system mechanics you might need, including counterhit bonuses or other scaling such as the damage penalty incurred with systems such as Custom Combo. The final controller here will apply fvar(11) as our final proration value and scale our Attack stat accordingly. Note that this will only apply to damage dealt by the player and not any helper projectiles spawned by the player; in order to apply our damage proration to those, you'll need to apply the proration value directly to the attack's damage value in the hitdef: damage = ceil(220.0*root,fvar(11)),44 Here, we see a helper projectile with a base damage of 220 having the root's (aka the player's) proration value applied. The ceil function is needed to ensure that the damage never falls below 1 and always returns an integer value. Note that chip damage (block damage) is never scaled. Now that we have a proration system in place, all that's left is to actually apply the proration values. Go through each of your character's attacks and add a varset under their hitdef with the amount of proration you want to apply on hit: [State 200, Damage Dampen] type = varset trigger1 = movehit fvar(10) = fvar(10)*0.92 ignorehitpause = 1 persistent = 0 Above, we see a controller for attack that deals 92% proration on hit. As mentioned at the beginning, this will multiply the proration value by whatever proration is set by the attack, which is then applied to the damage of the next attack in the combo. If you're doing this in a helper projectile, you'll want to substitute this for an equivalent parentvarset controller: If an attack deals multiple hits, you'll need to apply a proration controller for each individual hit in a similar fashion; this can be accomplished through the use of the animelemno() and animelemtime() triggers, or whatever system you are using to keep track of multiple hits.
  7. Homing/Tracking/Aimed Projectiles Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN Another relatively simple concept; you have a projectile spawned at a stationary location and want it to either aim in the opponent's direction or to home in on the opponent. For this you'll need a few variables to spare and simply place the following at the beginning of the projectile's state: [State 24010, Conditional Varset] type = null triggerall = time = 0 ;<-- See notes below trigger1 = numenemy trigger1 = (fvar(0):= (enemynear(0),pos x - pos x) * facing) || 1 trigger1 = (fvar(1):= enemynear(0),pos y - pos y + enemynear(0),const(size.mid.pos.y)) || 1 trigger1 = (fvar(2):=((fvar(0)**2.0)+(fvar(1)**2.0))**0.5) || 1 trigger2 = !numenemy trigger2 = (fvar(0):= 320.0 * facing) || 1 trigger2 = (fvar(1):= 0.0) || 1 trigger2 = (fvar(2):=((fvar(0)**2.0)+(fvar(1)**2.0))**0.5) || 1 What this does is uses simple trigonometry to calculate the vectors between the opponent and the projectile. The second set of triggers (trigger 2) is necessary in the event that an opponent doesn't exist so that the code doesn't bug out, and will simply cause the projectile to fire in a straight line if there is no opponent. You might be wondering about that triggerall line at the top. Depending on what this value is will determine on whether or not the projectile is aimed or homing; an aimed projectile will simply track the opponent's position at the time of creation and fire at that direction, while a homing projectile will continuously chase the opponent for as long as the projectile exists. The above code is for an aimed projectile, but to change this to a homing projectile, simply replace "triggerall = time = 0" with "triggerall = 1". But we're not done yet. We still need to apply these vectors to the projectile's velocity. Assuming that the projectile's base velocity is 10: [State 24010, Velset] type = velset trigger1 = 1 x = 10.0*fvar(0)/fvar(2) y = 10.0*fvar(1)/fvar(2) ignorehitpause = 1 What we're doing here is normalizing our vectors and applying them to our projectile's base velocity. This is what will cause the aimed/homing behavior of the projectile. If for some reason you also need your projectile to rotate in the direction it's traveling, make sure to add the following under your velset controller: [State 2010, AS] type = varset trigger1 = vel x != 0 fvar(3) = atan(vel y/vel x)*(-180.0/pi)+((vel x<0)*180) [State 2010, AS] type = varset trigger1 = vel x = 0 fvar(3) = ifelse(vel y<0,90,-90) [State 2010, AS] type = angledraw trigger1 = 1 value = fvar(3) ignorehitpause = 1 Just make sure that your projectile's graphic is facing horizontally or you'll need to make adjustments to the above code. This also checks if the projectile is traveling straight up or down; since the tangent of 90 degree angles are undefined, we need that second state controller there as a failsafe or else the code will bug out and you won't get a proper rotation.
  8. Pretty much this, its one thing to say what character you want, but without a solid game plan in mind as to how the character should play, there isn't much that can be done.
  9. So its been almost 6 months since the last post here and there's a been a number of changes to the gameplay system, especially now that we have an actual playable demo of the system in the form of IZ Yukari, which was released last month. I suggest taking a look there for the most up to date changes to the system compared to what's listed here. I kinda of want to steer the direction of this toward the next three characters planned for this system: Marisa, Sakuya, and Reimu. While these three won't receive that many drastic changes as Yukari did (it was mostly a last-minute decision due to her being included in 15.5, which was released in December), I do feel that I should go over some of the changes they'll be receiving, as well as any ideas anyone else has in mind.
  10. Improved Guarding States for Crossup Detection Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN In most fighting games, you need to hold the joystick in the direction away from the opponent in order to guard, which is straightforward when the opponent is directly in front of you. But when the opponent is behind you, such as during an attack that crossed up the opponent, holding back should not allow you to guard an opponent's attack, only when holding forward. By default, Mugen's default guarding states cannot take into account these cross-up attacks. The following modifications to Mugen's guard states will replicate this proper behavior. First, go through States 120, 130, 131, and 132 and search for the following block of code: [State 132, Stop Guarding] type = ChangeState trigger1 = command!="holdback" trigger2 = !inguarddist value = 140 Replace this with the following: [State 132, Stop Guarding] type = ChangeState trigger1 = cond(p2dist x<0,(command!="holdfwd"),(command!="holdback")) trigger2 = !inguarddist value = 140 What this does is tells the engine to stop guarding if we are holding back and player 2 is behind us. In a similar fashion, check states 132 and 155 for the following: [State 132, 6] type = ChangeState trigger1 = sysvar(0) trigger1 = command="holdback" trigger1 = inguarddist value = 130 Replace with this block of code: [State 132, 6] type = ChangeState trigger1 = sysvar(0) trigger1 = cond(p2dist x<0,(command="holdfwd"),(command="holdback")) trigger1 = inguarddist value = 130 This will do the opposite: Tell the engine to start guarding if we are holding back ONLY when the opponent is in front of us, and when holding forward ONLY when the opponent is behind us.
  11. Hitdef Animtype Quirk Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN This is more of a bug in Mugen/IKEMEN's parser. Basically, Mugen's parser only checks the first letter of the Animtype parameter (L for Light, M for Medium, H for Heavy, B for Back, U for Up, and D for Diagup), while ignoring the rest of the parameter's value. This means that Animtype = Hard and Animtype = Heavy are functionally equivalent. This also means that some silly parameter values that normally shouldn't be accepted by the engine are valid values: Animtype = Hamburger resolves to Animtype = H (Heavy) Animtype = Methamphetamine resolves to Animtime = M (Medium) Animtype = Boobies resolves to Animtype = B (Back) Basically, as long as the parameter's argument begins with an L, M, H, B, U, or D, the engine will accept it as a valid parameter.
  12. Multiple Attack Variants Using a Single State Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN This one is fairly simple, and makes use the assignment operator. Instead of defining Light, Medium, and Heavy variants of a special move in separate states, have the changestate in -1 as follows: [State -1, Shoryuken] type = ChangeState value = 1100 triggerall = ctrl trigger1 = command="DP_X" trigger1 = (var(10) := 1)||1 trigger2 = command="DP_Y" trigger2 = (var(10) := 2)||1 trigger3 = command="DP_Z" trigger3 = (var(10) := 3)||1 As we can see here, each command will still bring us to our main Shoryuken state, but will keep track of which version we are using. If you have multiple different animations or anything else that varies depending on the version of the move used, you can simply refer to the variable as follows: [Statedef 1100] type = S movetype = A physics = S ctrl = 0 poweradd = 20 anim = 1100+1*(var(10)=2)+2*(var(10)>=3) sprpriority = 1 facep2 = 1 [State 1100, Hitdef] type = HitDef trigger1 = movecontact = 0 && movereversed = 0 trigger1 = animelemtime(1)>=0 attr = S, SA damage = 60+10*(var(10)=2)+20*(var(10)=3),11+2*(var(10)=2)+4*(var(10)=3) As we can see here, animations 1100, 1101, and 1102 each correspond to the Light, Medium, and Heavy versions of our DP command, and the damage values can be modified with this as well.
  13. Please don't post or redirect to any links containing warez/other illegal or pirated software. The links in your video contained downloads of .gba files, which, despite being ROM hacks, are still pirated copies of the official Pokemon games. Links to IPS patches, on the other hand, are fine, since they only contain the necessary changes, and not the ROM itself.
  14. More Efficient Random Number Spreads Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN Many times I've seen authors use modulo division to generate a spread of random numbers for whatever purpose (be it for AI triggers, random animations, or whatever). For those who don't know what I'm talking about, I'm referring to pieces of code like this: To understand why the above code is inefficient, we have to take a deeper look into the results its producing. For those who don't already know, in MUGEN, random generates a random integer from 0 to 999 (effectively producing 1 of 1000 different values each time random is called), each with an equal probability of being returned by random. With the % operator, such as in expression X%Y, we are dividing value X by value Y and returning only the remainder as a result. 17%10, for example, would return 7 as its value (17/10 = 1 R7). If we were to apply modulo division to random, for instance, we would be generating a random value from 0 to 999 and then dividing this number by an arbitrary value and returning its remainder as a result. By applying modulo division to random, we expect to see results that have an equal probability of being generated, as follows: Random%10 generates: As we can see above, we have a nice even spread of the 10 possible values that random%10 can generate. While this works great for numbers that are factors of 1000 (such as 2, 4, 5, 10, 20, 50, 100, etc), more arbitrary values won't be as neat and organized. As an arbitrary example, instead of 10 values, we try for 666 (which should return an even spread of numbers ranging from 0 to 665). The results are listed below: Random%666 generates: The problem should be immediately clear: the values ranging from 0-333 each have a 0.20% probability, while values ranging from 334-665 each have a 0.10% probability. If this were an even spread, we should expect any value from 0-332 to be generated only 50% of the time, but instead we see that numbers in this range are generated 66.6% of the time! If we were relying on a number being generated from this range, random%666 would be returning these values TWICE as often as the rest of the spread. The solution? Rather than using modulo division, we use the following: What this does is multiply arbitrary value X by random, then divide by 1000, then floor the result to produce an integer value. This results in a spread ranging from 0-X, but in a much more even fashion. Say we revise our above code to the following: floor(666*random/1000.0) generates: While this isnt foolproof, as we still have values that are twice as likely to be returned than the other values, you'll notice that the spread is much more even. Values ranging from 0-332 now have a 50% chance of being generated, as we would expect them to be, as opposed to the 66.6% probability we were generating before.
  15. Asymmetrical Palette Display using ReMapPal (aka The Gill Effect) Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN You've probably heard of the term "Gill Effect" or something similar before if you've ever played any of the Street Fighter III games; a character with an asymmetrical color scheme on their body. In Mugen, attempting to replicate this would require a duplicate of every sprite with the reversed palette, but even then custom states cause a problem. With the ReMapPal controller introduced in Mugen 1.0, this can now be done easily with a simple controller: The idea is simple; using the new SFFv2 format, instead of duplicating each sprite, duplicate each palette and then remap the palettes with the new controller depending on the direction the character is facing. However, keep in mind that executing a ReMapPal controller conflicts with an earlier state controller; PalFx. To get an idea of what I'm talking about, here we have the same attack which puts p2 into a custom state that applies a PalFX controller to simulate being frozen. One default Kung Fu Man, while the other is a character that continuously applies a ReMapPal controller in her -2 state in order to simulate the Gill effect; Purely discovered by accident, I was easily able to find a workaround to this by, rather than continuously applying ReMapPal, instead only apply the controller when it needs to be. This can be done with a variable to act as a flag and compare it to the current direction the character is facing. If they do not match, only then should ReMapPal be applied, with the flag set to that facing value to avoid the controller being executed again until needed. This isn't a perfect workaround, however, as custom states that both apply a PalFX controller and repeatedly changing the opponent's facing direction may still cause the PalFX to end prematurely. In the end, to address the issue outlined above, your code should look something like this: The way it works is simple: You'll need a variable to keep track of which direction your character is facing: 1 for facing right, 2 for facing left. Additionally, you'll need to have two palette groups for each direction as well. The above code will check which direction you're currently facing and if you were previously facing the opposite direction; if you were, change the palette to the opposite palette group, otherwise don't change anything. This will also simultaneously set the value of the palette group to use.
  16. Hitdefs with Multiple Attributes Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN Ever wondered if you could assign multiple properties to a hitdef, but didn't want multiple hitdefs conflicting with each other each tick? Thanks to a discovery by a friend of mine, you might not need to: The tested code in question: [Statedef -2] [State 0, HitOverride] type = HitOverride trigger1 = 1 attr = SCA,AA slot = 1;0 stateno = 1200 ;Melee counter state time = 1 forceair = 0 ignorehitpause = 1 [State 0, HitOverride] type = HitOverride trigger1 = 1 attr = SCA,AP slot = 0;1 stateno = 1300 ;Projectile counter state time = 1 forceair = 0 ignorehitpause = 1 Other stuff to make note of due to this bug: If an attack is attributed as multiple levels and KOs the opponent, MUGEN will flag the victory condition in the order of Special, Hyper, and Normal (ie: S,NA,SA,HA will be attributed as a Special). Similarly, MUGEN will prioritize the Throw win flag if the attack is attributed as a combination of Throw and either Attack or Projectile. Both of these conditions will ignore the ordering of multiple hitoverrides. Some practical uses of this bug include the ability to code melee attacks that can destroy helper-based projectiles without needing to code in an additional Helper to handle projectile collisions:
  17. Workaround for Missing "ParentExist" Trigger Compatibility: WinMUGEN Mugen 1.0 Mugen 1.1b IKEMEN Have you ever had a situation where you needed to create a complex projectile or effect that utilized a single helper creating multiple helpers that were bound to it, only to encounter a glitch where, in the event that the parent helper was destroyed, the child helpers would just sorta stay on screen and Mugen's debug is spitting out complaints that all your child helper's bindtoparent controllers have no parent to bind to. You rush to alter your child helper's Destroyself controller, only to realize that there is no "ParentExist" trigger you can use to force them to destroy themselves. Sounds like all hope is lost right? Fortunately there is a clever workaround using trigger redirection. For each parent helper, you'll need to reserve one variable for a unique ID, while each child helper will require two variables; one to keep track of the parent's unique ID, and one to keep track of the parent helper's playerID, which is created by the engine each time a helper is created and are periodically recycled as helpers are destroyed and new helpers created to take their place. In the first state of parent helper, at the following line of code to the beginning of its state: [State 20000, Parent ID] type = varset trigger1 = time = 0 var(0) = random*1000+random This will generate a unique, 8-digit ID when the parent helper is created. You only have to set this once each time the helper is created, even if the helper goes through multiple states. Note that there is a very small chance (approx 0.0001%) that the same ID will be created twice, but the chance is so miniscule that this will rarely, if ever, happen. That's all for the parent helper. The child helper is where things start to get a bit complicated, so I'll go through each part here. In the first state the child helper is created in, add the following to the beginning of the state: [State 20010, Parent Destruct Safeguard] type = varset trigger1 = time = 0 var(1) = parent,id ;Set to parent's PlayerID [State 20010, Parent Destruct Safeguard] type = varset trigger1 = time = 0 trigger1 = playeridexist(var(1)) var(0) = playerid(var(1)),var(0) What you are basically doing is copying the values of both the parent helper's playerID (which is set by the engine) and the 8-digit ID that you generated earlier, into the child helper. The reason for copying both of these values into the child helper is to check for two possible scenarios: Scenario 1: Parent no longer exists, Helper with Parent's Player ID doesn't exist Scenario 2: Helper with Parent's Player ID exists, but unique ID don't match Scenario 1 is pretty straightforward; if a helper with the parent helper's PlayerID doesn't exist, then that means that the parent helper doesn't exist and you can safely destroy the child helper. Scenario 2 is a bit more complicated to understand, and requires a bit of understanding of how the MUGEN engine assigns PlayerIDs. As stated before, PlayerIDs are recycled by the engine each time a helper is destroyed; MUGEN will typically use the first available free PlayerID in these cases. In other words, you may run into situations where a helper with the parent's PlayerID exists, but the helper with that ID was actually created after the actual parent helper destroyed itself! It is for this reason that we needed that unique 8-digit ID number, as PlayerID alone is not enough to check if the parent helper no longer exists. To satisfy both of these scenarios when checking to see if a child helper's parent exists, your triggers should typically look something like this: trigger1 = !playeridexist(var(1)) trigger2 = playeridexist(var(1)) trigger2 = playerid(var(1)),var(0) != var(0) Trigger1 will satisfy the first scenario; because there is no helper that exists with the parent helper's PlayerID, we can safely say that the parent was destroyed. Both Trigger2s satisfy the second scenario; a helper exists with the same PlayerID as our child helper's parent, but their unique 8-digit ID number does not match what we initially recorded, indicating that the original parent helper was destroyed. If you want to prevent any unusual debug errors, you should also add the following triggers to all State Controllers utilizing a parent that isn't the root (ie ParentVarSet, BindToParent, etc.): triggerall = playeridexist(var(1)) triggerall = playerid(var(1)),var(0) = var(0) These triggers will check for the same consistency as the ones we defined above. If everything checks out, then the state controllers will execute without any problems. Otherwise, the controllers will not execute and prevent unnecessary debug flood.
  18. This will mostly be a repository for anything that I've come across during my experience with the engine.
  19. Koishi updated Adjustments to dash behaviors. Fix to guard behaviors regarding crossups. Adjustments to invincibility on Guard Cancel. Adjustments to reset behaviors. 6z: Damage decreased (80->70), Power gains decreased (120/60->90/45). 4z: Damage decreased (90->80), Power gains decreased (120/60->90/45). j5x: Damage decreased (50->40). j5y: Damage decreased (65->55). j6z: Damage decreased (90->80), Power gains decreased (120/60->90/45). j2z: Damage decreased (90->80), Power gains decreased (120/60->90/45). Catch & Rose: Damage decreased (111->101), Y & Z versions now properly deal chip damage. "Superego": Startup decreased by 8f, corrected persistent sound effect when Koishi is interrupted.
  20. Hong Meiling & Lie Meiling updated Adjustments to dash behavior. Corrected guarding behavior in regards to crossups. Adjusted handling of invulnerability on Guard Cancel. Adjustments to the handling of resets. 5x: Startup increased by 1f, hitvels slightly adjusted. 5x: Damage decreased (25->20), proration decreased (95%->93%). 5y: Damage decreased (60->50). 5y: Can now only be jump cancelled on hit when used outside of Fierce Tiger's Inner Strength. 5z: Damage decreased (70->60), proration decreased (85%->80%). 2x: Damage decreased (25->20). 2z: Damage decreased (70->60), proration decreased (75%->70%). Descending Flower Slam: Now always causes a Hard Knockdown. Minor adjustments to dashing behaviors. Fixed guarding behavior in regards to crossups. Adjustments to invulnerability handling on Guard Cancel. Changes to reset behavior.
  21. Eirin updated Minor adjustments to dash behavior. Fixed guarding behavior in regards to crossups. Adjustments to how resets are handled. Fixed issue regarding when Eirin is knocked down. Guard Cancel: Adjustments to invinicibility, startup decreased by 5f. Fixed issues with several projectiles being able to move during super pause.
  22. Added the following: Aya Shameimaru by Barai Reisen U. Inaba by Gondwana Couldnt add the others since the site isnt working for me at the moment.
  23. IZ Yukari updated with some fixes. Changed aesthetics of Alignment selector. Added C button shortcut for X+Y+Z, due to popular demand. Adjustments to reset behavior. Bewitching Bait: Now removes itself properly if Yukari is hit before lasers are created. "Unmanned Abandoned Railroad Car Bomb": Resolved hitbox issue in corner. "Phantasm, Foam, & Shadow": Base damage per hit increased (100->120), proration decreased (92%->87%). "Phantasm, Foam, & Shadow": Now becomes unblockable at maximum charge.
  24. To reduce the workload for when Ryoucchi gets back, I've updated the first post with the following additions: Dream World by Nomucoke Dream World by GarchompMatt Byakuren Hijiri by Boomer Suika Ibuki by RicePigeon Incident Zero-styled Yukari Yakumo by RicePigeon Boomer's AI patch for RicePigeon's Sanae Feel free to keep submitting new entries for the collection as usual.
×
×
  • Create New...