That said, I don't want to argue any longer
Personally, I see this as a discussion, not an argument.
I don't like people who write "all this stuff is done with AI," without knowing whether it's true or not, or those who dismiss AI, given that everyone uses it these days.
You can dislike me for my statements if you want, but I will try to explain why I think it's unwarranted. The reality you should accept is that most people have a similar bias, or will develop one. Everyone with sufficient experience using AI understands that most AI outputs need to be discarded, so it's both natural and inevitable that nearly everyone will develop pattern recognition to identify whether content is possibly non-human. Content generation increases with AI, so humans need to optimize their consumption of it, and sometimes that will lead to dismissal of AI content that may be even better than human content. This is not something to get upset about, but rather something to be aware of so that you can present your work in a way that minimizes unfavorable outcomes.
If you analyze my earlier responses carefully, you will find I reviewed all the changes carefully, evaluated them for their merit, applied the ones I agreed with, and even shared my analysis in case any human (or AI) wanted to receive the feedback, opening the door for continued discussion. Objectively, that means I did not dismiss the changes.
Thanks for providing these metrics. This really helps anchor the discussion.
An important thing to keep in mind is that ItemRetriever is effectively replacing multiple vanilla functions, which means that some game logic would have run in its place (if the plugin was unloaded), and the run-time of that game logic was not factored into the hook time measurement. For example, the game could have taken 1ms to find player items, whereas the plugin took 1.1ms (due to additional logic and framework overhead), which would mean the plugin contributed only 0.1ms, but from the framework perspective, the plugin spent 1.1ms. The more game functions a plugin replaces, the more the plugin takes the performance blame for vanilla game logic. It's important to be mindful of this when triaging performance metrics because this phenomenon often leads to server owners removing plugins and/or prioritizing optimization in the wrong places.
Additionally, depending on how SuperCrafter integrates with ItemRetriever, particularly with the "Item Suppliers" use case, SuperCrafter delegate functions may be directly invoked by ItemRetriever, for which ItemRetriever would get the blame, whereas the true culprit could be SuperCrafter logic.
In any case, I thought the cache was necessary because I saw the number of calls made to the plugin per second. It consumed up to 2GB, and it's currently the plugin with the highest hook time, according to RustMetrics.
The memory consumption metric provided by frameworks is often misunderstood. People tend to think it means that the plugin is currently consuming the amount seen (e.g., 2 GB), but it actually means that the plugin has allocated that much memory of the course of its lifetime (since it was loaded). The reality is that the vast majority of the memory allocations were reclaimed by the garbage collector within seconds or minutes of the allocation. Such allocations are often referred to as a "garbage allocation". Gargabe allocations are ideally minimized as they create GC pressure which increases CPU usage, but some cannot be avoided.
Some allocations are totally irrelevant (not even garbage allocations), such as the plugin getting an object from a pool which is currently empty (due to current demand from other plugins or game functions), resulting in an object creation, but that object will be released back to the pool and reused by other plugins or game functions, meaning the plugin got blamed for essentially nothing (just unlucky: right place, wrong time).
Another example of a low-relevance allocation is a vehicle spawner plugin. If a player repeatedly spawns and despawns a vehicle via a plugin, the memory consumption metric reported by the framework will be the sum of the memory of all those vehicles.
One of the sources of garbage allocations in ItemRetriever is the OnIngredientsCollect hook, which creates a new temporary List<Item> during every invocation. If you look at the vanilla game logic that is being replaced, the vanilla game is doing the exact same thing, so this is another case of the plugin getting blamed for vanilla game logic.
In any case, the player kicking issue remains; it happens less often now, but it still happens.
In any case: If you want to reproduce the problem, I have a test server where the problem is present, I give you access to the server, with my Pterodactyl Panel
Ideally, I would like to see more engagement from the SuperCrafter developer here. That plugin builds largely upon work I have released for free, and they are charging money. They should be doing more by reproducing and investigating this issue. Glancing at your support thread with them, it seems they are undergoing some [hopfully temporary] personal issues, so I'm happy to proceed with this route. You can message me on Discord.