RF455-127 RF 4.55: the 18 cash-shop armour exchange coupons can never be redeemed, their combine rows have no output
Game: RF 4.55 (Dragonborn), server v0.5.0, Windows build (stock gameserver.exe).
Client: the supported Taiwan build, RF_Online.bin SHA-256 46528aac…2bbc558 (2025-07-16), Language=Taiwan.
Suggested component: data (game data and scripts).
This is the same shape of problem as RF455-084Released item 3 (the premium reward coupons), which you fixed in v0.4.0 by filling in the recipes' outputs. Eighteen more coupons — these ones sold for cash points — still have it.
Summary
The 黃金黑 / 聖金黑 ("Golden Black" / "Saint Golden Black") armour exchange coupons are cash-shop items whose own description says to combine them at the Hero NPC for a 5-piece armour set. The combine always fails with "Item combination materials are incorrect".
The cause is in the data, not in the player's hands: each coupon has exactly one recipe row, and every one of
that row's 24 output slots is -1. loadCombineRecipe discards a recipe with an empty output list, so
CombineRecipeFor reports "not found" and the request is refused before the civil mask, the fee and the
materials are even looked at.
They are the only coupons in the game that are both sold in the cash shop and impossible to redeem.
How to reproduce
- Buy (or GM-grant)
iyetw32, 聖金黑防具兌換券[阿克雷提亞發射器型] —bootyitem7140, cash shop row 352 (cash353), 682 CP,m_bView1 — on an Accretia character. - Talk to a Hero NPC (
storelisttrade type 26:030F1"Bo Hammer",040F1"Ziz Oadasha",050F1"Lothan the 3rd") and open the Item combiner. - Put the coupon in the centre slot. The window quotes the row's fee, "You need 0's money for combining fees".
- Confirm → "Item combination materials are incorrect", and the server logs:
[2026-10-26T19:55:17] INFO combine refused {"session": 2, "err": 1, "reason": "unknown manual index"}Only iyetw32 was tried live; the other 17 rows are identical in shape (section 3), so the same follows.
1. The recipe exists but produces nothing (read, gamedata_rf455.db)
iyetw32 is a material in exactly one row of the three combine tables — combinetable2 30145,
m_strCode cocsa90521 (so combine index 60376 + 30145 = 90521, which matches the code):
combinetable2 row 30145 (combine index 90521) code=cocsa90521 civil=00001000 exist=1 fee=0 material iyetw32 x1 聖金黑防具兌換券[阿克雷提亞發射器型] outputs NONE
The row is otherwise complete and looks intentional: m_bCombineExist 1, m_nOutNum 1, m_dwEffectType 1,
m_dwResultEffectMsgCode 3605, m_nOperationCount 1, m_strCivil 00001000 (Accretia, which matches the
coupon's name). Only m_itmPdOutput … m_itmPdOutput_24 are all -1.
For comparison, the Armor Set Coupons that do work are built exactly the same way but with their outputs filled in:
combinetable2 row 10095 (combine index 70471) code=cocsa70471 civil=11111000 exist=1 fee=1000 material iygco44 x1 Accretia Launcher Armor Set Coupon [Level 53] output ihafb53 x1 weight 2000 Intense COS Head output iuafb53 x1 weight 2000 Intense COS Core output igafb53 x1 weight 2000 Intense COS Arm output ilafb53 x1 weight 2000 Intense COS Leg output isafb53 x1 weight 2000 Intense COS Landing
(The five weights sum to 10000, so the set is always granted.)
2. Why the server refuses (read, rf455-v0.5.0\server\windows\gameserver.exe)
loadCombineRecipe0x14051e120picks the table:cmp ebx, 0xebd7at0x14051e160— index < 60375 readscombinetable, index ≥ 0xEBD8 readscombinetable2at index − 0xEBD8 (lea edx,[rbx-0xebd8]0x14051e194).- Its tail at
0x14051fcd3is the gate:cmp qword [rax+0x50], 0; je(the material slice's length) thencmp qword [rax+0x68], 0; jne(the output slice's length). With either list empty it returns nil (0x14051fce2). (+0x48/+0x50 is the material slice —combineMatchMaterials0x14088a4c0loads it at0x14088a5a4and walks it with stride 0x20; +0x60/+0x68 is the output slice —combineDraw0x14088bec0loads both at0x14088bff6.) CombineRecipeFor0x14051df40returns found = (pointer ≠ nil),setne blat0x14051e0c7.handleCombineExItem0x140887ca0:test bl,bl; je 0x14088811fat0x140887ee0→combineRefuse0x140887a60with code 1 and the reason "unknown manual index" (0x140cdb6d4).- The civil check (code 2,
0x1408880f8), the dalant check (3,0x1408880d1) andcombineMatchMaterials(0x23,0x140888050) all sit after that branch, so nothing the player did is ever inspected. The client's "materials are incorrect" wording is misleading here.
The client cannot warn about it: DataTable\ItemCombine.edf carries each recipe's index, fee and civil mask but
no outputs (outputs are server-side only), so the window opens and quotes the 0 fee whatever will happen next.
3. It is all 18 coupons
Every row below has m_bCombineExist 1, one material (the coupon, ×1), fee 0, and no output. The last
column is the set each coupon's own name asks for; all 90 item codes exist in the item tables.
| Coupon | Name | Cash shop | combinetable2 row | civil | Set the name asks for |
|---|---|---|---|---|---|
iyetw15 | 黃金黑防具兌換券[貝爾托戰士型] | row 341, 937 CP | 29922 | 11000000 | ihbwg55 iubwg55 ilbwg55 igbwg55 isbwg55 |
iyetw16 | 黃金黑防具兌換券[貝爾托巡察隊型] | row 342, 937 CP | 29923 | 11000000 | ihbrg55 iubrg55 ilbrg55 igbrg55 isbrg55 |
iyetw17 | 黃金黑防具兌換券[貝爾托能力型] | row 343, 937 CP | 29924 | 11000000 | ihbfg55 iubfg55 ilbfg55 igbfg55 isbfg55 |
iyetw18 | 黃金黑防具兌換券[克拉戰士型] | row 344, 976 CP | 29925 | 00110000 | ihcwg55 iucwg55 ilcwg55 igcwg55 iscwg55 |
iyetw19 | 黃金黑防具兌換券[克拉巡察隊型] | row 345, 976 CP | 29926 | 00110000 | ihcrg55 iucrg55 ilcrg55 igcrg55 iscrg55 |
iyetw20 | 黃金黑防具兌換券[克拉能力型] | row 346, 976 CP | 29927 | 00110000 | ihcfg55 iucfg55 ilcfg55 igcfg55 iscfg55 |
iyetw21 | 黃金黑防具兌換券[阿克雷提亞戰士型] | row 338, 1041 CP | 29928 | 00001000 | ihawg55 iuawg55 ilawg55 igawg55 isawg55 |
iyetw22 | 黃金黑防具兌換券[阿克雷提亞巡察隊型] | row 339, 1041 CP | 29929 | 00001000 | iharg55 iuarg55 ilarg55 igarg55 isarg55 |
iyetw23 | 黃金黑防具兌換券[阿克雷提亞發射器型] | row 340, 1041 CP | 29930 | 00001000 | ihafg55 iuafg55 ilafg55 igafg55 isafg55 |
iyetw24 | 聖金黑防具兌換券[貝爾托戰士型] | row 353, 682 CP | 30137 | 11000000 | ihbwg65 iubwg65 ilbwg65 igbwg65 isbwg65 |
iyetw25 | 聖金黑防具兌換券[貝爾托巡察隊型] | row 354, 682 CP | 30138 | 11000000 | ihbrg65 iubrg65 ilbrg65 igbrg65 isbrg65 |
iyetw26 | 聖金黑防具兌換券[貝爾托能力型] | row 355, 682 CP | 30139 | 11000000 | ihbfg65 iubfg65 ilbfg65 igbfg65 isbfg65 |
iyetw27 | 聖金黑防具兌換券[克拉戰士型] | row 356, 682 CP | 30140 | 00110000 | ihcwg65 iucwg65 ilcwg65 igcwg65 iscwg65 |
iyetw28 | 聖金黑防具兌換券[克拉巡察隊型] | row 357, 682 CP | 30141 | 00110000 | ihcrg65 iucrg65 ilcrg65 igcrg65 iscrg65 |
iyetw29 | 聖金黑防具兌換券[克拉能力型] | row 358, 682 CP | 30142 | 00110000 | ihcfg65 iucfg65 ilcfg65 igcfg65 iscfg65 |
iyetw30 | 聖金黑防具兌換券[阿克雷提亞戰士型] | row 350, 682 CP | 30143 | 00001000 | ihawg65 iuawg65 ilawg65 igawg65 isawg65 |
iyetw31 | 聖金黑防具兌換券[阿克雷提亞巡察隊型] | row 351, 682 CP | 30144 | 00001000 | iharg65 iuarg65 ilarg65 igarg65 isarg65 |
iyetw32 | 聖金黑防具兌換券[阿克雷提亞發射器型] | row 352, 682 CP | 30145 | 00001000 | ihafg65 iuafg65 ilafg65 igafg65 isafg65 |
The coupon → set column is inferred, from three things that agree: the coupon's own name (race, class and
the 黃金黑 / 聖金黑 grade word), the armour's name (iuafg65 is "Saint Golden Black Launcher Core", iuawg55
"Golden Black Eloi Core"), and the row's m_strCivil, which is read and already matches the race in the
coupon's name. Everything else in this report is read from the data or the binary.
Cash shop rows are read from cashshop (m_strCsItemCode, m_nCsPrice, m_bView); the server prices orders
from that same table (priceCashOrder 0x1408378e0, which logs "no cashshop row %d").
4. The same thing was fixed once already
RF455-084Released item 3 reported that the premium reward coupon iyevn10 combined into nothing. Comparing the three
server versions we have:
combinetable2 row | material | v0.3.1 | v0.4.0 and v0.5.0 |
|---|---|---|---|
| 22858 | iyevn10 ×1 | -1 | ipevn08 ×1 |
| 22859 | iyevn10 ×3 | -1 | ipcsb36 ×1 |
| 22860 | iyevn10 ×5 | -1 | irchm36 ×1 |
| 22861 | iyevn10 ×10 | -1 | ircry01 ×2 |
| 22862 | iyevn10 ×15 | -1 | bxpcr01 ×30 |
| 22863 | iyevn10 ×30 | -1 | bxpcr01 ×65 |
So the fix for these 18 is the one you already applied there: fill the rows' outputs. Row 30145 is byte-for-byte unchanged across v0.3.1, v0.4.0 and v0.5.0.
Related, for the same pass
combinetable2 has 19,464 rows with no output and 18,030 of those still carry m_bCombineExist 1;
combinetable has 126, all flagged. Among them, 110 take an iyetw* item as their first material,
including:
iyetw34–iyetw62, the "self-select vouchers" (55B/60B/65B/70B/75B weapon, 5-piece armour, shield, cloak);iyetw01–iyetw13, the Halloween recipes.
And nine set coupons named exactly like the working ones have no recipe row at all: iygco90–iygco98, the
"… Armor Set Coupon [Level 50]" family (the Level 53/57/63/65 ones, iygco18–iygco53, all work).
Local workaround
None. The coupon cannot be redeemed, and it cannot be traded away either (m_bExchange 0); an
NPC will take it (m_bSell 1) but pays nothing for it (m_nMoney 0). A GM can hand out the five armour pieces
directly instead.