Skip to content

Conversation

@PhoenixVX
Copy link
Contributor

Bikeshed:tm: on new branch

Bikeshed:tm: on new branch
Copy link
Contributor

@BoogieMonster1O1 BoogieMonster1O1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The id should definitely not be hardcoded
Registering blocks and items imo should be in registry sync as it would involve remapping the registry to match ids

"package": "net.textilemc.textile.mixin.recipe",
"compatibilityLevel": "JAVA_8",
"mixins": [
"RecipeDispatcherMixin"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops... left over from copying that module. Will fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About the ID, would you figure out what is needed for that?

Copy link

@amusingimpala75 amusingimpala75 Nov 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean about id? if you mean where it says id-256, that is what vanilla uses in the blockItem registry. See the bottom of the static constructor for Block.class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

He's talking about, that we have to hardcode an ID for our block and that would conflict with any other mod which uses the same ID. We need to use a registry sync so that isn't a problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also adding blocks is gonna require batching into terrain.png

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A custom block class could be used to detect if and from where we need to draw from an external png rather than from terrain.png

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sschr15 should be adding a resource loader api, which would probably be something like `FabricLoader.getInstance().getModContainer("mymodid") + "/resources/blah.png"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s a lot of features in Block that require dehardcoding
Until there’s resource loader and texture api I’d suggest stalling

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. Speak on discord in #github for quicker responses.

@@ -0,0 +1,16 @@
package net.textilemc.textile.utils;

public class Pair<T, M> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn’t guava have Pair?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not this should probably go in api base

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guava isn't an included library, so we can decide to keep our own, or use Guava here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loader uses guava iirc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? if it does, then could you ready up a commit for using that Pair instead?

@@ -0,0 +1,2 @@
accessWidener v1 named
accessible method net/minecraft/block/Block <init> (ILnet/minecraft/block/Material;)V
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary access widener

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That AW is necessary for Pair to function.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? It wasn't when I used it

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, I was using a custom block class

Copy link
Contributor Author

@PhoenixVX PhoenixVX Nov 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because you instantiated your Block (Stone) class, I had to instantiate it as a Block as I don't want to hardcode it to be "Stone" or whatnot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is a Block access widener necessary

Copy link

@amusingimpala75 amusingimpala75 Nov 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps in the future write a more extensive api that has all modded blocks be instances of a FabricBlock, and thus all with same numerical id, but also have a unique String id, which is checked every time the numerical id is checked, but that would require many mixins to fix that, and that is probably later down the rodd

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at the top issue. I commented about some ways to do that.

"environment": "*",
"accessWidener": "textile-utils-api-v1.accessWidener",
"mixins": [
"textile-utils-api-v1.mixins.json"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn’t have any mixins

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, need to remove that as said before, leftover from copying module.

version = '1.0.0'

dependencies {
implementation project(':textile-api-base')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary dependency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is unnecessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually keep this but move Identifier to api base

Copy link
Contributor

@sschr15 sschr15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean up the listed Mixin-related problems and re-request a review, and I'll approve

Thanks to @amusingimpala for doing this.
Copy link
Contributor

@BoogieMonster1O1 BoogieMonster1O1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a few extra changes

}

minecraft {
accessWidener "src/main/resources/textile-utils-api-v1.accessWidener"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link

@amusingimpala75 amusingimpala75 Dec 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? We need to open up Block.id, Item.id and Block.BLOCKS from being final

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesnt need an access widener

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m afraid I still don’t understand what you mean. Do you mean 1) that what is being widened is unnecessary, 2) that although it is needed for compilation it is not needed in production, or 3) something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not necessary to use an access widener here. accessors will suffice

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessors can modify final variables? I had forgotten that. Okay that makes sense then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Adding a @Mutable does the trick


@Inject(at=@At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/world/World;Ljava/lang/String;)V", ordinal = 1), method = "joinWorld(Ljava/lang/String;)V")
public void removeConflictOlderVersion(CallbackInfo info) {
mapBlockToDat(new File(new File(mcDir, "saves"), name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use nio
File is gonna block the thread

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mcDir.toPath().resolve("saves").resolve(name)

return path;
}

public CompoundTag toTag(CompoundTag tag) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don’t need a CompoundTag for this. That just wastes bytes
Store it as a StringTag

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What’s the use case of CompoundTag vs Tag?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CompoundTag is a maplike tag
Tag is the base class for tags

@Unique
private void mapBlockToDat(File saveDir) {
if (!(new File(saveDir, "block_registry.dat")).exists()) {
System.out.println("Saving Block Registry to .minecraft/saves/" + name + "/block_registry.dat");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use LOGGER.debug here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If LOGGER doesn't exist (which it probably doesn't), just create a @Unique private static final Logger LOGGER. Also please (as the above comment says) use paths instead of File objects...


public class RegistrationManagerEntrypoint implements ModInitializer {

public static Logger LOGGER = LogManager.getLogger("Textile API");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static Logger LOGGER = LogManager.getLogger("Textile API");
public static Logger LOGGER = LogManager.getLogger("Textile Utils API");

@BoogieMonster1O1
Copy link
Contributor

imo since this basically only handles the registration of blocks, the module name should be textile-block-api-v1

@amusingimpala75
Copy link

I would agree with BoogieMonster, except for Identifier. That should stay in Util

@BoogieMonster1O1
Copy link
Contributor

I would agree with BoogieMonster, except for Identifier. That should stay in Util

Identifiers can be used in any module. That can go in api base.

@BoogieMonster1O1
Copy link
Contributor

honestly anything made as a utility is either

  • related to a specific thing, or
  • can be used by multiple things

@amusingimpala75
Copy link

I might also consider having the id retriever(s) throw a new ArrayOutOfBounds exceptions citing too many blocks if trying to register more than 256 total.

Copy link
Contributor

@sschr15 sschr15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although Minecraft itself couldn't possibly have used nio libraries, Fabric Loader does, so please use those. Also, Identifier serialization is strange, so I've requested changes there as well.

@Unique
private void mapBlockToDat(File saveDir) {
if (!(new File(saveDir, "block_registry.dat")).exists()) {
System.out.println("Saving Block Registry to .minecraft/saves/" + name + "/block_registry.dat");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If LOGGER doesn't exist (which it probably doesn't), just create a @Unique private static final Logger LOGGER. Also please (as the above comment says) use paths instead of File objects...

}

@Unique
private void mapBlockToDat(File saveDir) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path saveDir

}
@Inject(at=@At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/world/World;Ljava/lang/String;)V", ordinal = 2), method = "joinWorld(Ljava/lang/String;)V")
public void removeConflictOlderVersion2(CallbackInfo info) {
mapBlockToDat(new File(new File(mcDir, "saves"), name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mcDir.toPath().resolve("saves").resolve(name)


@Inject(at=@At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/world/World;Ljava/lang/String;)V", ordinal = 1), method = "joinWorld(Ljava/lang/String;)V")
public void removeConflictOlderVersion(CallbackInfo info) {
mapBlockToDat(new File(new File(mcDir, "saves"), name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mcDir.toPath().resolve("saves").resolve(name)


@Unique
private void mapBlockToDat(File saveDir) {
if (!(new File(saveDir, "block_registry.dat")).exists()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!Files.exists(saveDir.resolve("block_registry.dat"))

}
}
try {
Util.writeCompressed(tag, new FileOutputStream(new File(saveDir, "block_registry.dat")));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files.newOutputStream(saveDir.resolve("block_registry.dat")

System.out.println("Matching old Block Registry read from .minecraft/saves/"+name+"/block_registry.dat");
CompoundTag tagFromFile;
try {
tagFromFile = Util.readCompressed(new FileInputStream(new File(saveDir, "block_registry.dat")));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files.newInputStream(saveDir.resolve("block_registry.dat")

}
}
}
throw new NullPointerException("Could not find block! You should only see this if you removed the mod which it was in, in which case your world will have corrupted!! Please make a new World!!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps don't throw an NPE, instead send a message to the player on world load to tell the player that a block may be missing?

Comment on lines +23 to +28
public CompoundTag toTag(CompoundTag tag) {
CompoundTag subtag = new CompoundTag();
subtag.putString("namespace", this.getNamespace());
subtag.putString("path", this.getPath());
tag.put("nameId", subtag);
return tag;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public CompoundTag toTag(CompoundTag tag) {
CompoundTag subtag = new CompoundTag();
subtag.putString("namespace", this.getNamespace());
subtag.putString("path", this.getPath());
tag.put("nameId", subtag);
return tag;
public CompoundTag toTag(CompoundTag tag) {
tag.putString("nameId", this.getNamespace() + ':' + this.getPath());
return tag;

Comment on lines +31 to +33
public static Identifier fromTag(CompoundTag tag) {
return new Identifier(tag.getString("namespace"), tag.getString("path"));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the toTag method just above, you save this to a nameId entry. You should then retrieve the identifier the same way.

Suggested change
public static Identifier fromTag(CompoundTag tag) {
return new Identifier(tag.getString("namespace"), tag.getString("path"));
}
public static Identifier fromTag(CompoundTag tag) {
String[] value = tag.getString("nameId").split(":");
return new Identifier(value[0], value[1]);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serialization should not be done directly to a compound tag. nameId sounds weird.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact, the compound tags in fromTag and toTag are meant to be of that object, so the only data you read is the data you’ve serialized

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and since Identifiers don’t use compound tags anymore, this should just be a toString and a tryParse

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(so that the caller can choose any key name and so as to not violate the method contract)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants