(removing the sides of the cube does not count)
Sorry dude, that is what you have to do if you want this to be efficient and work every time. The reason you're getting those lines is slight depth buffer inconsistencies (also known as z-fighting). The sides of the blocks are almost at exactly the same depth as the tops of the nearer blocks.
Ideally, in a block-based game, for performance you really ought to delete non-visible faces. Here's some pseudocode of how you might do it:
// Generate a mesh of a 3D grid of blocks. Mesh GenerateMesh(Block[, , ] blocks) Mesh out_mesh; // Loop through every block. for x = 0 : blocks.max_x: for y = 0 : blocks.max_y: for z = 0 : blocks.max_z: Block block = blocks[x, y, z]; // Check each face of the block for face = 0 : 6: Block neighbor = block.GetNeighbor(face); // If the neighbor doesn't exist, add the triangles // from that face. if (!IsOccupied(neighbor)): out_mesh.AddVertices(block.GetFace(face)); return out_mesh;