You are browsing as a guest. Sign up (or log in) to start making projects!

jpeisach

@jpeisach

Joined June 5th, 2026

  • 10Devlogs
  • 5Projects
  • 1Ships
  • 8Votes
Incoming freshman to Stevens Institute of Technology (CS Major).

Ubuntu Cinnamon Lead, Ubuntu Member, Wikipedia contributor, new Linux Kernel contributor

Been into CS pretty much my entire life. This summer is my last chance to use Hack Club, so I'm trying to grind for a Framework laptop.

Website: https://jpeisach.github.io/
Open comments for this post

1h 44m 59s logged

libspacetime - mkmarstime function

Wow, what a sprint!

Part of the C date and time functions is mktime. It takes a struct tm object (which is a “broken down” time structure), and converts it into the time_t format (seconds since 1970). For libspacetime and the Darian Calendar, we need mkmarstime to track time on Mars.

In some ways, this ended up not being harder than I thought it was, and in some ways it did.

Leap Years

In the Gregorian Calendar, we have leap years every 4 years - except when the year is divisible by 100, unless divisible by 400. Yeah, it’s confusing.

The Darian Calendar, in it’s wording from the website and also Wikipedia confused me. I thought Intercalation was the length of a year, but no, it’s actually just getting the # of leap years that have passed at a given year number.

Darian Calendar rules are actually, every odd numbered year is a yeap lear, except for decades (10, 20, 30). Exception to that is if the year is divisible by 100, and again for divisible by 1000.

In the commented code, you can see how I put down my train of thought, but ended up coming to what the actual source was anyway.

Basically, you find the number of leap years, multiply by 669 days, then non-leap years, multiply by 668.

Fun fact: Glibc in its tm structures, according to POSIX specs, starts the year at 0. I believe it is because it could make those numbers fit in a smaller data structure. For us, the Darian year is 221. I guess I could maybe try to shave it down? But these are things I’ll have to decide before any release.

Months

Every month has 28 days, except for the last month in each “quarter”, which has 27.

You could calculate this, but Glibc, for the Gregorian Calendar actually has a static table that lists the amount of days since each month starts. This way it doesn’t have to do the multiplication every time.

I was doing it manually, and I was going to write out the expressions - 281, 282, etc. but it got complicated when also having to add like, 287 + (271) and I didn’t know which I was on track for. By using the example website, I got the numbers by manual conversion.

Leap Days

The table makes sense in Glibc for another reason: The leap day in the Gregorian Calendar is so early in the year, it shifts every day forward by one.

In the Darian Calendar, the leap day is actually at the end of the last month of the year. So we don’t need to store duplicate entries, or actually really worry about it for this function. (Not sure whether it is my job to handle invalid values). But basically if the current year is a leap year, we can still work as normal, and then just add on the day as requested. Nice!

The rest

Days, hours, minutes, seconds are all as normal.

The epoch

The Darian Calendar epoch actually begins in 1609. But.. the Mars Sol Date, which is unofficial but even used in NASA’s Mars24 program, has its “0” date at Dec 29 1873. So we need to subtract to make up for the difference.

If you use dates before MSD 0, you get negative mars_time_t values.

I couldn’t figure out what the epoch meant, until I realized it was just MSD 0. I also found that marsclock.com’s “midday” is actually off by about 177 seconds. But I calculated MSD 0 to be what you see in the code (I need to save characters so I can submit this), and off I went.

Testcases

Yeah, this needs tests. Even more than what I put in for this devlog (MSD 0 and Unix Epoch 0).

Unfortunately in Mars -> Earth time, I am losing about an Earth second in conversion. I’ll try to debug this now. But it causes some tests, like the epoch to be incorrect - it returns a mars_time_t of what would be unix epoch -1.

Overall thoughts

The genius of how Glibc handles the months was probably the coolest part. Most challenging, the leap year intercalation for sure.

Now, onto more test suites, and more functions.

libspacetime - mkmarstime function

Wow, what a sprint!

Part of the C date and time functions is mktime. It takes a struct tm object (which is a “broken down” time structure), and converts it into the time_t format (seconds since 1970). For libspacetime and the Darian Calendar, we need mkmarstime to track time on Mars.

In some ways, this ended up not being harder than I thought it was, and in some ways it did.

Leap Years

In the Gregorian Calendar, we have leap years every 4 years - except when the year is divisible by 100, unless divisible by 400. Yeah, it’s confusing.

The Darian Calendar, in it’s wording from the website and also Wikipedia confused me. I thought Intercalation was the length of a year, but no, it’s actually just getting the # of leap years that have passed at a given year number.

Darian Calendar rules are actually, every odd numbered year is a yeap lear, except for decades (10, 20, 30). Exception to that is if the year is divisible by 100, and again for divisible by 1000.

In the commented code, you can see how I put down my train of thought, but ended up coming to what the actual source was anyway.

Basically, you find the number of leap years, multiply by 669 days, then non-leap years, multiply by 668.

Fun fact: Glibc in its tm structures, according to POSIX specs, starts the year at 0. I believe it is because it could make those numbers fit in a smaller data structure. For us, the Darian year is 221. I guess I could maybe try to shave it down? But these are things I’ll have to decide before any release.

Months

Every month has 28 days, except for the last month in each “quarter”, which has 27.

You could calculate this, but Glibc, for the Gregorian Calendar actually has a static table that lists the amount of days since each month starts. This way it doesn’t have to do the multiplication every time.

I was doing it manually, and I was going to write out the expressions - 281, 282, etc. but it got complicated when also having to add like, 287 + (271) and I didn’t know which I was on track for. By using the example website, I got the numbers by manual conversion.

Leap Days

The table makes sense in Glibc for another reason: The leap day in the Gregorian Calendar is so early in the year, it shifts every day forward by one.

In the Darian Calendar, the leap day is actually at the end of the last month of the year. So we don’t need to store duplicate entries, or actually really worry about it for this function. (Not sure whether it is my job to handle invalid values). But basically if the current year is a leap year, we can still work as normal, and then just add on the day as requested. Nice!

The rest

Days, hours, minutes, seconds are all as normal.

The epoch

The Darian Calendar epoch actually begins in 1609. But.. the Mars Sol Date, which is unofficial but even used in NASA’s Mars24 program, has its “0” date at Dec 29 1873. So we need to subtract to make up for the difference.

If you use dates before MSD 0, you get negative mars_time_t values.

I couldn’t figure out what the epoch meant, until I realized it was just MSD 0. I also found that marsclock.com’s “midday” is actually off by about 177 seconds. But I calculated MSD 0 to be what you see in the code (I need to save characters so I can submit this), and off I went.

Testcases

Yeah, this needs tests. Even more than what I put in for this devlog (MSD 0 and Unix Epoch 0).

Unfortunately in Mars -> Earth time, I am losing about an Earth second in conversion. I’ll try to debug this now. But it causes some tests, like the epoch to be incorrect - it returns a mars_time_t of what would be unix epoch -1.

Overall thoughts

The genius of how Glibc handles the months was probably the coolest part. Most challenging, the leap year intercalation for sure.

Now, onto more test suites, and more functions.

Replying to @jpeisach

0
1
Open comments for this post

23m 8s logged

Earth Timekeeping to Mars Timekeeping Conversions

Because I’m going out to see family today - might as well get something done. I was going to add “mktime” but I realized that I’ve done Mars to Earth but not vice versa. Besides, I need an “epoch” to start time from.

Technically, I already had done this with mars_time(), I just needed to do it with any timestamp. I did “0” (January 1, 1970, midnight) locally to verify, then chose the Mariner 9 enter orbit as a testcase.

I will note, Wikipedia shows MSD (Mars Sol Date) but also Mars Julian Sol. I wonder if I’ll have to do that later.

I also will probably need to organize my tests/Makefile.am for further testcases. It will grow once I start adding time tests and not just MSD.

Earth Timekeeping to Mars Timekeeping Conversions

Because I’m going out to see family today - might as well get something done. I was going to add “mktime” but I realized that I’ve done Mars to Earth but not vice versa. Besides, I need an “epoch” to start time from.

Technically, I already had done this with mars_time(), I just needed to do it with any timestamp. I did “0” (January 1, 1970, midnight) locally to verify, then chose the Mariner 9 enter orbit as a testcase.

I will note, Wikipedia shows MSD (Mars Sol Date) but also Mars Julian Sol. I wonder if I’ll have to do that later.

I also will probably need to organize my tests/Makefile.am for further testcases. It will grow once I start adding time tests and not just MSD.

Replying to @jpeisach

0
3
Open comments for this post

1h 17m 19s logged

libspacetime - creating a testsuite

But first, pre-stardance talk

I’ve known the Darian Calendar existed, and my goal is to spend my time over the summer to try to make it as close to system level support as possible. This includes trying to get it at kernel-level - which is another project.

Anyways, libspacetime is basically time.h but for other planets. I want it to be portable and work on as many systems as possible. For this reason I setup a GNU Autotools project (autoconf, automake, that fun stuff).

Now, the Darian calendar is not standard, but C date and time functions are. Also, timekeeping is actually complicated. So I’m kind of.. mimicking the standards, and I may not get there in terms of implementation for a while, but I try my best.

Using some sites:

And after fighting with type versions, I eventually got a current unix time, represented in Martian seconds, in a way that you can get to the current Mars Sol Date (MSD).

Uh.. I’m not a mathematician. How does the timekeeping and conversions work, I honestly don’t know off hand. This will prove to continue being a challenge… especially because like, “ok, so what is our “epoch” for mars? Still Jan 1 1970 on Earth? But the existing proposed calendar conversions use this date instead?” - lots of fun in the future.

Okay, basically pre stardance was just mars_time and the initial project.

Creating the testsuite

For test runners, there are options - TAP, DejaGNU, etc. But this isn’t Meson where you can setup test targets.

Autotest is kind of weird (that seems to be the general consensus). If you are testing executable programs, it’s great, because you can get a fixed output. But at the base level, it’s really just a bunch of shell scripts.

So in test “setup”, I want to compile my “tests”. But a user building the library may not have libspacetime headers or library installed, so we need to not only build a C target (which in itself is weird, the GNU Autotools docs for test suites doesn’t suggest this as far as I know), but we need to link against the library built in the src folder of the project and also include its headers. Kinda janky.

The lack of useful documentation examples is what I spent a lot of time on. There is also the thing with atlocal, which I think is like.. empty? But docs suggest it should be generated?

package.m4 files exist now, which I did a great job filling out now that I look back at it -_-

when it comes to actual test checks (testsuite.at), apparently it compares output, not status code.. so I have to like, verbatim tell “I expect this output”. So there goes printing out the status of the current times I am testing.

Also it is so specific, like I can’t use a newline character in the printf in the test executable.

The print is useful because a round conversion from Earth -> Martian -> Earth results in a one earth second loss. I don’t know if it’s because of floating point precision or because of the time it takes to execute the conversion from the processor.

Ideally, the application can ask the kernel for the time and it uses its own clocks - which can use a counter chip, and using the amount of increases per a set of time, can figure out how long a “cycle” is and keep time that way. That was sort of the goal of my kernel “spacetime” support, but I wanted it to show up in lsclocks, and after all clocksource is like, a hardware abstraction, not an actual clock. Idealy a clocksource could just have a lower multiplier, but the kernel still uses the best clocksource which certainly won’t be the martian one.

Anyways, use janky tools (Autotest framework), get janky results. Cheers to more date and time functions and tests.

libspacetime - creating a testsuite

But first, pre-stardance talk

I’ve known the Darian Calendar existed, and my goal is to spend my time over the summer to try to make it as close to system level support as possible. This includes trying to get it at kernel-level - which is another project.

Anyways, libspacetime is basically time.h but for other planets. I want it to be portable and work on as many systems as possible. For this reason I setup a GNU Autotools project (autoconf, automake, that fun stuff).

Now, the Darian calendar is not standard, but C date and time functions are. Also, timekeeping is actually complicated. So I’m kind of.. mimicking the standards, and I may not get there in terms of implementation for a while, but I try my best.

Using some sites:

And after fighting with type versions, I eventually got a current unix time, represented in Martian seconds, in a way that you can get to the current Mars Sol Date (MSD).

Uh.. I’m not a mathematician. How does the timekeeping and conversions work, I honestly don’t know off hand. This will prove to continue being a challenge… especially because like, “ok, so what is our “epoch” for mars? Still Jan 1 1970 on Earth? But the existing proposed calendar conversions use this date instead?” - lots of fun in the future.

Okay, basically pre stardance was just mars_time and the initial project.

Creating the testsuite

For test runners, there are options - TAP, DejaGNU, etc. But this isn’t Meson where you can setup test targets.

Autotest is kind of weird (that seems to be the general consensus). If you are testing executable programs, it’s great, because you can get a fixed output. But at the base level, it’s really just a bunch of shell scripts.

So in test “setup”, I want to compile my “tests”. But a user building the library may not have libspacetime headers or library installed, so we need to not only build a C target (which in itself is weird, the GNU Autotools docs for test suites doesn’t suggest this as far as I know), but we need to link against the library built in the src folder of the project and also include its headers. Kinda janky.

The lack of useful documentation examples is what I spent a lot of time on. There is also the thing with atlocal, which I think is like.. empty? But docs suggest it should be generated?

package.m4 files exist now, which I did a great job filling out now that I look back at it -_-

when it comes to actual test checks (testsuite.at), apparently it compares output, not status code.. so I have to like, verbatim tell “I expect this output”. So there goes printing out the status of the current times I am testing.

Also it is so specific, like I can’t use a newline character in the printf in the test executable.

The print is useful because a round conversion from Earth -> Martian -> Earth results in a one earth second loss. I don’t know if it’s because of floating point precision or because of the time it takes to execute the conversion from the processor.

Ideally, the application can ask the kernel for the time and it uses its own clocks - which can use a counter chip, and using the amount of increases per a set of time, can figure out how long a “cycle” is and keep time that way. That was sort of the goal of my kernel “spacetime” support, but I wanted it to show up in lsclocks, and after all clocksource is like, a hardware abstraction, not an actual clock. Idealy a clocksource could just have a lower multiplier, but the kernel still uses the best clocksource which certainly won’t be the martian one.

Anyways, use janky tools (Autotest framework), get janky results. Cheers to more date and time functions and tests.

Replying to @jpeisach

0
1
Open comments for this post

34m 8s logged

Fixing Minecraft Realms support

Introduction to OneDot (Pre-Stardance)

I started this before Hack Club, so it’s worth the explanation. Since Mojang announced they would remove the “1.”, I felt like it was too iconic to be removed. So, I setup a mod template and combed through MC version code. It turned out that there is the SharedConstants class, which contains a “WorldVersion” and a human-readable “name” string. We just need to add “1.” to the start of the string. That is basically it.

Now since WorldVersion is an interface, I took the SharedConstants CURRENT_VERSION variable and basically just made another WorldVersion with my modification.

Finally on the client side, I have to call the SharedConstants.setVersion method. I thought I could just do this without the mixin but the game won’t let you change constants like that. But, if I don’t call the setVersion (that I modified to include the “1.”), nothing will happen. Probably because the setVersion is called before any mods are loaded (it’s like, one of the first things the game does as you launch it - possibly before the window is even made! I remember thinking the LAUNCHER did it via some java executable flag, but I’m not sure).

Realms fixing (Stardance)

A few weeks ago, I saw a bug https://github.com/JPeisach/OneDot/issues/1 about how Realms would say “client incompatible!”. Now I don’t use realms, but as hypothesized in the bug report, the RealmsClient in Vanilla does indeed send the client version number to the realm for authentication. And of course, with the “1.” at the start, that makes a version mismatch.

The nice thing about the SharedConstants solution is that it appeared everywhere - the window title, the title screen on the lower left corner, the F3 menu - but this is a case where we don’t want the version number to change.

I quickly traced down the call to WorldVersion.name. Thankfully in the code, Mojang abstracted all the execute functions that send the version in the request to the same function. After fighting around with Mixins and figuring out where best to inject my replaced String, I got a proposed patch. (Thankfully with the IntelliJ Minecraft modding plugin, it could provide a Mixin reference. But until then I forgot about it and tried to manually play with it. I looked at docs, and tried redirecting the method call, or injecting into the returns - I settled on ModifyArg). For simplicity, I just substringed the first three characters instead of trying to play with indexOf in case another “1.” appears in the version number.

Oh yeah, and that requires another mixin. Unlike the SharedConstants mixin, it actually lies in the client only, so there has to be a client mixin package now. No biggy.

Takeaways:

  • As always, you are playing with fire when trying to modify a constant
  • Thorough testing is needed, and if I had used Realms I probably would have thought about this long ago (It doesn’t impact regular Java servers, but it does for Realms - perhaps if needed I can remove the “1.” In any version requests to multiplayer servers)
  • This new mixin will also need to be added to the Neoforge branch, which hopefully will be easy.
  • The mod being so small, and the SharedConstants and WorldVersion class not changing makes the mod easy to “maintain”, because it stays compatible. I just need to check on Modrinth the “supported versions” and check every now and then that the mod launches. This may change that - if Mojang changes the RealmsClient class, things may need to change.
  • Work smarter, not harder (should’ve used the Mixin target reference from the start instead of wasting like 10 minutes on it)

Testing needed

I don’t have access to realms, I need someone else to test to make sure they can still reach it. But this fix should work. If you have access to a realm, please let me know. (I’ve also contacted the initial bug reporter).

Fixing Minecraft Realms support

Introduction to OneDot (Pre-Stardance)

I started this before Hack Club, so it’s worth the explanation. Since Mojang announced they would remove the “1.”, I felt like it was too iconic to be removed. So, I setup a mod template and combed through MC version code. It turned out that there is the SharedConstants class, which contains a “WorldVersion” and a human-readable “name” string. We just need to add “1.” to the start of the string. That is basically it.

Now since WorldVersion is an interface, I took the SharedConstants CURRENT_VERSION variable and basically just made another WorldVersion with my modification.

Finally on the client side, I have to call the SharedConstants.setVersion method. I thought I could just do this without the mixin but the game won’t let you change constants like that. But, if I don’t call the setVersion (that I modified to include the “1.”), nothing will happen. Probably because the setVersion is called before any mods are loaded (it’s like, one of the first things the game does as you launch it - possibly before the window is even made! I remember thinking the LAUNCHER did it via some java executable flag, but I’m not sure).

Realms fixing (Stardance)

A few weeks ago, I saw a bug https://github.com/JPeisach/OneDot/issues/1 about how Realms would say “client incompatible!”. Now I don’t use realms, but as hypothesized in the bug report, the RealmsClient in Vanilla does indeed send the client version number to the realm for authentication. And of course, with the “1.” at the start, that makes a version mismatch.

The nice thing about the SharedConstants solution is that it appeared everywhere - the window title, the title screen on the lower left corner, the F3 menu - but this is a case where we don’t want the version number to change.

I quickly traced down the call to WorldVersion.name. Thankfully in the code, Mojang abstracted all the execute functions that send the version in the request to the same function. After fighting around with Mixins and figuring out where best to inject my replaced String, I got a proposed patch. (Thankfully with the IntelliJ Minecraft modding plugin, it could provide a Mixin reference. But until then I forgot about it and tried to manually play with it. I looked at docs, and tried redirecting the method call, or injecting into the returns - I settled on ModifyArg). For simplicity, I just substringed the first three characters instead of trying to play with indexOf in case another “1.” appears in the version number.

Oh yeah, and that requires another mixin. Unlike the SharedConstants mixin, it actually lies in the client only, so there has to be a client mixin package now. No biggy.

Takeaways:

  • As always, you are playing with fire when trying to modify a constant
  • Thorough testing is needed, and if I had used Realms I probably would have thought about this long ago (It doesn’t impact regular Java servers, but it does for Realms - perhaps if needed I can remove the “1.” In any version requests to multiplayer servers)
  • This new mixin will also need to be added to the Neoforge branch, which hopefully will be easy.
  • The mod being so small, and the SharedConstants and WorldVersion class not changing makes the mod easy to “maintain”, because it stays compatible. I just need to check on Modrinth the “supported versions” and check every now and then that the mod launches. This may change that - if Mojang changes the RealmsClient class, things may need to change.
  • Work smarter, not harder (should’ve used the Mixin target reference from the start instead of wasting like 10 minutes on it)

Testing needed

I don’t have access to realms, I need someone else to test to make sure they can still reach it. But this fix should work. If you have access to a realm, please let me know. (I’ve also contacted the initial bug reporter).

Replying to @jpeisach

0
2
Open comments for this post

40m 1s logged

26.2 port, actually

So the jar actually only contained the code for the mod loader client, and not the common code. Oops.

Thanks to some help in the Architectury discord, I found that I needed to upgrade to another “shadow” gradle plugin (on another ID) and also apply some changes. Now everything is correct.

Since I messed up, I made a new release (1.0.3), and it also gave me the chance to update the repository information since I changed my GitHub name from ItzSwirlz to JPeisach (I think I’d prefer “jpeisach” but I don’t know if I can be that specific - regardless, the url is case insensitive).

26.2 port, actually

So the jar actually only contained the code for the mod loader client, and not the common code. Oops.

Thanks to some help in the Architectury discord, I found that I needed to upgrade to another “shadow” gradle plugin (on another ID) and also apply some changes. Now everything is correct.

Since I messed up, I made a new release (1.0.3), and it also gave me the chance to update the repository information since I changed my GitHub name from ItzSwirlz to JPeisach (I think I’d prefer “jpeisach” but I don’t know if I can be that specific - regardless, the url is case insensitive).

Replying to @jpeisach

0
3
Open comments for this post

39m 37s logged

So Let’s Set The Ore On Fire - 26.2 Port

After skipping 26.1 because Architectury (mod loader abstraction library) didn’t have a version available (as far as I knew), and since the update was well.. nothing interesting, since one now exists for 26.2 I took the time to port SLSTOOF (So Let’s Set The Ore On Fire) to 26.2.

Mod Introduction

SLSTOOF is a mod that adds the other kinds of fire types. In real life, if you light copper on fire, the color actually ends up being a little bit light-blueish. For example, Copper Torches. I think Mojang did this in education edition, but not in Java. They would eventually add it (and I would need to create “aliases” to automatically migrate world blocks from the mod’s copper torch to the game’s copper torch, but that happened pre-Star dance).  Iron also lights a bit more “yellowish”, and also, since redstone torches are red, I made redstone fire “red”.

Aside from the “fire block” that is made depending on which surface you light the fire on, I also took the time to place in the missing torches and campfires. I also made the redstone campfire emit signal :)

You can also see that I put in GameTest tests. For now, I just did basic flame ignition. In the future, I could add more to ensure things like crafting or item drops work. But believe me, this is useful for when you have to make a minor upgrade and don’t want to have to start the game to check if anything broke.

26.2 Porting (this declog)

The main headaches were:

  • Java 25 or later
  • Architectury and Gradle
  • The code changes since 1.21.11

Java 25 and later

Just some manual configurations like using JAVA_HOME to specify which Java version to use. It took me an embarrassing long time to realize that the “unsupported major class version” errors were because of this.

Gradle

Gradle was updated to 9.5.0.

Architectury Loom (fork of Fabric Loom, which I think helps manages dependencies and mod toolchain but I forgot), had also gotten updates. Same with the Architectury Gradle Plugin. Since obfuscation is no longer a thing, I had to tell gradle to stop complaining about the lack of “mappings” dependency, and I also had to bounce around snapshot versions of Architectury Loom until I found the solution for porting my project, because official docs for porting had not been updated yet and neither had the mod template generator.

By combing through Discord messages on the Architectury Discord, and lots of trial and error, I eventually got things to work.

Code changes since 1.21.11

Access Wideners: named -> “official” (also required a change in gradle config)

RenderTypeRegistry was used to ensure that the blocks that do not take up entire 1x1x1 spaces, like torches and campfires, don’t get registered as such. Otherwise they have a black border above the actual texture.

It seems that this is no longer needed, as I can just set the Campfire BlockEntityType list to include my custom campfires - and everything else seems to not be affected. Go Mojang refactoring, I guess?

Anyways, it worked out. I think another class was renamed in the Fabric/Neoforge side of things, but I tested everything and all is good.

After missing 26.1, I was a little worried - I thought that I may have to switch to Balm, another mod loader abstraction library, in hopes that it would be more up to date. But, probably since college has ended, people had time to work on it and I am now able to deliver only two days after release, which is pretty good.

The ported versions of the mod are now available on GitHub and Modrinth for Fabric and NeoForge.

Happy porting and world upgrading everyone! (Oh and thanks Zed for not counting the like, hour I think, I spent fighting with Gradle before I switched to IntelliJ, maybe rerunning the Hackatime install script did something, but nevertheless it’s about 37 minutes of actual “code” time).

So Let’s Set The Ore On Fire - 26.2 Port

After skipping 26.1 because Architectury (mod loader abstraction library) didn’t have a version available (as far as I knew), and since the update was well.. nothing interesting, since one now exists for 26.2 I took the time to port SLSTOOF (So Let’s Set The Ore On Fire) to 26.2.

Mod Introduction

SLSTOOF is a mod that adds the other kinds of fire types. In real life, if you light copper on fire, the color actually ends up being a little bit light-blueish. For example, Copper Torches. I think Mojang did this in education edition, but not in Java. They would eventually add it (and I would need to create “aliases” to automatically migrate world blocks from the mod’s copper torch to the game’s copper torch, but that happened pre-Star dance).  Iron also lights a bit more “yellowish”, and also, since redstone torches are red, I made redstone fire “red”.

Aside from the “fire block” that is made depending on which surface you light the fire on, I also took the time to place in the missing torches and campfires. I also made the redstone campfire emit signal :)

You can also see that I put in GameTest tests. For now, I just did basic flame ignition. In the future, I could add more to ensure things like crafting or item drops work. But believe me, this is useful for when you have to make a minor upgrade and don’t want to have to start the game to check if anything broke.

26.2 Porting (this declog)

The main headaches were:

  • Java 25 or later
  • Architectury and Gradle
  • The code changes since 1.21.11

Java 25 and later

Just some manual configurations like using JAVA_HOME to specify which Java version to use. It took me an embarrassing long time to realize that the “unsupported major class version” errors were because of this.

Gradle

Gradle was updated to 9.5.0.

Architectury Loom (fork of Fabric Loom, which I think helps manages dependencies and mod toolchain but I forgot), had also gotten updates. Same with the Architectury Gradle Plugin. Since obfuscation is no longer a thing, I had to tell gradle to stop complaining about the lack of “mappings” dependency, and I also had to bounce around snapshot versions of Architectury Loom until I found the solution for porting my project, because official docs for porting had not been updated yet and neither had the mod template generator.

By combing through Discord messages on the Architectury Discord, and lots of trial and error, I eventually got things to work.

Code changes since 1.21.11

Access Wideners: named -> “official” (also required a change in gradle config)

RenderTypeRegistry was used to ensure that the blocks that do not take up entire 1x1x1 spaces, like torches and campfires, don’t get registered as such. Otherwise they have a black border above the actual texture.

It seems that this is no longer needed, as I can just set the Campfire BlockEntityType list to include my custom campfires - and everything else seems to not be affected. Go Mojang refactoring, I guess?

Anyways, it worked out. I think another class was renamed in the Fabric/Neoforge side of things, but I tested everything and all is good.

After missing 26.1, I was a little worried - I thought that I may have to switch to Balm, another mod loader abstraction library, in hopes that it would be more up to date. But, probably since college has ended, people had time to work on it and I am now able to deliver only two days after release, which is pretty good.

The ported versions of the mod are now available on GitHub and Modrinth for Fabric and NeoForge.

Happy porting and world upgrading everyone! (Oh and thanks Zed for not counting the like, hour I think, I spent fighting with Gradle before I switched to IntelliJ, maybe rerunning the Hackatime install script did something, but nevertheless it’s about 37 minutes of actual “code” time).

Replying to @jpeisach

0
1
Open comments for this post

2h 15m 47s logged

Phew, another dev log!

For me, I had to figure out, what code should be part of the API, and what is the purpose of the coordinator?

I compared to ha-wiiu (https://github.com/wiiu-smarthome/ha-wiiu/blob/main/custom_components/nintendo_wiiu_ristretto/coordinator.py) as an example, and decided that:

  • The “API” is the equivalent of “ha-wiiu” coordinator’s “Wii” object - it contains the methods for actually doing the requests. (For this project, Pywikibot does not use asyncio, so the “API” is our “wrapper” so the API calls do not interrupt the main loop)
  • The “coordinator” is.. well, now it makes more sense to say it is a coordinator. It will poll the API when needed, but store data that is actually relevant.

So once I figured that out, it was off to me playing around with pywikibot to see how I could get site-specific user contributions. It seems that I will just have to count items in the contribution list, but for global site info (so, like all Wikimedia projects), it has its own accessible field.

So now I have a “0” in the sensor reading “Contributions”, which is correct because I have not made any edits to Test Wikipedia. I should soon be able to hook things up to other MediaWiki instances and see actual values!

Phew, another dev log!

For me, I had to figure out, what code should be part of the API, and what is the purpose of the coordinator?

I compared to ha-wiiu (https://github.com/wiiu-smarthome/ha-wiiu/blob/main/custom_components/nintendo_wiiu_ristretto/coordinator.py) as an example, and decided that:

  • The “API” is the equivalent of “ha-wiiu” coordinator’s “Wii” object - it contains the methods for actually doing the requests. (For this project, Pywikibot does not use asyncio, so the “API” is our “wrapper” so the API calls do not interrupt the main loop)
  • The “coordinator” is.. well, now it makes more sense to say it is a coordinator. It will poll the API when needed, but store data that is actually relevant.

So once I figured that out, it was off to me playing around with pywikibot to see how I could get site-specific user contributions. It seems that I will just have to count items in the contribution list, but for global site info (so, like all Wikimedia projects), it has its own accessible field.

So now I have a “0” in the sensor reading “Contributions”, which is correct because I have not made any edits to Test Wikipedia. I should soon be able to hook things up to other MediaWiki instances and see actual values!

Replying to @jpeisach

0
1
Open comments for this post

1h 9m 18s logged

Another small victory, but worth logging - turned out sign in is easier than I expected! (It only took me an hour to see if I wanted OAuth options, which I was going to use but I think basic client login will work)

Another small victory, but worth logging - turned out sign in is easier than I expected! (It only took me an hour to see if I wanted OAuth options, which I was going to use but I think basic client login will work)

Replying to @jpeisach

0
2
Open comments for this post

2h 0m 53s logged

Started taking the integration blueprint and did, something with it.

The MediaWiki API can take requests, which may be easier to code, but then the results have to be parsed. So I’ve decided to use the pywikibot library results, which sends things in a nicer way.

However, Home Assistant expects integrations to not make blocking calls.. and I think that actual network requests are made when you call for the operation. So if you make a page object, I don’t think it actually gets anything until you call page.extracts(). So the entity can’t call that, otherwise you get a blocking call. The coordinator needs to manage things specifically.

So this will eventually tie into making appropriate entities and representations of data - which, may be difficult, because HA does not expect entities to store the entire text of a Wikipedia article. But things like feeds are in RSS, so they may need separate handling - so basically, a bit of work to do of how this can be put into practice. I imagine a “Today’s featured article” kind of thing, but maybe that can be done simply with RSS feeds.. but I don’t think pywikibot handles that (it expects JSON responses). So, much more to dive into!

Started taking the integration blueprint and did, something with it.

The MediaWiki API can take requests, which may be easier to code, but then the results have to be parsed. So I’ve decided to use the pywikibot library results, which sends things in a nicer way.

However, Home Assistant expects integrations to not make blocking calls.. and I think that actual network requests are made when you call for the operation. So if you make a page object, I don’t think it actually gets anything until you call page.extracts(). So the entity can’t call that, otherwise you get a blocking call. The coordinator needs to manage things specifically.

So this will eventually tie into making appropriate entities and representations of data - which, may be difficult, because HA does not expect entities to store the entire text of a Wikipedia article. But things like feeds are in RSS, so they may need separate handling - so basically, a bit of work to do of how this can be put into practice. I imagine a “Today’s featured article” kind of thing, but maybe that can be done simply with RSS feeds.. but I don’t think pywikibot handles that (it expects JSON responses). So, much more to dive into!

Replying to @jpeisach

0
2
Open comments for this post

31m 39s logged

Another 31 minutes of me just running around, looking at examples and examining how timekeeping and clocks work in the kernel. End goal is to eventually have some way of tracking Martian time/Darian Calendar in linux, and I’m trying to go as low as possible. I’m probably going to make a special POSIX clock module that does the multiplier and calculations (then I guess make a “util-linux” fork for lsclocks to parse the date with a separate “libspacetime” library I started and then paused a few months ago because conversion is complicated)

Another 31 minutes of me just running around, looking at examples and examining how timekeeping and clocks work in the kernel. End goal is to eventually have some way of tracking Martian time/Darian Calendar in linux, and I’m trying to go as low as possible. I’m probably going to make a special POSIX clock module that does the multiplier and calculations (then I guess make a “util-linux” fork for lsclocks to parse the date with a separate “libspacetime” library I started and then paused a few months ago because conversion is complicated)

Replying to @jpeisach

0
1

Followers

Loading…