Little Fighter Empire - Forums
Community Project: Little Fighter Online – English Translation & Modding Initiative - Printable Version

+- Little Fighter Empire - Forums (https://lf-empire.de/forum)
+-- Forum: Little Fighter Zone (https://lf-empire.de/forum/forumdisplay.php?fid=20)
+--- Forum: Little Fighter Online (https://lf-empire.de/forum/forumdisplay.php?fid=22)
+--- Thread: Community Project: Little Fighter Online – English Translation & Modding Initiative (/showthread.php?tid=11429)



Community Project: Little Fighter Online – English Translation & Modding Initiative - theunderdark - 04-14-2025

Hey everyone!

I’d like to kick off a community-driven project focused on Little Fighter Online (LFO).

Project Goal

The main goal is to fully translate Little Fighter Online into English to make it more accessible to international fans. In the long term, we aim to mod, extend, and enhance the game – similar to what the LF2 community has done so successfully over the years.

If you're interested in translation, reverse engineering, game development, pixel art, or modding, you’re more than welcome to join!

1. Current Game Version (Story & Missions in English, UI still in Chinese)

Download: https://mega.nz/folder/9zJV0bCa#Sxxq7XdPnwpuq3M4v1o0KQ
ZIP Password: WirLiebenLFO
How to use & play: https://lf-empire.de/forum/showthread.php?tid=11180
Original (Untranslated) Source: https://gitlab.com/str1ckland/lfo/-/archive/master/lfo-master.zip

2. Important Files for Modding (LF2 equivalent: Data, Sprites, etc.)

Compared to LF2's simpler structure (Data, Sprite, bgm), LFO includes several more folders.
All *.lfo files are actually password-protected zip files.
You can rename .lfo to .zip, extract them with a password, edit, then re-pack and rename them back to .lfo.

Example:
Rename string.lfo to string.zip → extract → modify → re-pack → rename to string.lfo

File Names & Passwords:
Code:
is.lfo:c254K136/108y276H321w274j167-2945114o78;120j1670203^249)290t271 pak.lfo:e350M2321204{372J417y370l263/3907210q174=216l2632299`345+386v367 loadsprite.lfo:c348K230/202y370H415w368j261-3885208o172;214j2610297^343)384t365 loadstorylist.lfo:)196o78S50?218l263=2160109Q236Y56520_620109T145$191M232:213 string.lfo:~187f69J416209c2544207'100H227P47,11V53'100K136y182D2231204 story.lfo:k356S2387210#378P423!376r2695396=216w180C222r2698305f3511392|373 spe.lfo:q362Y244=216)384V429'382x275;402C222}186I228x275>311l3577398$379 map.lfo:g352O2343206}374L419{372n26513929212s176?218n2654301b347-388x369 bg.lfo?:P2358117z89f2575302d255W148x275"95\59(101W148{184K230t271a252 speb?:2205x87\59H227u272F2259118Z245b65>29h719118]154-200V241C222 spew.lfo:G226/108q80]248,293[246N139o266w86S50}92N139r175B221k262X243 spes.lfo:C222+104m76Y244(289W242J135k262s82O46y88J135n171>217g258T239 talk.lfo?:4207z89^61J229w274H227;120\247d67@31j73;120_156/202X243E224 spec.lfo:3206y88]60I228v273G226:119[246c66?30i72:119^155.201W242D223 script.lfo:|185d67H394207a2522205%98F225N45*9T51%98I134w180B221/202 spen.lfo:>217&99h71T239#284R237E130f257n77J41t83E130i1669212b253O234

Quick File Overview

is.lfo
Likely just a version tracking file. Contains simple text.

pak.lfo
Loads moves, scenes, characters – core game data.

loadsprite.lfo
Loads characters, NPCs, weapons, effects, etc. If something doesn’t appear in this file, it won’t appear in-game.

loadstorylist.lfo
References all story/mission files. Points to *.dat files like loadstory.dat.

string.lfo
Manages all text in the game: character names, level names, dialogs.

story.lfo
Main story and mission content. You can design or alter stages here.

talk.lfo
All dialogs between characters.

script.lfo
Controls character behavior in scenes – position, actions, dialogs.

spe.lfo
Main file for player characters – controls movement, attributes, etc.

spes.lfo
Visual effects (e.g. explosions, lightning, etc.).

spec.lfo
Enemy data.

spen.lfo
NPC definitions.

map.lfo
Stage maps. Each file can contain multiple scenes.

bg.lfo
Background.

(Note: I haven't figured out all files yet. But using my LF2 experience, I've been able to make progress. I'll try to share more in-depth documentation soon.)

A bit of fun in the meantime:
https://www.youtube.com/watch?v=Wg_tzTz7maY&list=PLQKmpJTenVjgXaT7yHN96-qg545fdz-eF

I've uploaded a modified version of the story where all NPCs join your team. Inspired by LF2 Stage 5 (LouisEX, Bat join scene ?)

3. Graphic Files – .tzw (Similar to LF2: Sprites)
These .tzw files contain graphics and are doubly compressed.
With the help of AI, I’ve managed to extract and re-import them.

BUT there’s a problem: After re-importing, the game doesn’t accept the modified .tzw files. Using hex editors like HxD, I found header differences but haven’t solved it yet.

Test file:
Try modifying lfo33.tzw (only one move for the character Milo). If you manage to import it and it works, please let me know! :D

Python script to extract images:

Code:
import os import sys def find_image_chunks(data, signatures):     found_chunks = []     for fmt, sig in signatures.items():         index = 0         while index < len(data):             idx = data.find(sig, index)             if idx == -1:                 break             if fmt == "PNG":                 end = data.find(b'IEND', idx)                 if end != -1:                     end += 8  # Include CRC                     chunk = data[idx:end]                     found_chunks.append((fmt, idx, chunk))                     index = end                     continue             elif fmt == "JPEG":                 end = data.find(b'\xff\xd9', idx)                 if end != -1:                     end += 2                     chunk = data[idx:end]                     found_chunks.append((fmt, idx, chunk))                     index = end                     continue             index = idx + 1     return found_chunks def main(input_path):     with open(input_path, "rb") as f:         data = f.read()     signatures = {         "PNG": b"\x89PNG\r\n\x1a\n",         "JPEG": b"\xff\xd8\xff",     }     chunks = find_image_chunks(data, signatures)     output_dir = os.path.splitext(input_path)[0] + "_extracted_images"     os.makedirs(output_dir, exist_ok=True)     for i, (fmt, offset, chunk) in enumerate(chunks):         ext = ".png" if fmt == "PNG" else ".jpg"         out_path = os.path.join(output_dir, f"image_{i+1}_{offset}{ext}")         with open(out_path, "wb") as out_file:             out_file.write(chunk)         print(f"Extracted: {out_path}")     print(f"{len(chunks)} Bilder gefunden, gespeichert im Ordner: {output_dir}") if __name__ == "__main__":     if len(sys.argv) != 2:         print("Verwendung: python extract_images.py <Dateipfad>")     else:         main(sys.argv[1])

Usage: python extract_images.py path_to_file.tzw
Example: python .\exportLFO.py .\lfo33.tzw


Script to re-pack .tzw files:
(Contains a simple UI. Just run it.)

Code:
import os import tkinter as tk from tkinter import filedialog, messagebox def repack_images_from_folder(input_folder, output_path):     try:         files = sorted(os.listdir(input_folder), key=lambda x: int(x.split('_')[2].split('.')[0]))         with open(output_path, 'wb') as out:             for fname in files:                 path = os.path.join(input_folder, fname)                 with open(path, 'rb') as f:                     out.write(f.read())         messagebox.showinfo("Erfolg", f"wurde neu verpackt als {output_path}")     except Exception as e:         messagebox.showerror("Fehler", str(e)) def select_folder_and_pack():     # Get the script's root directory     root_directory = os.path.dirname(os.path.realpath(__file__))     folder = filedialog.askdirectory(initialdir=root_directory, title="Wählen Sie den ursprünglichen Bildordner aus")     if not folder:         return     output_path = filedialog.asksaveasfilename(         initialdir=root_directory,  # Set the default directory to the script's root         defaultextension=".tzw",         filetypes=[("TZW-Datei", "*.tzw"), ("Alle Dateien", "*.*")],         title="Gepackte Datei speichern"     )     if not output_path:         return     repack_images_from_folder(folder, output_path) if __name__ == "__main__":     root = tk.Tk()     root.title("TZW Repacker (Bit Preservation)")     root.geometry("320x130")     label = tk.Label(root, text="Klicken Sie, um einen Ordner auszuwählen und in .tzw neu zu packen .tzw", font=("Arial", 12))     label.pack(pady=10)     btn = tk.Button(root, text="Ordner auswählen und packen", command=select_folder_and_pack, font=("Arial", 12))     btn.pack(pady=5)     root.mainloop()


Note: This script was built with ChatGPT’s help. If you know a better solution (especially one that works 100%), please share!

4. Multiplayer – The Big Problem
Currently, the game only works in single player mode via StartLFO.exe.
The reason: No server is available and we cannot decode the binary.bin file.

The reason: No server is available and we cannot decode the binary.bin file.

LFO is launched using StartLFO.exe, which is a NW.js app. Pressing F12 opens the dev tools where client-server communication is visible.
The file binary.bin seems to contain server config (character data, levels, etc.) and is loaded like this:

Code:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0"> <title>StartLFO</title> </head> <body> <div id="root"></div> <script> const binary = process.platform == "darwin" ? "binary_mac.bin" : "binary.bin" nw.Window.get().evalNWBin(null, binary) </script> </body> </html>

If anyone is able to decode binary.bin – I would be endlessly grateful!

Download StartLFO.exe + binary.bin separately: https://mega.nz/folder/9zJV0bCa#Sxxq7XdPnwpuq3M4v1o0KQ


This is a summary of all the work I’ve done so far. I’ve probably forgotten a few things over the years, but I’ll happily answer any questions. I also think a Discord group might be a good idea.

With open hands and hope – I’m truly asking for the community’s help.