Single npc / mob tutorial

jrowe47
New member
 
Posts: 4
Joined: Sun Mar 08, 2015 01:08

Single npc / mob tutorial

by jrowe47 » Sun Mar 08, 2015 01:20

Hi there! I've been lurking for months, and while I've seen (and tried) several mob frameworks and tinkered a bit with them, I've not been able to find a good tutorial about creating mobs in the first place.

I've searched high and low, and come to the conclusion that I don't know enough about what I'm searching for, or it doesn't exist.

Does anyone know where I can find a simple breakdown of what it takes to put a mob in game? I'd like to shoot for something like a single block that I can give behaviors and so forth. I need a guide that covers core principles, and nothing more.

If there's a framework or existing mod that is well documented, or provides a simplistic example, that would be great. I want to know what it takes to get a simple entity into the game. One cube that moves around.

Thank you in advance!
 

User avatar
TenPlus1
Member
 
Posts: 1874
Joined: Mon Jul 29, 2013 13:38
GitHub: tenplus1

Re: Single npc / mob tutorial

by TenPlus1 » Sun Mar 08, 2015 09:30

Check out Mobs Redo 1.02 and each of the monster/animal .api's which are commented on how they work:

https://forum.minetest.net/viewtopic.php?f=9&t=9917

...also added a beta test NPC mob which will protect the player when a monster appears or attack player if he's threatened... Can also feed him food to restore health and right click with gold lump to trade for a random item...
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: Single npc / mob tutorial

by Wuzzy » Sun Mar 08, 2015 10:09

I think the most tricky part is to create the mob model. I might need some help here, too.

I have started to learn blender a few months ago. But I don't know exactly what to do in order to “import” (???) a model into Minetest and how to create these “.x” files and what it is all about with these animations and stuff.
Is there anything I need to know? Anything specific to Minetest, etc.

AFAIK the only mob mod which at least has documentation is Mod Framework, but this mod is a bit too overwhelming for me for now.
 

User avatar
rubenwardy
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: Single npc / mob tutorial

by rubenwardy » Sun Mar 08, 2015 11:12

Do you want to just add a mob, or do you want to make a whole mob AI mod for yourself? Simple Mobs has a very simple API if you just want to add a mob. You need to learn how to use Lua Entities to make your own mob mod.
 

User avatar
TenPlus1
Member
 
Posts: 1874
Joined: Mon Jul 29, 2013 13:38
GitHub: tenplus1

Re: Single npc / mob tutorial

by TenPlus1 » Sun Mar 08, 2015 11:41

Wuzzy: minetest can not use .b3d files directly also without converting to .x :)
 

jrowe47
New member
 
Posts: 4
Joined: Sun Mar 08, 2015 01:08

Re: Single npc / mob tutorial

by jrowe47 » Sun Mar 08, 2015 12:17

So is a framework required?

I want to use existing models - a block - and place the block in the game, and make it move around.

I see from the mobs framework api that you've got a lot of features secondary to my goal. I'd like to iterate through some extremely simplistic processes to get a workable mob, with the idea of knowing exactly what's going on.

I guess a good place to start would be to strip away everything that is peripheral to this goal from the api . I'm looking at adding features to a single mob that are a bit different and more resource intensive than something that would fit inside the normal gameplay. I'd like to try out neural network controlled mobs - https://github.com/wixico/luann is my ANN framework.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
mobs = {}
-- Set global for other mod checks (e.g. Better HUD uses this)
mobs.mod = "redo"

function mobs:register_mob(name, def)
   minetest.register_entity(name, {
      name = name,
      physical = true,
      collisionbox = def.collisionbox,
      visual = def.visual,
      visual_size = def.visual_size,
      mesh = def.mesh,
      walk_velocity = def.walk_velocity,
      drawtype = def.drawtype,
      type = def.type,
      sounds = def.sounds or {},
      animation = def.animation,
      jump = def.jump or true,
      walk_chance = def.walk_chance or 50,
      floats = def.floats or 1, -- floats in water by default
      stimer = 0,
      timer = 0,
      state = "stand",
      v_start = false,
      old_y = nil,
      lifetimer = 600,
      last_state = nil,

      set_velocity = function(self, v)
         local yaw = self.object:getyaw()
         if self.drawtype == "side" then
            yaw = yaw+(math.pi/2)
         end
         local x = math.sin(yaw) * -v
         local z = math.cos(yaw) * v
         self.object:setvelocity({x=x, y=self.object:getvelocity().y, z=z})
      end,
      
      get_velocity = function(self)
         local v = self.object:getvelocity()
         return (v.x^2 + v.z^2)^(0.5)
      end,

      set_animation = function(self, type)
         if not self.animation then
            return
         end
         if not self.animation.current then
            self.animation.current = ""
         end
         if type == "stand" and self.animation.current ~= "stand" then
            if self.animation.stand_start
            and self.animation.stand_end
            and self.animation.speed_normal then
               self.object:set_animation({x=self.animation.stand_start,
                  y=self.animation.stand_end},self.animation.speed_normal, 0)
               self.animation.current = "stand"
            end
         elseif type == "walk" and self.animation.current ~= "walk"  then
            if self.animation.walk_start
            and self.animation.walk_end
            and self.animation.speed_normal then
               self.object:set_animation({x=self.animation.walk_start,y=self.animation.walk_end},
                  self.animation.speed_normal, 0)
               self.animation.current = "walk"
            end
         end
      end,
      
      on_step = function(self, dtime)
         local yaw = 0
         if self.state == "stand" then
            -- randomly turn
            if math.random(1, 4) == 1 then
               -- if there is a player nearby look at them
               local lp = nil
               local s = self.object:getpos()

               if lp ~= nil then
                  local vec = {x=lp.x-s.x, y=lp.y-s.y, z=lp.z-s.z}
                  yaw = math.atan(vec.z/vec.x)+math.pi/2
                  if self.drawtype == "side" then
                     yaw = yaw+(math.pi/2)
                  end
                  if lp.x > s.x then
                     yaw = yaw+math.pi
                  end
               else
                  yaw = self.object:getyaw()+((math.random(0,360)-180)/180*math.pi)
               end
               self.object:setyaw(yaw)
            end

            self.set_velocity(self, 0)
            self.set_animation(self, "stand")

            if math.random(1, 100) <= self.walk_chance then
               self.set_velocity(self, self.walk_velocity)
               self.state = "walk"
               self.set_animation(self, "walk")
            end

         elseif self.state == "walk" then

            if math.random(1, 100) <= 30 then
               self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi))
            end
            if self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then
               local v = self.object:getvelocity()
               v.y = 5
               self.object:setvelocity(v)
            end
            self:set_animation("walk")
            self.set_velocity(self, self.walk_velocity)
            if math.random(1, 100) <= 30 then
               self.set_velocity(self, 0)
               self.state = "stand"
               self:set_animation("stand")
            end

      on_activate = function(self, staticdata, dtime_s)
         local pos = self.object:getpos()
         self.object:setacceleration({x=0, y=-10, z=0})
         self.state = "stand"
         self.object:setvelocity({x=0, y=self.object:getvelocity().y, z=0})
         self.object:setyaw(math.random(1, 360)/180*math.pi)

         if staticdata then
            local tmp = minetest.deserialize(staticdata)
            if tmp then
               if tmp.lifetimer then
                  self.lifetimer = tmp.lifetimer - dtime_s
               end
            end
         end
      end,

      get_staticdata = function(self)
         -- set mob texture and model
         local textures = def.available_textures["texture_"..math.random(1,def.available_textures["total"])]
         local mesh = self.mesh

         local tmp = {
            lifetimer = self.lifetimer,
            mesh = mesh,
            textures = textures,
         }
         self.object:set_properties(tmp)
         return minetest.serialize(tmp)
      end,
   })
end

mobs.spawning_mobs = {}
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height)
   mobs.spawning_mobs[name] = true   
   minetest.register_abm({
      nodenames = nodes,
      neighbors = {"air"},
      interval = 30,
      chance = chance,
      action = function(pos, node, _)
         -- spawn above node
         pos.y = pos.y + 1
         -- are we spawning inside a node?
         local nod = minetest.get_node_or_nil(pos)
         if not nod or minetest.registered_nodes[nod.name].walkable == true then return end
         pos.y = pos.y + 1
         nod = minetest.get_node_or_nil(pos)
         if not nod or minetest.registered_nodes[nod.name].walkable == true then return end
         if minetest.setting_getbool("display_mob_spawn") then
            minetest.chat_send_all("[mobs] Add "..name.." at "..minetest.pos_to_string(pos))
         end
         -- spawn mob half block higher
         pos.y = pos.y - 0.5
         local mob = minetest.add_entity(pos, name)
      end
   })
end      


Here's the API, with just the trivial stuff, like walk and stand, minimal animation, no gravity or type checks. Here's what a trivial chicken would look like:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- trivial chicken by JRowe47

mobs:register_mob("mobs:trivial_chicken", {
   -- textures and model
   collisionbox = {-0.3, -0.75, -0.3, 0.3, 0.1, 0.3},
   visual = "mesh",
   mesh = "chicken.x",
   drawtype = "front",
   available_textures = {
      total = 2,
      texture_1 = {"mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png",
               "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png",
               "mobs_chicken.png", "mobs_chicken.png", "mobs_chicken.png"},
      texture_2 = {"mobs_chicken_black.png", "mobs_chicken_black.png", "mobs_chicken_black.png",
               "mobs_chicken_black.png", "mobs_chicken_black.png", "mobs_chicken_black.png",
               "mobs_chicken_black.png", "mobs_chicken_black.png", "mobs_chicken_black.png"},
   },
   -- speed and jump
   walk_velocity = 1,
   jump = true,
   -- model animation
   animation = {
      speed_normal = 15,
      stand_start = 0,
      stand_end = 1, -- 20
      walk_start = 20,
      walk_end = 40,
   },

})


I think this might work. I'll have to dig around some more and start experimenting.

I plan on adding things incrementally, like sensors, some rough approximation of vision, hearing, smell, and so forth, and actuators that drive movement and other interactions like attacks, chat window output, noises, and so forth.

Once I've got a creature roughed in, then I'll start adding neural networks as controllers. This should be fun. :)
 

jrowe47
New member
 
Posts: 4
Joined: Sun Mar 08, 2015 01:08

Re: Single npc / mob tutorial

by jrowe47 » Sun Mar 08, 2015 12:21

rubenwardy wrote:Do you want to just add a mob, or do you want to make a whole mob AI mod for yourself? Simple Mobs has a very simple API if you just want to add a mob. You need to learn how to use Lua Entities to make your own mob mod.


Lua Entities is what I was looking for , and http://dev.minetest.net/LuaEntitySAO has exactly what I wanted.

Thank you! I'll be using the mobs redo framework as a reference point, and Lua Entity for guidance. Great stuff!
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: Single npc / mob tutorial

by Wuzzy » Sun Mar 08, 2015 12:58

rubenwardy wrote:Do you want to just add a mob, or do you want to make a whole mob AI mod for yourself? Simple Mobs has a very simple API if you just want to add a mob. You need to learn how to use Lua Entities to make your own mob mod.


I prefer to use [mobapi] by Casimir. This is just another Simple Mobs fork but without pre-installed mobs.

I also already have successfully created mobs, but all of them are either using a simple cube shape or pre-existing models.

The question was only about the models themselves, and how Minetest uses them. Is there anything in particular I should know? Any unexpected things, etc.?


Wuzzy: minetest can not use .b3d files directly also without converting to .x :)

I already knew that.
 

jrowe47
New member
 
Posts: 4
Joined: Sun Mar 08, 2015 01:08

Re: Single npc / mob tutorial

by jrowe47 » Mon Mar 09, 2015 04:45

mobapi looks good - still has some of the extras, but closer to the barebones that I was looking for. Almost identical to the hacked up mobs redo I posted, lol.

There are some fun things afoot.
 

Sokomine
Member
 
Posts: 2980
Joined: Sun Sep 09, 2012 17:31

Re: Single npc / mob tutorial

by Sokomine » Thu Mar 19, 2015 02:01

Wuzzy wrote:The question was only about the models themselves, and how Minetest uses them. Is there anything in particular I should know? Any unexpected things, etc.?

If you want to use your mobs with mobf as well, rotate your model by 270 degrees. Else it'll move sideways.
A list of my mods can be found here.
 

twoelk
Member
 
Posts: 1092
Joined: Fri Apr 19, 2013 16:19

Re: Single npc / mob tutorial

by twoelk » Thu Mar 19, 2015 14:19

jrowe47 wrote:...
I want to use existing models - a block - and place the block in the game, and make it move around.
...

hmm cubic mobs?
Like these?
CUTE CUBIC MOBS that come in the flavors of chicken, cow, nyan cat, pig, rabbit and sheep;
and Workers that introduced Harvey the harvester, Benjo the builder, Garren the gardener, Mordec the miner, Gredo the guard, Asvard the assasin, Toco the thief and Cardon the cop.
Please keep in mind that some of this might be outdated code, so please read the complete threads and regarding the Workers you may want to rather download the version posted by LionsDen and also consider the changes suggested by cornernote and Krock.

An incomplete list of mods that add mobs or include relevant code can be found on the Mobs wiki page.
 


Return to Modding Discussion

Who is online

Users browsing this forum: No registered users and 12 guests

cron