published on February 17, 2025 in devlog
Michi writes about the progress on PRO license time gifting and remote stores.
Michi (molp)
In last week's devlog (#470), I wrote about the upcoming license time gifting feature. It will allow gifting some of your own PRO time to another player.
I finished the implementation this week, up to the point where I have to call the account registry to do the actual transfer of license time. Backend systems are usually Martin's responsibility. After a bit of back and forth between us, it was clear what the API endpoint should look like, and Martin got to work.
Interesting fact: Our production system and the test server use different databases for the game data, but the same account backend to identify users. This is why we will disable the license gifting on the test server. Any changes made there will have an effect on your actual account and license status, but it will not be visible on the production server. This is due to how we separate concerns between the game and the account registry: The account registry doesn't need to know about license gifts at all. It just cares about the license and its expiry date. The game knows about the gifts, who gifted whom and when, but doesn't care about the expiry date. It will receive that bit of information from the account registry every now and then. So gifts created on the test server will only be visible on the test server, not on production.
While waiting for Martin to complete the endpoint, I started looking into the implementation of gateways again. In devlog #466 I explained why a material transfer between a local store and a shared/remote store can be challenging: Since the source and destination stores of the material transfer are part of two different entities, a lot of things can go wrong while transferring materials. If implemented with a single message from source to destination, the message could get lost, resulting in no material transfer at all, or, even worse: the source store could already have removed the materials, and the target never receives the materials.
We encounter this type of problem quite often and the solution we have for it is to implement the transfer as a transaction. A lot of things happen during a transaction, and that's the reason why it takes a while to implement. Here is an example where we send some materials from a source store to a remote store. The source side initiates the transaction by removing the materials to be transferred from the inventory and replacing them with a block, that has the same weight and volume, but which can’t be moved. A message about the transfer is sent to the remote store. The remote store checks whether it has enough room to store the materials, if the sender is allowed to store materials and some other checks. If a check fails the transaction is cancelled and the block in the source store replaced by its original content. If the checks are okay the remote store adds the materials to its store and sends back a success message. Once the success message arrives at the source store, the block (and thus the materials to be transferred) is removed from the store.
The transaction system keeps track of each sent message, and in case one is lost, tries to send it again. This is a very helpful tool, and keeps the state in sync, even across multiple entities.
As always, we'd love to hear what you think: join us on Discord or the forums!
Happy trading!