LV
0
- Joined
- May 28, 2026
- Messages
- 31
- Reaction score
- 21
- Points
- 13
- Location
- Chaos Tower
- Website
- chaospirates.com
Modding Weapon Glows & Gem Sockets in Tales of Pirates (DX9)
A complete, code-verified guide to the two things people always ask about: why a weapon glows (and how to add / change / escalate it), and how gem sockets work. It also covers the parts the classic guides leave out — the level-escalation layer, and an engine init-order bug that makes perfectly-correct glow data render nothing.
Part 1 - Weapon glows / effects
A weapon's glow is built from three independent layers. Older guides cover the first two; the third (escalation) is under-documented, and a separate engine bug can stop even perfect data from rendering. All three are below.
The resolve chain (driven by the socketed gems):
Myth-buster: some guides say "gems only add stats; the glow is forge-only." That is wrong. The socketed gems drive the glow: their COLORS pick which glow shows, their combined LEVEL picks the intensity tier. The "+N" on the weapon name is the sum of socketed gem levels.
Layer 1 - COLOR (which glow) = the gems' colors
Layer 2 - LOOK / SIZE = ItemRefineInfo + ItemRefineEffectInfo
Layer 3 - LEVEL ESCALATION (the part the classic guides omit)
The trap that bites everyone (reserved ID range): sceneffect IDs 1000-3000 are reserved by the Magic / skill system. Register a weapon glow there and it collides with a spell (or renders nothing). Use the 300-400 band (the stock weapon glows) or 4000+ for brand-new effects.
"My data is correct but the glow shows nothing / never gets bigger" - the engine init-order bug
This one is in no older guide. If your color/size data AND your per-tier .par files are all correct, but the weapon still shows no glow or the glow never escalates with level, check the client error log for:
That means CEffectObj::Create(sEffectID*10+tier) failed - the particle isn't in the effect registry even though the .par exists on disk. Root cause in the shared DX9 client: the engine scans effect\*.par into the resource manager inside LoadTotalPartCtrl(), but that runs before the effect path (_pszEFFectPath) is set, so the scan hits an empty path and registers nothing. Every particle effect (forge glows - and often skills, melee, fairies) then fails to resolve.
Fix: re-run the .par scan once a real in-world character exists (the path is set by then) - i.e. re-invoke the InitRes3() / LoadTotalPartCtrl() scan on first character-create / equip. After that, Create() resolves and the tiers render. If you cannot rebuild the engine DLL, trigger the one-time re-scan from the game layer on the first in-world frame.
Filebase caveat: different bases (mothannakh, alex, corsairs, top-recode, ...) ship these pieces in different states - some have the data but not the render path, some the reverse. Before expecting tiered glows, verify the whole chain: (a) the sceneffectinfo per-tier variants (base*10 + 0..3); (b) the tier formula in SItemForge::Refresh; (c) Item_Stoneeffect in scripts.lua; (d) populated ItemRefineInfo columns + ItemRefineEffectInfo rows for the weapons you care about.
Two more "no escalation" gotchas:
How to (glows):
Part 2 - Gem sockets (compatibility, new gems, stats)
Two layers run this: the server decides whether a gem may go into a piece and computes the stat; the client shows the socket UI and which gems are valid.
The server side - GemVar (the source of truth) - in resource/script/calculate/variable.lua:
The check, in forge.lua:
So a gem fits a piece if and only if the piece's ItemInfo type is in that gem's Equip list.
Common equipment type numbers: 1=1H weapon, 2=2H weapon, 3=bow, 4=gun, 7=dagger, 9=staff/wand, 11=chest, 22=head, 23=accessory, 24=boots, 27=gloves.
The client side - StoneInfo.txt (server resource/ + client scripts/table/):
equipTypes here is the client UI mirror of GemVar.Equip (col5 = the COLOR used by Part 1's glow). Keep these in sync with the server or the UI and the server will disagree.
Sockets on the equipment: a piece's socket count lives in its ItemInfo.txt row (the max-holes column). Gems themselves are ItemInfo type 49.
How to (gems):
Applying your changes (gotchas)
A complete, code-verified guide to the two things people always ask about: why a weapon glows (and how to add / change / escalate it), and how gem sockets work. It also covers the parts the classic guides leave out — the level-escalation layer, and an engine init-order bug that makes perfectly-correct glow data render nothing.
Part 1 - Weapon glows / effects
A weapon's glow is built from three independent layers. Older guides cover the first two; the third (escalation) is under-documented, and a separate engine bug can stop even perfect data from rendering. All three are below.
The resolve chain (driven by the socketed gems):
Code:
socketed gems' COLORS
-> Item_Stoneeffect(c1,c2,c3) (scripts.lua) -> index 1..14
-> ItemRefineInfo.txt (per weapon: a glow id per color slot + size floats)
-> ItemRefineEffectInfo.txt (glow id -> sceneffect id(s) + light id, per char & dummy)
-> sceneffectinfo.txt (sceneffect id -> .par particle file)
-> Client/effect/*.par
Myth-buster: some guides say "gems only add stats; the glow is forge-only." That is wrong. The socketed gems drive the glow: their COLORS pick which glow shows, their combined LEVEL picks the intensity tier. The "+N" on the weapon name is the sum of socketed gem levels.
Layer 1 - COLOR (which glow) = the gems' colors
- StoneInfo.txt col5 = the gem's color: 1=Red, 2=Blue, 3=Green, 4=Yellow. Row legend: ID | Gem Name | Gem ItemID | ForgeIntoItemType(csv) | GemColorGlow | hint [| hexcolor].
- The client feeds the 3 socketed gems' colors into Lua Item_Stoneeffect(c1,c2,c3) -> an index 1-14 -> that picks a column in the weapon's ItemRefineInfo row (col0=red, col1=blue, col3=yellow, the rest = color mixes). Mixed colors -> a combo slot, so one weapon can show multiple colors at once.
- The weapon model also gates which glows can render - some effects only show on certain models.
Layer 2 - LOOK / SIZE = ItemRefineInfo + ItemRefineEffectInfo
Code:
ItemRefineInfo row: ItemID | Name | Eff1..Eff14 (glow id per color slot) | sizeLance sizeCarsise sizePhyllis sizeAmi
e.g. 5283 Barborosa's Knife 3 3 0 12 12 0 3 0 3 0 0 3 0 0 0.61 0.61 0.61 0.61
- The 14 columns are glow ids keyed by color slot; set them all equal to force ONE glow regardless of gem color.
- The 4 trailing floats are static per-character glow SIZE (0.1 tiny ... 2.6 giant).
- ItemRefineInfo only ASSIGNS a glow id; ItemRefineEffectInfo STORES the actual glow. One ItemRefineEffectInfo row can hold several simultaneous effect slots (centre orb + spinning ring + blade trail + tip-balls), each with its sceneffect id, a light id (nLightID = the blade-texture glow; 0 = none), and a dummy/bone for attachment.
Layer 3 - LEVEL ESCALATION (the part the classic guides omit)
- The client renders each effect as sEffectID * 10 + tier. So base effect 315 renders as 3150 / 3151 / 3152 / 3153 for tiers 0/1/2/3 - these must be four distinct sceneffectinfo entries, each pointing at its own .par.
- tier = (combinedGemLevel - 1) / N, capped at 3 (4 tiers). Official Tales of Pirates steps at +4 / +7 / +10 = (nLevel-1)/3. Most shared private-server source ships (nLevel-1)/4 = +5 / +9 / +13; change that one divisor in SItemForge::Refresh (UIItemCommand.cpp) to match retail.
The trap that bites everyone (reserved ID range): sceneffect IDs 1000-3000 are reserved by the Magic / skill system. Register a weapon glow there and it collides with a spell (or renders nothing). Use the 300-400 band (the stock weapon glows) or 4000+ for brand-new effects.
"My data is correct but the glow shows nothing / never gets bigger" - the engine init-order bug
This one is in no older guide. If your color/size data AND your per-tier .par files are all correct, but the weapon still shows no glow or the glow never escalates with level, check the client error log for:
Code:
ERROR msgSceneItem SetForgeEffect effect fail,ID 3151
Fix: re-run the .par scan once a real in-world character exists (the path is set by then) - i.e. re-invoke the InitRes3() / LoadTotalPartCtrl() scan on first character-create / equip. After that, Create() resolves and the tiers render. If you cannot rebuild the engine DLL, trigger the one-time re-scan from the game layer on the first in-world frame.
Filebase caveat: different bases (mothannakh, alex, corsairs, top-recode, ...) ship these pieces in different states - some have the data but not the render path, some the reverse. Before expecting tiered glows, verify the whole chain: (a) the sceneffectinfo per-tier variants (base*10 + 0..3); (b) the tier formula in SItemForge::Refresh; (c) Item_Stoneeffect in scripts.lua; (d) populated ItemRefineInfo columns + ItemRefineEffectInfo rows for the weapons you care about.
Two more "no escalation" gotchas:
- A gem missing from the client StoneInfo doesn't count. The client only sums a slot's level if the gem resolves in StoneInfo - a gem missing/misaligned there contributes neither its COLOR (wrong/empty glow) nor its LEVEL (tier never climbs).
- Live refresh: the glow refresh early-returns when the forge value is unchanged - re-equip or relog to force a re-evaluate after forging.
How to (glows):
- Give a glow to a weapon that has none: point that weapon's ItemRefineInfo color columns at an existing glow id (copy a glowing weapon's row).
- Change a glow: swap the glow id in its ItemRefineInfo row, or repoint that glow's sceneffect id in ItemRefineEffectInfo.
- Resize: edit the 4 size floats at the end of the ItemRefineInfo row (0.1 ... 2.6).
- Force one glow for any gem combo: set all 14 color columns equal.
Part 2 - Gem sockets (compatibility, new gems, stats)
Two layers run this: the server decides whether a gem may go into a piece and computes the stat; the client shows the socket UI and which gems are valid.
The server side - GemVar (the source of truth) - in resource/script/calculate/variable.lua:
Code:
GemVar[1] = {ID = 878, Level = 6, Type = 1, Effect = 4, Attribute = ITEMATTR_VAL_MNATK, Equip = {1,0}}
GemVar[2] = {ID = 879, Level = 6, Type = 1, Effect = 6, Attribute = ITEMATTR_VAL_MNATK, Equip = {2,3,4,7,9,0}}
- ID = the gem's ItemInfo id
- Level = max gem level
- Effect = stat per level -> final bonus = Effect x gemLevel
- Attribute = which stat (ITEMATTR_VAL_STR/AGI/CON/DEF/HIT/...)
- Equip = {...,0} = the list of equipment TYPES this gem may socket into (0-terminated). This is the real compatibility gate.
The check, in forge.lua:
Code:
function CheckStoneType(Item, Stone1, Stone2)
...
for a = 1, #GemVar do
if GemVar[a].ID == GetItemID(Stone1) then
for b = 0, #GemVar[a].Equip do
if GemVar[a].Equip[b] == GetItemType(Item) then return 1 end -- allowed
if GemVar[a].Equip[b] == 0 then return 0 end -- end of list -> denied
end
end
end
return 0
end
Common equipment type numbers: 1=1H weapon, 2=2H weapon, 3=bow, 4=gun, 7=dagger, 9=staff/wand, 11=chest, 22=head, 23=accessory, 24=boots, 27=gloves.
The client side - StoneInfo.txt (server resource/ + client scripts/table/):
Code:
index | name | itemID | equipTypes | colorGlow | hintID | colorHex
1 Fiery Gem 0878 1 1 ItemHint_LieYanS F6D243
2 Furious Gem 0879 2,3,4,7,9 4 ItemHint_ZhiYanS F6D243
Sockets on the equipment: a piece's socket count lives in its ItemInfo.txt row (the max-holes column). Gems themselves are ItemInfo type 49.
How to (gems):
- Add a brand-new gem:
- ItemInfo.txt - add the gem item (type 49) with a name/icon.
- StoneInfo.txt - add a row: itemID, the equipTypes it fits, its color, hint, colour (client).
- variable.lua - add GemVar[n] = {ID=<itemId>, Level=..., Effect=..., Attribute=ITEMATTR_VAL_..., Equip={types...,0}} (server stat + gate).
- Let a gem socket into gear it currently can't (e.g. a weapon-only gem into armour): add the new type numbers to both GemVar[n].Equip (server) and the gem's equipTypes in StoneInfo.txt (client). Example - allow Furious Gem (0879) into chest/head/gloves: Equip = {2,3,4,7,9,11,22,27,0} and equipTypes = 2,3,4,7,9,11,22,27.
- Give a piece more sockets: raise its socket-count column in ItemInfo.txt.
Applying your changes (gotchas)
- Server reads the .txt tables on boot; the client reads compiled .bin. After editing client tables (StoneInfo, ItemInfo, the refine tables) recompile them so the client matches, and restart the GameServer for server-side .txt/Lua (variable.lua, forge.lua).
- Edit BOTH copies of any shared table (server resource/ and client scripts/table/) - they are separate files.
- GemVar.Equip is the server's authority - if the UI lets you try but the socket "fails", it is almost always a GemVar.Equip mismatch.
- Weapon glows are gem-driven - color (gem colors) + intensity (combined gem level). If a glow won't escalate and your data is right, it is the engine init-order bug above - check the client log for "SetForgeEffect effect fail".
- Don't use sceneffect IDs 1000-3000 for glows (Magic system).