A monorepo of young ideas
README.md

Foreversight #

Keep track of and plan your characters in WoW Forever.

Foreversight has two halves:

  • The addon (addon/Foreversight) records each character's bags, bank, mail, equipment, skills, gold, and level into the account-wide ForeversightDB SavedVariable.
  • The app imports those SavedVariables into its own database and lets you search every item across all your characters, warns before items in the mail expire, and shows each character's professions. It's built on Shikra, and is a motivating example for what Shikra needs next.

Setup #

  1. Link the addon into WoW's addon folder:

    ln -s "$PWD/crates/foreversight/addon/Foreversight" "<WoW>/<flavor>/Interface/AddOns/Foreversight"
    
  2. Log in to each character. Open the bank and the mailbox once on each, since they can only be read while they're open. /foreversight shows what's been recorded, and /foreversight mail shows the mail.

  3. Log out or /reload. WoW only writes SavedVariables then.

  4. Run the app and choose your WoW directory. It finds the WTF/Account/*/SavedVariables/Foreversight.lua files under it, and reloads them when they change. It remembers the directory in settings.json in the platform's config directory (~/.config/foreversight on Linux), or at FOREVERSIGHT_SETTINGS. Change it in the settings, from the button at the bottom of the sidebar.

    cargo run -p foreversight
    

    To script it, pass the directory, or set FOREVERSIGHT_WOW_DIR. Either one takes the place of the chosen directory for that run:

    cargo run -p foreversight -- "<WoW>"
    

    Click an item's name, or focus it and press Enter, to open it on Wowhead.

To try it without WoW, use the sample data. Point FOREVERSIGHT_DATABASE and FOREVERSIGHT_SETTINGS somewhere else, so the sample characters don't end up alongside yours, and choosing a directory doesn't replace yours:

FOREVERSIGHT_DATABASE=/tmp/sample.db FOREVERSIGHT_SETTINGS=/tmp/sample.json \
  cargo run -p foreversight -- crates/foreversight/fixtures/Sample.lua

The directory picker is the system's, through xdg-desktop-portal on Linux. If there's no portal, the app says so under the button that opened it.

Where characters are kept #

The app keeps characters in a SQLite database, foreversight/foreversight.db in the platform's data directory (~/.local/share on Linux), or at FOREVERSIGHT_DATABASE. Each time the SavedVariables change, it imports them, keeping whichever record of each character is newest. So characters stay after their SavedVariables are gone, and the app shows them even when it's run without any. There's no way to forget a character yet, short of deleting the database.

The code is split so the SavedVariables are only one way in:

  • domain has the characters and their items, and the CharacterRepository they're kept in, without knowing how.
  • import reads SavedVariables into the domain and saves them to a repository.
  • persistence keeps the domain in SQLite. Change the schema by adding a migration to the end of MIGRATIONS, never by editing one.

Icons and tooltips #

Item icons and tooltips come from Wowhead's tooltip data for each item (Forever's database, or Classic's for items Forever's doesn't have yet), which has the tooltip's HTML and the name of the item's icon. The icon images, and coins, come from Wowhead's CDN, wow.zamimg.com. Everything is cached in ~/.cache/foreversight (or the platform's cache directory), so each is only downloaded once, and at most four icons and four tooltips are downloaded at a time. Delete the directory to download them again. Icons that fail to load show an empty frame, coins fall back to colored discs, and tooltips fall back to the item's name.

Tooltips for items with random enchantments are incomplete: the tooltip data for ?bonus= has the version's name and some of its stats, but Wowhead's page script adds the rest, like resistances. The Short Bastard Sword of Fire Protection is missing its +1 Fire Resistance.

These endpoints are undocumented, and we haven't confirmed that Wowhead's terms allow using them this way. IconSource and TooltipSource keep the sources swappable.

The data format #

The addon writes ForeversightDB in the format described at the top of Foreversight.lua. When it changes, bump FORMAT_VERSION in both the addon and saved_variables.rs.

fixtures/Sample.lua is generated by running the real addon against a fake WoW API, so it's also a test of the addon:

cd crates/foreversight/fixtures
nix shell nixpkgs#lua5_1 -c lua generate.lua > Sample.lua

What we know about Forever's addon API #

  • Characters have a first name and a surname. UnitName("player") only gives the first name, and UnitFullName("player") gives the surname where other clients give the realm. The addon keys characters by both.
  • Bags, equipment, and money are gone by PLAYER_LOGOUT, so the addon records them as they change instead.
  • GetInventoryItemID gives 0, not nil, for the ammo slot (0), which Forever doesn't have.
  • Item links use the newer quality markup, like |cnIQ1:|Hitem:…|h[Name]|h|r.
  • Items with random enchantments, like "Short Bastard Sword of Fire Protection", share an item ID. The version is a bonus ID in the link, not a suffix ID: |Hitem:3192::::::::6:1486:::1:12741::::::|h. Wowhead takes it as ?bonus=12741.

Open questions #

  • The TOC's ## Interface: 16001 comes from another addon that was ported to Forever. Check it in game with /dump select(4, GetBuildInfo()).
  • The addon handles both the classic bank (bank container plus bank bags) and the newer bank tabs. We don't know yet which one Forever has.
  • Is using Wowhead's tooltip data and image CDN for icons OK under its terms? Blizzard's Game Data API has official item media, but needs API credentials, and may not cover Forever.
  • Forever doesn't have the skill frame's list of every skill, GetNumSkillLines and GetSkillLineInfo, but does have GetProfessions and GetProfessionInfo, which the addon records professions with. /foreversight skills shows them as recorded.
  • The mail API is the one other modern clients have (GetInboxHeaderInfo, GetInboxItem, and MAIL_INBOX_UPDATE), and hasn't been checked on Forever yet. /foreversight mail shows the mail as recorded.
  • Equipment seems not to be loaded at PLAYER_LOGIN or PLAYER_ENTERING_WORLD, so the addon also records it on UNIT_INVENTORY_CHANGED. If equipment is still missing, /foreversight equipment shows what the client gives for each slot.

What Shikra needs #

Gaps that Foreversight works around today, roughly in order of how much they matter here:

  • Text truncation, for long item names in narrow rows.
  • Window-wide key listeners, so Escape can close a tooltip opened by the mouse while focus is elsewhere, like in the search field.