Skip to content

Commit

Permalink
Initial Version
Browse files Browse the repository at this point in the history
These are the initial start to my demos for the TypeScript types of NBT structures within world saves. This is a continuation of these issues here:
Offroaders123/NBTify#6
sandstone-mc/sandstone#202

For context of the files present here, this is the huge write-up I just did over in the second issue listed above. Rather than summarizing it, or just linking to it, I think having it here to start with is the best context :D

Listening to a ton of my favorite albums today/tonight, it's been great. On Voyage 34: Phase IV right now :)

---------------------------------------------

It may be out of the scope of this project, but I thought I'd mention it just to get a little conversation going.

I've been working on a TypeScript NBT library to work with editing world saves, and manipulating any data that it holds anywhere in the save. I'm still working on getting the world format logic set up, but my NBT library is fully functional at this point. It supports big and little endian, and compressed or uncompressed NBT files.

With how I've shaped the data structures that are output by my NBT library, I have the eventual goal of making TypeScript definitions for world save NBT data structures, which could allow for a lot quicker development pace in terms of iteration time, and working between the different world formats.

With this goal in mind, I'd like to use those type definitions to possibly make a world format converter between the different versions, which would be strongly driven by those type definitions. I think if there are definitions for all of the different structures, it would actually make it a fair bit easier to describe the shapes of the actual data inside of our world saves, and it may possibly make it much more easy to debug the shapes of each world format. Say, if the converter were to go between Java, Bedrock, or Legacy Console Edition.

Here's a link to my NBT library, [NBTify](https://github.com/Offroaders123/NBTify). It's built using TypeScript and ESM, and it works directly in the browser or Node, out of the box.

I only just found your project tonight, and it already looks very awesome, using functional APIs for Minecraft development has been a dream of mine for a while, and the first sight I saw here looked both very promising and inspiring. These are the kinds of structures I'd like to provide for working with world saves too.

I started working on a demo set of type definitions while finishing up writing this, but it started to get really big. I'm going to demo it out some more, and publish it as a new repo to get some more ideas flowing. Using `.d.ts` files for demoing API designs is a very helpful way to figure out how you want things to work, before you know how they work internally, would recommend! I will add an update with a reference to the repo once I have it up and running.

For a few more references, I've started working on an NBT editing PWA called [Dovetail](https://github.com/Offroaders123/Dovetail), which supports all of the formats mentioned above.

Still in the demo/experimental stages, I have some other projects which I am using to explore opening the world formats themselves:

- [Gamedata-Parser](https://github.com/Offroaders123/Gamedata-Parser) (Legacy Console `GAMEDATA` files)
- [MCRegionJS](https://github.com/Offroaders123/MCRegionJS) (Legacy Console Region files)
- [Bedrock-LevelDB](https://github.com/Offroaders123/Bedrock-LevelDB) (Bedrock Region files)

I haven't looked into Java quite yet (I just have a small local demo), funnily enough because it was the *most* documented out of them all. So, to make sure that this could be somewhat fairly doable, I wanted to start out with the less-documented, more challenging versions which are a bit more obscured in their format, before thinking the rest would be as straightforward as Java.
  • Loading branch information
Offroaders123 committed Apr 25, 2023
0 parents commit 9b39bd3
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
._*
Desktop.ini
Thumbs.db

/node_modules
/dist
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"nbtify": "^1.20.1"
}
}
9 changes: 9 additions & 0 deletions src/demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { openWorld, saveWorld, type JavaWorld } from "./index.js";

const javaWorld = await openWorld<JavaWorld>("~/.minecraft/saves/Solo-Survival/");
console.log(javaWorld.kind);

const bedrockWorld = await javaWorld.toBedrock();
console.log(bedrockWorld.kind);

await saveWorld("~/Desktop/",bedrockWorld);
53 changes: 53 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
export declare type Kind = "bedrock" | "java" | "legacy-console";

export declare abstract class Chunk {
abstract readonly version: number;
}

export declare class BedrockChunk extends Chunk {
readonly version: number;
}

export declare abstract class World {
abstract readonly kind: Kind;

abstract toBedrock(): Promise<BedrockWorld>;
abstract toJava(): Promise<JavaWorld>;
abstract toLegacyConsole(): Promise<LegacyConsoleWorld>;
}

export declare class BedrockWorld extends World {
readonly kind: "bedrock";

toBedrock(): Promise<BedrockWorld>;
toJava(): Promise<JavaWorld>;
toLegacyConsole(): Promise<LegacyConsoleWorld>;
}

export declare class JavaWorld extends World {
readonly kind: "java";

toBedrock(): Promise<BedrockWorld>;
toJava(): Promise<JavaWorld>;
toLegacyConsole(): Promise<LegacyConsoleWorld>;
}

export declare class LegacyConsoleWorld extends World {
readonly kind: "legacy-console";

toBedrock(): Promise<BedrockWorld>;
toJava(): Promise<JavaWorld>;
toLegacyConsole(): Promise<LegacyConsoleWorld>;
}

/**
* Reads the world from the given directory in the file system.
* Returns a World object which can manipulate properties of the world from a high level.
*/
export declare function openWorld(path: string): Promise<World>;
export declare function openWorld<T extends World = World>(path: string): Promise<T>;

/**
* Saves a world back to a given directory in the file system.
*/
export declare function saveWorld(path: string, world: World): Promise<void>;

0 comments on commit 9b39bd3

Please sign in to comment.