Giter VIP home page Giter VIP logo

Comments (7)

Grokmoo avatar Grokmoo commented on May 18, 2024 1

Hey! Jumping in and working on the AI would be great! There is a ton of work that could be done there.

By the way, I am working on outlining the world, races, and lore right now on the website, which you had mentioned earlier.

To address your question: right now, the AI script only runs on the owner's turn, there is no way for the AI to create hooks in to be called at other times. But, this is clearly needed for robust AI, so I will log an issue for this to get to.

A workaround to get you started on your idea (not what we would want to do long term though):

Create a dummy ability, give it to all the creatures you want to have the improved AI in the abilities section in the actor definition.

The ability looks something like this:

id: ai_dummy
name: "" # name being blank should prevent ability activation from showing up overhead
icon: empty
description: "AI Dummy Helper ability"
active:
  script: "ai_helper"
  group: Fighter # this needs to be an ability group the AI has access to.  You may want to create an "AI" group and put it in the standard Fighter, Rogue, Mage class defs.
  ap: 0
  duration:
    Rounds: 1000
  cooldown: 1000
  ai:
    priority: 1 #priority of 1 means the current AI script will prioritize activating it
    kind: Buff
    group: Single
    range: Personal
  short_description: ""

The "ai_helper.lua" script looks something like this:

function on_activate(parent, ability)
    effect = parent:create_effect(ability:name(), ability:duration())
    cb = ability:create_callback(parent)
    cb:set_after_defense_fn("after_defense")
    effect:add_callback(cb)
    effect:apply()
end

function after_defense(parent, ability, targets, hit)
    if hit:total_damage() < 10 then return end
    target = targets:first() # this is the attacker (should be player)
    #  save the target ID to the parent as a preferred target
end

Unfortunately after_defense will only be called on attacks or abilities that make an attack (like Mighty Blow). But, its a start - and I can implement an on_damaged callback type to cover all cases.

from sulis.

Grokmoo avatar Grokmoo commented on May 18, 2024

Created #49 to address this.

from sulis.

Grokmoo avatar Grokmoo commented on May 18, 2024

You should now be able to accomplish this with the latest on master. It will probably break what you are doing a bit, but should be easy to fix. Actor's ai field now points to an AI object that includes a hooks section:

id: ai_basic
script: ai_basic
hooks:
  OnDamaged: on_damaged

So, now all actors with the ai_basic script will fire the "on_damaged" function in their ai script every time they are damaged. There is a sample on_damaged function in the ai_basic script:

function on_damaged(parent, targets, hit)
    target = targets:first()
	
	game:log(parent:name() .. " damaged by " .. target:name() .. ": "
	    .. hit:kind() .. " for " .. hit:total_damage() .. " damage.")
end

Let me know how things go. I'd love to see a PR with these ideas implemented, if you have the time.

from sulis.

ernierasta avatar ernierasta commented on May 18, 2024

Thank you for great info!

  1. Lore - that is exactly what I had in mind. I had read it almost all and well written, interesting. Leaves plenty of room to create small stories out of it. I have a small script of possible village quests, I will change them to fit the lore and hopefully write them as dialog scripts one day. ;-)

  2. Will try to do as much as I can. I have few behaviors in mind. Time is what I do not have, but I really want to play with it, so hopefully I will send something useful soon. Currently I get stuck on ... how to get ID? I feel I am missing something very basic, but would expect something like parent:id()(in practice I need target:id() where returned id can be used in game:entity_with_id(id)).

Next thing I want to do is ability to run away. Determining direction to which entity should run may be tricky (probably I should calculate distance from enemies and figure out on which direction it will rise for every enemy or few of them), but probably there no method for telling entity to go somewhere else besides to entity. It will be best if we have move_away_from_enemies, but of course move_to_point would be more universal. :-)

Is there a way to hot reload/reread script (without re-launching Sulis)?

from sulis.

ernierasta avatar ernierasta commented on May 18, 2024

Btw: if anyone would be interested in the future, that is how quick find available methods:
https://gist.github.com/ernierasta/b5f71981c4e42b646a0b12251837d2ef

It is probably to early to make any sort of documentation and maybe it would make sense to add comments to code and use rustdoc, so docs/wiki will stay up to date.

from sulis.

ernierasta avatar ernierasta commented on May 18, 2024

Just quick info. I had been able to implement "taunting"(remembering attacker who did big damage) using on_damaged hook, but if I try to set flag on parent Sulis will crash. I was able to set flag on attacker (targets:first()) containing parent name ("Goblin Archer" for example), but it is not ideal (no good way to set this for many enemies). Instead of some ID I am using name, which is not ideal and probably unusable if we have two ordinary "Goblin Archer"s for example. Have to go now. ;-)

from sulis.

Grokmoo avatar Grokmoo commented on May 18, 2024

Hi,

Thanks for those one-liners; definitely useful. I see several issues coming out of this:

  1. Having docs available for everything in the scripting API is definitely a must. Agreed that rustdoc should work for this.
  2. Fix crash when setting parent flag - this is probably a double borrow error and should be easy enough.
  3. The reason there is no "id" method exposed is that I don't currently have a unique ID for each entity. So, the current ID is actually no better than the name for this purpose. We could use the entity index but that will change when loading a save file. I'll need to implement something for this.

I will log issues for these.

Separately, I think I misunderstood what you were trying to accomplish. I thought when a player does major damage to an AI controlled creature, you would set the player's name / ID on the AI's flags. Sounds like you are doing something slightly different (which is fine).

from sulis.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.