So I'm participating in Hacktoberfest, and for my first contribution, I worked on a project called libplanet, which is a .NET library for creating peer-to-peer multiplayer online games using blockchain technology.
Blockchain in C#/.NET for on-chain, decentralized gaming
Libplanet
Libplanet is a .NET library for creating multiplayer online game in
decentralized fashion, which means the whole gameplay occurs on a
peer-to-peer network among equal nodes rather than an authorized central
server. Under the hood, it incorporates many features (e.g
digital signature, BFT consensus, data replication) of a blockchain.
It has competitive advantages over other solutions for decentralized gaming:
Embeddable: A game app does not have to communicate with another running
process, hence it doesn't require extra marshaling or processes management
To draw a parallel, Libplanet is closer to SQLite than MySQL or PostgreSQL.
Isomorphic: Libplanet is a .NET library, so every game logic can be
written in the same language, C#, and run on the blockchain. No glue
code or "smart contracts" are needed.
Token-independent: Unlike almost every blockchain system, it does not
force users to create and deal with yet-another-cryptocurrency. Your
game…
My contribution wasn't as exciting as that makes it sound - I fixed a bug in a script that generated the version names for the project releases. The timestamps in the version names were in the wrong order when sorted alphanumerically.
If you amended well, it expects to generate VersionSuffix: dev.20240910010203+xxxxxxx for the date (year: 2024, month: 9, day: 10, hour: 1, minutes: 2, seconds: 3)
I discovered the issue using a bottom up approach where I'd search for open issues on GitHub and try to find one that looked like a good fit. This was the first time I'd be contributing actual code to someone else's project, and not just documentation, so I wanted to start with something small. The maintainer included the snippet of code that needed to be worked on when filing the issue, and I saw it was in JavaScript, which I'm very familiar with, so I thought I'd give it a shot and asked if I could work on it.
// The original codeconsttimestamp=awaitgetCommitTimestamp();constts=`${timestamp.getUTCFullYear()}${timestamp.getUTCMonth()+1}${timestamp.getUTCDate()}${timestamp.getUTCHours()}${timestamp.getUTCMinutes()+0}${timestamp.getUTCSeconds()}`;versionSuffix=`dev.${ts}`;
Getting to work
When I got to work, I was surprised to find that the rest of the project was in C#. For a second, I thought this issue would end up being trickier than I expected. But on closer inspection, the file I had to work on was a standalone JavaScript script that didn't interact with the rest of the project. The maintainer was even kind enough to include the command to test the script when filing the issue.
The actual fix was very straightforward. I just had to add zero padding to date strings so that the timestamps generated for the version numbers would be sorted in chronological order when sorting alphanumerically. I remembered handling this same situation for an earlier JavaScript project.
To be honest, my initial attempt looked pretty ugly. The original code used a template literal, and in the spirit of sticking to the maintainers' vision, I added a bunch of extra lines to format and store the date values in variables and then pass them to the template literal.
// My initial fixconsttimestamp=awaitgetCommitTimestamp();constformattedMonth=(timestamp.getUTCMonth()+1).toString().padStart(2,"0");constformattedDate=timestamp.getUTCDate().toString().padStart(2,"0");constformattedHours=timestamp.getUTCHours().toString().padStart(2,"0");constformattedMinutes=timestamp.getUTCMinutes().toString().padStart(2,"0");constformattedSeconds=timestamp.getUTCSeconds().toString().padStart(2,"0");constts=`${timestamp.getUTCFullYear()}${formattedMonth}${formattedDate}${formattedHours}${formattedMinutes}${formattedSeconds}`;
Making it prettier
One of the maintainers mentioned that with my fix, the template literal ended up being over 80 characters in a line, and asked if it could be changed. So I split the template literal on each variable.
I noticed my editor would undo this change on saving (because I had the "format on save" setting enabled) but assumed that was just a problem on my end, and went with it anyway. The maintainer then responded saying his editor would also undo the changes I made, and proposed splitting the template literal using +s.
// The maintainer's suggestionconstts=`${timestamp.getUTCFullYear()}`+`${formattedMonth}`+`${formattedDate}`+`${formattedHours}`+`${formattedMinutes}`+`${formattedSeconds}`;
This change was much more visually appealing. Since it broke up the template literal, I figured it'd also be okay to just get rid of it entirely. The extra horizontal space gained by splitting the literal also allowed us to do the formatting in-line and not have to declare any variables.
// The final changeconstts=timestamp.getUTCFullYear().toString()+(timestamp.getUTCMonth()+1).toString().padStart(2,"0")+timestamp.getUTCDate().toString().padStart(2,"0")+timestamp.getUTCHours().toString().padStart(2,"0")+timestamp.getUTCMinutes().toString().padStart(2,"0")+timestamp.getUTCSeconds().toString().padStart(2,"0");
With that, the maintainers approved the changes and merged the pull request. And so, I'd officially made my first Hacktoberfest contribution, and for the first time, written code for a real project.
With two contributions under my belt, I was becoming comfortable with the open source workflow. I wanted to work on something bigger. I wanted to make the most of Hacktoberfest, so I decided that for my next PR, it was time to ramp things up and work on a feature.