Rise to Ruins

Rise to Ruins

View Stats:
zekaonar Apr 24, 2020 @ 8:22pm
AI Mods
I'm really enjoying the game! It's come a long way since early access.

I have some Java skills and I don't see any mod support outside of languages so I hope you don't mind if I looked at some decompiled code and sampled the threads in VisualVM to try to get an idea what is going on :-)

Job assignment seems to struggle when you have a big spread out base and/or you are trying to build many things at the same time. I think it can be optimized by weighting the priority vs the distance you need to walk and better managing the number of other workers. I want more efficiency out of my builders but the more I watch behavior and look at code, the more I think this is a complex relationship that I need to iterate on instead of just posting suggestions.

Tweaking algorithms to make better choices appeals to me as fun. Any chance you support some kind of open source modding for those that want to play with your game code and maybe contribute game improvement pull requests?

< >
Showing 1-6 of 6 comments
Tiberiumkyle Apr 24, 2020 @ 8:58pm 
Ray has mentioned before that he won't open source the code until he's officially done and moving on from the game, which currently looks to not be for at least several more years. You're welcome to decompile the code, poke around, and recompile your own changes, even share them, just be sure to give proper credit and such.

I will warn you, the AI is probably the most complicated code in the game, and takes up a huge part of the codebase.
zekaonar Apr 28, 2020 @ 7:23am 
I've been tinkering and I've found a few changes that satisfy me :-) I'd put up a little mod for people to try except that I would want to publish my source code with it and I wouldn't feel comfortable publishing decompiled source without explicit permission.


Carrying resources to a jobsite seems to be the bottleneck with construction.

The vanilla AIDeliverConstructionResource job gets a list of building sites that need resources sorted by user controlled priority, then uses AIUtilities.createLowestPriorityStorageListHashMap() to choose where to grab resources. For wood and stone this means the Camp and Ancillaries(LOW) are the preferred locations to pick up resources even if you are standing next to a full Lumber shack or full wood storage(MEDIUM). The Builder or Organizer might be able to carry 8 items but the Ancilliary might only have 1 Wood or the logic tells them to pick up 1 wood off the ground. And there is a random pick in which resource type to deliver so you might be delivering a resource to a low priority building from the randomness. The vanilla AI will walk across the map to pull wood out of an ancillary in the opposite direction of the build site and it doesn't give preference to convenient locations.

My changes:
  • Emphasize the priority list to give users real control over what gets built first. Removed the resource shuffle.
  • I treat all storage that is MEDIUM resource priority and below as the same priority. If a builder pulls from the Mining Facility then the Miners have less distribution to do and can keep working.
  • The mob now favors pulling from a storage location where they can get as much as they can carry to reduce trips.
  • The nearest storage to the mob or the build site is favored to reduce walking.

A Builder will walk across the map to give a building 1 tap even if another builder is already on site and could have taken 1 more second to finish it.

AIBuildWork allows 6 builders to work on the same building. 6 is good for creating the first camp but after that you will have builders taking long walks to tap a building that could have been finished up by the builder already on site. I want a dynamic builder cap of: # of buildings under construction / # of builders so there is less tap stealing when there is a builder on site that can do it quicker.

My changes:
  • findWorkWithBuilding() and continueBuildWork() no longer looks at workerCountTooHigh(). The mob is on site, it is a builder and there is build work to do. Tap it until it is done.
  • findWorkNewBuilding() prioritizes the closest building to the builder. Favoring priority order in the resource delivery already favors build priority better than before, now we can go for efficiency.
  • workerCountTooHigh() no longer uses a fixed 6 worker cap and instead uses builders / build sites. And if a site is more than 30 tiles away and there is a builder already on site then check returns true.

Villagers random food choices harm your ability to make raw food into rations.

If they eat all your raw meat, your supply chain gets messed up and you have idle workers. Sometimes they will pick it up off the ground to equip it faster than it can be stored.

My changes:
* AIFindFood and AIFindFoodCheck now use a food priority order: RATION, COOKED_MEAT, BOILED_EGG, then either RAW_VEGETABLE or RAW_MEAT whichever you have most of in storage or on the ground followed last by EGG.


Repair jobs and building new road jobs never seemed to happen unless the whole base was idle.

It took me a while to understand the AI failbranch loop but once I did I figured out that AIRepairWork is the lowest priority job for everyone. I was hoping to make it the top priority for Maintainers but everyone really has the same AI loop and hardcoding job priorities take away some of the extensibility of the loop and flag system that is in the code. So instead I shuffled the default priority tasks.

My changes:
  • AICriticalRepairWork is now first. Really you shouldn't have Builders making new buildings or clearing land when an existing building is almost burned down.
  • I also had to alter AIRepairWork to comment out the line if (objectCheck.getHitPoints() + workerCount * 25 >= objectCheck.getHitPointsMax() && objectCheck.getFireDamageArray().size() - workerCount <= 0) as workers deliverying bolts or building were counted as workers and it prevented repairs from happening.
  • I move AIRepairWork way up in the order ahead of most of the other tasks Maintainers do.
New Order:
AIStart
AIAttemptWork
AICriticalRepairWork
AIPatrolVillage
AIPatrolFrontLine
AICaptureAnimals
AICaptureAnimalsInHand
AISlaughterAnimalInHand
AIPlantResourceInHand
AIDismantleWork
AIClearTopographyFromRoadWork
AIClearTopographyWork
AIRemoveRoadWork
AIDigWork
AIBuildWork
AIRepairWork
AIRoadWork
AIRepairRoadWork
AIClearResourcesFromRoadWork
AIConstructionHarvestWork
AIRefineResource
AIProcessTrash
AIMedicWork
AIHarvestFarmWork
AITendFarmsWork
AIPlantResource
AIRefineWaterBottle
AIDeliverConstructionResource
AIDeliverRoadConstructionResourceInHand
AIDeliverCourierResource
AIRedistributeResources
AISlaughterAnimalInHand
AIBuyLaborer
AIBuyFromProvisioner
AISellResource
AIStoreResource
AIStoreTrashInTrashCan
AIMakeTrashyCube
AIHarvestWork
AIHarvestWaterWork



Essence Collectors are constantly burning Crylithium when it isn't needed.

ObjectBase.energyRegenerate() will use Crylithium even if you are just 1 energy point short of full. I was not able to play with this code very much as ObjectBase has a lot of code and the decompiling process introduces too many runtime errors. My goal was to use fuel at 80% and see if the natural collection mechanics were used more.


I also changed the RoadModule ROAD_TRAFFIC_TO_CREATE_PATH = 2000; I like this change (spotted on another thread) and the paths help you figure out the best place to make roads. If 2000 steps can wear down a road then 2000 steps should be able to wear a path in the grass.


Next up I was going to look at AIStoreResource vs AIRedistributeResource. I think Miners spend too much time walking stone to Ancilliaries around the map. They should dump their stone at the closest location with capacity and get back to work. Looks like I can just change their flags from this.canWorkerSortEvenly.add(ResourceModule.ResourceType.ROCK) to this.canWorkerSortClosest.add(ResourceModule.ResourceType.ROCK) but if I do the same to a Fletcher, will Organizers pick up the slack on the Tower ammo deliveries?
Rayvolution  [developer] Apr 28, 2020 @ 12:15pm 
Originally posted by zekaonar:
I've been tinkering and I've found a few changes that satisfy me :-) I'd put up a little mod for people to try except that I would want to publish my source code with it and I wouldn't feel comfortable publishing decompiled source without explicit permission.

Post away, I don't really care much. Someday in the far future RtR will go open source anyway. :)
zekaonar Apr 29, 2020 @ 6:16am 
Thanks for letting me tinker! And thanks again for the fun game!

I'm happiest with my building changes but I didn't quite solve the food problem, they are still equipping raw meat and the repair issue still exists because maintainers will cycle between repair and repair road jobs and in a spread out base they are walking instead of fixing. It is tricky to improve something without breaking something else.
zekaonar May 2, 2020 @ 1:29pm 
I had to do more improvements beyond what I put above. Even though I rewrote a big chunk of AIFindFoodCheck and AIFindFood it was still stealing all the raw meat. It turned out this was from AIEqiupResource. I ended up changing all raw food to an itemLevel of 1. They will still equip raw meat but they are more likely to grab raw veggies if you have an abundance of them.

For the repair changes my reordering did nothing. I had to change AIRepairWork so that if the mob successfully repairs something it continues repairing other things if there are still damaged buildings before we cycle to other jobs.

My mod is shared here:
https://drive.google.com/drive/folders/1Bw_TZxpX0mGHWedhMwBCx4GxF7mztHJj

Put all files in your game folder, probably a path like:
C:\Program Files (x86)\Steam\steamapps\common\Rise to Ruins

It mods using classloader order. The contents of the bat file is:

java -Duser.country=US -Duser.language=en -cp AITweaks.jar;Core.jar rtr.system.Launcher

If you launch the game using the bat file you play modded, otherwise if you launch using the steam url it plays unmodded. If the game updates it will overwrite the bat file and undo the mod. Nothing touches savegame just behaviors and so playing with/without the mod won't break anything.

Source code included in the jar, feel free to make your own tweaks and play with it. It will be a small subset of the original game source, only files I touched or was considering touching.

TODO list:

AIDeliverConstructionResource - if it picks up off the ground it only gets 1 item. Need to port/call the gather up logic from AIStoreResource.

I'm considering limiting the range of Gatherer workers. If you start clearing corruption all the workers stop what they are doing and pick up stone/wood/trash from the recently cleared space. It is usually a long walk and it effectively halts resource gathering until it is done. Maybe use building range to limit their store resource jobs and keep them harvesting. Then you actually need organizers if your logistics route gets longer.
Wow, thank you for such an inspiring post! Almost five years ago already, ahaha
I mod all the games I love, and I love this game to death. After looking at the Workshop a couple times over the last few years, I concluded modding isn't super viable. I edited some strings in the game's announcements (like death messages) to be more to my liking, but other than that, I haven't done much.

But my fingers are always itching -- ITCHING -- to do some actual coding. The AI problems you describe in your posts are exactly what I've concluded from observing them all this time also. And then how you talk about how you went about fixing those complaints you had about them, super easy to follow and makes sense to me!

I'm excited to see if I can just hot-drop this into the game files even now after a couple of updates -- I remember excessive Crylithium burning in the Essence Collectors haha -- good change that that mechanic was removed in favour of Praying.

This will give me a great jumping-off point to start my own coding adventure for Rise to Ruins. Thank you so much, again.
< >
Showing 1-6 of 6 comments
Per page: 1530 50