On 2019-08-02 11:46 a.m., Coda Highland wrote:
>
>
> On Fri, Aug 2, 2019 at 9:41 AM Coda Highland <chighland@gmail.com
> <mailto:chighland@gmail.com>> wrote:
>
>
>
> On Fri, Aug 2, 2019 at 2:33 AM Egor Skriptunoff
> <egor.skriptunoff@gmail.com <mailto:egor.skriptunoff@gmail.com>>
> wrote:
>
> On Fri, Aug 2, 2019 at 12:19 AM Soni "They/Them" L. wrote:
>
> > On 2019-08-01 6:05 p.m., Egor Skriptunoff wrote:
> >> Could you provide an example to show benefits of traits?
> >> What kinds of tasks traits solve better than conventional
> >> 'objects-and-methods' approach?
> >>
> >
> > I recommend reading
> https://en.wikipedia.org/wiki/Entity_component_system
>
> (Well, besides reading that, I recommend actually checking
> out Rust and
> using it for a while. You'll see what I mean.)
>
>
> Could you just show a simple example from real-life
> programming where using traits is better than not using them?
> Such example should be understandable by any Lua programmer
> (without Rust knowledge).
> If you can't provide such example then why Lua users might
> want to use Cratera?
>
>
> If your own example on SO satisfies you, then let me rewrite it
> using standard Lua syntax (not Cratera traits because I'm not
> familiar enough):
>
> all_entities = {]
>
> function HealthRegen(self, entity, dt)
> self.current_hp = math.min(
> self.max_hp,
> self.current_hp + self.max_hp * dt / (5*60)
> )
> end
>
> traits = {
> Health = function(hp) return { max_hp = hp, current_hp = hp,
> update = HealthRegen },
> Velocity = function(max) return { max_speed = max, speed_x = 0,
> speed_y = 0 }
> }
>
> function Instantiate(type)
> local obj = {}
> for trait, param in pairs(type) do
> obj[trait] = traits[trait](param)
> end
> table.insert(all_entities, obj)
> return obj
> end
>
> Player = { Health = 42, Velocity = 1.0 }
> Monster = { Health = 100, Velocity = 2.5 }
>
> player = Instantiate(Player)
> monster = Instantiate(Monster)
>
> function update(dt)
> for _, entity in pairs(all_entities) do
> if entity.update then entity:update(dt) end
> for _, trait in pairs(entity) do
> if trait.update then trait:update(entity, dt) end
> end
> end
> end
>
>
> Forgot to mention...
>
> function HealthDamage(self, entity, amount)
> self.current_hp = self.current_hp - amount
> if self.current_hp <= 0 then
> self.current_hp = 0
> if entity.OnDeath then entity:OnDeath() end
> end
> end
>
> monster.Health:damage(monster, 10)
>
> This isn't quite compatible with how Cratera's syntax does it, because
> at this point I would want to write monster:[Health]:damage(10) and I
> can't do that. But it should still get the point across.
>
> /s/ Adam
>
>
you don't need to write monster:[Health]:damage(10) because you can just
write monster[Health] inside damage. e.g.:
function Health.damage(entity, amount)
local healthComponent = entity[Health]
-- ...
end
entity = {[Health] = Health.new()}
entity:[Health].damage(amount)
I realized that while I was writing the message but the quick-and-dirty ECS scheme I had cobbled together there wasn't written with the Cratera style of doing things in mind and it was too late to amend it. Thanks for following up with a better description.
/s/ Adam