Compare commits

...

5 Commits

Author SHA1 Message Date
transoptimal ccd33e2b15 add various rambles to readme. 2023-06-25 12:22:29 +02:00
transoptimal f6ad3da13b rewrite readme info about exiting boxes. 2023-06-25 00:53:13 +02:00
transoptimal bf7e29f7f1 don't render box contents if they would be small enough to be invisible. 2023-06-24 20:49:02 +02:00
transoptimal 4debf84e68 refactor graphics code.
separate tile drawing from box/world drawing, and simplify some of the
math.
2023-06-24 19:16:16 +02:00
transoptimal 6666c31b51 track nesting depth in boxes. 2023-06-24 18:51:42 +02:00
3 changed files with 46 additions and 18 deletions

View File

@ -4,7 +4,7 @@ the player character is currently the dark green square. creating new tiles crea
moving onto boxes makes you enter them. right now, this doesn't change your position; in the future entering a box from e.g. the left side will make you move to its left edge.
moving out of bounds makes you exit the box, if you're in one. this also doesn't change your position yet. if you exit at a position where there's another box in the one you exit into, you'll immediately enter that box.
moving outside of the edge makes you exit the box you're in, if you're currently inside a box. this also doesn't change your position yet. if you exit at a position where there's another box in the one you exit into, you'll immediately enter that box.
there's a demo video at `/assets/demo_video.webm`.
@ -20,3 +20,25 @@ there's a demo video at `/assets/demo_video.webm`.
# how to play
run a server in the root directory and open `index.html` in a web browser.
# more info & thoughts
the program currently autosaves to the web browser's `localStorage` every 3 seconds. it also tries to load a world from there when you first load the page.
the term "box" is used in the code both to refer to a set of tiles organized in a certain spatial structure, and to a kind of tile which contains such a space (or any specific instance of that kind of tile). this might sometimes be confusing.
i've noticed 2 different directions in which i might want to take this: a game focused on resource management & renewal; and a toy for drawing stuff.
the latter might make more sense within an [infinite tree](https://www.boristhebrave.com/2023/01/28/infinite-quadtrees-fractal-coordinates/) space, than in this more finite one.
the former feels to me like it wants to be created within the thematic context of life, growth, plants. it would probably be hard to include animals in such a game, in a way that makes them both relevant to gameplay, and doesn't make simulated specieist violence a useful strategy for game progression.
i think such a game would benefit from conserving mass throughout most transformations between different resources. look at [nodecore](https://content.minetest.net/packages/Warr1024/nodecore/) for an example of a game that does this a lot.
i don't know how ease of box acquisition might affect gameplay in such a game. newly created boxes could be empty, which would mean that they only provide more space; they could contain tiles, which would mean that creating new boxes would create new resources.
prepopulated boxes could either contain (on average) more or less mass than what went into creating them.
if less, it makes the effective price of creating a box cheaper, as long as you can afford a certain "threshold cost". if more, it might concentrate strategy around creation, content extraction, and disposal, of boxes. unless the amount of mass created is tiny in comparison to the box creation cost. boxes could potentially also contain worlds which are interesting to explore, and not necessarily easy to extract fungible resources from.
to the extent that mass is conserved, it would make sense gameplay-wise to make transformations of different materials have inverses made up of other transformations. (this would possibly create a [group](https://en.wikipedia.org/wiki/Group_(mathematics).) the reason for this is that otherwise there would be materials which can't be created from any other materials, and materials which can't be destroyed by turning them into other materials.

View File

@ -13,7 +13,7 @@ graphics.set_size(canvas.width, canvas.height);
const BASE_SCALE = 81;
export function draw_tile (x, y, size = BASE_SCALE) {
export function draw_rect (x, y, size = BASE_SCALE) {
graphics.fill_rect(x, y, size, size);
}
@ -28,39 +28,43 @@ export function draw_floor (start_x, start_y, scale, invert = false) {
} else {
graphics.set_color("#888");
}
const [visual_x, visual_y] = project_pos(x, y, scale);
draw_tile(start_x + visual_x, start_y + visual_y, scale);
draw_rect(x * scale + start_x, y * scale + start_y, scale);
});
}
export function draw_world (box, start_x = 0, start_y = 0, scale = BASE_SCALE) {
if (scale < 1) return;
draw_floor(start_x, start_y, scale, !checkerboard(start_x, start_y));
iter_2d(range(0, world.BOX_SIZE - 1), (x, y) => {
const tile = world.get_tile(box, x, y);
const [visual_x, visual_y] = project_pos(x, y, scale);
switch (tile.type) {
case "box": {
draw_world(tile.box, start_x + visual_x, start_y + visual_y, scale / world.BOX_SIZE);
break;
}
case "paint": {
graphics.set_color(tile.color);
draw_tile(start_x + visual_x, start_y + visual_y, scale);
break;
}
}
draw_tile(tile, x * scale + start_x, y * scale + start_y, scale);
});
entity.for_each((entity, id) => {
if (entity.box !== box) return;
graphics.set_color(entity.color);
const [visual_x, visual_y] = project_pos(entity.x, entity.y, scale);
draw_tile(start_x + visual_x, start_y + visual_y, scale);
draw_rect(start_x + visual_x, start_y + visual_y, scale);
});
}
function draw_tile (tile, x, y, scale) {
switch (tile.type) {
case "box": {
// recursively draw box contents.
draw_world(tile.box, x, y, scale / world.BOX_SIZE);
break;
}
case "paint": {
graphics.set_color(tile.color);
draw_rect(x, y, scale);
break;
}
}
}
function project_pos (x, y, scale) {
return [x, y].map(a => a * scale);
}

View File

@ -8,6 +8,7 @@ export const CENTER = Math.floor(BOX_SIZE / 2);
function create_world (size) {
return {
tiles: Array(size).fill(0).map(_ => Array(size).fill(0)),
depth: 0,
};
}
const world = create_world(BOX_SIZE);
@ -29,6 +30,7 @@ export function get_tile (world, x, y) {
export function create_box (parent) {
return {
...create_world(BOX_SIZE),
depth: parent.depth + 1,
parent,
};
}