Jump to content

Recommended Posts

Hi friends!

 

Really simple question: Is there a way to obtain a list which contains every flower present in the simulation?

 

Bonus question: Is there a way to obtain a list of every collectible (that is, pick up off the ground) entity?

 

Bonus Bonus Question: Are either of these list representations available in some kind of graph format? (Think vertices and edges)

 

Back-story:
So a friend and I are taking a college course called "Intelligent Systems." In this class, we are able to self-select a project that relates to the development of intelligent systems (AI). So instead of doing a boring-ol' puzzle solver/chess player, we decided to create an NPC mod for Don't Starve!

So our project is very straight-forward. We're going to spawn in a monster  whose only goal is to collect as many flowers(Or collectible resource) as it can in as little time as possible. This will require some fancy-shmancy path-finding. Unfortunately for us, this forum seems to consist mostly of questions like "NEED HELP WITH NEW CHARACTER. FLYING ABILITY + SANITY INVERTER." This is completely understandable, considering a custom character is a bit more exciting than path-finding, but it means that you all can expect more AI-related questions out of me as my friend and I try to push the boundary for Don't Starve's AI. 

 

If there's interest, we can share all of our project details as well as any useful code we produce. I'll obviously post it to a separate project thread. As a bonus, we could also share our project updates and deadlines and general woes/worries :-)

 

Later!

~BBox

 

P.S: If anyone knows of any AI-heavy mods, we'd surely like to look at them. The more code examples we have to look at, the better!!

Sadly I dont know answer on any of your question, but idea for  better AI controlled npc sounds great. Wish you luck. :)

 


If there's interest, we can share all of our project details as well as any useful code we produce. I'll obviously post it to a separate project thread.

Any reference can be help for other people trying to do simmilar mod.

Really simple question: Is there a way to obtain a list which contains every flower present in the simulation?

This will get all entities with the tag "flower":

local point = Vector3(0,0,0)local searchradius = 10000local allflowers = TheSim:FindEntities(point.x, point.y, point.z, searchradius, {"flower"})
 

Bonus question: Is there a way to obtain a list of every collectible (that is, pick up off the ground) entity?

This will get all entities with the "pickable" component:

-- version of simutil.lua's FindEntity that returns all entities and takes a point instead of a prefablocal function FindEntities(x, y, z, radius, fn, musttags, canttags, mustoneoftags)	local ents = TheSim:FindEntities(x, y, z, radius, musttags, canttags, mustoneoftags)	local validents = {}	for k, v in pairs(ents) do		if v.entity:IsValid() and v.entity:IsVisible() and (not fn or fn(v)) then			table.insert(validents, v)		end	end	return validentsendlocal point = Vector3(0,0,0)local searchradius = 10000local ispickablefn = function(inst) return bush.components.pickable ~= nil endlocal allpickables = FindEntities(point.x, point.y, point.z, searchradius, ispickablefn)
 

Bonus Bonus Question: Are either of these list representations available in some kind of graph format? (Think vertices and edges)

Don't think so.

Note: The posted code is untested, but should work.

Edited by squeek

Also note that it might be worth hooking into the things you are interested in and maintaining your own list of them, so that you don't have to iterate through all entities every time.

Something like:

local AllPickables = {}local Pickable = require "components/pickable"-- constructorlocal Pickable_ctor_base = Pickable._ctorPickable._ctor = function(self, inst)	Pickable_ctor_base(self, inst)	table.insert(AllPickables, inst)end-- called when the component is removed from its prefablocal Pickable_OnRemoveFromEntity_base = Pickable.OnRemoveFromEntity or function() endPickable.OnRemoveFromEntity = function(self, inst)	Pickable_OnRemoveFromEntity_base(self, inst)	-- util.lua helper function	RemoveByValue(AllPickables, inst)end-- called when the prefab is removed from the worldlocal Pickable_OnRemoveEntity_base = Pickable.OnRemoveEntity or function() endPickable.OnRemoveEntity = function(self, inst)	Pickable_OnRemoveEntity_base(self, inst)	-- util.lua helper function	RemoveByValue(AllPickables, inst)end
See this thread for an explanation of how require is used in the above code. Edited by squeek

Don't use FindEntities when you are looking for all the versions of something in the world. Iterate through (global) variable "Ents" instead, that way you skip all the distance calculations (and you are not bound to only look for tags either). Building your own list like @squeek suggests would be a much better idea if you intend to run the check regularly, and if you intend to have more than one of the AI running.

 

@BlackBox there are two main problems as I see it. First, monster AI does not run "off-screen". Once a monster gets enough distance between player and itself, it is put to sleep and will stay there until player returns. The distance is variable, and smaller when you run the game on a netbook. Second, as far as I understand, the pathfinding for the basic movement in the game is put inside the .exe and thus cannot be modified. This does not prevent you from building your own pathfinding, but it will have to be from scratch and using a different set of tools, and ultimately will depend on their pathfinding as a subset. I do not know to what degree those obstacles can be overcome.

 

My Summons mod plays around a little with AI, you might find it interesting if you want to see different in-game behaviours implemented.

Edited by Heavenfall

@EmielRegis thank you for the well-wishes! We'll do our best! :) 

 

@squeek, thank you so much for the code example. Whether we use it or not (based on the advice given by @Heavenfall) is another thing. But we are very thankful regardless.

 

Don't use FindEntities when you are looking for all the versions of something in the world. Iterate through (global) variable "Ents" instead, that way you skip all the distance calculations (and you are not bound to only look for tags either). Building your own list like @squeek suggests would be a much better idea if you intend to run the check regularly, and if you intend to have more than one of the AI running.

 

@BlackBox there are two main problems as I see it. First, monster AI does not run "off-screen". Once a monster gets enough distance between player and itself, it is put to sleep and will stay there until player returns. The distance is variable, and smaller when you run the game on a netbook. Second, as far as I understand, the pathfinding for the basic movement in the game is put inside the .exe and thus cannot be modified. This does not prevent you from building your own pathfinding, but it will have to be from scratch and using a different set of tools, and ultimately will depend on their pathfinding as a subset. I do not know to what degree those obstacles can be overcome.

 

My Summons mod plays around a little with AI, you might find it interesting if you want to see different in-game behaviours implemented.

 

@Heavenfall thank you for the tip! As for your second paragraph... That's a little more frightening... 

 

First: You mentioned that this distance is variable - is that variable within our reach at all? Or is it completely hidden by the engine? Whether or not we're able to change this variable does not affect (effect?) the success or failure of our project - but it does change any future, potentially interesting, applications. 

 

Second: I'm not if we're on the same page as far as what falls under the definition of "Path finding." Are we not able to command a creature to go from A to B? Can we not then build up (and store) a discrete list of such commands? If we're able to do that, we shouldn't have a problem - right? 

First: You mentioned that this distance is variable - is that variable within our reach at all? Or is it completely hidden by the engine? Whether or not we're able to change this variable does not affect (effect?) the success or failure of our project - but it does change any future, potentially interesting, applications.

You can read some more about this here: http://forums.kleientertainment.com/topic/30342-mod-request-chunk-loaders/ 

 

Second: I'm not if we're on the same page as far as what falls under the definition of "Path finding." Are we not able to command a creature to go from A to B? Can we not then build up (and store) a discrete list of such commands? If we're able to do that, we shouldn't have a problem - right?

Check out scripts/components/locomotor.lua and then check out all the behavior scripts in the scripts/behaviors folder.

Second: I'm not if we're on the same page as far as what falls under the definition of "Path finding." Are we not able to command a creature to go from A to B? Can we not then build up (and store) a discrete list of such commands? If we're able to do that, we shouldn't have a problem - right? 

 

Yes, you could do that. Eventually it comes down to telling something to move from x to y, and then it falls back to the .exe Pathfinder component. It probably will not matter at all if the distances you tell something to move are short steps. The longer the step, the more likely it will be that the Pathfinder chooses a different route. If you are building your own pathfinder then you always want it to move right away exactly to where you tell it to.

 

Actually, you can probably just ask @Cheerio or one of ze devs to post their Pathfinder.cpp.

Edited by Heavenfall

You can read some more about this here: http://forums.kleientertainment.com/topic/30342-mod-request-chunk-loaders/ 

 

Check out scripts/components/locomotor.lua and then check out all the behavior scripts in the scripts/behaviors folder.

Once again @squeek thank you :) I admire the dedication you have displayed so far. 

 

 

 

Yes, you could do that. Eventually it comes down to telling something to move from x to y, and then it falls back to the .exe Pathfinder component. It probably will not matter at all if the distances you tell something to move are short steps. The longer the step, the more likely it will be that the Pathfinder chooses a different route. If you are building your own pathfinder then you always want it to move right away exactly to where you tell it to.

 

Actually, you can probably just ask @Cheerio or one of ze devs to post their Pathfinder.cpp.

 

@Heavenfall so it might be helpful if I give a better description of what we need to be able to do. This is more for me, because I think you understand what I want to do - but it'll be easier if we're able to speak in terms of an example :)

 

Suppose you spawn a new simulation and this magical path finding NPC - let's call him the "scraper" because he scrapes resources up off the ground :) - spawns next to you.

 

The scraper's goal is to pick up 6 flowers before we consider him a success. Let's also assume 6 flowers happen to be laid out in a line stretching away from the scraper. Let's also say the flower closest to us is F1 and the furthest flower is F6 (with F2, F3, F4, F5 lying in between).

 

Are we able to direct the scraper (either manually or programatically) to collect F6 -> F1 -> F5 -> F2 -> F4 -> F3 using what's readily available to the modding community? If yes, I think we'll be able to do what we want. Of course, our final product may end up being so ugly that it's completely useless outside of this prototype - but that's irrelevant :) 

Are we able to direct the scraper (either manually or programatically) to collect F6 -> F1 -> F5 -> F2 -> F4 -> F3 using what's readily available to the modding community? If yes, I think we'll be able to do what we want. Of course, our final product may end up being so ugly that it's completely useless outside of this prototype - but that's irrelevant :-)

Yes. That's not dissimilar from what Krampus does (see scripts/brains/krampusbrain.lua):

 

local function StealAction(inst)    if not inst.components.inventory:IsFull() then		local player = GetPlayer()		local target = FindEntity(inst, SEE_DIST, function(item) 			if item.components.inventoryitem and 				item.components.inventoryitem.canbepickedup and 				not item.components.inventoryitem:IsHeld() and				item:IsOnValidGround() and 				not item:HasTag("irreplaceable") and				not item:HasTag("prey") and				not item:HasTag("bird") then									return player and player:GetDistanceSqToInst(item) > TOOCLOSE*TOOCLOSE				end			end)	    		if target then			return BufferedAction(inst, target, ACTIONS.PICKUP)		end	endend
Krampus looks for new entities to steal every 10 seconds, but I guess in your case you'd want to find all the target entities beforehand, sort them however you want, and then buffer all those actions (as far as I can tell, EntityScript and the Locomotor component only keep track of one buffered action, so you might have to implement an action queue yourself). Edited by squeek

Krampus looks for new entities to steal every 10 seconds, but I guess in your case you'd want to find all the target entities beforehand, sort them however you want, and then buffer all those actions (as far as I can tell, EntityScript and the Locomotor component only keep track of one buffered action, so you might have to implement an action queue yourself).

 

 

 

@squeek I think you nailed it. 

 

And I was just about to begin typing exactly what my partner and I are looking to do - but I think I managed to derail my thread enough as it is already :) I'll discontinue discussion on this thread for right now (Unless @Heavenfall decides to throw another monkey-wrench into things ;) (Or unless someone else wants to throw something into the mix!)) 

 

You can expect to see me kicking around with more questions. Heck, maybe I'll just make a general QA thread where you guys can solve all of my problems :)

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...