struct Entity {
components: Vec<Box<dyn Component>>,
}
At this point you're effectively just hand-rolling your own ECS - and perhaps being in denial about it by touting the fact that the ECS is half implemented at best - rather than eschewing an ECS outright, IMO. If you want to skip the ECS, embrace the natural typing of the language - then you don't need to build something to query and filter components, and can instead just use the language's built-in constructs:
struct Entity {
pub position: Option<XY>,
pub sprite: Option<SpriteId>,
pub scripts: Vec<ScriptRef>,
//...
}
fn render_world(entities: &[Entity]) {
for entity in entities {
if let Entity { position: Some(xy), sprite: Some(sprite), .. } = entity {
// ...
}
}
}
Entity may eventually become a merge hazard on larger teams, and Entity enumeration without archetype filtering may eventually become a performance hazard if done too frequently and naively, but this kind of approach can work fine for many smaller projects.