LF2 Online by Xôi · the fifth computer-player level

INSANE!

A computer player above CRAZY! that follows no hand-written script for any fighter. Right before the match it learns the fighter's moves from the mod's own data, then fights by predicting which blow lands, and when the opponent can guard or strike back. It works with every mod this site plays.

What INSANE! is

The original Little Fighter 2 has four computer levels: Easy, Normal, Difficult and CRAZY!. Its computer player is a set of rules written for the original fighters, keyed by their ids. Put it in a mod (One Piece GrandWorld, Naruto: The Setting Dawn, KT-LF2, Sx2…) and it has no idea what the new moves are, so it mostly punches, kicks and throws the odd D+A at random.

INSANE! is a fifth level, selected right after CRAZY! on the character selection screen (and in Tournament and Battle mode). It contains no line about Luffy or Naruto: everything it knows about a fighter comes from playing each of that fighter's moves itself, in a private copy of the match, before the match begins. That is why it can use the moves of mods nobody has ever written an AI for.

How to select it: on the character selection screen, cycle the difficulty Easy → Normal → Difficult → CRAZY! → INSANE! (→ XOI, the strongest level after it: tuned numbers and notes of training, below). In a network room the host picks the level; every machine in the room computes exactly the same thing, so the match and its recording (replay) always stay in sync.

How it learns and fights

All of it lives in one Lua file. There is no training step and no GPU: all of its "knowledge" is recomputed from the mod's data when a match starts, in exactly the same way on every machine.

  1. Learning the moves. For each fighter, the AI builds a small private copy of the match (just the fighter and a dummy) and presses every key combination: D+A and D+J in each direction, D+J+A, the punches, the running, jumping and dashing attacks, and the keys pressed during a move (chains, including counters out of the guard). It records where and when each move hits, how hard, what it costs in MP, when the fighter is free again, and where the things the move spawns (projectiles, clones, fields) fly.
  2. Predicting. Every frame of the match it works out which enemy attack is about to reach it (including projectiles in flight), how long the opponent stays stunned or down, whether the opponent is blinking (invulnerable), and after how many frames each of its own moves would land if started now.
  3. Choosing a move. Each move is scored: damage, the chance of being guarded, the risk that the opponent hits back before the move lands, MP cost, how long the fighter is left open afterwards. Slow moves (Luffy's 585-damage special takes 44 frames to come out) are used only when the opponent is locked down long enough. A move not yet used in the match gets a small bonus, so spectators see the whole kit.
  4. Defence and positioning. Guard or sidestep what is coming, never guard a blow that would break the guard, stand just outside the opponent's arms so it has to walk into the AI's own blow, avoid the danger zones of its quick strong moves, walk around obstacles, run when far away, jump in or dash in when an air move would land.
  5. Stances and charging. Held moves (Blackbeard's dark field, the chakra charge in Naruto) are kept as long as they serve and left in time; MP is charged when the opponent is far away or lying down.
  6. Knocked down. When sent flying, the AI flips back up early only if the landing spot is safe; if the opponent is waiting there, it lets the fall finish (a lying fighter cannot be hit), gets up during the invulnerability blink, and uses that blink to strike first.
  7. Knowing the opponent. The opponent's data says what it can do; how it plays says what it will do. During the match the AI counts what its opponent does: the blows it guards against the blows that land, how often it attacks when someone is within its reach, whether it flips up out of every fall, how much it jumps. A guard-happy opponent makes guard-breaking moves and grabs worth more and ordinary blows worth less; a passive one is walked up to instead of baited; one that always flips up is met where its roll ends. Everything is counted from the match state alone, so network games stay in sync.
  8. Weapons, teleports and a partner. A knife, stick, stone or drink lying nearby is walked onto and picked up when nothing presses; the AI plays its moves again with the weapon in hand, so it knows what the fighter does with it (swing, throw, drink) and uses it like any other move — a knife is thrown at the opponent, a drink is kept for when HP or MP run low. Moves that teleport to the enemy are aimed from where the fighter lands, not from where it stands. Two against one, the second fighter goes round to the other side so the enemy cannot guard both.
  9. Forms of a mod's own making. Many mods build a stronger form on an invisible item: Luffy's Gear Second in One Piece GrandWorld is a defend move that lays down an item nobody sees and picks it up at once, and with that item in hand every key does something else — faster runs, harder blows, a drain on MP every frame. The AI finds such moves because the item ends up in its fighter's hand, plays the form's keys in the copy too (its attacks, jumps, runs and what they chain into), measures what it burns and how fast it runs, and weighs it against the fighter's ordinary kit. A form worth it is entered when the opponent is held or far enough away, fought in with its own moves and runs, and, when its MP is about to run out, let end away from the enemy's arms. Sanji's Diable Jambe and a Rasengan formed in the hand work the same way; a form reached from inside another form (Zoro's Asura) is not learned yet.
  10. Untouchable forms, healing, flight. Mods keep bodies far above or below the visible layer — a thousand pixels and more — for interactions of their own, and a frame whose bodies are all out there is out of reach of every blow except those aimed at the same layer. Drake's T-rex and Magellan's Venom Demon in One Piece GrandWorld are built that way: invulnerable while MP lasts. The AI reckons, for each opponent, which of its own frames that opponent's blows (and what it throws) can still reach; a form whose resting and moving frames none of them reaches is worth entering for that alone, and in it the fighter walks straight up and strikes instead of minding the opponent's reach — its own run or creeping walk steered onto the opponent's line and stopped with the form's own key. A move that restores HP (Marco's phoenix, state 1700) is measured in the copy with HP missing, and used when much of the HP lost can still come back and nothing can reach the fighter meanwhile. The roll out of a run is learned with what its frames lead to (Marco takes off as a phoenix with jump and strikes from the flight), and a flight that steers in depth is flown onto the opponent's line.
  11. Respecting the get-up. A fallen opponent cannot be hit until it is up again, and after it rises it is invulnerable for a moment while it can already strike. Until the AI's quickest blow could land as that moment ends, it waits outside the opponent's arms instead of beside it — farther away, and longer, when its own HP is low.
  12. Approaching beside the line of fire. A free opponent with a long blow — a beam, a sweep, a special struck out of the guard — covers the whole line between the two fighters, and a melee fighter walking straight along it steps into that blow at every pace. The AI now approaches such an opponent beside the line, offset in depth by the blow's width, and steps onto the line only as its own blows come into reach.
  13. Trapped opponents. Some mods hold an opponent with an object (Yamato's wood prison in Naruto: The Setting Dawn). The AI knows a held opponent is harmless and, when the trap lets blows through, hittable: it walks up and strikes — or, when its MP is short of a strong move and the hold has time to spare, charges MP first, while the trap keeps the opponent harmless, and lands the strong move before the hold ends. A trap is never set again on an opponent already held: cast on and on from afar, it only held the opponent on, and the two fighters stood there for the rest of the match.
  14. Out of the wake-up blows. A fallen opponent gets up invulnerable for a moment and can strike at once — in some mods with a blow that reaches half the stage (Yamato's wood spike). Standing beside it is a blow taken for nothing, and so is standing anywhere its quick moves reach. The AI now works out where those moves strike (and how far in depth, with the step the opponent can take once it is up) and is out of that zone by the time the opponent is on its feet, by the quicker way: a few steps in depth off its line, or back out of reach, as on a stage too shallow for the first; off the line it may wait at its own range rather than far away. Which side of the line has room is judged from the opponent's line, so on a stage only a few steps deep it does not turn back and forth (version 28: before, Rock Lee walked to and fro on a fallen Neji's line on Hot Springs until Neji got up, or waited just off it, to be inside the zone again as Neji rose). It does not charge MP, drink or pick up a weapon inside the zone, and a charge stance beside a fallen opponent is left early enough to get out.
  15. Weighing the counter along the way. Before a move, the AI already asked whether the opponent's quickest answer would land first; it asked that from where the fighter stood. A rush or a jump-in carries the fighter into blows that did not reach its starting spot, and a punch the opponent starts as the rush sets off lands first there. The question is now asked along the move's own path, frame by frame, and out of the air for a jump-in. An opponent in a charge stance is known to be free the moment it can leave the stance, with the MP the charge brings in meanwhile; a trade (both blows landing together) is struck first only when the AI's blow is clearly the heavier.
  16. Weighing the risk, and learning it in the match. Version 23 did not start a blow that the opponent's quicker answer could beat on its way — as if the opponent always fired at the worst moment. A fighter that has to rush in (Rock Lee against Neji, whose quick beam covers the whole line) then rushed half as often and lost its share of the fight while walking about: standing off is no answer to long arms either. Version 24 weighs such a blow instead: what it brings if the answer does not come, against the answer's damage times how often this opponent has answered so far — counted in the match itself, from the AI's own rushes that were struck before they landed, starting hopeful. Against an opponent that punishes, the AI soon stops rushing; against one that does not, it keeps going. Like everything else, the count is taken from the match state alone.
  17. Out of the way with a move of its own. When something is coming that no step in depth, jump or step back gets the fighter out of, version 25 looks through the fighter's own moves for one whose path no blow on its way meets: a teleport, a rush, a leap. Kuma in One Piece GrandWorld vanishes as he jumps (defend pressed in the jump — keys a mod's jump takes are now learned as moves too) and comes down behind the enemy, untouchable on the way. Such a move is taken against a blow the guard cannot hold, against a heavy one when MP is left for a strong move afterwards, or when it strikes back on the way; otherwise the AI guards in time rather than start a move that cannot come out before the blow lands. A teleport is reckoned to land where the game puts it: in front of the enemy, or behind it when the move turns the fighter round first.
  18. Steady on its feet. In LF2 a direction key turns the fighter and walks it, so every turn round is a step. Version 25 forgot that at the edges it keeps: it stepped back from an enemy much too close, turned round to face it — a step back in — and stepped back again, frame after frame; the same at the edge of an enemy's quick blows and of a fallen enemy's wake-up blows, and between two ways out of them. The faster the fighter walks the worse it was (a Naruto of Naruto 2.4 walks 17 pixels a frame), and the less MP, the more of a match goes on walking — players saw it most at low MP and took it for the AI torn between a weapon on the ground and its opponent. Version 26 steps back until turning round again leaves room, waits at those edges instead of stepping in and out, keeps a way out once chosen, and turns round at most once every few frames while walking. In 70 games of Naruto 2.4, turns within three frames of the previous one fell from 116 to under 3 in every thousand frames.
  19. Beside the line of a wave. Neji's air palm in Naruto 2.4 is a wind sent along the ground at 55 pixels a frame, across the stage, and it cannot be guarded. The approach beside the line of a long blow (version 22) looked only at a move's first frames, so from afar the line seemed safe; it also stopped while Neji charged chakra or was short of MP, which he charges back in moments; and a run was steered back onto the line right after a palm was dodged. Version 26 reckons such a wave all the way out, keeps beside its line whenever the opponent will be free and able to pay for it by the time the fighter gets there, and steps or steers onto the line only once no wave flies along it. Gaara, who lost to Neji 16 games in 20, now wins 17 in 20; the single palm hits him a tenth as often.

A mod's own AI scripts (ai/*.as, as Dragon Ball Super's or Sauce's "lf2-AI VS and Stage Challenge") play its fighters at CRAZY! and below; INSANE! and XOI play at their own levels whatever scripts the mod has (up to version 40 a fighter with a script of its own kept it at those levels too, which in Sauce's pack made the levels named INSANE! and XOI that AI).

What INSANE! is aware of — and where it stands

A summary of what the computer player perceives, what it can do with it, and what is still to come. Each line names the version that brought it; the page's version badge above is read from the game build itself.

Awareness / abilityStatusSinceWhat it means in a fight
Its own moves, learned from the dataDonev14Every D-combo, punch, air, run and dash attack of any fighter in any mod: where and when it hits, what it costs, when the fighter is free again.
Chains, stances, charging, guard countersDonev15–16Keys pressed during a move, held moves left in time, MP charged when safe, striking out of the guard.
Jumping in and dashing inDonev16The air kit is used when a jump would land a move; the flight is computed from the fighter's own jump data.
The opponent's moves and projectilesDonev14What is about to hit, from which frame of which move, and everything in flight; its reach and danger zones shape the spacing.
Timing: stuns, knockdowns, invulnerabilityDonev15–16Attacks land as the opponent becomes hittable; flips up or stays down by the blows on their way; strikes first while blinking.
The opponent's habitsDonev19Guard rate, how pressing it is, whether it flips up: guard breakers against turtles, walking up to passive players, meeting flippers where the roll ends.
WeaponsDonev20, v45Picks up knives, sticks, stones and drinks when nothing presses; swings, throws or drinks by what it learned with the weapon in hand. From v21 to v44 that learning was lost: the weapon in hand was left out of what the private copy watched, so no swing and no throw was known to do anything, in any game. A fighter still walked to a stick and picked it up, and was left with its D-moves alone — short of MP it stood before its enemy, and two of them each with a stick stood for good (Deep and John in KT-LF2). v45 put the weapon back: against an opponent that never moves, a fighter with a stick had not won after 900 frames and now has within 540.
Teleport movesDonev20, v25Moves that teleport to the enemy (state 400) are aimed from where they land: 120 in front of the target, or behind it when the move turns the fighter round first.
Escaping with a moveDonev25When no step avoids what is coming, a teleport, rush or leap whose path no blow meets: against an unguardable or heavy blow, or to strike back; otherwise the guard.
Forms of a mod's own making (Gear Second, Diable Jambe)Donev21, v27A move that leaves an item in the hand is a form: its keys, runs, MP burn and worth are learned; entered when worth it and safe, fought in, and let end out of reach; a form entered from the guard (Magellan) or one that creeps on by itself is handled too. Forms inside forms (Zoro's Asura) not yet.
Untouchable forms (bodies on far layers)Donev27Which of its own frames each opponent's blows can reach at all: a form out of everyone's reach (Drake's T-rex, Magellan's Venom Demon) is entered for that alone and fought in up close; a phoenix flight is flown onto the opponent's line.
Get-up invulnerability spacingDonev21, v23, v28Out of a fallen or just-risen opponent's wake-up blows — its quick moves, however far they reach, and the step it can take once up — until its blink ends: a few steps in depth off its line (on shallow stages too), or back out of reach; no charging, drinking or weapon pick-up in that zone; farther at low HP.
Approach beside the line of fireDonev22, v26Against an opponent whose long blows cover the line between them (a beam, a wave across the stage — reckoned all the way out), closes in offset in depth and steps onto the line only when its own blows reach; also while the opponent charges MP or is busy for a moment, and never while a wave flies along the line.
Steady footworkDonev26A turn round is a step too: no stepping in and out at the edge of a distance, of an enemy's reach or of its wake-up blows; a way out once chosen is kept; while walking it turns round at most once every few frames.
Trapped opponents (a mod's holds)Donev22, v27An opponent held by an object is known to be held and, when the hold lets blows through, hittable: struck, or MP charged first and a strong move landed before the hold ends. A trap is not set again on an opponent already held. A grab is worth what follows it, and no guard holds it.
Weapons versus specialsDonev22With MP for its own specials, a weapon is worth only the few steps to one close by; drinks are taken whenever HP or MP are wanted.
Counters along a move's pathDonev23, v24The opponent's quickest answer is reckoned where a rush or a jump-in takes the fighter, not where it starts, and weighed against what the blow brings by how often this opponent has answered such a blow in the match so far. A charging opponent is known to be free as soon as it can leave the charge, with the MP it gained.
Team play (2 on 2, Stage)Partialv19–20Prefers the busy, the weak and the enemy holding a teammate; the second attacker goes round to the other side. No shared plan yet.
Healing movesDonev27A move that restores HP is measured with HP missing and used when much of the HP lost can come back and nothing reaches the fighter meanwhile (Marco's phoenix); drinks as before.
Summons that strike late (shadows, clones)Donev32A move none of whose objects has struck when the fighter is free again is followed on in the private copy until they do: Crimson's D^J in mode Convergence — five shadows that fly out, turn and slash back from frame 29, Crimson free from 25 — had been learned as doing nothing for 400 MP, and was never used.
Set-up moves (a shadow that strikes with the next move)Donev33A move that strikes nothing itself but leaves objects standing that strike with the fighter's next moves is learned as such: Crimson's DvJ in mode Convergence leaves a shadow (three or five with J pressed on) that copies her D>A, D^A or DvA from where it stands. In the private copy the set-up is played with each D-move after it, and once without: what the shadows strike only after the D-move is their answer. In a match a D-move is weighed with the blows of the shadows standing then, and the set-up is laid when it is safe and a D-move can follow while they stand. Crimson against the mod's 20 other fighters: 48.5% of 1,196 games, v32's Crimson 46.1% (as XOI with the mod's numbers 53.3% against 51.5%); every other fighter plays exactly as before.
A move under way foreseen in timeDonev34The forecast of an enemy's move already under way took the step just taken for one still to come: its blow was seen a frame late, a slide's 12 pixels short (Brad's slip kick in mode Convergence), and a step ending at the edge of its depth was taken for safe; things flying were seen against where the fighter stood a frame before. Against v33 over five mods, every pair of 8 fighters both ways: 1,307 to 897 (59.3%); against Sauce's AI (the community's, for the ten original fighters) 57 of 360 games won, v33 27.
In-match lessons (the blows taken)Donev34Each blow taken counts against the enemy's move that dealt it and the answer given to it just before: a move that keeps landing while the fighter was free is foreseen a little wider each time, an answer that keeps failing against it is no longer given (the others still are), and a heavy blow whose ways out have all failed is guarded. Against other computer players it changes little (51.3% of 879 decided games against the same without it; against Sauce's AI 68 of 360 games won, 57 without it): they do not change their habits.
Juggling (follow-ups in the air)Donev35An opponent knocked into the air is foreseen along its flight — the blow's impulse once its hit lag has passed, gravity, the falling frame by its speed, the landing and the lying after it — and only blows that touch a falling fighter count (fall 41 and more, whirlwinds). A knock-up is followed into the air: the D-sequences a move's frames take (Woody's D>J out of his flip kick's landing, the project owner's example) are learned as chains of the move, and the fighter's own D-moves start out of a move's recovery when they land first; a blow landing once the opponent may flip up is worth less by how often this one flips. Knock-ups followed up: 0 of 26 in v34's games of Woody against Sauce's Davis, about 4 in 10 now.
Rolls out of a run and the landing crouchDonev35Defend out of a run, and out of the landing crouch (frame 215, where a jump or an air move comes down), rolls: a way out of a blow that no step clears, where a run has no guard and the crouch no feet yet. On One Piece GrandWorld the rolls alone are worth about 20 of 448 games against v34.
Grabbing a dizzy opponentDonev35A dizzy opponent is walked into with the direction key held, so that the walking frames' catch takes it, when the hold is worth more than the best blow at it (its worth read from the fighter's data: the punch's injury and what a punch costs the hold's timer, the throw's injury), there is time and nothing else reaches the fighter on the way; held, it is punched while the timer has room for a punch and the throw (a punch's real cost measured on the first) and thrown then, toward the nearer wall. In 60 games against Sauce's AI the opponent went dizzy 17 times: 11 grabs (v34 none), about 55 HP a hold.
Steering in depthDonev35In a frame of a move that a direction key steers (its dvz) the fighter bends onto the opponent's line; a ball, a thrown thing or a missile leaves with the depth the key gives it, so a move whose object would miss straight and land steered is chosen and steered — the forecast knows the bend, and the key is held as the thing leaves. The forecast also reckons the attacker's own speed in depth (a dash kick flown onto the line from off it), and a running enemy's dash kick from the dash's first frame on, its depth steered toward the fighter at worst.
Who is passiveDonev35An opponent that hardly ever attacks when it could was taken for passive, its counters no longer expected — Sauce's AI attacks little and punishes much, and INSANE! started slow moves into its dash kicks. Passive now also means it has not landed a blow on the fighter in a move of the fighter's own.
Reversals (a mod's keys when hit)Donev36A move of the fighter's own out of being hit — a key the injured, falling, guard-broken, dizzy, lying or frozen frames take (the original's fighters have none): Kizaru of One Piece GrandWorld vanishes with defend and the game puts him behind the enemy, from where attack kicks it away; every fighter of Naruto: The Setting Dawn 2.6 has the substitution; Hell's have wake-up moves out of lying. Learned in the private copy from the frame that takes the key, with what the move's own frames take as its chains (a continuation from a frame reached turned round is read the way the fighter faces then). Hit, with a blow on its way, the reversal is the answer — the one that strikes first, else one out of the blow's way when it strikes back, the blow is heavy or MP stays; with none coming, the one whose blow lands before the opponent can hit back, when worth its MP. The opponent's reversal counts among its answers. INSANE! used to fire Kizaru's teleport without knowing it (a guard pressed as the blow landed) and stand where it put him. Against v35 on the eight One Piece fighters with such keys: 233 to 205; the usual five mods 1,120 to 1,089.
XOI's numbers tuned against Sauce's AIDonev37The project owner's tuning (spsa.bat, DOI_THU=classic) on Sauce's lf2-AI VS and Stage Challenge: 50 rounds on 83 threads over the ten original fighters, about 377,000 pairs of games, each pair the two nudged sets against that AI; the tuning's own check, about 77,000 games a set, 42.8% won against it (v29's set 39.9%). Now XOI's default set, all 77 numbers named: bolder in close and about being countered (counter_price 0.57 → 0.22, guard_counter 0.35 → 0.20, danger_sure 0.65 → 0.80), a hit on a target long free trusted less for longer, spots within slow or guard-breaking blows a quarter as dangerous, knocking down worth little of itself (fall_bonus 12 → 1.5), MP held dearer, weapons worth more steps, waiting further out of quick blows but closer to a fallen enemy, fewer flips within reach, a later guard. Against XOI with its old numbers (8 fighters a mod, every pair both ways, 4 games, two seeds): the ten original fighters 196–156, Convergence 243–200, KT-LF2 253–182, Hell 263–180, DBS 217–162, One Piece 230–217, NTSD 2.6 221–227, Naruto 2.4 411–471 (four seeds); against Sauce's AI 150 of 360 games won, the old numbers 115; against INSANE! on the ten 109–67 (the old numbers 92–83). A mod's own xoi/tune.txt stands over the default as before.
XOI's numbers, second run against Sauce's AIDonev40The project owner's second SPSA run against Sauce's AI (60 rounds of 15 minutes on 83 threads over the ten originals, about 580,000 pairs of games) found numbers that beat that AI 343 of 720 games to version 37's 308 and version 37's own numbers 186 to 166 — bolder, guarding faster, keeping a little farther from longer arms — but lost a little on five mods without numbers of their own (2,128 to 2,249 of 4,480). XOI being one player for every mod, version 40 takes the mean of the two sets: the mods even (1,083 to 1,101), Sauce's AI 321 of 720, the originals 178 to 166. A pack carrying the run's own numbers has the whole gain; one run over Sauce's pack and the mods together is the way to one set with it all.
XOI's brain (a learned score, NNUE-like)Donev41A small network beside the hand-made score: given 58 numbers of the situation and the move (distances, heights, facing, HP, MP, speeds, weapons, both fighters' states, the target's wait and blink, frames since the last blow, positions, the move's hit time and hand-made score, its damage, MP, reach, length and kinds) it predicts what the move will bring — HP dealt minus HP taken over the next 45 frames — and XOI moves its score halfway to that. Learned from XOI's own games by the kit's hoc-sau.bat (record.lua writes every move with its outcome, train.lua trains inside the game, 150,000 samples a second on LuaJIT), carried by a mod as xoi/brain.txt. On Sauce's pack: predictions that go with the outcome at 0.455 where the hand-made score goes at 0.197; the ten originals 368 of 720 games against Sauce's AI (version 40 alone 321), 216 to 134 against XOI without it; a second round recorded with that brain, 377 of 720. The same brain did nothing for other mods: one brain per pack. Also: INSANE! and XOI now play at their levels in a pack with AI scripts of its own (in Sauce's pack those levels had been Sauce's AI); thrown things whose burst is random measured over six throws (Nya's die 35 HP, not 10); summons still alive followed; position jumps read as teleports; a stream of balls met as a heavy blow is, ways out before a guard that would break under them (XOI's Julian against Sauce's Julian 32 to 48 of 80 games, 29 to 51 before — a corner under steered skull blasts is still a problem). Checks: Sauce's AI on the ten originals 160 of 360 games (version 40: 164 on the same seeds); the five mods against version 40, 1,088 to 1,082 of 2,240. The project owner's first full run of hoc-sau.bat on Sauce's pack (10 rounds of 20 minutes on 80 threads, 29 million moves recorded): XOI with the brain won 57.4% of its games against Sauce's AI, XOI without it 45.8%, same opponent, same seeds.
Momentum, left to the tuningDonev42The HP the fighter dealt its target lately less the HP it took (each fading by half every 60 frames, over 60 HP) can make it bolder or warier: six numbers — the boldness ahead, the score a move needs and the price of the target's counter ahead and behind, the danger kept away from behind — that SPSA tunes with the others (88 now). All 0 by default: the fighter plays frame for frame as v41 (the same results game for game on Sauce's pack and on KT-LF2). Tried by hand first (bolder ahead, warier behind, both, the lead in the match instead, only while the target is free), nothing beat the fighter without it, some fighters' gains lost by others; each mod's own tuning can now find what it wants, either way. Besides, hoc-sau.bat takes DOI_THU=xoi: XOI records against itself in a mod with AI scripts of its own too, most of them far weaker than Sauce's.
Long-term value (late blows, random draws, swaps)Donev43What a move brings later or leaves standing, not only what its blows do at once (the project owner's look at Nya in Sauce's pack). A move that shows nothing on the learning's untouchable dummy is tried again on one it can touch, at four distances and from six points of the random sequence: Nya's swap of places is learned as a teleport reaching 450 pixels, her coin and her cards as moves of random draws (the share that strikes, the frames only the striking draws go through, whether the others leave things standing). A late blow about the fighter that knocks down — the coin bursts by her 40 frames after she is free — is weighed as the space it holds when it does not land on the enemy's way (only a mine within 150 pixels: weighed so, Kakashi's and Shino's late blows in Naruto: The Setting Dawn lost games); with the swap at hand the burst is brought onto the enemy, and the swap is a way out of a thing flying at her whose thrower is within reach (Dennis's own ball struck him in a test). Her cards, never used before, are drawn with the target far, twice a match, as Sauce's AI does. The threat forecast follows a thing's next: 999 to its frame 0 as the game does (Kaktena's trap was not foreseen). XOI's Nya against Sauce's AI: 293 of 1,200 games with v42, 355 with v43 (Louis 1 to 27 of 80, Deep 5 to 14, Rudolf 31 to 42); Stancher of mode Convergence, whose late burst is such a mine, 109 of 256 games against v42 (75 before); the five mods against v42: 1,096 to 1,088 of 2,240.
An enemy's move steered onto our lineDonev39A move's frames that take the up and down keys (dvz) let the one playing it bend the move toward the opponent as it goes — what this player does with its own moves since v35, and what Sauce's AI and a person do. The forecast of an enemy's move under way took it for going straight: FreezeRV of mode Convergence dashes and grabs (D>J, six frames at dvz 1), Freeze played by XOI steered it onto Firen's line, and Firen, 20 pixels off that line with the grab 15 wide, saw it passing him by, stood still and was caught — then struck through the hold for most of the damage he took. Now the blow is foreseen bent toward the fighter by as much as the move's frames from now to the blow can steer, at worst, and answered as any other. FirenRV against FreezeRV, both XOI with the mod's numbers: 4 of 40 won up to v38, now 27 (Sauce's AI plays the pair 6 to 14). Against Sauce's AI on the ten: 158 of 360 (v38 163). Five mods against v38 (4,480 games over four seeds): 2,207 to 2,135, as even as they can tell.
Kiting with the shootersDonev38A fighter whose plain attack is a shot — a cheap move from the feet that sends something off 150 pixels and farther, too slow (8 frames and more) to fire point-blank: Henry's arrow, Rudolf's star; no other original fighter has one — fought a rusher at arm's length, or walked backward from it at its own pace facing away, and lost (against Sauce's ten, 72 games each: Henry 3 won, Rudolf 7). Now, with the enemy at arm's length (110 pixels), free and not striking, and room behind, it runs two steps and jumps out of the run with the key toward the enemy: the dash turns round in the air (frame 214), the fighter flies away facing it and shoots out of the dash when its data lets it (Henry's 214 takes attack into his jump attack, an arrow forward and down, and the frame takes the key again for a second while he is high enough) — what a person does with Henry, and what Sauce's own Henry does (28 back dashes, 38 air arrows in a two-game match). Landed 180 pixels off it shoots from its feet as before and kites again once the enemy is adjacent. Against Sauce's AI: Henry 18 of 72 (v37 3), Rudolf 15 (7); the ten 163 of 360 (v37 150), the other eight frame for frame as before. Five mods against v37: 1,070–1,093, as even as 2,240 games can tell (only Deapis of Convergence has such a shot among their 40). Four of the kite's numbers (the distance that starts it, the room behind, the second air shot's height, the shots a dash takes) join the numbers SPSA tunes — 81 now.
What a random move's draws leave (a shield, a change back, things that are no fighter)Donev44The project owner's follow-up on Nya's cards in Sauce's pack. Her spade leaves her changed, and D+J+A then changes her back with a burst: v43 drew it and never let it off (0 bursts in 1,200 games); the change back is now a move learned and chosen like any other (143 bursts, 67 HP each). Her crystal breaks the enemy's plain balls as they appear: learned as a shield by putting two balls far from the fighter in the learning's copy (both break at once; a thing with a body that a ball merely runs into, like Crimson's shadows in mode Convergence, is none), and while a shield of a fighter's side stands plain balls land nowhere on it — those flying are no threat, the enemy's ball moves no danger, and a fighter facing an enemy's shield throws none. The crystal also holds a hidden copy of Nya (a character without a body, HP 500): no target any more, and with nothing else left to fight its holder is struck until it breaks — Nya beaten and her crystal standing, the round went on for good (7 of 1,120 games ran to the bench's three minutes so; none now). Her heart's heal was collected already (110 HP a game with a heart); weighing a draw by what its kinds are worth at the moment was no better than the plain rule (411 wins to 415 over the same games) and is left out. Game by game over the same 1,200 games, XOI's Nya against Sauce's AI: 406 with v43, 418 with v44 (with the owner's numbers and brain 409 and 435); XOI's fighters against Sauce's Nya: 798 of 1,120 and 801.
Buff and summon moves without damagePartialv44Moves whose effect is not a hit, a heal or MP have no score of their own yet. Since v43 a move of random draws whose other draws leave things standing (Nya's cards: a heal, a crystal that breaks thrown things, bouncing balls) is drawn when the target is far, twice a match. Since v44 a shield among what it leaves is known for one (see above); a move that only leaves such a thing, with no draw that strikes, is still not cast for it.
Its numbers tuned by play (SPSA)Donev29–v31The numbers its judgement rests on — 77 since v30: what a hit is worth against its cost, the score a move needs, how far ahead it answers a blow on its way and when it guards, boldness in a standoff, spacing, when to charge MP, how soon it gives up a move that keeps coming to nothing — are gathered in smart.tune_ranges and tuned by spsa.bat in the XOI kit, the way chess engines tune theirs. v29's first 31 came from 40 rounds on 99 threads over the original LF2, Naruto 2.4 and One Piece GrandWorld, about 850,000 pairs of games: a little bolder and surer, 52.0% of 76,286 games won against the hand-set numbers. Since v30 a mod can carry numbers of its own (xoi/tune.txt, which spsa.bat writes and packs into <mod>-xoi.zip). Since v31 the tuned numbers are XOI's alone — v29's, or the mod's own over them, every player of a room alike, the match showing mod tuned beside XOI — and INSANE! plays with the hand-set ones, so that the last level is plainly the stronger.
No endless loopsDonev30, v32, v45Ten seconds and more with no blow between the two fighters is taken for a loop: a move tried again and again to no avail is worth less with every try (something else gets its turn), no spot is kept out of the enemy's reach any more, and a thrower that keeps it dodging is jumped toward over its throws. Before that it plays as before. A heavy item in hand is thrown once the target comes near, landing or not, and a fighter at a wall no longer turns round on the spot. Loops seen and gone: Itachi's fireballs against Sai's ink birds and Gaara jumping Itachi's kunai on the spot (Naruto: The Setting Dawn), Kakashi with a stone and Gaara with a log face to face at a wall. Two fighters pressed against the same wall at the same x part (v32): one of them takes the other to be on the wall's side and steps out into the stage. Standoffs that someone has to end (v45, from the project owner's clip: XOI's Nya and XOI's Felix face to face in Sauce's pack, Felix jabbing into her guard, then both standing for good): in a loop the target's quicker answer rules a slower blow out no more — her punch lands in 4 frames, his in 3, so she had nothing she might start, while his jab was worth less with every guarded try — and after twice the loop's time the score a move needs comes down frame by frame until the best move that lands is started, each fighter in frames of its own (two of XOI's else start in the same frame every time: Stancher and Crimson in mode Convergence, each punch carrying them through the other, punched past each other without end). The time is the clock's now, not the frames the fighter was free to decide in, and steps in depth that move nothing go round the obstacle along x (Sanji before a heavy item with Ace behind it, One Piece GrandWorld). Nya against Felix, 40 games of XOI against itself: 17 stood to the bench's three minutes with the owner's numbers for the pack and 6 with the default ones; none now. All 210 pairs of Sauce's 15 fighters, twice: 17 and 16 of 420 games at three minutes, 2 and 4 now, fights with blows to the end. Six other mods, 672 games: 13 at three minutes and 5 of them standing; 6 now, none standing.
The same on every computer of a roomDonev45What is learned of a frame of no known move during play (a fighter on fire) is kept by the frame and by whether the fighter is in the air, each frame from a play of its own. Up to v44 it was kept as played from wherever the fighter was when the frame was first met: what a fighter knew then depended on the matches played since the game was opened, and two computers of a network room that had not played the same matches could come to decide differently — which ends the room's game with "Network HP synchronization mismatch". Found by playing the same game with and without another game before it: Louis on fire was judged otherwise, three minutes in, when a game against Firen had come first.
Memory across matchesExperimentalv25INSANE! learns habits within a match only (a memory kept on one machine would break the lock-step of network games). XOI plays with notes of training shipped inside the mod's file, the same on every machine: see XOI.

How smart is it now? Against the mods' own computer players at CRAZY! it wins most fights (table below); against the original fighters, which CRAZY! already knows by heart, it is only somewhat ahead; a human who keeps changing habits is still the hardest opponent, because every habit it learns takes some seconds of play to show.

Version history

XOI — INSANE! with tuned numbers and a memory of training

INSANE! starts every match knowing what each move can do, from playing it in a copy of the game — but not how it fares against one particular opponent: a combo that lands on a still dummy may be cut short by Neji's quick palm nearly every time, while a modest-looking special lands four times in five. XOI, the level after INSANE!, plays as INSANE! does, with two things INSANE! has not: the numbers its judgement rests on tuned by play, and notes of training.

INSANE!XOI
The 88 numbers of its judgementSet by handTuned by play (SPSA, since version 31 XOI's alone): version 37's set, the project owner's tuning against Sauce's AI over the ten original fighters (version 29's, from the original LF2, Naruto 2.4 and One Piece GrandWorld, until then) — or the mod's own, xoi/tune.txt, when it has them (the match shows mod tuned)
Notes of trainingNoneThe mod's xoi/notes.txt, when it has been trained (below)
Measured against INSANE!—Version 37's set against INSANE! on the ten original fighters: 109–67 of 180 games (version 29's set 92–83); version 29's set against the hand-set numbers: 52.0% of 76,286 games won by either. A mod's own numbers against the tuned set (the project owner's two PCs, November 3): HELL 65.4%, KT 54.9%, Naruto 52.0%, One Piece 51.2% (tens of thousands of games each). Notes of training: 54.9% of 640 games (Naruto, below). Each part adds to the others; dau-nhieu.bat measures XOI against INSANE! on a mod as a whole.
  1. Training. A bench job plays many games — 100 to 200 — of every pair of the mod's fighters, both played by INSANE!, and writes down, for each fighter against each opponent and each move it chose: how often it landed, how often the fighter was hit before it did, the damage dealt and taken while it ran (its follow-ups included) and what the AI expected of it; and how often the opponent struck first a move started at a risk. On Windows, xoi-hoc.bat spreads the pairs over every processor of the machine and packs the notes into a copy of the mod's file (xoi/notes.txt, beside its data folder), ready for the relay.
  2. Playing. At XOI a move's score is weighed by how much of what was expected of it, against this opponent, it brought — against how much the fighter's moves brought on the whole. A move seldom tried stays near the average (its record counts over a few starts' worth of the average), and the weight stays between 0.5 and 1.6: the notes tilt choices rather than make them. The opponent's answers to a risky rush are expected from what training saw, and the match goes on counting them.
  3. The situation, too (version 27). Training also writes down each move's record by the situation it was started in — what the opponent was doing (on its feet facing the fighter or turned away, busy in a move, in the air, guarding, hurt or held), how far off it was (near, middle, far) and whether the fighter's own HP had run low — and, for every spot the fighter stood on with both fighters free (by distance, depth and side), the damage dealt and taken in the 45 frames after. At XOI each side of the situation changes a move's weight by a small part only (three quarters to four thirds, all three together seven tenths to seven fifths), and only as far as the starts seen there bear it out; a step onto a spot training found clearly worse is not taken, one onto a clearly better spot within a few steps is — clearly meaning by more than either may be off.
  4. In step. The notes are part of the mod's file, which every machine in a network room has, so what XOI decides still depends only on the match and that file: rooms and replays stay in sync. A mod without notes plays XOI with its tuned numbers only; the match line shows (XOI v27, N matchups), or no notes. Notes trained before version 27 have no situations or spots: XOI then weighs moves as before.

First measurement, Naruto: The Setting Dawn: 8 pairs of fighters, 100 training games each (800 games), then XOI against INSANE! on the same pairs with random seeds training never used, each fighter of each pair played by XOI in 10 games a seed: with version 25, 82–77 and 94–62 (176–139 with 5 draws, 55.9%); with the play of version 24 before it, 171–146 with 3 draws. Together 347–285 over 640 games (54.9%, ±3.9% at 95%), XOI's blows struck first less often (1,497 against 1,823). A second round on the same pairs — XOI against XOI on the notes, 100 games a pair more, or simply 100 more games of INSANE! — did not add to the first measurably: 172–148 and 169–146 on the same games, against 176–139: the notes only weigh which move is chosen, and that is soon learned. The notes were made against INSANE!'s own play, and a human plays differently: that is why XOI is a level of its own and INSANE! is not changed by them.

The situations, measured (version 27): 100 training games on each of 8 pairs of Naruto 2.4 and of KT-LF2, then XOI with the situations and spots against XOI with the moves' weights alone, each fighter of each pair played by each in 10 games: 75–80 and 83–73, 158–153 together — as strong, not stronger. A first, bolder version (situations added up in full, weights from 0.4 to 1.8) lost 63–93 on Naruto: a move's record split three ways rests on few starts, and much of what it shows is chance. What a situation adds is kept small for that reason; it is a memory to grow with more training rather than a gain yet.

Train XOI for your own mod, or play any mod with INSANE! and XOI on Windows instead of its own .exe (which stops at CRAZY!): the files you need, setup, training, measuring and sharing, step by step, in English and Vietnamese — INSANE! & XOI on your PC.

Benchmark results

INSANE! against CRAZY! (the mod's own computer player), 40 one-on-one games per mod over 10 different fighter pairs, 9000 frames per game at most, with a fixed random seed so anyone can reproduce the exact result.

ModINSANE! winsCRAZY! winsDrawsAverage HP left (INSANE! / CRAZY!)
One Piece GrandWorld3910479 / 1
Naruto: The Setting Dawn 2.43820350 / 4
KT-LF2 v3.0 (original LF2 roster plus new fighters)3640308 / 19
Sx2 ~ The power of emancipation3640320 / 11

Version 27 figures with --seed 12345 (version 26 gave 38–1 with a draw, 40–0, 29–11 and 36–4, version 25 40–0, 39–1, 31–9 and 38–2, version 24 35–4 with a draw, 35–4 with a draw, 30–10 and 37–3, version 23 34–5 with a draw, 37–3, 30–10 and 35–5, version 22 36–3 with a draw, 39–1, 29–11 and 38–2, version 20 35–5, 35–5, 28–12 and 30–10 on the same games; the LuaJIT desktop build and the Lua 5.2 web build give the same result frame for frame). Another seed (777) gives 38–2, 40–0, 32–8 and 37–3 for version 26 (38–2, 36–4, 30–10 and 38–2 for version 25; 34–6, 40–0, 33–7 and 38–2 for version 24; 37–2 with a draw, 39–1, 33–7 and 39–1 for version 23): against CRAZY! versions 22 to 26 are about equal, single pairs swinging by a game or two either way. The differences show against a strong opponent, head to head over the same ten pairs of each mod, three seeds, 240 games: version 23 against version 22 137–88 with 15 draws (Naruto 62–56, One Piece 75–32), taking fewer than half the hits from a just-risen opponent (90 against 211) and a fifth less damage; version 24 against version 23 120–107 with 13 draws (Naruto 59–61, One Piece 61–46), landing a fifth more blows; version 25 against version 24 115–112 with 13 draws (Naruto 56–63, One Piece 59–49). With each fighter of each pair played by each version (8 pairs, 10 games each way), version 25 beats version 24 87–70 and 86–73 in Naruto, where Sasuke's teleport now lands where the game puts it, and plays One Piece about even (67–72, 21 draws), cut short less often in both. Version 26 against version 25 the same way: 94–66 and 86–71 in Naruto, 83–62 (15 draws) and 75–71 (14 draws) in One Piece — 338–270 over the four, hit less often in each (86–71 and 83–62 were measured just before a last small change to the walk to a weapon; on Naruto's first seed it moved 93–66 to 94–66); Gaara against Neji, both played by one version, wins 17 games in 20 with version 26 and 4 with version 25. Version 27 against version 26 the same way: 82–74 and 89–65 in Naruto, 77–68 (15 draws) and 75–69 (16 draws) in One Piece, 76–79 in KT-LF2 and 76–79 in Sx2 — 475–434 over the six, ahead where the new reckoning has something to work on (untouchable forms, traps, grabs, charging) and level elsewhere; Naruto, Kakashi, Kankuro, Jiraiya and Kisame against Neji, both played by one version, win 10 games in 50 with version 27 and 4 with version 26. In the matchup that version 24 was made for, Rock Lee against Neji in Naruto, 20,000 games between versions 24 and 23 end 10,928–9,047 with 25 draws (54.7%, ±0.6%): version 24's Lee wins 38.9% against version 23's Neji, where version 23's own Lee won 28.2%, and its Neji is as strong as version 23's. (Until 1 November 2026 the two players of a head-to-head match on the bench shared one context — how they read the fighters' moves — which skewed matches between versions that read moves differently; the figures above are measured with separate ones.) "HP left" is the average over all 40 games, lost games counting as 0. In KT-LF2 the original computer player already knows the original fighters' moves, so the two are close; in mods with new fighters it barely knows how to use them.

Source code and building on it

The whole project is MIT-licensed (the original game and the mods are not covered). The AI is a single Lua 5.2 file that runs identically on the web, Windows, Linux, macOS and Android. Read it, change it, send a pull request.

scripts/base/game/smart_ai.luaAll of INSANE!: learning (analyze, play), prediction (earliest_threat, move_hits), scoring and choosing (best_attack, attack_score, approach_attack), defence (answer), and the per-frame control loop (smart.control). scripts/base/game/ai_scripts.luaRuns a mod's own AI scripts (ai/*.as) at CRAZY! and below. scripts/base/game/ai.luaThe original LF2 computer player (Easy to CRAZY!), for comparison. scripts/base/game/match.luaWhere the AI is called each frame (read_input) and where the fighters are learned when a match is created. scripts/base/ui/character_select.luaAdds INSANE! to the difficulty cycle (Tournament and Battle mode have their own files in the same folder). tools/ai-bench/The test bench: runs INSANE! against the original computer player in bulk, lists what the AI learned about a fighter and how often it uses each move, compares two versions of the AI file.

Good places to start

# Run the bench on your machine (see tools/ai-bench/README.md): 40 games of INSANE! against CRAZY! in the One Piece mod
openlf2 --pack onepiece.zip --mod tools/ai-bench --seed 12345 --input-trace ""
# Two computer players against each other: brains = {"smart", "smart@ai_alt"} in config.lua, ai_alt.lua being
# another version of smart_ai.lua — or your own player, started from tools/ai-bench/ai_template.lua
# audit = true adds, per brain, blows started, landed and interrupted, hits taken from a just-risen opponent or at a wall,
# trades, and what the fighter was doing when hit: the numbers a change is judged by, next to the score

Anyone can write a computer player of their own in the template's shape (a Lua module with prepare and control) and run it against INSANE! or any other player with the bench; an open arena where such players are submitted and ranked is the natural next step, and this is its ground floor.

Every decision depends only on the state of the match — the AI draws no random numbers of its own — so recordings and network games always replay exactly. After changing the AI, run replaytest in the bench to make sure that still holds.

About this build

LF2 Online is the OpenLF2 build maintained by Xôi: the web page, the relay server for network rooms with its library of mods, the Vietnamese player guide, and the INSANE! computer player. INSANE! was Xôi's problem statement; Xôi tested it mod by mod and gave feedback over many versions, and the programming was done together with Claude (Anthropic). OpenLF2 itself is the open-source project of the OpenLF2 community.

Sauce shared his lf2-AI VS and Stage Challenge openly: a computer player for the ten original fighters, written for LF2's AI script engine (ai\<id>.as). OpenLF2 runs those scripts as they are (from package 56), so INSANE! and XOI could fight a player made by someone else — the measure quoted in the history above — and v35 learned several of its habits, worked out in a form that holds for every mod: grabbing a dizzy opponent and punching before the throw, rolling out of a run or the landing crouch, holding a direction to steer a move or a ball onto the opponent's line, and following a knock-up into the air. Thank you, Sauce.