LF2 Online by Xôi · the fifth computer-player level
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.
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.
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.
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).
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 / ability | Status | Since | What it means in a fight |
|---|---|---|---|
| Its own moves, learned from the data | Done | v14 | Every 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 counters | Done | v15–16 | Keys pressed during a move, held moves left in time, MP charged when safe, striking out of the guard. |
| Jumping in and dashing in | Done | v16 | The 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 projectiles | Done | v14 | What 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, invulnerability | Done | v15–16 | Attacks land as the opponent becomes hittable; flips up or stays down by the blows on their way; strikes first while blinking. |
| The opponent's habits | Done | v19 | Guard rate, how pressing it is, whether it flips up: guard breakers against turtles, walking up to passive players, meeting flippers where the roll ends. |
| Weapons | Done | v20, v45 | Picks 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 moves | Done | v20, v25 | Moves 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 move | Done | v25 | When 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) | Done | v21, v27 | A 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) | Done | v27 | Which 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 spacing | Done | v21, v23, v28 | Out 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 fire | Done | v22, v26 | Against 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 footwork | Done | v26 | A 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) | Done | v22, v27 | An 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 specials | Done | v22 | With 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 path | Done | v23, v24 | The 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) | Partial | v19–20 | Prefers the busy, the weak and the enemy holding a teammate; the second attacker goes round to the other side. No shared plan yet. |
| Healing moves | Done | v27 | A 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) | Done | v32 | A 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) | Done | v33 | A 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 time | Done | v34 | The 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) | Done | v34 | Each 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) | Done | v35 | An 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 crouch | Done | v35 | Defend 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 opponent | Done | v35 | A 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 depth | Done | v35 | In 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 passive | Done | v35 | An 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) | Done | v36 | A 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 AI | Done | v37 | The 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 AI | Done | v40 | The 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) | Done | v41 | A 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 tuning | Done | v42 | The 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) | Done | v43 | What 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 line | Done | v39 | A 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 shooters | Done | v38 | A 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) | Done | v44 | The 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 damage | Partial | v44 | Moves 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) | Done | v29–v31 | The 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 loops | Done | v30, v32, v45 | Ten 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 room | Done | v45 | What 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 matches | Experimental | v25 | INSANE! 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.
smart_ai.lua as well.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 judgement | Set by hand | Tuned 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 training | None | The 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. |
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.(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.
.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.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.
| Mod | INSANE! wins | CRAZY! wins | Draws | Average HP left (INSANE! / CRAZY!) |
|---|---|---|---|---|
| One Piece GrandWorld | 39 | 1 | 0 | 479 / 1 |
| Naruto: The Setting Dawn 2.4 | 38 | 2 | 0 | 350 / 4 |
| KT-LF2 v3.0 (original LF2 roster plus new fighters) | 36 | 4 | 0 | 308 / 19 |
| Sx2 ~ The power of emancipation | 36 | 4 | 0 | 320 / 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.
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.
smart.levels: the reaction time of each level; a new level is one more line.attack_score: the formula that scores a blow. To make the AI bolder or more careful, change it here.danger_at, preferred_range: how the AI chooses where to stand.approach_attack: jumping in and dashing in; stance_exit: held stances.watch, guard_rate, pressure, flips_up: the opponent model,
counted once a frame; add a habit there and use it in attack_score or the positioning.weapon_to_take, over_weapon, armed_analysis, view_of: which
weapon is worth picking up, and the fighter's moves re-learned with each kind of weapon in hand.mode_entries, mode_drain, enter_mode, mode.worth: a form of
the fighter's own making (an item of its own in hand), what its keys do, what it burns, and whether it is worth
entering; the "enter mode" and "mode run" blocks of smart.control enter it and move in it.wake_zone, wake_escape: where a fallen opponent's wake-up blows strike and the quicker
way out; counter_along, enemy_reach with a path: the opponent's quickest answer where a move
takes the fighter; stance_leave: how soon an opponent can leave a charge or a field;
answer_chance, worth_the_risk: how often this opponent has struck a risky blow of ours
first, and whether a blow is worth that risk.# 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.
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.