Dragolantis Posted April 6, 2022 Share Posted April 6, 2022 Hello! I was looking around the interwebs for info on how to get a good creature mod tutorial to mod a creature into DST. There is supposed to be a tutorial made by Klei themselves, but does anyone know if it still works. Its several years old and hasn't been updated since 2013. If it doesn't, could someone please send me a working tutorial on the basics of mob creation for dst? Link to comment Share on other sites More sharing options...
-LukaS- Posted April 7, 2022 Share Posted April 7, 2022 I've made a tutorial about mob creation that should be up to date so feel free to check it out. 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted April 7, 2022 Author Share Posted April 7, 2022 @-t- Thank you so much! This will be very useful! Link to comment Share on other sites More sharing options...
Dragolantis Posted April 8, 2022 Author Share Posted April 8, 2022 I've hit another roadblock. @-t- you're the only one who has seemed to help me with my problems before. The mob I'm working on is supposed to drop materials for a new hat. I can't figure out how to make it equipable to the headslot even after finding a headslot item (seriously I had to download one they make it so hard to find). Link to comment Share on other sites More sharing options...
-LukaS- Posted April 8, 2022 Share Posted April 8, 2022 Assuming you already have the sprites for your item... To make something equippable you need to add the equippable component to it, like this: inst:AddComponent("equippable") -- Adding the component inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.HEAD -- Setting the right equip slot for the item 2 functions are also needed for the item to work properly: local function onEquip(owner) owner.AnimState:OverrideSymbol("swap_body", "your_swap_item_name", "swap_body") -- Change player body sprite to show that your item is equipped end local function onUnequip(owner) owner.AnimState:ClearOverrideSymbol("swap_body") -- Clear the body sprite back to its base look end inst.components.equippable:SetOnEquip(onEquip) -- Setup the function inst.components.equippable:SetOnUnequip(onUnequip) -- Setup the function You might also want to add an inventoryitem component: inst:AddComponent("inventoryitem") inst.components.inventoryitem.imagename = "tex_file_name" inst.components.inventoryitem.atlasname = "images/atlas_file_name" If you have all of this and there still is a problem post it here. If it crashes the game post the client log and the server log, that almost always points to what's wrong. 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted April 21, 2022 Author Share Posted April 21, 2022 On 4/8/2022 at 8:26 AM, -t- said: Assuming you already have the sprites for your item... To make something equippable you need to add the equippable component to it, like this: inst:AddComponent("equippable") -- Adding the component inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.HEAD -- Setting the right equip slot for the item 2 functions are also needed for the item to work properly: local function onEquip(owner) owner.AnimState:OverrideSymbol("swap_body", "your_swap_item_name", "swap_body") -- Change player body sprite to show that your item is equipped end local function onUnequip(owner) owner.AnimState:ClearOverrideSymbol("swap_body") -- Clear the body sprite back to its base look end inst.components.equippable:SetOnEquip(onEquip) -- Setup the function inst.components.equippable:SetOnUnequip(onUnequip) -- Setup the function You might also want to add an inventoryitem component: inst:AddComponent("inventoryitem") inst.components.inventoryitem.imagename = "tex_file_name" inst.components.inventoryitem.atlasname = "images/atlas_file_name" If you have all of this and there still is a problem post it here. If it crashes the game post the client log and the server log, that almost always points to what's wrong. Thank you for this code! I'm sure this will help me a ton! I kinda shelved my mod for a bit as I got busy (distracted) with something (*cough cough* mhw *cough cough*). With this new piece of data I might be able to get my mod to a proper working prototype, if I can keep my focus on it. 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted May 20, 2022 Author Share Posted May 20, 2022 hello again! I know its been awhile, but I'm getting to the brain part of the mob code. Some behaviors, like 'behaviors/avoidlight' and 'behaviors/attackwall' are self explanatory, but others, like 'behaviors/useshield' and 'behaviors/doaction' are less easy to understand their function. I was wondering if there is anywhere I can find a list of these behaviors and what they do, as I personally do not want to have to script a custom behavior for my mob. I'd just like to once again say thanks for helping me out with all this stuff, and I hope to potentially have a working prototype eventually. Link to comment Share on other sites More sharing options...
-LukaS- Posted May 21, 2022 Share Posted May 21, 2022 I doubt there is a complete list of fully documented behaviours. If that helps the UseShield behaviour makes a mob hide when sufficient damage has been dealt. It is used in brains of: Cave spiders Rock Lobsters Slurtles and Snurtles Celestial Champion (first phase) DoAction is a bit more flexible. It allows the mob to do practically any action that exists in the GLOBAL.ACTIONS table. The getactionfn needs to return a BufferedAction. The simplest DoAction can look something like this: DoAction(self.inst, GoHomeAction), With the GoHomeAction looking like this: local function GoHomeAction(inst) local spawnpoint_position = inst.components.knownlocations:GetLocation("spawnpoint") -- Get the spawn point from knownlocations component if spawnpoint_position == nil or inst:GetDistanceSqToPoint(spawnpoint_position:Get()) < TUNING.ALTERGUARDIAN_PHASE3_GOHOMEDSQ then -- If spawnpoint doesn't exist or the mob is already near it return nil (no action) return nil else return BufferedAction(inst, nil, ACTIONS.WALKTO, nil, spawnpoint_position) -- If spawn point exists and the mob is far away then return a BufferedAction end end This example was pulled from alterguardian_phase3brain.lua (Celestial Champion phase 3) If you want to see exactly how BufferedAction looks it's in bufferedaction.lua 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted May 21, 2022 Author Share Posted May 21, 2022 Thanks for the info! While I didn't really need help with the UseShield behavior specifically, I do think the DoAction behavior is necessary in my mob (Even if it isn't required, I'll still probably need it for something). I think It'd be good to elaborate on what I'm trying to implement. I'm actually making two mobs, although the distinction between them is small. One of them is meant to be a pack leader of sorts, with the other mob serving as the pack leader's goons. The basic goon as you could say would have about 200 health, making them a bit more of a nuisance than the normal spider, and the pack leader would have around 1000. Just to refresh on health values, the regular pack member would have double the health of a spider, and the pack leader would have half the health of a small treeguard. Both mobs would possess a leap attack in addition to a basic melee, not unlike warrior spiders, and the pack leader would posses an ability to rally the rest of the pack, not unlike bee queen. The only thing I am unsure of is the spawning mechanic. I want them to naturally spawn in the world, but I'm not sure how. I'm wondering what behaviors I would need to accomplish this. I just felt I needed to clarify what it was I was trying to accomplish, as there is no definitive list, I figured you might know enough to tell me what behaviors I could use to make my job a lot easier. Link to comment Share on other sites More sharing options...
-LukaS- Posted May 22, 2022 Share Posted May 22, 2022 Checking the spider brain and the spider queen brain should give you the answers you need. About the spawning tho, generally mobs should have a set condition or a spawner to spawn. For example Deerclops spawns at the end of winter (condition), ocean fish spawn from fish spawners (spawner). If you want your mob to randomly spawn in the world somewhere near the player you could check how the Suspicious Dirt Piles spawn. They're bound to players hunter component. It handles random spawning of dirt piles, it might help you with that. 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted May 23, 2022 Author Share Posted May 23, 2022 14 hours ago, -t- said: Checking the spider brain and the spider queen brain should give you the answers you need. About the spawning tho, generally mobs should have a set condition or a spawner to spawn. For example Deerclops spawns at the end of winter (condition), ocean fish spawn from fish spawners (spawner). If you want your mob to randomly spawn in the world somewhere near the player you could check how the Suspicious Dirt Piles spawn. They're bound to players hunter component. It handles random spawning of dirt piles, it might help you with that. Neat! When I was originally typing out my reply, while I also didn't know how to cause my mob to spawn naturally, I was really talking about how I was unsure how I actually wanted it to spawn. I was unsure if I wanted to tie it to the suspicious dirt piles, some spawner in a certain biome, or something else. I think I'm going to go with the suspicious dirt piles, setting it up kinda like the clay varg. Even if I don't use it (yet) all of this information will be helpful. I'll comment again if I run into any more roadblocks. Link to comment Share on other sites More sharing options...
Dragolantis Posted May 24, 2022 Author Share Posted May 24, 2022 Look @-t-, I apologize if it feels as if I'm wasting your time. I understand what I need to get my creature mod up and running, but I'm running into problems. I'm trying to get a simple template creature up and running using that creature tutorial you posted. I got to a point, but I can't spawn my creature whatsoever. I basically replicated your code, aside from replacing any instances of custommob and CUSTOMMOB with my creature name in respective caps or no caps. The game only crashed once, and that was from an error when entering inspection dialogue for it. I feel this would be the last time I would need to ask for help, at least for a long while. Again, I hope I'm not wasting your time with all the questions, I would really be appreciative. Link to comment Share on other sites More sharing options...
-LukaS- Posted May 24, 2022 Share Posted May 24, 2022 Send your mob lua file and maybe the file the examination quotes are in and I'll check what's up. Link to comment Share on other sites More sharing options...
Dragolantis Posted May 24, 2022 Author Share Posted May 24, 2022 9 hours ago, -t- said: Send your mob lua file and maybe the file the examination quotes are in and I'll check what's up. Here they are.modmain.luacustommob.lua Link to comment Share on other sites More sharing options...
-LukaS- Posted May 25, 2022 Share Posted May 25, 2022 You're missing a ( here: Other than that, I can't find a PrefabFiles table in your modmain. Do you have it somewhere else? 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted May 25, 2022 Author Share Posted May 25, 2022 @-t- I didn't even realize I was missing a ( there. I essentially followed the creature tutorial you sent word for word, but it didn't mention anything about a PrefabFiles table. Link to comment Share on other sites More sharing options...
-LukaS- Posted May 25, 2022 Share Posted May 25, 2022 Oh, I guess I should've mentioned it in the tutorial. Well, the PrefabFiles table contains the names of your prefab files. That way the game can run these specific files and create prefabs from them. In modmain.lua you should add: PrefabFiles = { "name_of_your_prefabs_file", } Whenever you create a prefab file it needs to be added to this list. Link to comment Share on other sites More sharing options...
Dragolantis Posted May 25, 2022 Author Share Posted May 25, 2022 After some messing around and figuring out what a PrefabFiles table was. I came to this error upon startup. [string "../mods/workshop-2811951071/scripts/prefabs/mymob.lua"]:25: '<name>' expected near '(' Nvm, I'm stupid Link to comment Share on other sites More sharing options...
Dragolantis Posted May 25, 2022 Author Share Posted May 25, 2022 Now it's a problem with the locomotor. It attempts to call a nil value. @-t- (I @ed you because I think we live in different time zones and I think it allows you to respond quicker). I think I can check for a nil value, but how do I do that, and if it is nil, what do I do? Link to comment Share on other sites More sharing options...
-LukaS- Posted May 26, 2022 Share Posted May 26, 2022 When trying to set the run speed you spell locomotor, locomoter. Since this component doesn't exist (is nil) it causes a crash. 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted May 26, 2022 Author Share Posted May 26, 2022 1 hour ago, -t- said: When trying to set the run speed you spell locomotor, locomoter. Since this component doesn't exist (is nil) it causes a crash. Did I? I have to check My two braincells are doing their best. Link to comment Share on other sites More sharing options...
Dragolantis Posted May 26, 2022 Author Share Posted May 26, 2022 I'm trying to work on giving my creature that leap attack, but I can't seem to find the code anywhere. If I had to take a guess, it's hidden somewhere in the spiderbrain, but I can't find it. Link to comment Share on other sites More sharing options...
-LukaS- Posted May 27, 2022 Share Posted May 27, 2022 Spider Warriors jump attack is in SGspider.lua. Instead of adding a new action to the brain, spider warriors use normal attack node and simply use a different state to attack. EventHandler("doattack", function(inst, data) if not (inst.sg:HasStateTag("busy") or inst.components.health:IsDead()) then if inst:HasTag("spider_warrior") then -- Here it checks whether the spider has the 'spider_warrior' tag inst.sg:GoToState( data.target:IsValid() and not inst:IsNear(data.target, TUNING.SPIDER_WARRIOR_MELEE_RANGE) and "warrior_attack" -- If yes it goes to the 'warrior_attack' state or "attack", data.target ) warrior_attack state: State{ name = "warrior_attack", tags = {"attack", "canrotate", "busy", "jumping"}, onenter = function(inst, target) inst.components.locomotor:Stop() inst.components.locomotor:EnableGroundSpeedMultiplier(false) inst.components.combat:StartAttack() inst.AnimState:PlayAnimation("warrior_atk") inst.sg.statemem.target = target end, onexit = function(inst) inst.components.locomotor:Stop() inst.components.locomotor:EnableGroundSpeedMultiplier(true) inst.Physics:ClearMotorVelOverride() end, timeline = { TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound(SoundPath(inst, "attack_grunt")) end), TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound(SoundPath(inst, "Jump")) end), TimeEvent(8*FRAMES, function(inst) inst.Physics:SetMotorVelOverride(20,0,0) end), TimeEvent(9*FRAMES, function(inst) inst.SoundEmitter:PlaySound(SoundPath(inst, "Attack")) end), TimeEvent(19*FRAMES, function(inst) inst.components.combat:DoAttack(inst.sg.statemem.target) end), TimeEvent(20*FRAMES, function(inst) inst.Physics:ClearMotorVelOverride() inst.components.locomotor:Stop() end), }, events= { EventHandler("animover", function(inst) inst.sg:GoToState("taunt") end), }, }, 1 Link to comment Share on other sites More sharing options...
Dragolantis Posted May 28, 2022 Author Share Posted May 28, 2022 so it's the stategraph that holds the attacks... I'll have to keep this in mind going forward. Link to comment Share on other sites More sharing options...
Dragolantis Posted May 31, 2022 Author Share Posted May 31, 2022 This may be me not understanding some of the code, but I do not understand the ShouldWake and their complementary function ShouldSleep. ShouldWake is sometimes called ShouldWakeUp in some prefabs. I found this out while looking at the koalephant code trying to make sense of the function. I understand what this function does in game, it causes the mob to wake up or go to sleep respectively. What I don't understand is the trigger. I'm only looking at prefabs right now, but in the spider prefab, the shouldwake function looks like this: local function ShouldWake(inst) return not TheWorld.state.iscaveday or BasicWakeCheck(inst) or (inst:HasTag("spider_warrior") and FindTarget(inst, TUNING.SPIDER_WARRIOR_WAKE_RADIUS) ~= nil) end and the koalephant shouldwakeup looks like this: local function ShouldWakeUp(inst) local x, y, z = inst.Transform:GetWorldPosition() return DefaultWakeTest(inst) or IsAnyPlayerInRange(x, y, z, WAKE_TO_RUN_DISTANCE) end The differences between the wake and the sleep functions are very minor, so I didn't put them here. I wanted to send these to someone who actually knows how to read this kind of code. I can understand some of it, but I'm not understanding all of it. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now