I wanted to help the community, and maybe some of the devs, out by explaining how dupes happen and why they are so complicated to find and fix.
If you are looking for instructions, you won’t get those. Sorry, you are out of luck. This won’t teach you how to dupe items in the game.
Rather, I am a developer who works at the hardware level and I am going to teach you why the software can sometimes copy things. This is fairly specialized knowledge, so it may take a second, but at the end hopefully everyone can group together with some knowledge about how this happens and how it can be tracked/fixed.
First we need to go over how software actually modifies values. A computer can never work with a value in memory directly. This is the root of the problem.
Let me explain how a computer actually works with values using an example of gold. Let’s say you have 100 gold and that is represented by a memory address with the value of 100 in it. Now if the game wants to subtract 1 gold from you the following process must occur.
The value in the memory address is COPIED into a register on the processor.
The processor then subtracts 1 from the value in the register resulting in 99 IN THE REGISTER.
The computer then COPIES the value from the register back into the memory address.
This all happens blazingly fast, often in less than 1 millionth of a second, but it does take time. And, the game is not a single thread. So let’s consider the following.
A thread in the game wants to subtract 1 gold from your total, and another thread wants to add 1 gold to your total AT THE EXACT SAME TIME.
In theory 100 - 1 + 1 = 100 Right?
So thread “A” COPIES the value of 100 from the memory location with your total into a register.
Right after that thread “B” COPIES the value of 100 from the memory location with your total into a different register.
Now thread “A” subtracts 1 from the register it is working with resulting in a value of 99 in that register.
Thread “B” adds 1 to the register it is working with resulting in a value of 101 in that different register.
Remember both threads COPIED the original value of 100.
Thread “A” finishes its calculations and then COPIES the value of 99 back into the memory location for your total. Your total is now 99.
But, then Thread “B” finishes its calculations and then COPIES the value of 101 back into the memory location for your total.
COPIES always OVERWRITE any values already there…
So now your total is 101 in memory. 100 - 1 + 1 = 101?
Lets ponder on how this works in game terms. Lets say you open a trade with a friend. you have 100 gold and you put a trade of 1 gold in the trade window to give that to your friend. You then click confirm AND cancel on the trade window and those go to the server at the same time.
If things are unlucky then one thread will handle the trade giving 1 gold to your friend and leaving you with 99 THEN the cancel will get handled returning your gold value to 100. You have 100 gold AND your friend has 1 gold.
This all happens because memory can not be worked with directly and it is possible for 2 different parts of the game code to be working with the memory location at the same time.
Now there are ways to prevent this, none of them are easy. This is REALLY REALLY HARD and why really good database developers are worth every cent.
The scary part is this is a potential problem every time you modify the database. What happens at a crafting table, when you upgrade a city, when you trade, when you put something on the ah, … This is why we are having a little pause here as they look.
It gets even more complicated when we consider there are likely thousands of cores running each with their own prefetch and cache.
So this has slipped through. We all need to give a little time for a fix to be implemented and understand it isn’t easy. However, there is some good news.
Dupes of this sort always have 2 modifications of the value back to back. IF the database of your gold logs all changes that happen due to trading windows then the log will show a change from 100 to 99 then to 101 all within a fraction of a second. In theory this log could be searched for this pattern and 100% of duplications can be found. So this issue may be 100% traceable.
Don’t Dupe, you DO leave footprints.
If anyone has any questions, feel free to ask and I will try and clarify however I can.
Shameless plug here, if AGS needs expertise to find this stuff I will gladly donate some time because I love the game, and If you need a lot of time accommodations can be made.
-Z