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.
planetarium / libplanet
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.
Invalid order of NuGet dev releases #3955
When I looked at Libplanet's NuGet dev releases, they were not well ordered by release date.
It is because the version suffix is generated without zerofill. (20240901
with zerofill, 202491
without zerofill)
To resolve this issue, you can amend scripts/determine-versions.js
file. You can see the logic to determine a version suffix at the below lines:
You should update the part to declare ts
variable.
You can test the script easily by running the node scripts/determine-version.js
command.
$ node --version
v20.4.0
$ node scripts/determine-version.js
VersionPrefix: 5.3.0
VersionSuffix: dev.202491004320+f6cd63d
PackageVersion: 5.3.0-dev.202491004320
VersionType: dev
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)
Discovering the issue
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 code
const timestamp = await getCommitTimestamp();
const ts = `${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 fix
const timestamp = await getCommitTimestamp();
const formattedMonth = (timestamp.getUTCMonth() + 1)
.toString()
.padStart(2, "0");
const formattedDate = timestamp.getUTCDate().toString().padStart(2, "0");
const formattedHours = timestamp.getUTCHours().toString().padStart(2, "0");
const formattedMinutes = timestamp
.getUTCMinutes()
.toString()
.padStart(2, "0");
const formattedSeconds = timestamp
.getUTCSeconds()
.toString()
.padStart(2, "0");
const ts = `${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.
// Failed formatting attempt
const ts = `${timestamp.getUTCFullYear()
}${formattedMonth
}${formattedDate
}${formattedHours
}${formattedMinutes
}${formattedSeconds}`;
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 suggestion
const ts =
`${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 change
const ts =
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.
fix: add zero padding to version timestamp #3957
Fixes https://github.com/planetarium/libplanet/issues/3955. I declared variables to store each formatted portion of the date for readability. Please let me know if you'd liked anything changed.
Moving forward
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.
More on that next week.
Top comments (0)