#My own trait implemented for Component causing problems

1 messages · Page 1 of 1 (latest)

solid phoenix
#

In an RTS game, I have multiple types of storages systems that need to store "metal" in different ways in my game. Two examples are a metal quarry and a conveyor belt.
"Drones" need to be able to take metal and give metal too storage systems. I want the drones to be able to take from and put on metal at any point on the conveyor belt.

I made a Storage trait, Drones should use the trait to interact with a storage device.

A metal quarry stores metal, and allows drones to take from it, but not give as shown by this code here.

pub trait Storage{
    fn try_give_amount(&mut self, amount: u16)->u16;
    fn try_take_amount(&mut self, amount: u16)->u16;
}

#[derive(Component)]
pub struct Quarry{
    current: u16 //amount of metal the quarry is currently holding
}
impl Storage for Quarry{
    fn try_give_amount(&mut self, _amount: u16)->u16 {
        0
    }
    fn try_take_amount(&mut self, amount: u16)->u16 {
        let amount_taken = amount.clamp(0, self.current);  //ensures a drone cant take more metal than there is
        self.current -= amount_taken;
        amount_taken
    }
}

A conveyor belt has a single parent "belt" and then many "beltchild" children along the length of the belt. I want drones to be able to interact with each "beltchild" so I was going to implement storage for beltchild

#[derive(Component)]
pub struct Belt{
    pub queue: VecDeque<bool>, //each bool is weather or not that "slot" on the belt is holding metal
}
#[derive(Component)]
pub struct BeltChild; //each belt child is an entity to represent a "slot" on the belt.
impl Storage for BeltChild{
    fn try_give_amount(&mut self, amount: u16)->u16 {}
    fn try_take_amount(&mut self, amount: u16)->u16 {}
}

The problem is that the functions dont have acess to the queue of bools that represent the metal on the belt.

Originally I wanted to try something like this

#[derive(Component)]
pub struct BeltChild{
  index_along_belt: u16,
  parent_belt: Entity
}
#

I still dont have acess the the parent belt unless I also make BeltChild hold Commands, but thats not a good idea.

There are going to be many different types of storages in my game. A drone should always fly over to the storage, and try to take or give metal.
What is wrong with the Storage trait? Is there a better way, or a fix to my problem?

shy pike
#

Why isn't storage itself a component?

#

So to be clear you want the drone to interact with the slot on the belt, take 1 and have the parent get a false for that slot?

solid phoenix
shy pike
#

I don't have a good answer, just I think that traits and components kind of clash here, and you can probably work it out going all in on one instead of the current mix

#

and then I'd favour components

#

some mix is possible for sure

#

could the slot not be the thing to implement storage btw?

#

oh it is

#

couldn't you write a separate system that syncs the boolmask of each belt with its children

#

or not even have the boolmask and only store that info in children?

solid phoenix
# shy pike or not even have the boolmask and only store that info in children?

Right. I thought about that.

I know premature optomization is usually a bad idea. However, im planning on having hundreds of conveyor belts that are going to be hundreds of slots long.

The VecDeque<bool> allows me move every item forward one in O(1) time complexity (very fast)
If I have each BeltChild slot store its own bool, the time complexity is going to have to be O(n) minimum in order to move items.

Items are going to move like 4 times per second.

I hope this makes sense

solid phoenix
#

This is kinda why I was thinking of just dropping bevy entirely, I dont know

#

Syncing the boolmask is definitly something i could do, it would be annoying and there should be a better way, and it is obviously slower

#

Is there a way to have a system that never runs unless I tel it to?

I could have the system that syncs the VecDeque<bool> with BeltChild and then have that system only run when a drone attempts to access storage.

shy pike
#

I believe so but I kinda forgot how

obsidian imp
#

@solid phoenix check the https://docs.rs/bevy/latest/bevy/ecs/schedule/common_conditions/index.html docs to see if one of these system run conditions fits your implementation needs. You'd use my_system.run_if(...) to run said system/s only when the conditions are met. This could be, for example, on_event (so you'd basically push events whenever the drones access the storage and the system will run), or whatever fits your needs.

solid phoenix
#

I'll look into that when I get the chance thanks