Posts Tagged ‘Net C#’

Desert Strife Post-Jam AI (with more code examples!)

Posted by
Wednesday, October 5th, 2016 2:31 am

GIF!

Intro

Took a while (too many projects at the moment; loving it!), but here it is: Part 2. The basis of the system is still a reactive AI using heuristics. It doesn’t plan ahead at all, which is good enough even if it does show every once in a while.

The full AI code can be found here, if you care for that sort of thing!

Heatmaps

Heatmap, the main technique utilized, simply stores values in an extra tilemap (int array!) for spatial information evaluation. In this case the heatmap stores threat and support values used in choosing the AI attack target and movement path.

Pic2Small

Heatmap visualization

The recursive heatmap function is called for each enemy and ally on the map

Threat evaluation

Calculating the threat (and support) values is a cinch: Add up the probable averages of all usable weapon types of your allies and enemies. There is a bit of quess work involved if the enemy ammo counts are not known already.

 

┬áNothing out of ordinary here I’d hope

Panic!

New feature alert! Taken that we already have threat values for each group and location data about safe areas, we might as well have a bit of fun with them! Every time a group gets into a fight its support value is compared to the threat level around it. A high enough difference will send the group in panic, running away from enemies and finally fleeing if reaching the level border. Now you can bully your enemies to submission!

PanicCalculation_

Panic also ensues if the total enemy force is overwhelming, but that is checked elsewhere

Conclusions

Simple and seems to work alright. In the next project I’ll be using Monte Carlo Tree Search, no doubt about that. It is much less work with potentially more intelligent results. Working on a generic version at the moment.

Play it here!

PS:

seththefirst suggested taking a look into AI utility functions in part 1 . The threat level comparison turned out to be sufficient so I didn’t implement anything like it, but maybe you (yes, you!) will find it useful.

Desert Strife Jam AI (with code examples!)

Posted by
Tuesday, September 6th, 2016 3:14 am

TL:DR KISS

The Post-Jam version is still far away (I’ve hardly had any time to work on it yet) so I might as well talk about the AI of the Jam version and the plan for the Post-Jam AI.

Version one

The first version of the AI was finished in the morning of the second day. It had one goal and one goal only, EXTERMINATE! In simple terms each unit finds the closest enemy and moves towards it. They also check that the path to the enemy is not blocked, by simply finding a path to it. This could cause slowdown with bigger maps and larger unit counts, but here it is just fine and dandy.

VIEW CODE (embedding doesn’t work unfortunately…)

Version two

So far the AI doesn’t take into consideration the main mechanic: scavenging technology. Implementing such behaviour, the quick and easy way, requires nothing more than adding technology distance checking into the previous code. If there’s technology closer to the unit than enemies, then that is what the unit will go for. On top of this the unit won’t move until it has completely excavated the technology.

VIEW CODE

Version three

I could have stopped here, but there was an annoying deficiency in the artificial thought process. The units don’t prioritize actions; In other words, an attacking unit is sometimes blocked by a scavenging unit.

The fix is slightly more elaborate than the previous step, but by no means complicated: tally up the best actions from all units and choose the most important one based on the target type and distance. Here’s the final AI in action.

NEW STUFF!

VIEW CODE

The future?

There are still a few things I’d like to implement in the AI, namely threat assessment and intelligent positioning. As luck would have it, there’s a single technique which can be used to achieve both of these goals: heatmaps! A heatmap is simply an extra tilemap which contains values based on unit proximity and threat level (if you are lazy you can even reuse the world tilemap objects for this purpose). Heatmaps can be used in selecting the target (lower threat value is preferred) and in pathfinding to choose the safest route to the target.

Conclusion

Keep it simple and you’ll go surprisingly far.

Play Desert Strife here

Transformagician – Performance Optimization

Posted by
Saturday, April 23rd, 2016 3:16 am

The jam is over, the entry turned out great and the WebGL build (which most people are going to play) runs quite badly. What to do? Optimize!

Identifying the problem

When trying to improve performance you should always go for the elephant in the room. In most cases (including this one) taming the alpha male is enough. Run the profiler on the target build and see what is up (milliseconds) and what is down (framerate!). Let’s look at the rendering performance of the following scene.

Image 1: Benchmark scene

Figure 1: Rendering performance in Unity editor

Not bad! The deferred renderer does a pretty good job at batching drawcalls.

Figure 2: Rendering performance in WebGL build

Very bad! The WebGL build seems to fall back to forward rendering before a deferred lighting pass. Maybe this is why the batching is botched, I’m not quite sure, but there most certainly is a drawcall problem.

Solving the problem

One solution immediately springs to mind: Mesh.CombineMeshes. After some modifications the script works like a dream.

The walls in the scene are combined into a single mesh and the floors into another. As long as all the meshes share the same material there will be no trouble and the combined mesh looks just like a bunch of individual objects.

The only difference being a drastic reduction in draw calls. Let’s see just how drastic we’re talking about here:

Figure 3: Rendering performance in editor (with MeshCombine)

Mere three times faster… I think we can do better.

Figure 4: Rendering performance in WebGL build (with MeshCombine)

Fifteen times faster! I rest my case.

Conclusion

Use the profiler, identify the worst offender, smite it and rejoice. There are further optimization I could do, but why bother. At this point it’s already an effort in diminishing returns.

Getting less than 60 frames per second? Time to look in the mirror and get to work!

[cache: storing page]