---
# System prepended metadata

title: A small rant on assets as entities

---

# A small rant on assets as entities

I think typed handles are a problem for engine design, specifically related to the renderer. We have a recent user-driven use case that I think demonstrates this: as a user, I'd like to be able to create a `Mesh` that is already pre-formatted and so doesn't incur additional copies to interleave its data. The immediate problem here is that the existing `Mesh` API is oriented entirely around having a fluent builder for creating meshes on the CPU. This is an important API to support but creates friction between an ergonomic CPU representation (separate attribute buffers) the efficient GPU representation (interleaved). 

This is probably fixable in our current implementation with some difficulty. We could store the interleaved vertices inside `Mesh`, and have the builder API handle locating them in the buffer, default initializing and entire vertex step, returning an iterator over just a single attribute, etc. But the broader question I'd like to ask is why we should be coupled to a singular mesh API and representation in the main world in the first place. 

In other words, why can't we just have a user provide their own custom `RawMesh` type?

There's a kind of existential question we have to ask here first, what is a `Mesh3d`? It's important to note that in the renderer, there is no such thing as `Mesh`, we just have a variety of data structures that do the bookkeeping for handling the mesh. But the actual interaction with a `Mesh`'s data is limited to getting a `&[u8]` on extract.

In that sense, the actual data part of the mesh that motivates it being an asset is the least important of a mesh from the renderer's perspective. The renderer is concerned about metadata like the physical allocation in a GPU buffer, the number of mesh instances in the ECS, or the vertex layout for specialization code. These items form a well defined interface between the main world and the render world. By virtue of being a byte buffer, the mesh's data is already type erased and could in theory be provided to the renderer by a number of sources.

On the contrary, `Mesh3d` is used all over the place in the main world as a visibility class marker that indicates an entity is a renderable 3d item. At the same time, the actual mesh *data* is basically never relevant for main world systems. We store an `Aabb` separately on a given mesh instance and things like physics tend to store a different efficient CPU representation anyway. For most systems, `Mesh3d` is really just a query filter.

However, if you wanted to implement something like a `RawMesh`, this immediately becomes a huge problem. `Mesh3d` wraps a typed `Handle<Mesh>`, which means that even though it's data is only ever accessed in a very specific location, it is used as a marker basically everywhere. If a user wants to write a custom extract for their `RawMesh`, they have to also update a huge number things like material caches, write a custom visibility class, etc., that make this exercise prohibitive.

I think the design of assets-as-entities unveils itself naturally here. `Entity` is by its nature already type erased. Render assets are always a combination of some kind of metadata (i.e. a descriptor) and actual data. If `Mesh3d` were simply a wrapper around `Entity` (or a relation) and it's constitutive parts were decomposed into a variety of components representing its layout, etc., it would be trivially easy to implement something like `RawMesh` by creating a custom component for the interleaved data and writing a single extract system that handles the mesh allocation.

Everything else that simply needs to ask "is this a 3d renderable" could rely on the `Mesh3d` marker without caring what the actual mesh representation is. And systems do *do* require a certain mesh representation could still query for an asset entity that has that component.