If your island keeps getting rejected with a “Skipped Island Review” citing rule 4.4.9 even though you already have PaidRandomItem = true set on your entitlement, this post is for you. The reviewer never tests in-game, they reject it straight from the metadata.
After several rejected submissions, I found the real cause and want to share it.
The problem
I had a paid random item (lootbox-style entitlement bought with V-Bucks). The entitlement was correctly defined with PaidRandomItem = true:
my_random_entitlement<public> := class<concrete>(entitlement):
var Name<override> : message = my_random_name
var Icon<override> : texture = my_icon
MaxCount<override> : int = 200
Consumable<override> : logic = true
PaidRandomItem<override> : logic = true // already set
ConsequentialToGameplay<override> : logic = true
The offer was also fine, so in theory everything was correct and yet, rejected over and over again.
What was actually wrong
I was also granting the SAME entitlement when the player obtained the item through normal gameplay (not from a paid purchase). I was using the entitlement count as a progress tracker, so on every legit acquisition I called:
// WRONG — granting a PaidRandomItem entitlement outside the paid flow
GrantFromGameplay(Player:player)<suspends>:void=
Granted := GrantEntitlement(Player, my_random_entitlement)
if (Granted?){}
Even though it was only being used internally as a counter, Epic’s automated moderation reads every GrantEntitlement call on a PaidRandomItem and flags it if it happens outside a V-Bucks transaction. That’s an instant 4.4.9 rejection, no in-game review needed.
The fix
Only call GrantEntitlement for PaidRandomItem entitlements inside the actual paid purchase flow:
// CORRECT — only granted from a successful BuyOffer
TryBuyRandom(Player:player)<suspends>:void=
Bought := BuyOffer(Player, my_random_offer{})
if (Bought?):
spawn{GrantFromPaidFlow(Player)} // OK here, paid flow
For tracking progress / counts from normal gameplay, use your own persistable data instead of the entitlement:
my_profile_data := class<final><persistable>:
UnlockedItems : []string = array{}
// ...
UnlockedItems.Length gives you the same count without touching the paid entitlement.
After making this change, my island was approved on the next submission.
TL;DR
If you have a PaidRandomItem entitlement and you’re getting rejected even with PaidRandomItem = true set, check that you are never calling GrantEntitlement on it from non-paid gameplay flows. Even using it as an internal counter triggers the 4.4.9 flag. Track gameplay progress with your own persistable data.
My opinion
Honestly I think this behavior is wrong. The whole point of having MaxCount on an entitlement is to be able to track how many of that item the player has — including ones they got outside of a paid transaction. Otherwise, why even have MaxCount if you can only ever grant it via BuyOffer?
It would make a lot more sense if Epic’s moderation flagged unpaid grants only when PaidRandomItem = true AND the entitlement was being granted at scale without purchases, instead of blocking it entirely. Right now you’re forced to maintain TWO separate counters (the paid entitlement + your own persistable data) for the same item, which is just unnecessary complexity.
Hope this saves someone a few days. ![]()