Open MrVintage710 opened 2 weeks ago
Hey @MrVintage710 thanks for writing this up! I like the tying of traits to a property on the internal data model. I also like how you could just create a 'tag' by implementing a marker trait.
I have some questions about how similar items can be identified differently. This example talks about two different types of armor, heavy_armor
and light_armor
.
Lets say heavy_armor
has a physical_damage_reduction
field. How could we add a PhysicalDamageReductionComponent
to heavy_armor
without modifying the leather_armor
definition?
I think updating the AcItem
would feel bad because leather_armor
doesn't need to know anything about physical_damage_reduction
.
I think this is important because we would want to handle leather_armor
and physical_damage_reduction
the same ways because they are both fundamentally armor, but we want to identify them as separate in a potential query to "select all armor that has a PhysicalDamageReductionComponent
".
Put another way, how are these two objects different component wise? With the proposed schema how can we share a base data container yet extend different components?
I'm almost feeling like we should not have any base data containers like AcItem
and instead rely solely on component mashups. Archetypes are just groups of components at the end of the day.
I see what you are saying, and I agree. However I think that Archetypes is still a concept that we need for this app. Like say I want to find all Armor
Items in my inventory. How would you search for that? Is it all armor? what about items that give you AC but aren't armor? An archetype helps you define what items to accept and reject.
When you are making an entity, don't think "what archetype should this be a part of", just add the components that it needs and then naturally it will arrive at the archetype needed to describe that item.
In short, Archetypes are just minimum set of components needed for an entity to be something. Every entity will have multiple archetypes that it is apart of.
That being said, maybe Archetypes in the rust side should be defined like so:
trait AcItem {}
impl <T : NameComponent + ArmorClassBonusComponent + BulkComponent> AcItem for T {}
Lets say heavy_armor has a physical_damage_reduction field. How could we add a PhysicalDamageReductionComponent to heavy_armor without modifying the leather_armor definition?
You would have to make a new archetype for Heavy Armor. While this isn't optimal, it is a byproduct of rusts type system. I should look into more options for storing this...
Maybe we use something like bevy_ecs
to store this data in ram. Then we would just have to make a translation layer for the front and backend (probably with a serde
json parser)
Also here is something else that we have to think about: How should we do data validation? I don't think that we should have it in more than one spot. Probably put it in with the translation layer on the rust side.
Another thing to note is the debt accrued by managing component definitions in both TS and Rust. I wonder if defining these simple components in a language agnostic format like JSON or protobuff would work better. Both TS and Rust could then read from this shared object state.
Oh I love the idea of something like protobuff, however I think protobuff itself might be a bad fit for the project as it has no support for js or rust. What about Cap'n Proto?
Or what about Flat Buffer this one look promising as it has ts and rust supported, and they claim no parsing required!
Here is a good argument for flat buffers : https://www.youtube.com/watch?v=iQTxMkSJ1dQ
After talking yesterday with @MrVintage710, we decided it is best to use Cap'n Proto as our shared data serialization layer. We will define schemas, generate code, and then use this code in queries / rendering.
UPDATE - this issue will be where most of the discussion happens, its basically the parent to all the spun off issues. We will talk about features and create new issues from here.
The data model has been made with PR #25 and now data can be shared with PR #28.
Proposed Feature
We need a unified data model that will allow data to efficiently transfer from our backend to frontend, and visa versa. Based on previous discussions that I have had with @Gearhartlove, we want this data to be compositional. Then like items that share the same components can be sorted into groups called archetypes. For example, you could have an archetype called
Named Entities
that only requires that theName
Component is present on any given entity for it to be part of the archetype.To make this work, we need to have a standard that can be passed from one side of the app to the other. On the front end (typescript), and entity may look like this:
while on the back end (rust), it may look like this:
The rust version is a bit more verbose and doesn't have the general Entity that typescript has. However this seems to be a good starting place.
Without looking to much into the problem, I would imagine that the best place for this type of translation would be the backend tauri side. There we can define some
serde
traits that can translate between the front end json and whatever database format we choose.This issue should be somewhat related to issue #13
Acceptance Criteria
data_types.md
document that explains how data is laid out in the project for future contributors. Place this in thedocumentation/
directory.