Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f9ddce0
🚧 Ugrade svelte, switch to bun for package management
SnaveSutit Apr 14, 2026
d53daed
🚚 Move dialogs and their components into `src/dialogs`
SnaveSutit Apr 14, 2026
33e123a
🚚 Move panels and their components into `src/panels`
SnaveSutit Apr 14, 2026
09b84fb
🚚 Rename `components` -> `svelteComponents`
SnaveSutit Apr 14, 2026
33f901b
🚚 Move popups and their components into `src/popups`
SnaveSutit Apr 14, 2026
e8e9f3c
⚰️ Remove duplicate `changelogDialog.ts`
SnaveSutit Apr 14, 2026
4986f31
🩹 Fix import paths
SnaveSutit Apr 14, 2026
147ee27
⬆️ Switch to `esbuild-plugin-import-folder` library instead of local …
SnaveSutit Apr 14, 2026
647c589
🚧 Begin fixing svelte 5 errors
SnaveSutit Apr 14, 2026
52be62c
🩹 Fix deepslate imports
SnaveSutit Apr 14, 2026
15b5fef
🚚 Rename `tools` -> `.scripts`
SnaveSutit Apr 14, 2026
9d33190
✨ Upgrade to Svelte 5.0 & MCB 4.0.4
SnaveSutit Apr 14, 2026
d7663ed
🚧 Animated Java loads successfully in BB 5.0
SnaveSutit Apr 14, 2026
54d425d
🚧 (Mostly) Functional Blueprint Settings
SnaveSutit Apr 15, 2026
a8228d8
🐛 Fix exported 1.21.9 rotations
SnaveSutit Apr 15, 2026
e60a17b
🐛 Minor bugfixes
SnaveSutit Apr 15, 2026
2853b6c
🎨 Cleaned up keyframe easing system
SnaveSutit Apr 15, 2026
d9a07ab
🩹 Update Blueprint codec to BB 5.0
SnaveSutit Apr 15, 2026
aeaee99
✨ Update AnimationProperties to Svelte 5
SnaveSutit Apr 15, 2026
11b8a45
🩹 Update `fileSelect` and `folderSelect` components to BB 5
SnaveSutit Apr 15, 2026
4498ea5
🩹 Update systems to BB 5.0
SnaveSutit Apr 15, 2026
cd18bf6
🩹 Fix MCB 4.0.4 crashing when loading templates
SnaveSutit Apr 15, 2026
d67c93a
✨ Improved MC asset management & improved Blueprint DFU
SnaveSutit Apr 16, 2026
4cc94e1
✨ Make font loading JIT
SnaveSutit Apr 16, 2026
36a5b40
⚙️ Build and test workflow
SnaveSutit Apr 17, 2026
5796ea6
🩹 Blueprint version 1.10.0
SnaveSutit Apr 17, 2026
a295530
🐛 Fix display entity element panels and gizmos
SnaveSutit Apr 17, 2026
ce8a464
✨ Remove `data` entity & Improve looping animation performance.
SnaveSutit Apr 18, 2026
d5961f8
✨ Use new `book-and-quill` TextComponent library
SnaveSutit Apr 18, 2026
868455a
✨ Test on all export versions
SnaveSutit Apr 18, 2026
da2c9d0
🐛 Misc exported Data Pack bugfixes
SnaveSutit Apr 19, 2026
8dc05b3
🐛 Fix data garbage collection deleting the data of unloaded entities
SnaveSutit Apr 19, 2026
25448a1
✨ Add vanilla translation string resolution
SnaveSutit Apr 23, 2026
6117993
🚧 WIP Blueprint settings rework
SnaveSutit Apr 23, 2026
7288b92
✨ Update plugin compiler to support modern element rotation format
SnaveSutit Apr 24, 2026
b6d92ce
✨ Add support for custom namespaces
SnaveSutit Apr 24, 2026
d0c1bfe
✨ Improve Blueprint settings and node configs
SnaveSutit Apr 24, 2026
f0b1dcd
✨ Add zip export format support
SnaveSutit Apr 24, 2026
6d92cae
📋 Update all export targets with new tech
SnaveSutit Apr 24, 2026
6c1fd44
🗑️ Delete accidental zip
SnaveSutit Apr 24, 2026
e4f71ed
✂️ Remove unused code
SnaveSutit Apr 25, 2026
39db659
🩹 Minor Data Pack fixes
SnaveSutit Apr 25, 2026
d436ddb
✨ Improve display entity actions
SnaveSutit Apr 25, 2026
f445256
✨ Add Structure Group visualization
SnaveSutit Apr 25, 2026
d947a9b
🩹 Improve LineEdit based sidebar dialog item styling
SnaveSutit Apr 25, 2026
44c17c8
🩹 Fix codeEdit overflowing dialogs
SnaveSutit Apr 25, 2026
cac6e4c
✨ Improve Blueprint Settings
SnaveSutit Apr 25, 2026
d4d8dfb
🩹 Only request `fs` module when needed instead of immediately on inst…
SnaveSutit Apr 26, 2026
b7929c4
🔖 v1.10.0-beta.5
SnaveSutit Apr 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Build and Test

on:
pull_request:
branches: [main]

jobs:
publish:
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- uses: actions/checkout@v5
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org/

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Build
run: bun run build

- name: Run tests
run: bun test
File renamed without changes.
81 changes: 44 additions & 37 deletions tools/esbuild.ts → .scripts/esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ if (process.argv.includes('--mode=dev')) {
process.env.FLAVOR ??= `local`

import * as esbuild from 'esbuild'
import importFolderPlugin from 'esbuild-plugin-import-folder'
import ImportGlobPlugin from 'esbuild-plugin-import-glob'
import inlineImage from 'esbuild-plugin-inline-image'
import * as fs from 'fs'
import { load } from 'js-yaml'
import vscodeProblemsPatch from 'node-modules-vscode-problems-patch'
import * as path from 'path'
import { isAbsolute, join } from 'path'
import * as path from 'node:path'
import { isAbsolute, join } from 'node:path'
import {
createBlockbenchSvelteConfig,
esbuildPluginSvelte,
} from 'svelte-patching-tools/esbuildPlugin'
import { TextDecoder } from 'util'
import svelteConfig from '../svelte.config.js'
import assetOverridePlugin from './plugins/assetOverridePlugin'
import bufferPatchPlugin from './plugins/bufferPatchFunction.js'
import importFolderPlugin from './plugins/importFolder'
import langPlugin from './plugins/lang'
import mcbCompressionPlugin from './plugins/mcbCompressionPlugin'
import packagerPlugin from './plugins/packagerPlugin'
import sveltePlugin from './plugins/sveltePlugin'
const PACKAGE = JSON.parse(fs.readFileSync('./package.json', 'utf-8'))

const INFO_PLUGIN: esbuild.Plugin = {
Expand Down Expand Up @@ -134,34 +137,7 @@ function createBanner() {
return '│ ' + ' '.repeat(l) + v + ' '.repeat(r) + ' │'
})

const message = `
# Animated Java does not work in Blockbench 5

You will need to install and use Blockbench v4.12.6 to use Animated Java until it is updated to support 5.

## How to install Blockbench v4.12.6

1. Download the portable version of Blockbench 4.12.6 [here](https://github.com/JannisX11/blockbench/releases/download/v4.12.6/Blockbench_4.12.6_portable.exe).
2. Once it's finished downloading, double click the .exe file to run it.

If you're familiar with command line interfaces, you can use [Envbench](https://www.npmjs.com/package/envbench) to install and manage multiple Blockbench versions side by side.
`

const startupCode = `(() => {
if (!compareVersions('5.0.0', Blockbench.version)) {
const message = \`${message}\`;
Blockbench.showMessageBox({title: 'Animated Java - Incompatible Blockbench Version',message,width:600});
requestAnimationFrame(() => Plugins.registered['animated_java'].uninstall());
throw new Error(message);
}
})()`.trim()

const banner =
'\n' +
[header, ...lines, footer].map(v => `//?? ${v}`).join('\n') +
'\n\n' +
startupCode +
'\n'
const banner = '\n' + [header, ...lines, footer].map(v => `//?? ${v}`).join('\n')

return {
js: banner,
Expand Down Expand Up @@ -205,17 +181,27 @@ const yamlPlugin: (opts: {
},
})

import VSCODE_SETTINGS from '../.vscode/settings.json'
const IGNORED_SVELTE_WARNINGS = Object.keys(
VSCODE_SETTINGS['svelte.plugin.svelte.compilerWarnings']
)

const COMMON_CONFIG: esbuild.BuildOptions = {
banner: createBanner(),
entryPoints: ['./src/index.ts'],
outfile: `./dist/${PACKAGE.name}.js`,
bundle: true,
platform: 'node',
platform: 'browser',
external: ['node:*'],
loader: { '.svg': 'dataurl', '.ttf': 'binary', '.css': 'text' },
plugins: [
langPlugin({
languageFolder: 'src/lang',
}),
// @ts-expect-error broken default import
vscodeProblemsPatch.default(),
importFolderPlugin,
// @ts-expect-error broken default import
importFolderPlugin.default(),
// @ts-expect-error broken default import
ImportGlobPlugin.default(),
bufferPatchPlugin(),
Expand All @@ -224,15 +210,36 @@ const COMMON_CONFIG: esbuild.BuildOptions = {
}),
INFO_PLUGIN,
yamlPlugin({}),
sveltePlugin(svelteConfig),
esbuildPluginSvelte(
createBlockbenchSvelteConfig(PACKAGE.name, {
compilerOptions: {
warningFilter(warning: any) {
return !IGNORED_SVELTE_WARNINGS.includes(warning.code)
},
compatibility: {
componentApi: 4,
},
// @ts-expect-error - not typed correctly
generate: 'client',
},
})
),
packagerPlugin(),
assetOverridePlugin(),
mcbCompressionPlugin(),
DEPENDENCY_QUARKS,
],
alias: { svelte: 'svelte' },
alias: {
svelte: 'svelte',
module: './.scripts/fakeModule.js',
'node:module': './.scripts/fakeModule.js',
},
format: 'iife',
define: DEFINES,
inject: [
// Blockbench does not provide access to the global process, but some of our dependencies expect it to exist.
`./.scripts/fakeProcess.js`,
],
treeShaking: true,
}

Expand Down
8 changes: 8 additions & 0 deletions .scripts/fakeModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const Module = {
createRequire() {
return {}
},
}

export { Module as module }
export default Module
9 changes: 9 additions & 0 deletions .scripts/fakeProcess.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const process = {
__NOTE: 'This is a fake process object added by Animated Java. It is not the actual Node.js process object.',
cwd: () => '',
env: {},
version: 'v24.14.0',
argv: '',
}

export { process }
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Plugin } from 'esbuild'
import * as fs from 'fs/promises'
import * as pathjs from 'path'
import * as pathjs from 'node:path'

const ASSET_OVERRIDES_PATH = 'src/assets/vanillaAssetOverrides/'

Expand Down
20 changes: 20 additions & 0 deletions .scripts/plugins/lang.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
interface LangPluginOptions {
languageFolder: string
}

interface StructuredLanguageFile {
[key: string]: string | StructuredLanguageFile
}

interface LanguageDefinition {
name: string
structured: StructuredLanguageFile
flattened: Record<string, string>
}

declare module 'LANGUAGES' {
export const LANGUAGES: Record<string, LanguageDefinition>
export function flattenStructuredLanguageFile(
file: StructuredLanguageFile
): Record<string, string>
}
79 changes: 79 additions & 0 deletions .scripts/plugins/lang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/// <reference path="./lang.d.ts"/>

import ESBuild from 'esbuild'
import { existsSync } from 'fs'
import { readdir, readFile } from 'fs/promises'
import { load } from 'js-yaml'
import { join } from 'path'

const filterYamlFiles = (file: string) => {
return file.endsWith('.yml') || file.endsWith('.yaml')
}

const flattenStructuredLanguageFile = (file: StructuredLanguageFile): Record<string, string> => {
const result: Record<string, string> = {}
for (const key in file) {
if (typeof file[key] === 'string') {
result[key] = file[key]
continue
}

for (const [subKey, value] of Object.entries(flattenStructuredLanguageFile(file[key]))) {
result[`${key}.${subKey}`] = value
}
}
return result
}

const langPlugin = ({ languageFolder }: LangPluginOptions) =>
({
name: 'lang',
setup(build) {
if (!existsSync(languageFolder)) {
throw new Error(`Language folder "${languageFolder}" does not exist.`)
}

build.onResolve({ filter: /LANGUAGES/ }, () => {
return {
path: languageFolder,
namespace: 'language-file',
}
})

build.onLoad({ filter: /.*/, namespace: 'language-file' }, async () => {
const translations: Record<string, LanguageDefinition> = {}

const files = (await readdir(languageFolder)).filter(filterYamlFiles)
if (files.length === 0) {
console.warn(`No language files found in "${languageFolder}"`)
}

const watchFiles: string[] = []

for (const file of files) {
const path = join(languageFolder, file)
watchFiles.push(path)

const name = file.replace(/\.(yml|yaml)$/, '')
const structured: StructuredLanguageFile = await readFile(path, {
encoding: 'utf-8',
}).then(data => load(data, { filename: path }) as StructuredLanguageFile)
const flattened = flattenStructuredLanguageFile(structured)

translations[name] = { name, structured, flattened }
}

const contents =
`export const LANGUAGES = ${JSON.stringify(translations)};` +
`export const flattenStructuredLanguageFile = ${flattenStructuredLanguageFile.toString()};`

return {
contents,
loader: 'js',
watchFiles,
}
})
},
}) satisfies ESBuild.Plugin

export default langPlugin
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Plugin } from 'esbuild'
import * as fflate from 'fflate'
import * as fflate from 'fflate/browser'
import { existsSync } from 'fs'
import * as fs from 'fs/promises'
import * as pathjs from 'path'
import * as pathjs from 'node:path'

function zip(data: fflate.AsyncZippable): Promise<Uint8Array> {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -59,7 +59,7 @@ export default getZipFile('${localPath}')
const data = Buffer.from(zipped).toString('base64')
return {
contents: `
import * as fflate from 'fflate'
import * as fflate from 'fflate/browser'
const unzipped = fflate.unzipSync(Uint8Array.from(atob('${data}'), c => c.charCodeAt(0)))
export default function getFile(path) {
return Buffer.from(unzipped[path]).toString('utf-8')
Expand Down
Loading
Loading