Please don't talk to me about this. The first couple of hours of this
update were quite enjoyable, and then the rest was one of the most
miserable times I've had modding.
This has been a real slog, partly due to some large MC changes (item
models are a great change, but a pain to adapt to), and partly due to
mental health reasons — honestly, I've opened up my IDE so many times,
and then just closed it because I've hated the thought of even working
on this.
I will publish this to my maven, so mod authors can depend on it, but I
have no plans to publish a 1.21.4 version. 1.21.5 is right around the
corner (again, with some cool, but no-doubt painful changes), and I
need some time to focus on some breaking changes.
This commit actually includes the 1.21.3 update — the git history got so
messy here, so I just clobbered the whole thing. Sorry.
== Rendering ==
- Remove TBO monitor renderer: There was a big overhaul to how shaders
are defined and loaded in 1.21.2. It might have been possible to
update the monitor shader code to this version, it doesn't see much
use nowadays, so let's just delete it.
This is a real shame — the TBO renderer was one of my favourite
projects I've worked on. Unfortunately, it just doesn't seem worth
the ongoing maintenance burden. It lives on in the standalone
emulator :D.
- Similarly, the VBO rendering code got a bit of an overhaul. We no
longer use a custom VBO subclass, and instead just hack vanilla's to
support changing the number of vertices rendered.
This does mean we need to construct a MeshData, rather than a raw
ByteBuffer. This isn't too hard, but not sure how it'll play with
Iris. Given recent vanilla performance improvements, maybe we can
remove our Unsafe code and use a normal BufferBuilder now.
- Remove our custom emissive model code, now that vanilla supports
it. We should add emissive textures to some other models at some
point.
- Remove mod-loader specific model code, and replace it with vanilla's
ItemModel. This does constrain the design of turtle upgrade modellers
quite a bit — we now only accept an untransformed BakedModel or a
transformed ItemStack model. We may relax this in the future,
unclear.
This change does mean that updsidedown turtles are broken. RIP :(.
- Entity rendering now separates reading state from the entity from
actual rendering. This means we need to pass some extra state around
for item frames. Easy on Forge, but requires a mixin on Fabric.
== Recipes ==
There were several major changes to ingredients this update. The code
here hasn't been very well tested right now — might be nice to add some
game tests for this.
- Ingredients can no longer be constructed directly from a tag key (it
needs to be fetched from the current registries), so the recipe
generation code needs a bit of a reshuffle.
- DiskRecipe now accepts a custom list of ingredients, rather than
being hard-coded (fixes#1755). Recipes can now return custom
`RecipeDisplay`s used to show a recipe in the crafting book. We use
this to replace the impostor recipes.
I'm not entirely sure how well this'll play with other recipe
mods. Here's hoping.
- Similarly, our recipe mod integration has been updated to use
RecipeDisplay. We had to do this as ingredients no longer accept
arbitrary ItemStacks (only a specific item).
== Misc ==
- Blocks/items now need to know their ID ahead of time (so they can
compute their description). This requires some reshuffling to the
registration code, but it's pretty minor.
- updateShape and neighborChanged no longer take a direction (the
Orientation is mostly null) and so invalidates all redstone and
peripherals.
- All the positions were lowered by one in game tests. It's a good
change (they now match the positions in structures), but annoying to
update for!
As part of this, we also rewrite some of the turtle placing code, and
how it uses the turtle_can_use tag:
Minecraft 1.21 cleaned up the item/block clicking code a little bit,
splitting Block.use into Block.useItemOn and Block.useWithoutItem. The
first of these is pretty much exactly what we wanted in the first place,
so the tag was kinda redundant and we commented it out in the 1.21
update.
This was never meant to be a long-term fix, but time has gone by anyway.
We now check that tag, and call useWithoutItem() if present —
effectively restoring the previous behaviour.
Fixes#2011
- Disable Gradle module metadata for all Minecraft projects
- Run dependency exclusion code for all projects
We need the former for MDG on 1.21, so might as well do some other
cleanup while we're here.
Okay, listen. I started writing a few more gametests (see #1682), and
then thought I'd do a cheeky Gradle update. However, that broke
vanilla-extract[^1], and also triggered a load of deprecation warnings,
and at that point it was too late to separate the too.
[^1]: 8975ed5a7b
I've no motivation for modding right now, but always got time for build
system busywork!
CC:T (and CC before that) has always published its API docs. However,
they're not always the most helpful — they're useful if you know what
you're looking for, but aren't a good getting-started guide.
Part of the issue here is there's no examples, and everything is
described pretty abstractly. I have occasionally tried to improve this
(e.g. the peripheral docs in bdffabc08e2eb9895f966c949acc8334a2bf4475),
but it's a long road.
This commit adds a new example mod, which registers peripherals, an API
and a turtle upgrade. While the mod itself isn't exported as part of the
docs, we reference blocks of it using Java's new {@snippet} tag.
- Switch the Forge project to use NeoForge's new Legacy MDG plugin. We
don't *need* to do this, but it means the build logic for Forge and
NeoForge is more closely aligned.
- Add a new SnippetTaglet, which is a partial backport of Java 18+'s
{@snippet}.
- Add an example mod. This is a working multi-loader mod, complete with
datagen (albeit with no good multi-loader abstractions).
- Move our existing <pre>{@code ...}</pre> blocks into the example mod,
replacing them with {@snippet}s.
- Add a new overview page to the docs, providing some getting-started
information. We had this already in the dan200.computercraft.api
package docs, but it's not especially visible there.
MC 1.21.4 means we have to move more data generation code into the
client source set. Given all this code movement, it probably makes sense
to put data generation in a separate source set instead.
1.21.4 also has split data generators for client and server, but neither
mod loader recommends this. This means we can/should merge DataProviders
and ClientDataProviders into a single class.
Data generators are no longer bundled with the jar, which does reduce
file size, but by a tiny amount (~70KiB).
Iris now has built-in support for NeoForge, so we can use the same
integration on both.
We also re-enable Forge's client tests, and test Iris there too.
Fixes#1967
Under Forge, netty-codec lives on the BOOT layer. However, this means it
does not have access to our jzlib (which lives on the GAME layer). To
fix this, we now shadow netty-codec (and its dependents, like netty-http
and netty-proxy) rather than jar-in-jaring them.
This involves some horrible build logic, but means websocket compression
works on Forge.
Fixes#1958.
In c8eadf401190db2b9c3145f768063097b9c345bd we marked our various modems
as "brittle", which ensures they do not pop-off computers when the whole
structure moves.
However, this still requires the modem to be glued — if the modem is
outside the superglue range, it will still pop off. We can fix it by
registering a special "attached check" for the various modem blocks,
which says that the modem should be moved when the adjacent block does.
Fixes#1913
- Rename ToolActions to ItemAbilities. Closes#1881.
- Remove our source set helper, as NG has built-in support for this
now.
- Remove our code to generate new JavaExec tasks from runs, as NG now
generates JavaExec tasks normally.
- Update EMI and REI integration, and fix some issues with the upgrade
crafting hooks.
- Just use smooth stone for recipes, not #c:stone. We're mirroring
redstone's crafting recipes here.
- Some cleanup to printouts.
- Remote upgrade data generators - these can be replaced with the
standard registry data generators.
- Remove the API's PlatformHelper - we no longer have any
platform-specific code in the API.
In 1.20.1, Forge and Fabric have different "common" tag conventions (for
instance, Forge uses forge:dusts/redstone, while Fabric uses
c:redstone_dusts). This means the generated recipes (and advancements)
will be different for the two loader projects. As such, we run data
generators for each loader, and store the results separately.
However, aside from some recipes and advancements, most resources /are/
the same between the two. This means we end up with a lot of duplicate
files, which make the diff even harder to read. This gets worse in
1.20.5, when NeoForge and Fabric have (largely) unified their tag names.
This commit now merges the generated resources of the two loaders,
moving shared files to the common project.
- Add a new MergeTrees command, to handle the de-duplication of files.
- Change the existing runData tasks to write to
build/generatedResources.
- Add a new :common:runData task, that reads from the
build/generatedResources folder and writes to the per-project
src/generated/resources.
NF now loads mods from neoforge.mods.toml rather than mods.toml, so CC
wasn't actually being loaded. Tests all passed, because they didn't get
run in the first place!
BYTECODE WAS NOT SUPPOSED TO BE REWRITTEN
YEARS OF DEBUGGING REMAPPING FAILURES yet NO ACTUAL SOLUTION FOUND.
Wanted to use Mixins for anyway for a laugh? We had a tool for that: it
was called "FABRIC LOOM".
"Yes, please produce completely broken jars for no discernable reason"
Statements dreamed up by the utterly Deranged.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
This removes our two mixins used on Forge:
- Breaking progress for cabled/wired modems.
- Running client commands from chat click events. We now suggest the
command on Forge instead.
Occasionally we get issues where the mixin annotation processor doesn't
write its tsrg file in time for the reobfJar/reobfJarJar task. I thought
we'd fixed that cb8e06af2aefd931b1f6743849a7afb2a25ea0bd, but sometimes
we still produce missing jars - I have a feeling this might be to do
with incremental compilation.
We can maybe re-evaluate this on 1.20.4, where we don't need to worry
about remapping any more.
- Mark our core test-fixtures jar as part of the "cctest", rather than
a separate library. I'm fairly sure this was actually using the
classpath version of CC rather than the legacyClasspath version!
- Add a new "testMinecraftLibrary" configuration, instead of trying to
infer it from the classpath. We have to jump through some hoops to
avoid having multiple versions of a library on the classpath at once,
but it's not too bad.
I'm working on a patch to bsl which might allow us to kill of
legacyClasspath instead. Please, anything is better than this.
Forge doesn't run client-side commands from sendUnsignedCommand, so we
still require a mixin there.
We do need to change the command name, as Fabric doesn't properly merge
the two command trees.
Rather than mixing-in to CachedOutput, we just wrap our DataProviders to
use a custom CachedOutput which reformats the JSON before writing. This
allows us to drop mixins for common+non-client code.
- Add a check to ensure declared dependencies in the :core project, and
those inherited from Minecraft are the same.
- Compute the next Cobalt version, rather than specifying it manually.
- Add the gradle versions plugin (and version catalog update), and
update some versions.
Previously we prevented our published full jar depending on any of the
other projects by excluding the whole cc.tweaked jar. However, as Cobalt
also now lives in that group, this meant we were missing the Cobalt
dependency.
Rather than specifying a wildcard, we now exclude the dependencies when
adding them to the project.
This commit adds abstract classes to describe the interface for our
mod-loader-specific generic peripherals (inventories, fluid storage,
item storage).
This offers several advantages:
- Javadoc to illuaminate conversion no longer needs the Forge project
(just core and common).
- Ensures we have a consistent interface between Forge and Fabric.
Note, this does /not/ implement fluid or energy storage for Fabric. We
probably could do fluid without issue, but not something worth doing
right now.
Previously we had the invariant that if we had a server monitor, we also
had a terminal. When a monitor shrank into a place, we deleted the
monitor, and then recreated it when a peripheral was requested.
As of ab785a090698e6972caac95691393428c6f8370b this has changed
slightly, and we now just delete the terminal (keeping the ServerMonitor
around). However, we didn't adjust the peripheral code accordingly,
meaning we didn't recreate the /terminal/ when a peripheral was
requested.
The fix for this is very simple - most of the rest of this commit is
some additional code for ensuring monitor invariants hold, so we can
write tests with a little more confidence.
I'm not 100% sold on this approach. It's tricky having a double layer of
nullable state (ServerMonitor, and then the terminal). However, I think
this is reasonable - the ServerMonitor is a reference to the multiblock,
and the Terminal is part of the multiblock's state.
Even after all the refactors, monitor code is still nastier than I'd
like :/.
Fixes#1608
We can't use FriendlyByte.readCollection to read to a
pre-allocated/array-backed NonNullList, as that doesn't implement
List.add. Instead, we just need to do a normal loop.
We add a couple of tests to round-trip our recipe specs. Unfortunately
we can't test the recipes themselves as our own registries aren't set
up, so this'll have to do for now.
- Update to Loom 1.2 and FG 6.0. ForgeGradle has changed how it
generates the runXyz tasks, which makes running our tests much
harder. I've raised an issue upstream, but for now we do some nasty
poking of internals.
- Fix Sodium/Iris tests. Loom 1.1 changed how remapped configurations
are generated - we create a dummy source set and associate the
remapped configuration with that. All nasty stuff.
- Publish the common library. I'm not a fan of this, but given how much
internals I'm poking elsewhere, should probably get off my high
horse.
- Add renderdoc support to the client gametests, enabled with
-Prenderdoc.
- Split the front face of the computer model into two layers - one for
the main texture, and one for the cursor. This is actually a
simplification of what we had before, which is nice.
- Make the cursor layer render as an emissive quad, meaning it glows in
the dark. This is very easy on Forge (just some model JSON) and very
hard on Fabric (requires a custom model loader).
This adds SPDX license headers to all source code files, following the
REUSE[1] specification. This does not include any asset files (such as
generated JSON files, or textures). While REUSE does support doing so
with ".license" files, for now we define these licences using the
.reuse/dep5 file.
[1]: https://reuse.software/