Discussion
Loading...

#Tag

Log in
  • About
  • Code of conduct
  • Privacy
  • Users
  • Instances
  • About Bonfire
James Baillie boosted
nathan, an npc phd
nathan, an npc phd
@npcdev@mastodon.gamedev.place  ·  activity timestamp 3 weeks ago

My dissertation is now published: https://hdl.handle.net/2047/D20817765

It details my participatory + co-design research on EvolvingBehavior (https://evolvingbehavior.npc.codes), a creativity support tool for game designers - including why LLMs are NOT appropriate for game dev, and what we can collectively create instead. Happy to chat about it!

Relatedly, I'm now looking for (remote) game engineering positions, especially with cool game AI (non-LLM) or PCG work! My portfolio: https://npc.codes

#GameDev #GameAI

  • Copy link
  • Flag this post
  • Block
nathan, an npc phd
nathan, an npc phd
@npcdev@mastodon.gamedev.place  ·  activity timestamp 3 weeks ago

My dissertation is now published: https://hdl.handle.net/2047/D20817765

It details my participatory + co-design research on EvolvingBehavior (https://evolvingbehavior.npc.codes), a creativity support tool for game designers - including why LLMs are NOT appropriate for game dev, and what we can collectively create instead. Happy to chat about it!

Relatedly, I'm now looking for (remote) game engineering positions, especially with cool game AI (non-LLM) or PCG work! My portfolio: https://npc.codes

#GameDev #GameAI

  • Copy link
  • Flag this post
  • Block
kat
kat
@zkat@toot.cat  ·  activity timestamp 5 months ago

Seeking feedback from Bevy and Big Brain users: how does this new API look?

Under the hood, this would be a high-performance, low-overhead API powered by Observers, but this is all you would actually need to write yourself.

I'm pretty sure I can get this to work with Bevy's current featureset, including the Very Fun async actions situation here.

#Bevy #BigBrain #GameAI #Rust #RustLang

#[derive(Debug, Default, Clone, Copy, Component)]
pub struct Thirsty;

#[scorer_for(Thirsty)]
pub fn score_thirsty(score: Score, thirsts: Query<&Thirst>) -> Score {
    score.update(thirsts.get(score.actor()).unwrap().thirst)
}

#[derive(Debug, Clone, Copy, Component)]
pub struct Drink { rate: f32, per: Duration }
impl Default for Drink {
    fn default() -> Self {
        Self { rate: 0.5, per: Duration::from_millis(500), }
    }
}

#[action_for(Drink)]
pub async fn drink_action(
    action: Action<Drink>,
    mut thirsts: Query<&mut Thirst>
) -> Result<(), ActionFailure> {
    while let Ok(mut thirst) = thirsts.get(action.actor()) && thirst.thirst > 10.0 {
        action.check_cancelled()?;
        thirst.thirst -= action.data().rate;
        action.sleep(action.data().per).await;
    }
    Ok(())
}

fn spawn_entity(cmd: &mut Commands) {
    cmd.spawn((
        Thirst(70.0, 2.0),
        Thinker::new()
            .picker(FirstToScore { threshold: 0.8 })
            .when<Thirsty, Drink>(),
    ));
}
#[derive(Debug, Default, Clone, Copy, Component)] pub struct Thirsty; #[scorer_for(Thirsty)] pub fn score_thirsty(score: Score, thirsts: Query<&Thirst>) -> Score { score.update(thirsts.get(score.actor()).unwrap().thirst) } #[derive(Debug, Clone, Copy, Component)] pub struct Drink { rate: f32, per: Duration } impl Default for Drink { fn default() -> Self { Self { rate: 0.5, per: Duration::from_millis(500), } } } #[action_for(Drink)] pub async fn drink_action( action: Action<Drink>, mut thirsts: Query<&mut Thirst> ) -> Result<(), ActionFailure> { while let Ok(mut thirst) = thirsts.get(action.actor()) && thirst.thirst > 10.0 { action.check_cancelled()?; thirst.thirst -= action.data().rate; action.sleep(action.data().per).await; } Ok(()) } fn spawn_entity(cmd: &mut Commands) { cmd.spawn(( Thirst(70.0, 2.0), Thinker::new() .picker(FirstToScore { threshold: 0.8 }) .when<Thirsty, Drink>(), )); }
#[derive(Debug, Default, Clone, Copy, Component)] pub struct Thirsty; #[scorer_for(Thirsty)] pub fn score_thirsty(score: Score, thirsts: Query<&Thirst>) -> Score { score.update(thirsts.get(score.actor()).unwrap().thirst) } #[derive(Debug, Clone, Copy, Component)] pub struct Drink { rate: f32, per: Duration } impl Default for Drink { fn default() -> Self { Self { rate: 0.5, per: Duration::from_millis(500), } } } #[action_for(Drink)] pub async fn drink_action( action: Action<Drink>, mut thirsts: Query<&mut Thirst> ) -> Result<(), ActionFailure> { while let Ok(mut thirst) = thirsts.get(action.actor()) && thirst.thirst > 10.0 { action.check_cancelled()?; thirst.thirst -= action.data().rate; action.sleep(action.data().per).await; } Ok(()) } fn spawn_entity(cmd: &mut Commands) { cmd.spawn(( Thirst(70.0, 2.0), Thinker::new() .picker(FirstToScore { threshold: 0.8 }) .when<Thirsty, Drink>(), )); }
Federation Bot
Federation Bot
@Federation_Bot  ·  activity timestamp 5 months ago

Big Brain, btw, is designed to be data-oriented, so I might provide an API that lets you define game AI in .kdl files that look like this. It could also, for example, eventually use a hypothetical node editor (thing Blender Geometry Nodes), to define the same data.

#KDL #Bevy #BigBrain #GameAI

Thinker {
    picker FirstToScore threshold=0.8
    when Thirsty {
        GoToWater
        Drink
    }
    when Hungry {
        Eat
    }
    or Bored Paranoid {
        Thinker {
            when EnemySpotted {
                ShootEnemy
            }
            when FlowersSpotted {
                WalkToFlowers
                PickAFlower
                SmellFlower
            }
            otherwise {
                Parallel {
                    Wander
                    HumATune
                }
            }
        }
    }
}
Thinker { picker FirstToScore threshold=0.8 when Thirsty { GoToWater Drink } when Hungry { Eat } or Bored Paranoid { Thinker { when EnemySpotted { ShootEnemy } when FlowersSpotted { WalkToFlowers PickAFlower SmellFlower } otherwise { Parallel { Wander HumATune } } } } }
Thinker { picker FirstToScore threshold=0.8 when Thirsty { GoToWater Drink } when Hungry { Eat } or Bored Paranoid { Thinker { when EnemySpotted { ShootEnemy } when FlowersSpotted { WalkToFlowers PickAFlower SmellFlower } otherwise { Parallel { Wander HumATune } } } } }
  • Copy link
  • Flag this comment
  • Block
kat
kat
@zkat@toot.cat  ·  activity timestamp 5 months ago

FYI: As part of a larger move away from GitHub, I've archived Big Brain on it and moved all future development over to Codeberg, at https://codeberg.org/zkat/big-brain

Please use that repo from now on.

Additionally: I am in the process of trying a major rewrite of the crate that I'm hoping will be much simpler, and much more efficient, thanks to features now available in recent version of Bevy! I'm very excited :)

#GiveUpGitHub #GitHub #Bevy #Rust #RustLang #Codeberg

kat
kat
@zkat@toot.cat  ·  activity timestamp 5 months ago

Seeking feedback from Bevy and Big Brain users: how does this new API look?

Under the hood, this would be a high-performance, low-overhead API powered by Observers, but this is all you would actually need to write yourself.

I'm pretty sure I can get this to work with Bevy's current featureset, including the Very Fun async actions situation here.

#Bevy #BigBrain #GameAI #Rust #RustLang

#[derive(Debug, Default, Clone, Copy, Component)]
pub struct Thirsty;

#[scorer_for(Thirsty)]
pub fn score_thirsty(score: Score, thirsts: Query<&Thirst>) -> Score {
    score.update(thirsts.get(score.actor()).unwrap().thirst)
}

#[derive(Debug, Clone, Copy, Component)]
pub struct Drink { rate: f32, per: Duration }
impl Default for Drink {
    fn default() -> Self {
        Self { rate: 0.5, per: Duration::from_millis(500), }
    }
}

#[action_for(Drink)]
pub async fn drink_action(
    action: Action<Drink>,
    mut thirsts: Query<&mut Thirst>
) -> Result<(), ActionFailure> {
    while let Ok(mut thirst) = thirsts.get(action.actor()) && thirst.thirst > 10.0 {
        action.check_cancelled()?;
        thirst.thirst -= action.data().rate;
        action.sleep(action.data().per).await;
    }
    Ok(())
}

fn spawn_entity(cmd: &mut Commands) {
    cmd.spawn((
        Thirst(70.0, 2.0),
        Thinker::new()
            .picker(FirstToScore { threshold: 0.8 })
            .when<Thirsty, Drink>(),
    ));
}
#[derive(Debug, Default, Clone, Copy, Component)] pub struct Thirsty; #[scorer_for(Thirsty)] pub fn score_thirsty(score: Score, thirsts: Query<&Thirst>) -> Score { score.update(thirsts.get(score.actor()).unwrap().thirst) } #[derive(Debug, Clone, Copy, Component)] pub struct Drink { rate: f32, per: Duration } impl Default for Drink { fn default() -> Self { Self { rate: 0.5, per: Duration::from_millis(500), } } } #[action_for(Drink)] pub async fn drink_action( action: Action<Drink>, mut thirsts: Query<&mut Thirst> ) -> Result<(), ActionFailure> { while let Ok(mut thirst) = thirsts.get(action.actor()) && thirst.thirst > 10.0 { action.check_cancelled()?; thirst.thirst -= action.data().rate; action.sleep(action.data().per).await; } Ok(()) } fn spawn_entity(cmd: &mut Commands) { cmd.spawn(( Thirst(70.0, 2.0), Thinker::new() .picker(FirstToScore { threshold: 0.8 }) .when<Thirsty, Drink>(), )); }
#[derive(Debug, Default, Clone, Copy, Component)] pub struct Thirsty; #[scorer_for(Thirsty)] pub fn score_thirsty(score: Score, thirsts: Query<&Thirst>) -> Score { score.update(thirsts.get(score.actor()).unwrap().thirst) } #[derive(Debug, Clone, Copy, Component)] pub struct Drink { rate: f32, per: Duration } impl Default for Drink { fn default() -> Self { Self { rate: 0.5, per: Duration::from_millis(500), } } } #[action_for(Drink)] pub async fn drink_action( action: Action<Drink>, mut thirsts: Query<&mut Thirst> ) -> Result<(), ActionFailure> { while let Ok(mut thirst) = thirsts.get(action.actor()) && thirst.thirst > 10.0 { action.check_cancelled()?; thirst.thirst -= action.data().rate; action.sleep(action.data().per).await; } Ok(()) } fn spawn_entity(cmd: &mut Commands) { cmd.spawn(( Thirst(70.0, 2.0), Thinker::new() .picker(FirstToScore { threshold: 0.8 }) .when<Thirsty, Drink>(), )); }
  • Copy link
  • Flag this comment
  • Block

bonfire.cafe

A space for Bonfire maintainers and contributors to communicate

bonfire.cafe: About · Code of conduct · Privacy · Users · Instances
Bonfire social · 1.0.2-alpha.34 no JS en
Automatic federation enabled
Log in
Instance logo
  • Explore
  • About
  • Members
  • Code of Conduct