So what's your village management style?

Seems like this is gona be one sizzling hot competition, no snakes will survive, and while you enjoy your Java ill just C# to try obtain more wood

I doubt there would be any further room for las minute tweaking.

Cant say im dissappointed with my entry this year. Just hyper perfectionist and know I some stones unturned in my territory strat.

Still nervous and excited though.

As I told my partner, I always assume my opponent has the same bot I have but they also implimented the strategy I didnt get to.

I left my territory claim just a little too long but am very greatful that we had the Wednesday.
Starting territory at like 8PM on Tuesday was crazy stupid.

But I was dabling with buildings,
Spent 3 days on a Multi level simulation to manage my buildings only to observe a pattern that took me 30 mins to implement that makes the need for future simulations redundant anyways.

Wrestling with the problem is always one of my favourite parts of the challenge.

Id say if I had a chance to edit id likely just delete a few lines.
Move others.
I would honnestly add a single line added feature to unit recall.

But dont feel I need to mess with my bot much.
Still, peace of mind and perfectionism.

I have not opened my bot for a long time.
Like Kobus.
If theres a bug in there that i missed I would rather not know of it.

So now that the submission deadline for the finals have come and gone, what was everyone’s management style?

In the end, I didn’t see that much value in territory. I didn’t get the time to do as many tests as I wanted to, but it seems like the cost of having idle units early on offsets the possible gains from it, and it was very easy getting stuck in a fight for territory and spending a significant portion of your population trying to defend or occupy nodes, and for late game, there’re no more resources to mine so the buff/debuff is irrelevant. Lastly, with only a possible score of 3200 for controlling the whole map is insignificant in proportion to the final scores.

I ended up doing a fairly conservative territory strategy. Only claiming resource nodes directly touching my own territory with a very low cap of when to give up if the other person fights for it, and sending a single unit to all of my own resource nodes the moment I see another player occupying nodes. That way, if another bot tried to take that node, I would always be able to fight for it when I got around to mining it.

1 Like

I must say territory for me was just to get that reward multiplier.
I noticed I kept hitting max tier a lot on wood in early tests and used that to just burn wood, a lot of wood, my aim was to sustain a maximum of 421570 troops at end game, anything higher than this got hoarded.
This however only works against weak bots, with strong bots, wood gets fully depleted.
I also limited my buildings to when there was enough wood available to sustain my population, once it started get closer to available wood left in the game, I started been a hoarder until tier 6 at which point, I burnt all my wood as the game and tick limitations stopped you from growing past tier 6.
Towards end game, I had ample troops and only used a % of them to defend nodes.
My main aim on nodes were to only allow 70% of resources for other bots hitting those.
I flipped between outposts and lumber mills mostly so as to gain those multipliers.

1 Like

My strategy was fairly simple, I think its strong points probably lies in it being fairly well tuned for efficiency. My entire strategy revolved around optimizing the speed at which wood was being burnt, since to me that seemed to be the determining factor of a bot’s success. So, I did quite a few things to try and increase the rate of burning as much as I could:

  1. The core part of my strategy was my wood burning algorithm - it carefully tried to balance wood burning and consumption (heat) so as to not hit the tier max level for wood (which meant wasting units when gathering). I spent a lot of time tuning this (even playing around with feedback algorithms but they were unstable) and it ended up working fairly well. This meant that I could allocate as many units as I wanted to burning/lumbering and this would lead to faster heat generation without hitting limits (up until the wood collapse I usually had all my units allocated, with 90%+ of them busy with burning/lumbering). This lead to my heat/wood looking something like this:

image

It’s a bit difficult to see from this graph but for the most part the wood hovers below the max tier limits while the heat continues to grow. Also important was to monitor how much wood was left on the map (in my region) so that I could stop burning wood before I couldn’t reach tier 6 any more (which you can see in the graph when the heat stops growing).

  1. At first I didn’t pay much mind to buildings/territory but I realized if my bot grew territory fast enough that it would help increase the rate of wood income (which if balanced properly could lead to faster heat generation), so I tried to optimize that as well for fast expansion. I rotated through each building type (except road), to try and gain territory (prioritizing wood claims) as quickly as possible. Since the score gains were negligible compared to the final scoring I only did it to try and speed up resource gathering in the first half of the game.

  2. For territory attack/defense the same goes as for buildings (i.e. if done quickly I could gather wood faster before it gets depleted). I capped by department of defense to 20% of my population, first prioritizing defense of my own territory (again wood first, just reactively allocating units to a node if a enemy attacks it) and then if there was enough units left, attacking enemy territory at its weakest spots (aiming for wood). Also tried to leave nodes wherever I could to regain units. Also tried to keep attacking close to home so that I don’t end up expanding into far-off parts of the map.

  3. Finally I spent quite a bit of time to fine-tune spending to make sure that I didn’t miss tier advances (by capping spending wood/stone/gold), and also planning so that my bot never waited to get enough resources to advance - I put in checks so that by the time it reached the population max it would have all the resources that it needed to advance without waiting.

5.I also tried to make my bot as robust as I could against missing ticks. Even after rewriting it in golang and getting the computation down to the low 10’s of ms, I still detected missed ticks late in the game due to large state updates. Not detecting these lead to my bot sending invalid actions (usually because it sent two commands in one tick). I could mostly prevent those from happening (but not entirely because I could not predict if my actions would be received/processed in time) which probably also helped.

I’ll open-source my bot (with a ready-to-run docker image) once the finals have taken place for those interested, but yeah like you can see there’s not a lot of fancy stuff going on. I didn’t change my bot significantly for the finals, (I changed a one to a zero used in resource calculations) so not sure what’s going to happen at the there.

Really looking forward to seeing what other people did!

3 Likes

Curious, are those heat values close to 9 million, what range did your end game population run at in those matches?

Yeah the heat reached somewhere in the 8 million range before the deforestation caused population collapse. My population for that specific seed reaches a max of around ~330 000, and ends at around ~222 000 (depends on which player in the match I’m looking at)

1 Like

Overall, my strategy was very much the same.

I prioritized resources based on a weighting for each, calculated by taking into account the consumption per day (for wood this included the amount of wood required to produce enough heat to sustain the population), availability, mining reward+speed and closest distance to a significant amount of that resource. It would then just mine those resources in that ration and grow the population as fast as it can. This worked great for the first version of the bot where there was no max resources per tier and population growth was unchecked. In a 4v4 match, the map was cleared out of food at around tick 800…

After the update just before round 1, I changed my strategy to use the same weighting system, but once it gets close to max resources, it started cascading units towards wood and heat and burning all wood over the requirement for the next tier. I planned on rewriting my bot from scratch after round 1 but never got to it. As one does. I stop burning wood the moment there isn’t any more left on the map and let the population burn through the accumulated heat until it starts dropping. As of this final version, I added a check close the end of the game, if the population drops below a point where there is enough wood to sustain it and the population will provide more score than the wood, it will burn enough to maintain that population (although, looking at that code now, my score calculation for the population seems bugged, still seemed to work though).

For buildings, I started with a guild, built mills until I had 100 population, and from there I calculated a weighted score based on the resource weightings used for mining and built whichever ended up being the cheapest. I scanned the edge of my territory and picked the closest node that is on the edge of my territory and built there, excluding any locations where pending buildings will spawn their territory.

I feel like I didn’t quite optimize most of my calculation as well and there are lots of spaghetti and old useless pieces of code that never got removed. I plan on open sourcing my code as well if anyone wants to look at it and I’m sorry to anyone that does…

It’s been a very fun experience so far

Edit: Did I mention the extremely overcomplicated and redundant ways of doing very simple things because I was sleep depraved when writing them? So many dictionaries with the same things in them

2 Likes

I calculated a radius around my base that would give me that “perfect” score and added 1.
Then I would play very aggressive on those nodes.

But ignore whats outside it.

This did get more aggressive as the match continued.
And I think I limited my own strategy for this to around 10 units. because I did not want to drop 100 units on anything.

If I had to place my own strategy down its pretty much whats already been said.

I will prioritize gathering my own needs.
Thereafter I would prioritize:

Stone:
Gold
Wood

The reason I did stone first was it gave me first pick at territory.

My building is very very aggressive. But as a general rule I expand in my needs radius first, and will push deeper if needed.

Capturing enemy territory with buildings is a bit redundent. Because you can grab those back so fast.
BUT… I didnt throttle that part of my bot because I figured that if I ever end a bot that isnt prepared for my expansion it could get choked out very early…

The one function that really helped me was my starvation…
Essentially when I hit the 5th tierre (30516 population),
I will take complete wood stock…

A) MyWood, B My Lands, C) My Wood reserves

If then i see I still need more wood i will activate a form of starvation.
When my bot runs against itself the whole map is basically dry around Round 1500.

And thats more or less where the tierre advancement happens that gives you enough space / storage for the final part of the game.
I feel I start starving a bit too early… I could probably have done a lot more on the grounds of fighting for land and so on. Maybe till Round 1600.

I did try my hand at defence and offence, In hindsight I should probably have tried to defend and take when I reach that advancement.

But the nice thing is if I start killing units here. I also save exponential heat towards endgame.
Im not particularly confident in my approach.
I could even have a weaker bot than I had in the 3rd event.

Though I know my gathering is 10% more efficient, I also made a few other changes that could explode in my face.

In my current state I am merely hopeful for top 4. This year I have a I will be happy with top 4 entry.
Thats not even false humility.
If someone hits my bot in a certain way it will suffocate itself.

But I am very very confident in my first 1600 rounds.

I believe this year taught me some very deep lessons.

A) Plan, Plan, Plan…
I am like a beserker, I went in swinging very heavily. Over complicating most of what I was doing.
That made things like bug fixing and hunting much more complicated than it needed to be.

**One example, I calculated a wood need for my heat requirements,
Then For my minimum advancements, Then for my max storage, then for future storages, then for buildings thats going to finish, Then again for anything I burn now…

On monday I wrote a single function for all of this.

Look at how much wood I have, How much I’m going to spend,
Add and remove all pending actions. Subtract the max storage and try and get that amount of wood.

If I had done this for the very first event…
Seriously… I would have simplified my life in ways that I can barely comprehend.

So one focus I want to take is to take the complexity that is my own codebase, and learn ways to simplify them.

If you can do a single task in 10 lines instead of 50. (Seriously what I was doing…)
Then when you do see a problem you can really simplify your life.

So for me planning was a big lesson.

The second thing I want to work on after that is something that I heard in Kimetsu No Yaiba (Anime Series)…
If you can only do one thing, hone it to its absolute limits.

What I mean here is: I would, if Im fortunate enough to have more challenges with Entelect (I really every year have a worry that they will end). I would focus on one single aspect at a time instead of trying to build the whole thing in one go. So start as simple as possible and just expand.

**Do 2 levels of depth and perfect that. Dont start with 7…

I think this year learned me quite a bit of " Programming Etiquette"

Which is generally something I hate.
But I saw that small place of it where I can actually use it to make my own life much simpler.

Doing a visualiser was also quite fun and… Unexpected.
Now its not perfect, but I think it was cool and allowed me to build.

That also shows me how much I have advanced as a dev…
The person i was 5 years ago would never have shared a tool that would lower my chance of performing.
But I won in 2019 and that was a pretty large “goal” of mine. So now it feels better to try and help others and make the challenge more challenging.

Without flat out sharing strategies.

I feel like somewhere in the last month I broke through some programming limits I had.
Im pretty excited for that.

**Also excuse my dialogue,
I dont think Im fully rested after the push I had.

Cant wait to see others in the finals.
I am fully honnest in saying I have no idea what to expect.

A Resource management problem is crazy.

1 Like

PS Thank you very much for the visualizer, I used it quite a lot (as I’m sure many others did as well) - really made things a lot easier.

It was something new for sure.

Also feel your cleaner saved me a bit of time… The logs this year were crazy…

It’s interesting to see that many of us ultimately converged on a very similar strategy (albeit implemented in different ways) - chop down as many trees as possible and set fire to them, while using whatever units are left over to get food and mine other resources.

Compared to previous years, I entered quite late and probably spent relatively little time on my bot this year - so I was very happy to make it into the finals. The extra few days also allowed me to make some optimizations.

Funny enough, the reason why I entered late was also something that had some influence on my strategy. I’m busy studying towards a business degree (in addition to my full-time job, hence the issues around finding time) - so I looked at the challenge rules, and my brain went “nice, let’s go into the village business”. As always, it’s not a textbook AI approach, but it borrows some elements from utility-based AI and goal-oriented action planning (GOAP).

Following on the idea of running a village like a business, I divided my bot into three “layers”. I found that this also made it easier to wrap my head around it, because each layer has a very distinct purpose and it makes it easier to code, because of the well-defined boundaries.

Strategic layer
This is straightforward - it does nothing more than looking at the current state of affairs and allocating priorities to each type of action that the bot can take (lumbering, gathering food, making fires, building buildings, etc.). E.g. if the bot has too much food and not enough wood, this layer would decide to prioritize wood.

Tactical layer
This layer runs through the prioritized strategic objectives and allocates units to each objective. For resources, for example, it would identify the gap between what the bot currently has and what it believes to be the target amount (mostly a multiple of population that I refined over time through testing). For building, it tries to maintain a certain number of buildings of each type. The goal-oriented action planning that I referred to earlier also features here - if my bot needs stone, but there are no stone mines around, the code that deals with stone mining will allocate scouts. If there are not enough units available for a lower priority goal, it will be ignored.

It runs through two steps:

  1. Each tactical goal requests only the number of units that it actually needs (e.g. if the bot has 100 units available and it believes it needs 10 units for gold, it will only request 10 units and 90 are left over). For camp fires, this also checks how much wood I have vs. how many units I have to decide when to make fire.
  2. Once the required units have been allocated for each goal, I run through the prioritized actions again to allocate “reserve units” - everyone left over after the minimum required units have been allocated. This essentially tries to allocate enough units for each resource to hit the max for the tier. It mostly goes towards wood.

Operational layer
This is where the actual work happens. Based on the unit counts allocated in the tactical layer, this layer will try to find the most efficient way to put those units to work. When harvesting resources, I look at the travel time, reward, and work time to find the resource nodes that offer the highest return per second, then I send units there. If I happen to hover near the max wood for a tier, I deliberately send units to nodes that are far away to start mining them pre-emptively and to prevent the opponent from getting to them (a bit of a “scorched earth” strategy). When I build buildings, I look for the spot with the most resources in the vicinity. My territory strategy is also fairly basic - I don’t really bother to defend my borders and I target cells immediately adjacent to my territory, prioritising the ones that are the easiest to capture (lowest pressure) and the ones that have resources on them.

Once the finals are over, I’m happy to share the piece of code that shows how the layers work.

My bot was written in Java, and takes between 5 - 10 ms to issue a move when running on the portal.

2 Likes

And so it begins…

What a journey this challenge was for me… and it’s not over yet!

Being a first time participant I didnt really know what to expect or where I would fit into the mix. This challenge went from a fun side project I do when I want a break from everyday enterprise projects to basically taking over my life at times. It has a way of consuming you like you are in the tundra yourself trying to out survive everyone.

That being said , this is what I came up with in order of priority.

  1. Start of by sending units to scout.

  2. Feed the hungry and Keep the cold warm. First priority was to gather/generate enough food and heat for my population to grow optimally. Which nodes to gather from was decided by writing a calculation method for each node to determine the resources / per tick score a unit would receive if gathering there. Taking into account travel distance, work time, reward, multipliers etc.

  3. Gathering enough Wood, Food, Stone, Gold to upgrade to the next tier until tier 6 then this falls away.

  4. Max out Wood, Food, Stone, Gold to the resource cap. Excluding Food, I set food always to only 50% cap since its easy and quick to get. The only time I set it back to 100% is in end game so I can get the full score for it.

  5. Burn Extra Wood. Every time I hit the wood cap I order all available units to burn wood to start stocking up on heat as much as possible for when all the wood runs out.

  6. Build. I enjoyed coding this part the most probably, it basically boils down to 2 parts/questions. What to build and where to build it? As for what to build I firstly hard-coded to build a lumbermill, farmer’s guild and quarry first so one of each to get the gains. Then its all about whats cheapest to build next. I only build one outpost in every game since in my opinion you dont really gain anything later from it since most territory would already been taken up anyway, Roads I only build until most territory on the map was claimed then I switched back to the status gaining buildings only. As to where to build, I looked at each available space and calculated a score per resource found on the territory that building would cover if it was to be build there and the highest score would win

  7. Conquer. Claiming territory was a challenge , one which I would have liked to spend more time on until I could have clarity about how I felt about it. But I ended up with the following. Check all my wood nodes and all enemy wood nodes on my border that are under attack or that I don’t have the highest pressure on and respond by sending only 2 units at a time (tick) to them. The reason I went with only 2 is that it freed me up for having to manage bringing them back at all. They could just stay there until end game and it would not affect my gathering at all and I would still be able to put up a fight for territory, Yeah I know its no take over the world plan but I found it rather effective.

  8. Always be scouting. If I reach this while having units available go scout until the whole map is visible to me.

  9. If all else fails. This is just a fail save to make sure I’m always doing something at least - so its just goes and gathers whatever is available on the map

And thats basically it.

I am super hyped for the finals at CCA and to meet you guys! I ended top 4 in the 3rd phase and I am hoping I can do the same Saturday however, I have reached my goal for this year to reach the finals so the rest of it is just gravy!

3 Likes

Hi Team. Will be nice seeing you at the finals on Saturday. I have met some of you before (I was in the Worms final a few years back).

I spent a lot of time coding my bot in the first round. Had some interesting strategies going e.g., when I reached Tier 2 I went all-out to mine all the stone on the map to prevent the opposition from levelling up. Had some success, but then the game engine changed and this become obsolete.

In round 2 I experimented with the buildings, but somehow my results went pear-shape. Not sure what I did wrong, but I also hit the bug a few times where the engine stopped processing after sending people to construct buildings. In the end I did not build at all and rather spent some more time to optimize my resource gathering and heat generation.

In round 3 I had very little time available to code. Work commitments, loadshedding, and my focus on preparing for the Comrades Marathon (I ran #13) took priority. Was happy to be in the top 8.

What did I enjoy this year? – The RTS style game. I found it easy to start, but tough to master.
What did I not enjoy this year? – The HUGE game log JSON files. The incremental changes during the rounds. (Very frustrating when you try some machine learning algorithms and then have to start over with each change). The lack of logs from the competition games.
What would I like for next year? – Bring back the fun of watching the leaderboard as the games are playing out.

Thank you all!
Kuifie

4 Likes

Morning everyone, now that the finals have been concluded I’ve made my bot repos public. You can have a look at the code here: GitHub - kobus-v-schoor/entelect-2022. The main interesting bits are in this function: entelect-2022/bot.go at main · kobus-v-schoor/entelect-2022 · GitHub. If you want to run my bot locally the easiest way is using docker, I’ve got a built image here that you can use if you want: Docker Hub - v3.7 is the one I submitted to the finals.

2 Likes

Thanks @kobus-v-schoor ! Congratz again!

1 Like

Well done to all the finalists and @kobus-v-schoor for winning. It was nice meeting and chatting with all of you on Saturday.

The main logic for my bot lives in bitchassbot/BotService.cs at master · Seuntj1e/bitchassbot · GitHub, it’s a tremendous dish of spaghetti bolognaise. I made some small changes to the DTO class to allow some calculations happen on them, but you will see them referenced from the monster method.

1 Like
/*
Don't judge too harshly
for most of this
I could just barely
keep open my eyes.
lots of lines
written and rewritten
like the very unwise
between midnight
and copied and cut, and dawn.
there is no structure
or
form
and is not to be maintained
//as clearly displayed
//by the lack
//of
//strucutre
//or form
but enjoy this poem
and later the song
and remember
judge !harshly
slava Ukraine
*/
using BitchAssBot.Enums;
using BitchAssBot.Models;

:rofl: @Seuntjie giving us a masterclass in documentation. Thanks for sharing! Your commit history is a thing of beauty

You haven’t even gotten to the “Frozen” parody… needless to say, my head was mush by the end of the last few days of changes.

1 Like