Skip to content

About

Visual, no-code content builder for tswow: create WoW 3.3.5a spells, items, creatures, quests and addon UI with the mouse, get readable TypeScript datascripts out. Zero dependencies.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

tswow Content Studio

Build WoW 3.3.5a content with your mouse. Get readable TypeScript out.

A visual content builder for tswow — spells, items, creatures, game objects and quests — plus a WYSIWYG addon designer that draws with your client's real textures.

Node Dependencies Platform tswow

English · Русский


What this is

tswow lets you build World of Warcraft content by writing TypeScript datascripts. That is a great model — and a hard first step if you do not write code.

This studio is a local web app that puts a form in front of every one of those datascripts. You fill it in, press Generate module code, and it writes a plain, readable, compilable TypeScript datascript into your module. Nothing is hidden and nothing is locked in: the output is an ordinary tswow module that builds with build data and travels with you if you stop using the studio.

  • Zero dependencies, zero install. One folder, no npm install. It runs on the Node.js that already ships inside tswow.
  • Nothing is a black box. The generated code is commented, readable, and meant to be learned from.
  • Your hand-written code is safe. The studio only ever regenerates datascripts/generated/.
  • Bilingual. Full Russian and English interface, switchable at runtime.

Scope: this is a data tool. Maps, terrain and models are deliberately out of scope — use Noggit and a model editor for those. See What it deliberately does not do.

Screenshots

Creating a spell — recipe picker, form and the live generated datascript

Pick a recipe, fill in the form, and the datascript on the right updates as you type. Reference fields are checked against the game as you pick them — note the base spell resolving to Hammer of Justice (#853) ✓.

Creating a creature — the recipe decides which fields you see

Same flow for every content type: the recipe you choose decides which fields appear, and the emitted code maps to them one-to-one — no hidden state, no magic numbers.

Quick start

  1. Put the tswow-content-studio folder next to your tswow installation folder — the one that contains modules/ and bin/.
  2. Run start.bat.
  3. Your browser opens at http://localhost:8787.

That is the whole setup. There is nothing to install: the studio finds the Node.js bundled with tswow, and it has no dependencies of its own. If tswow lives somewhere else, set the path in the interface — it is saved to studio.config.json.

The first launch takes a couple of minutes. This repository ships code only: the game assets belong to Blizzard and cannot be redistributed. So the studio pulls icons and interface textures out of your own client on first start — in the background, with progress shown under Settings. FrameXML sources usually need no extraction at all: tswow unpacks them while building the dataset (<dataset>/luaxml_source/Interface), and the studio reads them straight from there — faster and more complete, because the file list inside the client MPQs is incomplete. Its own extraction stays as a fallback, for an installation whose dataset has never been built. After that everything comes from the local cache, and a repeat run only fetches what is missing. The same without the studio: unpack.bat all. Zone maps and parsed models are unpacked on demand, the first time you open a zone or an appearance.

Running it manually / on a different port
node server/main.mjs

Settings live in studio.config.json next to the studio (copy studio.config.example.json to start):

Key What it is
installPath Your tswow installation — the folder with modules/ and bin/
dataset Dataset to read DBCs from, e.g. default.dataset
port HTTP port, default 8787
openBrowser Open the browser on start
clientPath WoW client, used to extract UI textures and icons
iconsPath Folder of extracted icon PNGs (optional)
lang ru or en

All of them can also be set from the Settings screen in the UI.

Requirements

Required A working tswow installation (3.3.5a / WotLK)
Windows — start.bat, mysql.exe and the texture tooling are Windows-only
Node.js ≥ 18 — already included with tswow, only needed separately if you run it standalone
Optional A WoW 3.3.5a client — needed for the addon designer's real textures and for icon extraction
tools/mpqextractor.exe + blpconverter from tswow — for one-click icon extraction
A running tswow console — enables live world-database search (there is an offline fallback, see below)

How it works

module/
  content/            ← builder sources (JSON) — the studio edits these
    spells/*.json
    items/*.json
    ...
  datascripts/
    datascripts.ts    ← entry point; the studio adds one import here, once
    generated/        ← generated code, regenerated in full
      module.ts
      spells.ts
      items.ts
      ...
  • The source of truth is the JSON in content/. Keep it in git and ship it with your module — on someone else's machine the studio opens your content as its own.
  • generated/ is regenerated in full every time you press Generate module code. Do not edit it by hand; edits are overwritten.
  • Your own code lives happily alongside in datascripts.ts and elsewhere. The studio only ever touches generated/.

Then build as usual — in the tswow console: build data (plus build livescripts / build addon if your module has them).

What it can do

Section Recipes What's inside
Spells 34 damage, area damage, DoT, healing, HoT, health leech, weapon strike, shield, thorns, stat buff, group buff, run speed, attack speed, slow, crowd control, invulnerability, stealth, dispel, interrupt, taunt, knockback, charge, polymorph, transport, resource restore, resurrection, create item, teach spell, place game object, summon, teleport, passive, passive with a proc, expert mode
Items 8 weapon, armor, jewelry/cloaks/shields (all with random properties — "…of the Bear"/"…of the Eagle"), consumables, materials, quest items, key, book/letter with pages, expert mode
Creatures 6 enemy (with loot, loot groups and combat behavior), vendor (special price: honor, arena, tokens; stock and restock), quest giver, trainer, NPC with gossip, expert mode — all with "appears only during a game event"
Game objects 5 chest with loot, decoration, button/lever, door, quest object; lock (key item, lockpicking, mining, herbalism), game event binding
Quests 4 kill creatures, bring items, deliver a message, expert mode
Crafting 2 recipe for an existing profession (reagents, difficulty, crafting station, auto-learn by rank), new profession with ranks
Achievements 1 17 kinds of condition (kill, complete a quest, reach a level, obtain an item, reputation, emote…), points, hidden flag, reward with title/item/letter
Classes & gear 7 class starter kit (bag items, equipped items, level-1 spells, per race), talent tree, gathering spot, gem, enchant, glyph, mount
World & events 3 scheduled game event (yearly / weekly / daily / hourly / one-off), fishing in a zone (catch, groups, skill), flight path (two pads, waypoints, price, mount, flight masters)
Everything else 84 registries titles, factions, reputation, item sets, enchants, gems, glyphs, mounts, companions, currencies, game events, holidays, zones, triggers, graveyards, GM teleports, spawn groups, transports, creature texts, mail templates, languages, all 30 game object types…

The Everything else section is not hand-written — it is built from the types of your installed tswow version. The studio reads every std.* registry, its entry class and all editable fields (texts, numbers, enums, masks, references, nested substructures, lists), and the generated code mirrors the field path exactly: TITLES_HERO.Text.Male.enGB.set("…"). The same is true of spell expert mode: the effect and aura catalog is read from bin/scripts/wow/wotlk/std/**/*.d.ts, not hard-coded, so it always matches your tswow version.

UI designer (addon)

The 🖼️ Interface (addon) section is a WYSIWYG window editor for the game client, in two modes.

Mode 1 — build your own window

Assemble a screen with the mouse: panels with backgrounds and borders (presets "Dialog", "Tooltip", "Parchment", or your own files), texts using standard font objects, images with texcoord cropping, buttons (client templates or your textures), checkboxes, edit boxes, status bars, sliders, scroll areas, item slots, dropdowns, 3D model frames. Widgets drag, resize by the corner, nudge with arrow keys, and anchor to the parent or a sibling — nine anchor points, Y going up, exactly like WoW.

Behavior without writing code. A button's What the click does: close the window, show/hide a widget, open another screen of the module, write to chat, cast a spell / use an item / run a macro (via SecureActionButtonTemplate, so it works in combat), or send a packet to the server. Bars and texts get Live data: player/target health and resource, experience, name, level, zone, money, time — the window subscribes to the events and updates itself.

Conditions, WeakAuras-style. Any widget gets an "if … then …" list: in combat / out of combat, has target / hostile target, health or resource below %, has a buff or debuff by name, zone, mounted, resting, dead, in party / raid / instance → show, hide, recolor, set transparency.

Mode 2 — modify the default UI

A 1024×768 canvas where the stock Blizzard windows — player and target portraits, focus, party, runes/totems, minimap, buffs, action bars, micro menu, bags, chat, cast bar, timers, quest tracker — are drawn as they are in the client, from the FrameXML tree with real textures, fonts, sample icons, portraits and bar colors.

The list on the left is not limited to those thirty windows: the “Add a client window…” button opens a search across all 270 top-level FrameXML windows — merchant, bank, mail, quest log, the achievement window and the rest. An added window is stored in the draft itself, is drawn on the canvas only while selected (otherwise it would cover the whole HUD), and is removed with the bin button next to it. Windows from load-on-demand Blizzard addons (Blizzard_AchievementUI and the like) do not exist yet when you enter the world, so the studio also listens for ADDON_LOADED — without it the tweak would silently fail to apply.

Drag to move (ClearAllPoints + SetPoint + SetUserPlaced), set scale and transparency, hide what you don't want (the frame is reparented to a hidden parent, so Blizzard code cannot bring it back), swap health/mana bar textures. Then go deeper into window parts: click a portrait, border, label, button or bar and change its texture, vertex color, desaturation, font, size, outline, offset (Alt+drag), size, transparency or visibility. The generated code applies edits on entering the world and installs hooksecurefunc — with recursion guards — on the methods Blizzard uses to restore its own values (SetTexture, SetVertexColor, SetStatusBarColor, SetFont, Show…).

You can also add elements the client does not have: a micro-menu button (MainMenuBarMicroButton, 28×58, seated right after the help button like the stock ones), a bar backdrop segment to extend the art under it, a round icon button, or a label.

What gets written

The studio emits a normal tswow addon in TypeScript — same path as a hand-written one (addon/addon.ts → build addon → Lua in the client patch):

  • addon/generated/ui/<Name>.ts — the layout. create<Name>(handlers) builds the widgets with the stock WoW API (CreateFrame, SetPoint, SetBackdrop, button templates) and returns them by name (ui.okButton, ui.progress), plus show/hide/toggle. Regenerated in full.
  • addon/<screen>.logic.ts — yours, created once and never overwritten. Click/input/slider handlers with annotated stubs, a /name chat command, and optional server-talk stubs (CreateCustomPacket / OnCustomPacket).

Layout and behavior stay separated: design in the studio, logic in code, neither fighting the other.

Generate addon writes the files and wires them into addon/addon.ts; Check addon runs tsc against addon/tsconfig.json — the same config build addon uses.

Client textures — how the real WoW look gets into the preview

The Extract client textures button reads the file lists out of your client's MPQ archives and extracts Interface\* — excluding icons, which are handled separately, and world maps and loading screens — together with the fonts, into cache/ui. After that the preview draws real client borders, buttons and fonts, and the texture picker gains "Popular", folders and search.

Your own images are BLPs in modules/<module>/assets/Interface/…, referenced by the same kind of path.

The Modify the default UI canvas needs the FrameXML sources: the studio takes them from <dataset>/luaxml_source, or extracts them from the client itself if the dataset is not built yet.

A client subtlety the studio handles for you — anchors vs. SetWidth

If a window part's size comes from its anchors — stretched across the parent, or pinned by two corners — then SetWidth is silently ignored by the client. The studio detects this, warns you in the properties panel, and keeps a single anchor in the generated code so the size actually applies and position is computed from that anchor.

Why tswow TypeScript and not plain Lua?

The addon lives in the same module, is built with the same command, has its WoW API types checked by the compiler, and gets the server link (packets, livescripts) as an existing tswow mechanism. Lua is still what comes out the other end.

Working with existing game content

Spell card — like Spell Editor, no database needed

Every spell ID in the interface is clickable, and every row in the spell picker has an ⓘ. The card shows everything the DBCs know: the description with macros expanded ("deals 14–22 damage… over 4 sec" instead of "$s1… $d"), school, cast time, cooldown, cost, range, duration, level, stacks, effects (type, aura, value, targets, period, radius, what it triggers — with a link to follow) and attributes.

Supported macros: $s $m $M $o $d $t $a $h $n $u $x $e $q $b $i, cross-spell references ($12345s1), ${…} expressions, $<…> variables with condition chains, and $l… plurals.

Finding content — three sources, with an offline fallback
  • Spells, icons and zones are read straight from the DBCs of the selected dataset. No database needed.
  • Items, creatures, game objects and quests are searched in the world database via bin/mysql/mysql.exe. Credentials come from the installation's own config — node.conf (Database.WorldDest / WorldSource, Database.Prefix), database name <module>.<dataset>.world.dest, built exactly the way tswow builds it. This works while the tswow console is running, since that is what brings MySQL up. Localized names are read from the *_locale tables, and search matches both localized and English names.
  • If the tswow console is closed, the studio reads the TDB dump (bin/TDB_full_world_*.sql) itself — the way Spell Editor reads DBCs without a server. The first run builds an index (about two seconds, cached in cache/); after that, search and take as a draft work fully offline. Honest limitation, which the studio also states in the list: the dump does not contain your modules' content.
  • Icon images appear once you point Settings at a folder of extracted PNGs (file name = icon ID from SpellIcon.dbc). Without it the icon picker still works, by name.
Modifying existing entries instead of creating new ones

Everything else has a Modify existing toggle: pick a registry, find an entry from the game (Fireball, Linen Cloth, a wolf) and fill in only what you want to change — everything else on the entry is left alone. Spell effects are handled separately: either just the value ("damage 500 instead of 20"), or the effect redefined in full.

Things that save a beginner an afternoon

  • Reference checking. Next to any entry ID, the studio prints its in-game name — "Fireball (#133) ✓" — or warns that no such entry exists. Check compilation adds a module-wide summary of broken references.
  • Entries reference each other. "My entries" come first in every picker, so a quest can point at a wolf from the same module and the code gets NPC_WOLF.ID with the right import between files. Real IDs are assigned when tswow builds; you never type them.
  • Take from the game as a draft. Spells, items and creatures have a button that opens an existing entry with all its values filled in. Edit, save as your own.
  • Starter kits. Village (an elder with gossip and a quest, a vendor, a trainer, a guard, wolves, a chest), Caster class, Profession with recipes, Boss with mechanics — several linked entries in one click.
  • Plain-language explanations. For the 160 most-used effects and auras the studio carries a human-readable explanation of what the effect does and what its value means — shown in the picker (search matches it, so "shield" finds SCHOOL_ABSORB), in the effect card, and as a comment above the effect in the generated code, so the file reads as a lesson.
  • Auto-descriptions. Generate description from settings on a spell; if the description is empty the generator fills it in with $s1/$d macros the client will substitute.
  • NPC gossip that does things. A reply option can offer a quest, teleport the player, cast a spell on them or hand over an item — all through stock SmartScript.
  • Creature behavior without code. when → what → to whom rules: say a line on entering combat; every 12 seconds cast at a random enemy; at 30% health summon help; at 15% flee; on death yell; heal a wounded ally. Stock TrinityCore SmartScript, defined as data — no server programming, no restart.
  • Spell ranks. A "level → power as % of rank 1" list; the studio creates the chain, links it, and adds every rank to the trainer as one list.
  • Patrol paths for creatures: points with pauses, walk/run/fly.
  • Export / import a module's content as a single JSON, copy an entry to another module, version history (up to 20 per entry) with rollback.
  • A "what next" reminder after generating: which build commands to run, what to restart, and a check that the module is actually attached to the dataset (Dataset.Modules).
  • Search across your own content, empty-name highlighting, Ctrl+S to save, Ctrl+Enter to check.

Checking before you build

Check compilation runs the TypeScript compiler from your tswow installation across the module's datascripts and reports errors in the interface language, pointing at the object that has the problem. It is the same compiler build data will use, so "check passed" means the module will build.

It does not run the data build: it writes neither DBC nor SQL, and is safe to use while the server is running.

What it deliberately does not do

Maps, terrain and models are not the studio's job — Noggit and dedicated model editors exist for that. The studio deals with data: spells, items, creatures, game objects and quests.

Known limitations

  • The game itself caps things, and the studio warns you in advance: a spell cannot have more than three effects, an item more than ten stats and three sockets, a quest more than four objectives.
  • In the universal editor, lists with complex arguments (achievement conditions, talents, path points) are displayed but must be filled in by hand in code — the studio says so under the field.
  • Outside datascripts and therefore outside the studio: server-side logic (livescripts), new classes and races with their client-side patches, and maps/models/icons as files.
  • Checking compilation is not a substitute for running. Test in-game logic on a live server.

Project layout

server/          local HTTP server, no framework
  catalog/       reads tswow's own .d.ts types → registries, entities, fields
  codegen/       JSON → TypeScript datascript emitters (spell, item, creature, addon, classkit…)
  framexml*.mjs  parses the client's FrameXML tree for the default-UI editor
  dbc.mjs        DBC reader          sql.mjs / tdb.mjs   world DB + offline TDB dump index
  textures.mjs   MPQ texture extraction
shared/          code used by both sides
  recipes/       recipe definitions — the forms and their meaning
  i18n/          keys.json + en.json (key = the Russian source string)
web/             browser UI, plain ES modules
  app.mjs        shell            forms.mjs        recipe forms
  designer.mjs   addon designer   blizzard-*.mjs   default-UI editor
tools/
  i18n-extract.mjs   collects translatable strings; --check lists what's missing

No framework, no bundler, no dependencies — the server, the DBC reader, the TDB SQL indexer, the FrameXML parser and the TypeScript generator are all hand-written.

Development

node server/main.mjs                  # run
node tools/i18n-extract.mjs           # collect translatable strings
node tools/i18n-extract.mjs --check   # list untranslated strings

Translations. shared/i18n/en.json maps the Russian source string to its English text. Adding a language means adding a dictionary next to it. UI language is switched with the 🌐 button in the header, or "lang" in studio.config.json; it covers the interface, hints, messages and the comments in generated code — your own content (names, descriptions, entry names) is never touched.

Contributing

Issues and pull requests are welcome. Useful things to know:

  • Plain ES modules everywhere, .mjs, no build step. Open a file, edit it, restart the server.
  • A new content type is usually a recipe in shared/recipes/ plus an emitter in server/codegen/.
  • New user-visible strings should be run through node tools/i18n-extract.mjs so translators see them.
  • Please do not commit cache/, studio.config.json or extracted client assets — see .gitignore.

Credits

  • tswow — the framework this is built for.
  • TrinityCore — the server core underneath.
  • StormLib by Ladislav Zezula (MIT) — MPQ archive reading. tools/mpqextractor.exe is a small command-line wrapper around it, used to extract client textures and icons. Full notice in THIRD-PARTY-NOTICES.md.

License

MIT © 2026 Alexandr (MrGreenCheezz)

tools/mpqextractor.exe is redistributed under StormLib's MIT license — see THIRD-PARTY-NOTICES.md. No World of Warcraft game data ships in this repository.

Not affiliated with Blizzard Entertainment

This is an unofficial tool for private-server development. World of Warcraft and the assets it reads from your own client are the property of Blizzard Entertainment. No game data is redistributed here.

About

Visual, no-code content builder for tswow: create WoW 3.3.5a spells, items, creatures, quests and addon UI with the mouse, get readable TypeScript datascripts out. Zero dependencies.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages