Feedback wanted: Intended way to use custom components?

Hi,

I am wondering: If I want to add things in code that need updating, like for a simple example a thruster (which surely could be done via Physics, but that’s not the point), I could just do so via Scripts.
However if I want to access some values there from other scripts, I understand I should rather put that code in components? If I add a thruster that has the gas pedal position as input, I could use it for the player’s vehicle, then create a script that translates gamepad input into gas pedal position. For other vehicles, I could instead do AI scripts/components which also output a gas pedal position.

In any case, I would have to access the input property (or field) of the thruster, so I thought I could make a component and find that simply by type during script start.

Here is a full example. The component:

namespace MyGame1.CustomComponents
{
    [Display(40, "Thrusters", "Adds thrusters for acceleration", Expand = ExpandRule.Once)]
    [DataContract("ThrusterComponent")]
    [DefaultEntityComponentProcessor(typeof(ThrusterProcessor))]
    public class ThrusterComponent : EntityComponent
    {
        public static PropertyKey<ThrusterComponent> Key = new PropertyKey<ThrusterComponent>("Key", typeof(ThrusterComponent));

        public override PropertyKey GetDefaultKey()
        {
            return Key;
        }

        public ThrusterComponent()
        { // Nothing to do}

        // Linear thruster values

        [DataMember(1)]
        public float MaxAccel = 0.14f;

        [DataMember(2)]
        public float MaxSpeed = 0.06f;

        public float CurrentAcceleration = 0; // This is the gas pedal position from -1 to +1
        public float CurrentSpeed = 0;

        public void Update(GameTime time)
        {
            float elapsedSeconds = (float)time.Elapsed.TotalSeconds;

            // Accel
            CurrentSpeed += ForwardAccel * elapsedSeconds * CurrentAcceleration;
            CurrentSpeed = MathUtil.Clamp(CurrentSpeed, -MaxSpeed, MaxSpeed);

            // Apply speed
            this.Entity.Transform.Position.X += CurrentSpeed; // This simple example only works on the X axis
        }
    }
}

and this is the according processor:

namespace MyGame1.CustomProcessors
{
    public class ThrusterProcessor : EntityProcessor<ThrusterComponent>
    {
        public ThrusterProcessor()
            : base(new PropertyKey[] { ThrusterComponent.Key })
        {
            Order = -10;
        }
 
        protected override ThrusterComponent GenerateAssociatedData(Entity entity)
        {
            return entity.Get<ThrusterComponent>();
        }
 
        public override void Draw(RenderContext context)
        {
            if (this.Enabled)
            {
                foreach (var matchingEntity in enabledEntities)
                {
                    matchingEntity.Value.Update(context.Time);
                }
            }
        }
    }
}

and finally a script that would turn key strokes into acceleration:

namespace MyGame1
{
    public class InputToThrust : SyncScript
    {
        ThrusterComponent _thruster;

        public override void Start()
        {
            base.Start();

            _thruster = this.Entity.Get<ThrusterComponent>();
        }

        public override void Update()
        {
            if (Game.IsRunning)
            {
                // Translation
                if (Input.IsKeyDown(SiliconStudio.Paradox.Input.Keys.Up))
                {
                    _thruster.CurrentAcceleration = 1;
                }
                else if (Input.IsKeyDown(SiliconStudio.Paradox.Input.Keys.Down))
                {
                    _thruster.CurrentAcceleration = -1;
                }
                else
                {
                    _thruster.CurrentAcceleration = 0;
                }
            }
        }
    }
}

Now I have done that already and it seems to work fine for me (aside from some GC hickups which I am not sure about whether they started to occur since I added this stuff).

However due to the current lack of documentation I am very unsure whether I am doing things right or rather massively wrong. So I thought I’d better have someone with more in depth knowledge check on what I am doing before I proceed any further that way.

The thruster could as well be implemented as script, so I had to scan for that one in SyncScript.Start() instead of scanning for the component (which might bring sorting issues). Are there any pros and cons to either approach or is there a different one altogether?

I’d be glad if anyone could spare a minute to enlighten me. Thanks for your time.