2.) MMO From Scratch - The AI

Results 1 to 5 of 5
  1. #1
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    2.) MMO From Scratch - The AI


    RaGEZONE Recommends

    RaGEZONE Recommends

    Previous (Introduction)
    Table of Contents (Introduction)
    Next (Plant)

    When thinking of the living resources in Surface Tension, I didn't simply want the plants and animals to seem like they were thinking, I actually wanted to program them so they really were thinking. Grand Theft Auto uses statistical generation to make the world seem alive. In older versions of the game, you can see this when you look at the world and see some car and pedestrian objects. When you look away for a few seconds and look back, the cars and people will be different objects. The corvette you were planning on stealing may have been replaced by a police car!

    Grand Theft Auto is a great game, and in later versions the memory they have to work with in the PS4 is much more than that of the PS2, so the statistical generation of objects is much less of a problem for the player. I think I'll be forced to use statistical generation later, but right now I want to code a living world where objects don't spontaneously appear and disappear based on what the players can see. One reason I'm choosing this strategy, is because this is an MMO- and I want to assume that every section of the map is being viewed by at least one player at all times- worst case scenario for performance. If the game can load now under those conditions, I (hopefully) won't be surprised in the future when it cannot.

    This is a (bad?) decision that later forces me into premature optimization.

    I got my idea for this AI structure when reading Michio Kaku's book, "The Future of the Mind", where he talks about the different levels of intelligence measured by feedback loops. This is what I came up with.

    Here is the base AI that all of the living resources have:

    Code:
    function Ai() {
        "use strict";
        var self = this;
        var feedbackLoops = [];
        self.alive = true;
        function doFeedback(fn) {
            if (self.alive) {
                fn.cycle();
            }
        }
        self.createFeedback = function (Fn) {
            feedbackLoops.push(new Fn(self));
        };
        self.cycle = function () {
            feedbackLoops.forEach(doFeedback);
        };
    }
    module.exports = Ai;
    So, every AI instance has a method to create feedback loops and a method to cycle through those feedback loops.

    A brain has 2 hemispheres that function independently, sharing some information when needed. How a real brain decides which hemisphere to use to make a conscious decision or whether to use both or not, is something I don't quite understand. In any case, this is the code for the Brain in Surface Tension:

    Code:
    var Ai = require('./ai');
    module.exports = (function () {
        "use strict";
        function nil() {
            return;
        }
        function Decision(ai) {
            var self = this;
            ai.decisions = [];
            ai.addDecision = function (dec) {
                var decision = {
                    title: dec.title || "unknown",
                    weight: dec.weight || 0,
                    args: dec.args || [],
                    action: dec.action || nil
                };
                ai.decisions.push(decision);
            };
            self.cycle = function () {
                ai.decisions = [{
                    weight: 0,
                    action: nil,
                    title: "do nothing"
                }];
            };
        }
        function Remember(ai) {
            var self = this;
            ai.memories = {};
            self.cycle = nil;
        }
        return function Brain() {
            var self = this;
            self.right = new Ai();
            self.left = new Ai();
            self.left.sync = function (prop) {
                var chain = prop.split('.');
                var i;
                var l = self.left;
                var r = self.right;
                for (i = 0; i < chain.length - 1; i += 1) {
                    r = r[chain[i]];
                    l = l[chain[i]];
                }
                r[chain[chain.length - 1]] = l[chain[chain.length - 1]];
            };
            self.right.sync = function (prop) {
                var chain = prop.split('.');
                var i;
                var l = self.left;
                var r = self.right;
                for (i = 0; i < chain.length - 1; i += 1) {
                    r = r[chain[i]];
                    l = l[chain[i]];
                }
                l[chain[chain.length - 1]] = r[chain[chain.length - 1]];
            };
            function findDecision(list) {
                var i;
                var decision = list[0];
                for (i = 0; i < list.length; i += 1) {
                    if (decision.weight < list[i].weight) {
                        decision = list[i];
                    }
                }
                return decision;
            }
            function decide() {
                var decision;
                var context;
                var lDecision = findDecision(self.left.decisions);
                var rDecision = findDecision(self.right.decisions);
                if (!self.left.alive || !self.right.alive) {
                    return;
                }
                if (lDecision.weight < rDecision.weight) {
                    decision = rDecision;
                    context = "right";
                } else {
                    decision = lDecision;
                    context = "left";
                }
                self[context].memories.lastAction = decision.title;
                return decision.action.apply(self[context], decision.args);
            }
            self.createFeedback = function (fn) {
                self.right.createFeedback(fn);
                self.left.createFeedback(fn);
            };
            self.cycle = function () {
                self.right.cycle();
                self.left.cycle();
    
                return decide();
            };
            self.createFeedback(Remember);
            self.createFeedback(Decision);
        };
    }());
    The brain has the ability to store memories and make decisions. It also has a right and a left AI- each with the ability to create independent feedback loops. The brain has it's own createFeedback method which will create the same feedback loop on both left and right. Finally, the brain has a cycle method that will cycle through the right, then the left, and return a decision based on the weight of that decision- where a higher weight will be chosen as the decision to execute. The result of that decision is returned.

    There is also a way to sync memories from one side of the brain to the other. Memories are not shared between the left and right sides.

    Now, every living resource with a brain will have at least 4 feedback loops (Remember and Decision feedback loops assigned to both right and left).

    So, this is the base for the AI. Next I'll talk about setting up the basis for all plants and the basis for all herbs. What do plants have to think about? They are required to reproduce automatically, how will they do that?

    Previous (Introduction)
    Table of Contents (Introduction)
    Next (Plant)
    Last edited by s-p-n; 29-01-16 at 09:27 PM.


  2. #2
    The journey never ends. SYJourney is offline
    True MemberRank
    Mar 2015 Join Date
    FrankfurtLocation
    430Posts

    Re: 2.) MMO From Scratch - The AI

    This is a really ambitious and interesting project! Have you considered integrating you AI idea with some kind of evolution system? As in, an Ai is born with certain characteristics, some inherited from it's parents, or even communicated with other AIs. These characteristics could then influence how decisions are made. And the more of a positive effect on survival the characteristics have, the more they could spread among a type of being in your world.

  3. #3
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    Re: 2.) MMO From Scratch - The AI

    I'll go into DNA generation and more complicated decision-making much later when we get into animals ;)

  4. #4
    Programmer cyberinferno is offline
    True MemberRank
    Jun 2009 Join Date
    BangaloreLocation
    469Posts

    Re: 2.) MMO From Scratch - The AI

    Is the kind of AI used in building monster AI in MMORPG emulators like TrinityCore?
    Have a look at my simple Discord bot https://github.com/cyberinferno/discord-chum

  5. #5
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    Re: 2.) MMO From Scratch - The AI

    Quote Originally Posted by cyberinferno View Post
    Is the kind of AI used in building monster AI in MMORPG emulators like TrinityCore?
    I thought up this AI all by myself, and it has some major flaws, so I would hope nobody uses a style like this in a real MMO. It was really fun to think of AI as a sort of brain for each instance, but that's very inefficient and there are 1000s of redundant cycles taking place even with just a handful of instances.




Advertisement