This commit is contained in:
2026-03-27 16:21:56 -03:00
parent a736b9c5c0
commit 123a913d55
28 changed files with 476 additions and 70 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

+11
View File
@@ -0,0 +1,11 @@
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
import { register_block_item } from "$/common/utils.ts";
const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:coal_ore", {
id: "bworld:coal_ore",
textures: "bworld:stone_coal",
has_collision: true,
drop_table: "bworld:coal_ore",
});
register_block_item(block);
+11
View File
@@ -0,0 +1,11 @@
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
import { register_block_item } from "$/common/utils.ts";
const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:copper_ore", {
id: "bworld:copper_ore",
textures: "bworld:stone_copper",
has_collision: true,
drop_table: "bworld:copper_ore",
});
register_block_item(block);
+99 -41
View File
@@ -4,61 +4,110 @@ import { PlayerComponent } from "../player.ts";
import { GuiFurnace } from "$/client/gui/gui_furnace.ts"; import { GuiFurnace } from "$/client/gui/gui_furnace.ts";
import { register_block_item } from "../../common/utils.ts"; import { register_block_item } from "../../common/utils.ts";
function can_craft(container: Container) { interface FurnaceRecipe {
const input = container.get_item(0); input: string;
const output = container.get_item(2); output: ItemStack;
cook_time: number;
}
const FURNACE_RECIPES: FurnaceRecipe[] = [
{
input: "bworld:log",
output: new ItemStack("bworld:coal", 1),
cook_time: 100,
},
{
input: "bworld:coal_ore",
output: new ItemStack("bworld:coal", 1),
cook_time: 100,
},
{
input: "bworld:iron_ore",
output: new ItemStack("bworld:iron_ingot", 1),
cook_time: 200,
},
{
input: "bworld:tin_ore",
output: new ItemStack("bworld:tin_ingot", 1),
cook_time: 200,
},
{
input: "bworld:copper_ore",
output: new ItemStack("bworld:copper_ingot", 1),
cook_time: 200,
},
{
input: "bworld:gold_ore",
output: new ItemStack("bworld:gold_ingot", 1),
cook_time: 200,
},
];
function get_recipe(input?: ItemStack | undefined): FurnaceRecipe | undefined {
if (!input) { if (!input) {
return;
}
return FURNACE_RECIPES.find((r) => r.input === input.type_id);
}
function can_craft(container: Container, recipe?: FurnaceRecipe) {
if (!recipe) {
return false; return false;
} }
if (["bworld:log"].includes(input.type_id)) { const output = container.get_item(2);
return true;
}
if (!output) { if (!output) {
return true; return true;
} }
if (output.amount >= output.max_amount) { if (output.type_id !== recipe.output.type_id) {
return false; return false;
} }
return true; return output.amount < output.max_amount;
}
const FUEL_VALUES: Record<string, number> = {
"bworld:coal": 1000,
"bworld:log": 100,
};
function get_fuel_value(item?: ItemStack | undefined): number {
if (!item) {
return 0;
}
return FUEL_VALUES[item.type_id] ?? 0;
} }
function has_fuel(container: Container) { function has_fuel(container: Container) {
const fuel = container.get_item(1); return get_fuel_value(container.get_item(1)) > 0;
if (!fuel) {
return false;
}
if (["bworld:coal", "bworld:log"].includes(fuel.type_id)) {
return true;
}
return false;
} }
function consume_fuel(container: Container) { function consume_fuel(container: Container): number {
const fuel = container.get_item(1)!; const fuel = container.get_slot(1)!;
fuel.amount -= 1; const value = get_fuel_value(fuel.get_item());
container.set_item(1, fuel);
if (fuel.has_item()) {
fuel.amount! -= 1;
}
return value;
} }
function craft(container: Container, item: ItemStack) { function craft(container: Container, recipe: FurnaceRecipe) {
const input = container.get_item(0)!; const input = container.get_item(0)!;
const output = container.get_item(2); const output = container.get_item(2);
if (!output) { if (!output) {
container.set_item(2, item); container.set_item(2, recipe.output.clone());
} else { } else {
output.amount += item.amount; output.amount += recipe.output.amount;
} }
input.amount -= 1; input.amount -= 1;
container.set_item(0, input); container.set_item(0, input.amount > 0 ? input : undefined);
} }
interface TileChestData { interface TileChestData {
@@ -106,25 +155,34 @@ const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:furna
return; return;
} }
if (block_data.data.fuel > 0) { const data = block_data.data;
block_data.data.fuel -= 1; const container = data.inventory.container;
const input = container.get_item(0);
const recipe = get_recipe(input);
// burn fuel
if (data.fuel > 0) {
data.fuel -= 1;
} }
const container = block_data.data.inventory.container; if (!can_craft(container, recipe)) {
data.progress = 0;
return;
}
if (can_craft(container)) { // refuel
if (block_data.data.fuel === 0 && has_fuel(container)) { if (data.fuel === 0 && has_fuel(container)) {
consume_fuel(container); data.fuel = consume_fuel(container);
block_data.data.fuel = 200; }
}
if (block_data.data.fuel > 0) { // cook
block_data.data.progress += 1; if (data.fuel > 0 && recipe) {
data.progress += 1;
if (block_data.data.progress >= 100) { if (data.progress >= recipe.cook_time) {
block_data.data.progress = 0; data.progress = 0;
craft(container, new ItemStack("bworld:coal")); craft(container, recipe);
}
} }
} }
}, },
+11
View File
@@ -0,0 +1,11 @@
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
import { register_block_item } from "$/common/utils.ts";
const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:gold_ore", {
id: "bworld:gold_ore",
textures: "bworld:stone_gold",
has_collision: true,
drop_table: "bworld:gold_ore",
});
register_block_item(block);
+11
View File
@@ -0,0 +1,11 @@
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
import { register_block_item } from "$/common/utils.ts";
const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:iron_ore", {
id: "bworld:iron_ore",
textures: "bworld:stone_iron",
has_collision: true,
drop_table: "bworld:iron_ore",
});
register_block_item(block);
+5
View File
@@ -11,3 +11,8 @@ import "./snow.ts";
import "./glass.ts"; import "./glass.ts";
import "./hoed_dirt.ts"; import "./hoed_dirt.ts";
import "./leaves.ts"; import "./leaves.ts";
import "./coal_ore.ts";
import "./copper_ore.ts";
import "./iron_ore.ts";
import "./tin_ore.ts";
import "./gold_ore.ts";
+11
View File
@@ -0,0 +1,11 @@
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
import { register_block_item } from "$/common/utils.ts";
const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:tin_ore", {
id: "bworld:tin_ore",
textures: "bworld:stone_tin",
has_collision: true,
drop_table: "bworld:tin_ore",
});
register_block_item(block);
+38 -8
View File
@@ -1,4 +1,4 @@
import { Alea, create_noise_2d, NoiseFunction2D } from "@paulaboks/rng"; import { Alea, create_noise_2d, create_noise_3d, NoiseFunction2D } from "@paulaboks/rng";
import { CHUNK_SIZE, Dimension } from "./components/dimension.ts"; import { CHUNK_SIZE, Dimension } from "./components/dimension.ts";
type Biome = type Biome =
@@ -12,6 +12,22 @@ type Biome =
| "savanna" | "savanna"
| "swamp"; | "swamp";
type OreDef = {
id: string;
min_y: number;
max_y: number;
scale: number;
threshold: number;
};
const ORES: OreDef[] = [
{ id: "bworld:coal_ore", min_y: 20, max_y: 120, scale: 0.05, threshold: 0.55 },
{ id: "bworld:copper_ore", min_y: 10, max_y: 80, scale: 0.06, threshold: 0.6 },
{ id: "bworld:tin_ore", min_y: 5, max_y: 60, scale: 0.06, threshold: 0.62 },
{ id: "bworld:iron_ore", min_y: 5, max_y: 50, scale: 0.05, threshold: 0.65 },
{ id: "bworld:gold_ore", min_y: 0, max_y: 30, scale: 0.04, threshold: 0.7 },
];
function get_biome(temp: number, moisture: number): Biome { function get_biome(temp: number, moisture: number): Biome {
if (temp > 0.6) { if (temp > 0.6) {
if (moisture < -0.2) { if (moisture < -0.2) {
@@ -118,13 +134,6 @@ function place_tree(dimension: Dimension, x: number, y: number, z: number, biome
const trunk_block = "bworld:log"; const trunk_block = "bworld:log";
const leaves_block = "bworld:leaves"; const leaves_block = "bworld:leaves";
// if (biome === "jungle") {
// trunkBlock = "bworld:jungle_log";
// leavesBlock = "bworld:jungle_leaves";
// } else if (biome === "taiga") {
// leavesBlock = "bworld:spruce_leaves";
// }
for (let i = 0; i < height; i++) { for (let i = 0; i < height; i++) {
dimension.add_block({ x, y: y + i, z, id: trunk_block }); dimension.add_block({ x, y: y + i, z, id: trunk_block });
} }
@@ -167,6 +176,7 @@ export function generate_chunk(dimension: Dimension, cx: number, cz: number, see
const temp_noise = create_noise_2d(new Alea(seed + "_temp")); const temp_noise = create_noise_2d(new Alea(seed + "_temp"));
const moisture_noise = create_noise_2d(new Alea(seed + "_moisture")); const moisture_noise = create_noise_2d(new Alea(seed + "_moisture"));
const feature_noise = create_noise_2d(new Alea(seed + "_feature")); const feature_noise = create_noise_2d(new Alea(seed + "_feature"));
const ore_noises = ORES.map((ore) => create_noise_3d(new Alea(seed + "_" + ore.id)));
const biome_scale = 0.003; const biome_scale = 0.003;
const terrain_scale = 0.01; const terrain_scale = 0.01;
@@ -190,6 +200,26 @@ export function generate_chunk(dimension: Dimension, cx: number, cz: number, see
for (let y = 0; y <= height; y++) { for (let y = 0; y <= height; y++) {
let block = "bworld:stone"; let block = "bworld:stone";
if (y < height - 3) {
for (let i = 0; i < ORES.length; i++) {
const ore = ORES[i];
if (y >= ore.min_y && y <= ore.max_y) {
const noise = ore_noises[i](
wx * ore.scale,
y * ore.scale,
wz * ore.scale,
);
if (noise > ore.threshold) {
block = ore.id;
break;
}
}
}
}
if (y === height) { if (y === height) {
block = surface_block; block = surface_block;
} else if (y > height - 4) { } else if (y > height - 4) {
+16
View File
@@ -29,6 +29,22 @@ const recipes: CraftingRecipe[] = [
], ],
result: new ItemStack("bworld:chest", 1), result: new ItemStack("bworld:chest", 1),
}, },
{
width: 3,
height: 3,
pattern: [
"bworld:stone",
"bworld:stone",
"bworld:stone",
"bworld:stone",
undefined,
"bworld:stone",
"bworld:stone",
"bworld:stone",
"bworld:stone",
],
result: new ItemStack("bworld:furnace", 1),
},
]; ];
const PADDING = 10; const PADDING = 10;
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:axe", {
texture_id: "bworld:axe",
});
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:coal", {
texture_id: "bworld:coal",
});
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:copper_ingot", {
texture_id: "bworld:copper_ingot",
});
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:gold_ingot", {
texture_id: "bworld:gold_ingot",
});
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:hoe", {
texture_id: "bworld:hoe",
});
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:iron_ingot", {
texture_id: "bworld:iron_ingot",
});
+8
View File
@@ -1 +1,9 @@
import "./watering_can.ts"; import "./watering_can.ts";
import "./axe.ts";
import "./pickaxe.ts";
import "./hoe.ts";
import "./coal.ts";
import "./tin_ingot.ts";
import "./iron_ingot.ts";
import "./copper_ingot.ts";
import "./gold_ingot.ts";
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:pickaxe", {
texture_id: "bworld:pickaxe",
});
+5
View File
@@ -0,0 +1,5 @@
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
EverythingRegistry.register<ItemRegistry>("items", "bworld:tin_ingot", {
texture_id: "bworld:tin_ingot",
});
-1
View File
@@ -39,7 +39,6 @@ export function create_player(world: ClientWorld) {
// player_inventory.container.add_item(new ItemStack("bworld:potato_seeds", 64)); // player_inventory.container.add_item(new ItemStack("bworld:potato_seeds", 64));
// player_inventory.container.add_item(new ItemStack("bworld:pumpkin_seeds", 64)); // player_inventory.container.add_item(new ItemStack("bworld:pumpkin_seeds", 64));
// player_inventory.container.add_item(new ItemStack("bworld:carrot_seeds", 64)); // player_inventory.container.add_item(new ItemStack("bworld:carrot_seeds", 64));
player_inventory.container.add_item(new ItemStack("bworld:furnace", 1));
player.add(new Camera()); player.add(new Camera());
player.add(new CollisionCuboid(0.55, 1.79, 0.55)); player.add(new CollisionCuboid(0.55, 1.79, 0.55));
+29
View File
@@ -299,6 +299,35 @@ export function push_quad(
push_vertex(dx, y2, 0, u0, v1, r, g, b, a); push_vertex(dx, y2, 0, u0, v1, r, g, b, a);
} }
export function push_quad_vertices(
x0: number,
y0: number,
x1: number,
y1: number,
x2: number,
y2: number,
x3: number,
y3: number,
u0: number,
v0: number,
u1: number,
v1: number,
r = 1,
g = 1,
b = 1,
a = 1,
) {
// triangle 1
push_vertex(x0, y0, 0, u0, v0, r, g, b, a);
push_vertex(x1, y1, 0, u1, v0, r, g, b, a);
push_vertex(x2, y2, 0, u1, v1, r, g, b, a);
// triangle 2
push_vertex(x0, y0, 0, u0, v0, r, g, b, a);
push_vertex(x2, y2, 0, u1, v1, r, g, b, a);
push_vertex(x3, y3, 0, u0, v1, r, g, b, a);
}
// internal // internal
function update_camera() { function update_camera() {
+62 -1
View File
@@ -1,4 +1,4 @@
import { flush_batch, get_current_texture, gl, push_quad, set_current_texture } from "./core.ts"; import { flush_batch, get_current_texture, gl, push_quad, push_quad_vertices, set_current_texture } from "./core.ts";
import { Texture } from "./types.ts"; import { Texture } from "./types.ts";
export function load_texture(image: HTMLImageElement): Texture { export function load_texture(image: HTMLImageElement): Texture {
@@ -93,3 +93,64 @@ export function draw_texture_region(
push_quad(dx, dy, dw, dh, u0, v0, u1, v1, r, g, b, a); push_quad(dx, dy, dw, dh, u0, v0, u1, v1, r, g, b, a);
} }
export function draw_texture_region_skewed(
texture: Texture,
sx: number,
sy: number,
sw: number,
sh: number,
points: [
{ x: number; y: number }, // top-left
{ x: number; y: number }, // top-right
{ x: number; y: number }, // bottom-right
{ x: number; y: number }, // bottom-left
],
r = 1,
g = 1,
b = 1,
a = 1,
flip_x = false,
flip_y = false,
) {
if (get_current_texture() !== texture.tex) {
flush_batch();
set_current_texture(texture.tex);
}
let u0 = sx / texture.width;
let v0 = sy / texture.height;
let u1 = (sx + sw) / texture.width;
let v1 = (sy + sh) / texture.height;
if (flip_x) {
[u0, u1] = [u1, u0];
}
if (flip_y) {
[v0, v1] = [v1, v0];
}
const p0 = points[0];
const p1 = points[1];
const p2 = points[2];
const p3 = points[3];
push_quad_vertices(
p0.x,
p0.y,
p1.x,
p1.y,
p2.x,
p2.y,
p3.x,
p3.y,
u0,
v0,
u1,
v1,
r,
g,
b,
a,
);
}
+119 -14
View File
@@ -1,8 +1,9 @@
import { SLOT_SIZE } from "$/common/constants.ts"; import { SLOT_SIZE, TEXTURE_SIZE } from "$/common/constants.ts";
import { get_sprite_region } from "$/common/utils.ts"; import { get_sprite_region } from "$/common/utils.ts";
import { BlockRegistry, EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
import { AssetManager } from "$/client/assets.ts"; import { AssetManager } from "$/client/assets.ts";
import { ItemStack } from "../../inventory.ts"; import { ItemStack } from "../../inventory.ts";
import { draw_text, draw_texture_region, Texture } from "$/client/renderer/mod.ts"; import { draw_text, draw_texture_region, draw_texture_region_skewed, Texture } from "$/client/renderer/mod.ts";
export function draw_nine_slice( export function draw_nine_slice(
image: Texture, image: Texture,
@@ -199,18 +200,18 @@ export function draw_nine_slice(
} }
export function draw_item(item: ItemStack, x: number, y: number) { export function draw_item(item: ItemStack, x: number, y: number) {
const sprite_region = get_sprite_region(item.type_id); const item_info = EverythingRegistry.get<ItemRegistry>("items", item.type_id);
draw_texture_region(
AssetManager.instance.get("bworld:textures"), if (!item_info) {
sprite_region.x * 16, throw Error(`Didn't find item registry for '${item.type_id}'`);
sprite_region.y * 16, }
16,
16, if (item_info?.block_id) {
x + 3, draw_item_block(item, item_info, x, y);
y + 3, } else {
SLOT_SIZE - 6, draw_item_item(item, item_info, x, y);
SLOT_SIZE - 6, }
);
if (item.max_amount !== 1) { if (item.max_amount !== 1) {
draw_text( draw_text(
String(item.amount), String(item.amount),
@@ -227,3 +228,107 @@ export function draw_item(item: ItemStack, x: number, y: number) {
); );
} }
} }
// ey its not a bad name
function draw_item_item(item: ItemStack, item_info: ItemRegistry, x: number, y: number) {
let texture_id = "bworld:missing";
if (typeof item_info?.texture_id === "string") {
texture_id = item_info.texture_id;
} else if (typeof item_info?.texture_id === "function") {
texture_id = item_info.texture_id(item);
}
const sprite_region = get_sprite_region(texture_id);
draw_texture_region(
AssetManager.instance.get("bworld:textures"),
sprite_region.x * 16,
sprite_region.y * 16,
16,
16,
x + 3,
y + 3,
SLOT_SIZE - 6,
SLOT_SIZE - 6,
);
}
function draw_item_block(_item: ItemStack, item_info: ItemRegistry, x: number, y: number) {
const block_info = EverythingRegistry.get<BlockRegistry>("blocks", item_info.block_id!);
if (!block_info) throw new Error(`no textures for ${item_info.block_id}`);
let front_texture = "bworld:missing";
let top_texture = "bworld:missing";
let left_texture = "bworld:missing";
const textures = block_info.textures;
if (typeof textures === "string") {
front_texture = textures;
top_texture = textures;
left_texture = textures;
} else if ("top" in textures && "bottom" in textures && "side" in textures) {
top_texture = textures.top;
front_texture = textures.side;
left_texture = textures.side;
} else if ("front" in textures && "side" in textures) {
top_texture = textures.side;
front_texture = textures.front;
left_texture = textures.side;
}
const atlas = AssetManager.instance.get<Texture>("bworld:textures");
const top = get_sprite_region(top_texture);
const front = get_sprite_region(front_texture);
const left = get_sprite_region(left_texture);
const padding = 4;
const size = (SLOT_SIZE - padding * 2) / 2;
const cx = x + SLOT_SIZE / 2;
const cy = y + SLOT_SIZE / 2 - 10;
const half_w = size;
const half_h = size / 2;
const height = size;
draw_texture_region_skewed(
atlas,
top.x * TEXTURE_SIZE,
top.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
[
{ x: cx, y: cy - half_h },
{ x: cx + half_w, y: cy },
{ x: cx, y: cy + half_h },
{ x: cx - half_w, y: cy },
],
);
draw_texture_region_skewed(
atlas,
left.x * TEXTURE_SIZE,
left.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
[
{ x: cx - half_w, y: cy },
{ x: cx, y: cy + half_h },
{ x: cx, y: cy + half_h + height },
{ x: cx - half_w, y: cy + height },
],
);
draw_texture_region_skewed(
atlas,
front.x * TEXTURE_SIZE,
front.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
[
{ x: cx + half_w, y: cy },
{ x: cx, y: cy + half_h },
{ x: cx, y: cy + half_h + height },
{ x: cx + half_w, y: cy + height },
],
);
}
+1 -1
View File
@@ -16,7 +16,7 @@
"imports": { "imports": {
"$/": "./", "$/": "./",
"@gfx/canvas-wasm": "jsr:@gfx/canvas-wasm@^0.4.2", "@gfx/canvas-wasm": "jsr:@gfx/canvas-wasm@^0.4.2",
"@paulaboks/rng": "jsr:@paulaboks/rng@^0.0.2", "@paulaboks/rng": "jsr:@paulaboks/rng@^0.0.3",
"@std/fs": "jsr:@std/fs@^1.0.23", "@std/fs": "jsr:@std/fs@^1.0.23",
"gl-matrix": "npm:gl-matrix@^3.4.4", "gl-matrix": "npm:gl-matrix@^3.4.4",
"marked": "npm:marked@^17.0.3" "marked": "npm:marked@^17.0.3"
Generated
+4 -4
View File
@@ -2,7 +2,7 @@
"version": "5", "version": "5",
"specifiers": { "specifiers": {
"jsr:@gfx/canvas-wasm@~0.4.2": "0.4.2", "jsr:@gfx/canvas-wasm@~0.4.2": "0.4.2",
"jsr:@paulaboks/rng@^0.0.2": "0.0.2", "jsr:@paulaboks/rng@^0.0.3": "0.0.3",
"jsr:@std/encoding@1.0.5": "1.0.5", "jsr:@std/encoding@1.0.5": "1.0.5",
"jsr:@std/fs@^1.0.23": "1.0.23", "jsr:@std/fs@^1.0.23": "1.0.23",
"jsr:@std/internal@^1.0.12": "1.0.12", "jsr:@std/internal@^1.0.12": "1.0.12",
@@ -17,8 +17,8 @@
"jsr:@std/encoding" "jsr:@std/encoding"
] ]
}, },
"@paulaboks/rng@0.0.2": { "@paulaboks/rng@0.0.3": {
"integrity": "9b4833c80f09f2b6455f3d477977caaab0aac1b04a89970166a2c5169ab4687d" "integrity": "8d2571f9f406dab2674178f4034825cc654c5a52aa7c2a176a25f8b713eee202"
}, },
"@std/encoding@1.0.5": { "@std/encoding@1.0.5": {
"integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04"
@@ -52,7 +52,7 @@
"workspace": { "workspace": {
"dependencies": [ "dependencies": [
"jsr:@gfx/canvas-wasm@~0.4.2", "jsr:@gfx/canvas-wasm@~0.4.2",
"jsr:@paulaboks/rng@^0.0.2", "jsr:@paulaboks/rng@^0.0.3",
"jsr:@std/fs@^1.0.23", "jsr:@std/fs@^1.0.23",
"npm:gl-matrix@^3.4.4", "npm:gl-matrix@^3.4.4",
"npm:marked@^17.0.3" "npm:marked@^17.0.3"