A Windower 4 addon for Final Fantasy XI that records incoming tells, party chat, and linkshell messages to a local SQLite database and lets you search your message history with flexible filters.
- Records incoming tells, party chat, Linkshell 1, and Linkshell 2 messages automatically
- Your chat messages are stored in a local SQLite database stored on your machine and are not shared with anyone.
- Stores each message with the sender name, timestamp, and chat type
- Per-character database — each character you play gets their own history file
- Search by chat type, player name (partial match), date range, or any combination
- Control result count and sort order
- Built-in auto-pruning on login to keep the database from growing indefinitely
- Manual purge and vacuum commands for maintenance
- Windower 4 (includes the
lsqlite3library that this addon depends on) - Final Fantasy XI (Windows)
-
Download or clone this repository.
-
Copy the
ChatHistoryfolder into your Windower addons directory:<Windower install folder>\addons\ChatHistory\The result should look like:
Windower\ └── addons\ └── ChatHistory\ ├── ChatHistory.lua └── README.md -
Load the addon in one of two ways:
In-game (once):
//lua load ChatHistoryAutomatically on every login — add this line to your
<Windower>\scripts\init.txt:lua load ChatHistory
When the addon loads successfully you will see:
[ChatHistory] v1.0.0 ready (YourCharacterName). Type //ch help for usage.
The database file is created automatically at:
Windower\addons\ChatHistory\data\YourCharacterName.db
All commands use either //chathistory or the shorter alias //ch.
//ch search --type tell
//ch search --type party --order desc --limit 50
//ch search --player Shantotto
//ch search --type ls --from 2024-06-01
//ch search --player Maat --from 2024-01-01 --to 2024-03-31
//ch stats
//ch purge --days 30
//ch search [options]
All options are optional and can be combined freely. Results default to ascending order (oldest first) with a limit of 20.
| Option | Short | Value | Description |
|---|---|---|---|
--type |
-t |
see below | Filter by chat channel |
--player |
-p |
name | Sender name — partial, case-insensitive match |
--from |
-f |
YYYY-MM-DD | Return messages on or after this date |
--to |
YYYY-MM-DD | Return messages on or before this date | |
--limit |
-l |
number | Maximum rows to return (default: 20) |
--order |
-o |
asc / desc |
Sort direction (default: asc) |
| Value | What it returns |
|---|---|
tell |
Incoming tells only |
party or pt |
Party chat |
ls or linkshell |
Linkshell 1 and Linkshell 2 combined |
ls1 or linkshell1 |
Linkshell 1 only |
ls2 or linkshell2 |
Linkshell 2 only |
all |
Every recorded message type |
// All tells, oldest first (default order)
//ch search --type tell
// Last 10 party messages, most recent first
//ch search --type party --order desc --limit 10
// Everything from a specific player across all channels
//ch search --player Shantotto
// LS1 and LS2 messages since June 1, 2024
//ch search --type ls --from 2024-06-01
// Tells from a player within a specific month
//ch search --type tell --player Maat --from 2024-01-01 --to 2024-01-31
// 50 most recent messages of any type
//ch search --type all --order desc --limit 50
Date note:
--from 2024-06-01starts at midnight on that date.--to 2024-06-01ends at midnight, so to include the full day pass--to 2024-06-02or use--to 2024-06-01with--fromon the same date to get just that day's midnight-onward messages. For precise control you can use the full format:--from 2024-06-01and--to 2024-06-02.
Displays the number of recorded messages per type, the total row count, the date of the oldest stored message, and the path to the current database file.
//ch stats
Example output:
[ChatHistory] Statistics:
Tells: 142
Party: 891
LS1: 2,304
LS2: 47
Total: 3,384
Oldest: 2024-01-15
Path: C:\...\addons\ChatHistory\data\Warrior.db
Deletes all messages older than a given number of days. Useful for manually trimming history beyond the automatic pruning window.
//ch purge [--days N]
| Option | Default | Description |
|---|---|---|
--days N |
90 | Delete messages older than N days |
Examples:
// Delete messages older than the default (90 days)
//ch purge
// Delete messages older than 30 days
//ch purge --days 30
// Delete messages older than 1 year
//ch purge --days 365
After a large purge, run
//ch vacuumto reclaim the disk space.
Rebuilds the database file to reclaim disk space freed by deleted rows. This can take a moment on large databases but is safe to run at any time.
//ch vacuum
Prints the command summary in-game.
//ch help
Open ChatHistory.lua and edit the CONFIG block near the top of the file:
local CONFIG = {
-- Default number of results returned by //ch search
default_limit = 20,
-- Auto-prune messages older than this many days on login.
-- Set to 0 to disable automatic pruning.
prune_days = 90,
-- Print unrecognised incoming chat modes to the chat window.
-- Enable temporarily if a chat type is not being recorded.
debug_modes = false,
}Reload the addon after saving any changes:
//lua reload ChatHistory
| What | Where |
|---|---|
| Database files | <Windower>\addons\ChatHistory\data\ |
| One file per character | data\CharacterName.db |
| Format | SQLite 3 |
In normal use, no. FFXI chat volume is low compared to modern MMOs. With the default 90-day retention:
| Play style | Est. messages/day | 90-day rows |
|---|---|---|
| Casual (2 hrs) | ~100 | ~9,000 |
| Active (4 hrs) | ~300 | ~27,000 |
| Heavy (8 hrs) | ~600 | ~54,000 |
SQLite handles millions of rows efficiently; even at 100,000 rows a typical search completes in under 50 ms thanks to the indexes on type, sender, and timestamp.
If you want a longer history, raise prune_days — even 365 days is well within SQLite's comfort zone. If disk space is a concern, lower it or run //ch purge --days 30 periodically.
The incoming chat mode numbers in the addon (TELL=12, PARTY=13, etc.) are based on community documentation and may vary with certain Windower or FFXI versions.
To find the correct values for your setup:
- Open
ChatHistory.luaand setdebug_modes = truein theCONFIGblock. - Reload the addon:
//lua reload ChatHistory - Have someone send you a tell, speak in your party, or say something in your linkshell.
- Look for a line like:
[ChatHistory DEBUG] mode=12 text=PlayerName >> hello - Note the mode number for each chat type that was not recording.
- Update the corresponding value in the
CHAT_MODESblock:local CHAT_MODES = { TELL = 12, -- update if needed PARTY = 13, -- update if needed LINKSHELL1 = 14, -- update if needed LINKSHELL2 = 214, -- update if needed }
- Set
debug_modes = falseagain and reload.
This is normal if you loaded the addon from the main menu before selecting a character. The addon will initialise automatically once you enter the game world.
- Check that
--from/--todates are inYYYY-MM-DDformat. - Player name matching is partial but requires at least one character —
--player amatches anyone with "a" in their name. - Run
//ch statsto confirm the database has rows for the type you're searching.
Copy the .db file for your character out of the data/ folder:
Windower\addons\ChatHistory\data\YourCharacterName.db
It's a standard SQLite database file and can be opened with any SQLite browser (e.g. DB Browser for SQLite).
BSD 3-Clause License. See source file header for full text.