• 12 Posts
  • 18 Comments
Joined 2 years ago
cake
Cake day: June 6th, 2023

help-circle

  • Some high-level examples of how AI was deployed include:

    • AI pretending to be a victim of rape
    • AI acting as a trauma counselor specializing in abuse
    • AI accusing members of a religious group of “caus[ing] the deaths of hundreds of innocent traders and farmers and villagers.”
    • AI posing as a black man opposed to Black Lives Matter
    • AI posing as a person who received substandard care in a foreign hospital.

    Here is an excerpt from one comment (SA trigger warning for comment): "I’m a male survivor of (willing to call it) statutory rape. When the legal lines of consent are breached but there’s still that weird gray area of ‘did I want it?’ I was 15, and this was over two decades ago before reporting laws were what they are today. She was 22. She targeted me and several other kids, no one said anything, we all kept quiet. This was her MO

    What an unhinged study lol

















  • I patched together some version of this using nested dictionaries:

    var abilities: Dictionary = {
    	AbilityData.Trigger.BEFORE_ATTACK : {},
    	AbilityData.Trigger.ON_ATTACK : {},
    	AbilityData.Trigger.ON_HIT : {},
    	AbilityData.Trigger.ON_KILL : {},
    	AbilityData.Trigger.ON_DEATH : {},
    	AbilityData.Trigger.ON_JUMP : {},
    	AbilityData.Trigger.PASSIVE : {}
    }
    

    with each value being another key:value pair of { "ability_id": <ability-node> } so I can keep a reference to the Ability node and use dictionary functions like .has() to check if a character has a specific ability:

    func has_ability(ability_data: AbilityData) -> bool:
    	if abilities[ability_data.trigger_type].has(ability_data.id):
    		return true
    	return false
    

    Then when a trigger fires, it calls this (I omitted the return code):

    // Activates all abilities with the specified trigger type. Returns an array containing each ability that was activated this way.
    //trigger_type is an enum
    //data is just a resource containing things like position, target, ability owner, etc
    func trigger(trigger_type: AbilityData.Trigger, data: AbilityActivationData) -> Array[Ability]:
    	var abilities_to_activate: Dictionary = abilities.get(trigger_type)
    	
    	// Loops through the list of Ability nodes.
    	for ability in abilities_to_activate.values():
    		ability.activate(data)
    		abilities_activated.append(ability)
    

    This seems to work, but it still gives me that tickling sensation that it could be a little cleaner.


  • I think I understand…

    Instead of the player iterating through and calling all of its abilities, the ability just connects directly to whichever signal it needs on the player?

    My current setup is to add each Ability as a node to the player, so right now it follows the “call down, signal up” adage that I hear everyone say. What would be a good way to implment the other way? I assume I should rework my current setup otherwise it’d be “signal down, signal up”?






  • The longer I’m using the signal chain the more I’m wanting to rework it to just be a reference lol. Good point with checking if the instance is valid, if any other errors come up I could just patch around them in a similar fashion.

    That said, you can probably simplify your signal code if you connected the bullet killed_enemy signal directly to the player’s on-hit handler. It seems like the weapon on-kill handler is redundant?

    Ah I see what you mean, killed_enemy(enemy-object) signals directly to the player which can then pass that enemy to it’s abilities if needed. You’re correct that the weapon signal is mostly redundant, it was just the easiest node to connect to the bullet’s signals, as it’s responsible for spawning them.

    I think I’ll change the whole system to just use a reference. Thanks for your input!







  • Just tried this out in one of my projects, here’s what happened:

    • do something works without a problem.
    • do something else never goes off.
    • the rest of the game keeps running as normal. You can even call foo() again any number of times and do something will still go off.

    Having it waiting in the background didn’t seem to have much of a performance impact. I started 5000+ of them and foo() only took up ~0.6% frametime with the rest of my game running alongside it.