Jump to content

elantzb

Members
  • Posts

    25
  • Joined

  • Last visited

Converted

  • Gender
    Male
  • Personal Text
    devil worship at its finest.

elantzb's Achievements

Tree Puncher

Tree Puncher (2/8)

11

Reputation

  1. I haven't used a wiki in a while so any help would be appreciated.
  2. I haven't used a wiki in a while so any help would be appreciated.
  3. Have you tried re-skinning the normal in-game compass before? I wonder if compass.txt needs editing....
  4. my bad, should have camel-cased the "SansExtension:"
  5. Also, your unlocalized names for your blocks or items need to be "yourmodname:texturefilesansextension"
  6. the first two ints that you declare are for IDs, not Item information. Also, your ZanofiteItem class might be importing the wrong Item class. and setUnlocalizedName() should only need 1 argument.
  7. Awh thanks. Which wiki? I think that it could use some refining/feedback before I wiki it
  8. I was hoping that this thread would garner more attention seeing as how long it took me to put together, is there a better place to post/pin this?
  9. Here's the posting! http://www.minecraftforge.net/forum/index.php/topic,7351.0.html
  10. Minecraft NPC Villages Explained (Or, Why Are My Villagers Clumping Together?) Disclaimers: This explanation is current as of April 4, 2013, and pertains to vanilla Minecraft(no mods affecting the files mentioned within.) The names of all class files mentioned are current MCP mappings, and all code will be pseudo. This part only covers village expansion, more can be explained if people ask. Introduction So, one day I decided that I wanted to build a massive city, and populate it with NPC villagers. But with my villagers sticking together in one building like rare-earth magnets, and ignoring the gorgeous mansions that were waiting across the street, I knew that something was wrong. I began perusing forum posts for answers. Most of the results I found mentioned burying villagers alive, locking them up, or using various things to attract them. (Suggesting that they may like to gather around pumpkins, animals, prisoners, etc.) Others who understood more of how the invisible radius of a village works had better ideas, but there was a lot of micro-managing that did not account for some of the ways the code actually works. So, I began reading the Java code for my answers. (Thank you, MCP) The Explanation Everything starts in VillageCollection.java This class keeps track of the existing villages, and the positions of each villager in a list named villagerPositionsList. This list is mostly useless. In the class's tick() function, it iterates through each village that exists, calling their respective tick() functions, which call their Villagers' updateAITick() functions. VillageCollection then calls its function dropOldestVillagerPosition(), which removes the villager position from the top of the list. This is probably the only important use of this list. The oldest villager position is passed to VillageCollection.addUnassignedWoodenDoorsAroundToNewDoorsList() I should mention that each Village object keeps track of the wooden doors that belong to it, a list of VillageDoorInfo objects named villageDoorInfoList. The function VillageCollection.addUnassignedWoodenDoorsAroundToNewDoorsList() checks a list named newDoors and adds any *new* wooden doors to it that are within 16 blocks horizontally and 4 blocks vertically of the oldest villager position. Doors that already exist in a Village's villageDoorInfoList have their internal timer reset. This will be explained later. But, doors are only added to newDoors if they are "valid." addUnassignedWoodenDoorsAroundToNewDoorsList() calls VillageCollection.addDoorToNewListIfAppropriate(), which looks at the 5 blocks on either side of the door's base. It counts the number of "outside" blocks, that being blocks which the sun can shine on during the day. A door is "valid" if the number of outside blocks on one side *does not equal* the number on the other side. Returning from VillageCollection.dropOldestVillagerPosition(), the next step in tick() is to call VillageCollection.addNewDoorsToVillageOrCreateVillage(). If any doors in newDoors are close enough to an existing Village(within the Village's radius plus 32, squared), then that Village gets the door. Otherwise, a new Village is created and that door is given to it to handle. That sums up most of what happens inside of VillageCollection.java //within VillageCollection function tick { foreach Village, call Village.tick() call dropOldestVillagerPosition() call addNewDoorsToVillageOrCreateVillage() } function dropOldestVillagerPosition { pos = villagerPositionList.pop() call addUnassignedWoodenDoorsAroundToNewDoorsList(pos) } function addUnassignedWoodenDoorsAroundToNewDoorsList(pos) { foreach door within 16 of pos.x and 16 of pos.z and 4 of pos.y { if door is in a village then door.timer = 0 else call addDoorToNewListIfAppropriate(door) } } function addDoorToNewListIfAppropriate(door) { put 5 "outside" blocks on one side of door into list1 put 5 "outside" blocks on other side of door into list2 if list1.length is not equal to list2.length call newDoors.add(door) } function addNewDoorsToVillageOrCreateVillage { foreach door in newDoors { find a village where (distance between village center and the door)^2 < (32 + village radius)^2 if village found call village.addDoorInfo(door) else create new village.addDoorInfo(door) } } Now I will explain the relevant code in EntityVillager.java Most of the Villager's actions spawn from the function EntityVillager.updateAITick() It updates its position to VillageCollection's villagerPositionList, and sets its home to the nearest village. If no village is found, the Villager will wander until it finds one. The Villager's wander area is centered on the Village's center, with a radius that is 60% of the Village's radius. //within EntityVillager constructor EntityVillager { set wander area to home village with radius of village.radius * 0.6 } function tick() { set home village to closest village do villager stuff } And then onto Village.java Every time a Village's tick() function is called, it takes care of all sorts of code pertaining to population count and iron golems. It also calls Village.removeDeadAndOutOfRangeDoors(), which removes door info from villageDoorInfoList for any door that does not exist, or any door whose internal timer has passed 1200 ticks. The function then calls Village.updateVillageRadiusAndCenter(), which is also called when a new VillageDoorInfo is added to villageDoorInfoList. This method recalculates the Village's center by getting the mean of all the doors' positions. Then, it sets the Village radius to the distance between the center and the most distant door(unless it is within 32 blocks, 32 is the minimum radius). //within Village.java function tick { call removeDeadAndOutOfRangeDoors() } function removeDeadAndOutOfRangeDoors { foreach door in villageDoorInfoList if block at door is not a door OR if door.timer > 12000 then remove door } That is how the code works. Why I Call This Code "Broken" The code I have examined is meant to let the radius of a Village grow organically, as explained above. But, as I mentioned in the Introduction, this doesn't work. Village radius is based on the location of the furthest door in the Village, and doors are added by chance when a Villager is near them. But because the doors' internal timers expire before being noticed by passing Villagers, the radius shrinks. And Villagers prefer to stay within 60% of the Village's radius to its center, so they rarely see distant doors. I've been lucky enough to have a village of radius 35 (minimum is 32), even with lots of micro-managing. Hope I helped someone, please tell me how I can improve this post!
  11. /facepalm http://www.planetminecraft.com/blog/the-dummys-guide-to-modding---from-setup-to-advanced-1152101/
  12. check out this page, look at Step Four Part D.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.