Would you be able to post a picture of what you've got so far cus I can't really tell exactly what you mean?
I was gonna say, you can build the entire level in one vertex buffer, you'd just build the cubes\square faces where needed and use a tilemap with all the textures.
On minecraft, each cell in the grid has a flag\tag determining what material it is, and 0 is air.
Then the faces of the cubes are built by iterating through each cell and checking the neighbour cells to see if they are air or solid.
It can be done either by each air cell checking if any of it's neighbour cells are solid, or each solid cell checking if any of it's neighbour cells are air.
Though I think it'd be a bit simpler doing the latter cus then you don't have to get what the neighbour cell's material is when applying the textures.
So it would be like this:
for each cell
{
if the cell is solid (it's tag/flag is not zero)
{
for each of the 6 neighbour cells
{
if it's air
{
create a square with the orientation of that neighbour(up, down, north, south, east, west)
give the square uv coordinates on the tilemap depending what material flag it has
}
}
}
}
and you'd have to add an extra thing to determine what layer of the tilemap each square should use, but I'd start by getting this first part working first.
It won't slow the game down if you have as many cubes as on minecraft btw, not if you do it this way cus most of the cubes are invisible\have no geometry cus of them being hidden, and you can use chunking later down the line if the world is really big, so it'll be split into one vertex buffer per "view region", then only 4 need to be rendered at a time (the ones in the view region)
As you can see here, if the vertex buffers are the same size as the view region (or slightly larger), it's only possible for view region to be intersecting 4 at a time:
Then getting the cells to draw can be done by simply rounding the view's position divided by the grid res:
GML:
var
cx = clamp(round(global.view_x / global.chunk_grid_res), 1, global.chunks_x - 1),
cy = clamp(round(global.view_y / global.chunk_grid_res), 1, global.chunks_y - 1);
vertex_submit(world_chunk_vbuffers[cx, cy], pr_trianglelist, tilemap_texture)
vertex_submit(world_chunk_vbuffers[cx - 1, cy], pr_trianglelist, tilemap_texture)
vertex_submit(world_chunk_vbuffers[cx, cy - 1], pr_trianglelist, tilemap_texture)
vertex_submit(world_chunk_vbuffers[cx - 1, cy - 1], pr_trianglelist, tilemap_texture)