SandroHc / schematic4j

Java parser for the .schem/.schematic/.litematic Minecraft formats. 🗺
MIT License
16 stars 3 forks source link

[Feature Request] Support for serialization to schematic formats. #3

Open KevinDaGame opened 10 months ago

KevinDaGame commented 10 months ago

VoxelSniper used to have a proprietary system for stencils (basically schematics) which no longer works (due to block id's no longer numerical for many a year). In our fork we have refactored this to use schematics using Schematic4J. Creating schematics from an area selection is something that we still have to implement.

We would like to see a way to create a schematic from an input of blocks, entities etc. Perhaps something like a builder pattern.

Is this something you would consider within the scope of Schematic4J?

SandroHc commented 10 months ago

It's certainly something worth exploring. I'm currently working on supporting more schematic formats, so this will be my next priority after that.

Would the following API work for your needs?

Schematic schematic = SchematicBuilder().create()
    .name("My Schematic")
    .author("SandroHc")
    .block("minecraft:dirt").at(1, 1, 1)
    .blocks(blocks)
    .blockEntity("minecraft:chest", nbt).at(2, 2, 2)
    .entity("minecraft:creeper").at(3.0, 3.0, 3.0)
    .build();

SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toFile("exported.schem");
SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toOutputStream(new ByteArrayOutputStream(1000));
byte[] bytes = SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toByteArray();
NamedTag nbt = SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toNbt();
SandroHc commented 10 months ago

For the time being, you can try using SchematicSponge.Builder. But beware that I will introduce breaking changes to that class in the next release 1.1.0.

RyanLandDev commented 10 months ago

It's certainly something worth exploring. I'm currently working on supporting more schematic formats, so this will be my next priority after that.

Would the following API work for your needs?

Schematic schematic = SchematicBuilder().create()
    .name("My Schematic")
    .author("SandroHc")
    .block("minecraft:dirt").at(1, 1, 1)
    .blocks(blocks)
    .blockEntity("minecraft:chest", nbt).at(2, 2, 2)
    .entity("minecraft:creeper").at(3.0, 3.0, 3.0)
    .build();

SchematicExporter.export(schematic).toFile("exported.schem");
SchematicExporter.export(schematic).toOutputStream(new ByteArrayOutputStream(1000));
byte[] bytes = SchematicExporter.export(schematic).toByteArray();
NamedTag nbt = SchematicExporter.export(schematic).toNbt();

I'd be willing to do this aswell if you're OK with that.

SandroHc commented 10 months ago

@RyanLandDev Go for it, all the help is appreciated. 😁

The builder should be straightforward−a new CustomSchematic class with the necessary fields− but the extractor will be another story. Extractors will probably have to be lossy (e.g. there is no way to get Sponge's required mods from just the Schematic interface) and individual formats will have their own implementation details, like the varint block indices in Sponge.

KevinDaGame commented 10 months ago

It's certainly something worth exploring. I'm currently working on supporting more schematic formats, so this will be my next priority after that.

Would the following API work for your needs?

Schematic schematic = SchematicBuilder().create()
    .name("My Schematic")
    .author("SandroHc")
    .block("minecraft:dirt").at(1, 1, 1)
    .blocks(blocks)
    .blockEntity("minecraft:chest", nbt).at(2, 2, 2)
    .entity("minecraft:creeper").at(3.0, 3.0, 3.0)
    .build();

SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toFile("exported.schem");
SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toOutputStream(new ByteArrayOutputStream(1000));
byte[] bytes = SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toByteArray();
NamedTag nbt = SchematicExporter.export(schematic, SchematicFormat.SPONGE_V3).toNbt();

That looks good. We won't be implementing it straight away, but it's something I wanted when initially implementing our new stencils, so now that there is life in this project I figured I'd just leave the request and see what comes of it 😄