Author Topic: OP2 Scenario Project for C#  (Read 15092 times)

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #75 on: April 15, 2019, 02:48:18 AM »
Hmm. I went back and checked, and Tethys::GetRand works fine. Must have been really bad luck the handful of times I used it. Like flipping heads 15 times in a row... I have no idea.

Offline lordpalandus

  • Hero Member
  • *****
  • Posts: 770
Re: OP2 Scenario Project for C#
« Reply #76 on: April 15, 2019, 10:58:16 AM »
I use random number generation a lot in the video game I'm making, so some possible reasons it is returning 0:

1. You improperly set up the array / vector, so it is using an empty array/vector. Random number of 0 between the size of the array/vector would be 0, so it will always return 0.

2. It is choosing a random number as a float, and converted into an int. If the random number was 0.9, in floats that is nearly 1, but when converted to int it becomes 0. Some round up, some round down.

3. Some random number generators, like the one I use, utilizes different streams. If your random number generator requires a specific stream, that could be the issue.

Otherwise:

We will need to see what code you are trying to execute to provide more detailed assistance. Just because there is no syntax error, doesn't mean there isn't some unintentional logic error. Without the code in question, it is really hard to say.
Currently working on Cataclysm of Chaos, Remade.
Link to OPU page = http://forum.outpost2.net/index.php/topic,6073.0.html

Offline leeor_net

  • Administrator
  • Hero Member
  • *****
  • Posts: 2205
    • LairWorks Entertainment
Re: OP2 Scenario Project for C#
« Reply #77 on: April 17, 2019, 09:38:41 PM »
Gonna go out on a limb and assume the core code is just using a really shit PRNG. Haven't looked too far into it but I'd suggest using literally any other PRNG than whatever OP2's engine provides (unless for some reason mission DLL's must use that function as Hooman has suggested).
« Last Edit: April 17, 2019, 09:40:27 PM by leeor_net »

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #78 on: April 19, 2019, 01:11:28 AM »
Again, I don't know what happened. It's possible I coincidentally fixed some code the same time I swapped it out for C# Random. Tethys rand appears to be working, so I will leave it as is. It's easy enough to change the wrapper function to C# random later if needed.

---

I have need of accessing a lab's data for labor reassignment. Unfortunately, it appears that the lab variable addresses overlap the "bayItem" array, which are represented by different sizes. It's not simply a variable naming issue.

I assume then, that I need to put a union in here to make this work. Rather than hack a union in at that spot, what address marks the end of the base class and the beginning of each sub type?

Or am I approaching this entirely wrong?

--It just occurred to me while posting in another thread that instead of a union, I could create a separate struct and offset the address similar to how BeaconData is done. I will give this a shot.
« Last Edit: April 19, 2019, 01:36:10 AM by TechCor »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4798
Re: OP2 Scenario Project for C#
« Reply #79 on: April 19, 2019, 01:37:14 AM »
Correct about the union. Each unit type may have it's own specific unit related fields. That will make the non-common fields appear to overlap in memory, reusing the same offsets.

We don't have clear picture of the entire unit hierarchy, or how big each unit record is. We know a handful of them, and have some general sense of parts of the unit hierarchy, just not the full info. This is one of our long standing ToDo items.

In SVN: OllyDbg/InternalData/DataStructure Unit.txt, you can find many pieces of known memory layouts. Where base classes and hierarchy relationship are known, they are marked. Where the constructor sets a different set of flags (offset 0x44), they are marked. The meaning of flags may be dependent on unit type, and isn't fully detailed or separated out by unit type, though many details are known. Similarly which offsets and fields belong to which unit types or base types isn't fully worked out. The hierarchy has multiple levels, and is a bit lopsided, so there are many sizes and offsets involved in the unit structure breakdown. Many details are known about what values can be found at what offsets. It's the breakdown of those fields and offsets into unit types and base types that is lacking.

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #80 on: April 24, 2019, 01:29:28 AM »
I ended up going with a LabData struct with a direct pointer to the first variable's address.


Base, Labor and Research management are all at a nice first draft. Currently going through now and fixing bugs and adding extras such as DIRT, geocon, and magma well handling. Then I'll move onto task priorities, customization and finally combat management.

Looking forward to doing real world tests in the next month or so.

---
I really want to get this unit stuck bug fixed, so I no longer need to "help" the AI occasionally.

I'm thinking the best way is to find out where the unit is trying to move. If I knew that, I could check if it is occupied. Is there a way to get the adjacent tile that the unit is trying to move into? This would be different from its final destination. Then I could check if there is something in the way, and how to handle it.

The other "stuck" situation seems to be due to a bug in "UnloadCargo". 1 in 50 times, UnloadCargo will fail to trigger, and can't even be triggered manually in the agridome or smelter pane despite *not* being grayed out. I can't seem to figure out the pattern, but I've yet to see it happen while only a single cargo truck is trying to dock at the same port, making me think it happens when another truck is trying to push the one on the dock off. The truck on the dock reports "moDone", but building.UnloadCargo() is ignored. This bug is only an issue for Land Rush type games where you need to unload food and metals. Ore doesn't require UnloadCargo(), and therefore the bug never happens there.

Offline Crow!

  • Jr. Member
  • **
  • Posts: 70
Re: OP2 Scenario Project for C#
« Reply #81 on: April 24, 2019, 06:45:47 AM »
I've had the inability to unload cargo in the normal game from time to time.  The best way to fix it I've found is to order the truck to move onto the dock again, even if it's already on it.
Speedruns, my FFIV game randomizer, and more can be found at my twitch page:
https://twitch.tv/iicrowii

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #82 on: April 24, 2019, 03:44:05 PM »
Yes, it seems issuing any command to the truck will resolve it. The issue is detecting that the problem is happening in the first place.

I'm thinking maybe adding a timer linked to the unit index to determine if they have been on the dock idling too long. Maybe a tenth of a second with "moDone" is all that is needed to determine that it's "gone bad". Not as elegant of a solution as I was hoping for, but any fix is better than no fix.

This solution might work for the movement problem as well, if pixelX/pixelY is a reliable way of telling if a unit is moving.

EDIT:

Checking for "spinning wheels" and waiting 200 ticks before issuing a stop command seems to work. Wish this kind of handling was built into the engine, but whatever.
« Last Edit: April 24, 2019, 07:43:13 PM by TechCor »

Offline Arklon

  • Administrator
  • Hero Member
  • *****
  • Posts: 1225
Re: OP2 Scenario Project for C#
« Reply #83 on: July 11, 2019, 08:48:13 PM »
Has this been progressing lately?

The Python project has been slowly coming together, though as of late a combination of real life and making the mistake of getting Factorio has been getting in the way. Still, it is very close to being ready for 1.0 release - if we get back to crunching it like we were before, it'd be maybe a month or a couple months of work left. And seeing Factorio has given us ideas for how to improve OP2's mod system, but that will most likely be post-1.0.

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #84 on: July 15, 2019, 10:22:29 PM »
Hey,

The project stalled out as I needed to focus on getting work and making the monies. Things are starting to look good now. Perhaps too much work. ;) Let's not mention Anno 1800 is on my play list. I should be back on this project next month.

AI needs its CommandGrid optimized, some other Building AI related odds and ends, and the offensive strategies implemented.

These are nice things to have, but the SDK is plenty capable of full mission development. Check out the original post for things that are still missing that are in the C++ SDK - mostly minor stuff.
--

For the mod to support C#, these are the functions that need to be called. Pretty much what you would expect.

https://github.com/TechCor8/OP2DotNetMissionSDK/blob/master/NativeMissionSDK/DotNetInterop/CppInterface.h

Then you can tell me what extra functions you need to support registering the scenario parameters or other extended features.

--
As an aside, if anyone has a wishlist, feel free to add it here. I will look into it. If someone asks about something, it will get higher priority.

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #85 on: July 31, 2019, 09:58:25 AM »
Is it possible to modify the tile map at run-time? Or perhaps inject a map file at DLL init?

It would be nice to bypass the need for an external map file.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 899
Re: OP2 Scenario Project for C#
« Reply #86 on: August 01, 2019, 12:12:36 AM »
TechCor,

Yes it is possible. It is typically done during mission startup (initproc). I've never attempted it outside of initproc though.

Try these functions.

Code: [Select]
GameMap::SetCellType(loc, CellTypes::cellRubble);
GameMap::SetTile(loc, changeSet.ReplacementTileID(TethysGame::GetRand(changeSet.ReplacementTileRange())));

Example code that creates destroyed buildings on map startup by changing cell types and tiles:
https://github.com/Brett208/OP2MissionEvacuationUnderFire/blob/master/RubbleMaker.cpp

I suspect Outpost 2 only supports loading maps through standalone files or from volume (vol) files. We typically pack all the maps for a release into maps.vol so they do not clutter the directory.

I guess it could be possible to hook into the Outpost 2 code and change the default behavior to allow loading maps through other streams or something.

Hope this helps,
Brett

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #87 on: August 01, 2019, 11:57:59 PM »
Thanks.

I know about those functions, but I didn't realize you could set the tile to any graphic simply by changing the index. The Map internal data seems to indicate some kind of Tile Source. This will be useful later.


Update on AI Combat.

Added the CombatManager which requests and populates CombatGroups with military units. The BaseManager receives the requested list of units required to fill the groups and builds them.

Also added a PlayerStrengthMap which calculates the total damage each player can generate on a tile given their current units' positions and weapon ranges. This map will be used to help the CombatGroups navigate in and around enemy units without taking fire, as well as determining the combat strength required to overtake an area. This map accounts for both enemies, self and allies, so that it can make a well-informed decision.

I will be adding a PlayerUnitMap tomorrow, which will be used in conjunction with the strength map to detect the closest vulnerable buildings and units to CombatGroups.

Both of these maps get run through the A* pathfinder as "tile cost".


The final architecture of the combat AI is starting to take shape. Management will be split into two major components.

First, the CombatManager will generate a list of objects called "ThreatZones". These zones represent different areas on the map that require CombatGroups to move into them. Zones are generated for things like enemy units attacking allied structures, vulnerable structures and units, and enemy convoys/combat groups. The zone tracks important information such as the combat strength required to eliminate the threat and the relative importance of the zone.

The CombatManager will then assign CombatGroups to ThreatZones based on the group's type and distance to the zone, the importance, and the strength required (only send as many groups as needed). Groups will use the maps/pathfinder to find the safest path to the ThreatZone.

For the second part, when a CombatGroup enters a ThreatZone, the group's combat tactics kick in. Basic tactics that apply to all groups are things like avoiding combat when the group's strength is lower than what is detected on the PlayerStrengthMap. CombatGroups with specific tactics will engage in their specific targeting and movement procedures when in close proximity to enemy units, or are otherwise in the ThreatZone.

CombatGroups will stay in or near a ThreatZone until the importance drops, or the threat (and ThreatZone) is completely eliminated.

Hoping to have a first draft ready for GitHub in a week or two.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 899
Re: OP2 Scenario Project for C#
« Reply #88 on: August 02, 2019, 05:15:50 PM »
The AI Combat system sounds robust and flexible from what you describe.

You should be able to set to most any graphic. A few may cause problems like if you wanted to set a middle animation in a lava flow as I haven't tested things like that. As long as you are setting reasonable tiles though it should be okay.

-Brett

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #89 on: August 04, 2019, 01:52:50 AM »
EDIT:
Cleaned up to summarize problem.
  • Player.HasTechnology() has a random chance to throw an access violation on the first update frame.
  • Exception is thrown on the first call to HasTech (any player).
  • Value passed to HasTechnology is 1 (techID). Have not tried other values.
  • If the exception is not thrown on the first frame, mission runs fine (30+ minutes run-time).
  • Skipping the first update will cause it to happen on the next one.

Exception thrown at 0x00472D78 in Outpost2.exe: 0xC0000005: Access violation reading location 0x080D4F63.

On subsequent runs, thrown address stays the same, read location changes, so it is the same fail point every time in HasTech.

Test code used to simplify the error:
Code: [Select]
public void Main.Update()
{
/* First thing called on the first update frame after mission init.
   Will crash inside Outpost2.exe::HasTechnology()*/
TethysGame.GetPlayer(TethysGame.LocalPlayer()).HasTechnology(1);
}
Any help appreciated.


***
Elsewhere in the remote world of Outpost 2 coding...
***
UnitInfo.GetOwnerFlags returned "Both Colonies" for map_id.laser. Is there a correct way of determining if a player can build a unit? Right now I have Eden producing RPGs. I supposed I could hard-code a list...
« Last Edit: August 04, 2019, 06:43:35 PM by TechCor »

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 899
Re: OP2 Scenario Project for C#
« Reply #90 on: August 04, 2019, 05:42:09 PM »
TechCor,

I'm not sure what to say about the HasTechnology bug.

If you are having trouble determining which colony a weapon belongs to, check out:

https://github.com/OutpostUniverse/OP2Helper/blob/master/ColonyType.cpp

I'd be willing to expand this file's functionality if you needed it presented in a different manner. Again, not sure about the underlying bug, but in this case might be easier just to use OP2Helper.

-Brett

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #91 on: August 04, 2019, 07:03:40 PM »
I feel dumb now.

I just realized GetResearchTopic() returns the TechIndex, not the TechID (which is what HasTechnology uses). Arklon told me this before, and I did it right in code older than last week.

Need to add some comments about this...

Ran it 50 times and it didn't crash, so I'm going to call this fixed.

--
Since GetOwnerFlags doesn't work right, and OP2Helper is the recommended solution, I will replace GetOwnerFlags with a hard-coded list of colony types.

I can't really use OP2Helper directly because it is in C++, and interop would add unnecessary overhead. It's much easier to reimplement OP2Helper functionality in C#. That's the best option for anything open source that doesn't interface directly with Outpost2.exe.
« Last Edit: August 04, 2019, 10:33:51 PM by TechCor »

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #92 on: August 06, 2019, 02:38:39 AM »
First draft of Combat System is now on GitHub. AI has the combat strategy of a cockroach, but it's a start.

The mission is set to start with 2 bots in Land Rush, 1v1. It was fascinating to watch, especially since the combat does not work as expected. I watched until there were too many units and the pathfinder slowed the game to a crawl. Yeah, gotta find some way to optimize without causing desync for multiplayer.

With base management, I can actually see what the AI is doing, but the combat system is so abstract it's an enigma. Is there a way to render rectangles and lines on the map so I can see zones and paths?

EDIT:
Made a workaround by creating/destroying markers at zones and path destinations.

Turns out the vehicle pathing had some bugs.

80% of the performance problems are coming from the pathfinder, and the algorithm is as fast as I can make it. Going to move pathfinding to a thread pool and use an "execution tick" set to a few ticks into the future. If the pathfinder finishes early, it waits for the "execution tick", if it takes too long, it blocks on the "execution tick".

For the moment though, going to try to improve attack strategy.


UPDATE:

Added an AsyncPump that delays execution for any tasks by some amount of TethysGame.Time(). This has been integrated into the Pathfinder. Already seeing substantial improvements in performance with one AI having over 60 combat units moving around without issue.

Not all SDK functionality has been made thread-safe, but I will add it to important classes. I haven't decided yet whether to lock the OP2 API (and the entire .exe), or instead flag those functions when calling from off the main thread. Locking the entire executable might be a significant bottleneck that async support for the OP2 API may not be worth it. In most cases, you can simply perform calculations in the worker thread, and call the API when it completes on the main thread.

Now that is out of the way, going to start improving combat strategies. I already see some problem points. In particular, there is an over-reliance on bombers. While one AI did achieve victory-by-starflare, it was quite a slow way of doing it.

EDIT:
It occurred to me that thread safety is not enough. A Time() desync will occur if, say, the PlayerUnitMap updates while in the middle of pathfinding. Instead of locking classes, I'm going to create a StateSnapshot class that captures the game state at a particular TethysGame.Time() as an immutable object. While more memory will be used, locks will no longer be necessary outside of the AsyncPump, and it is easier to use since all async code will rely on the StateSnapshot. Then later I will add asserts to everything else to prevent use outside of the main thread.
« Last Edit: August 13, 2019, 10:50:41 PM by TechCor »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4798
Re: OP2 Scenario Project for C#
« Reply #93 on: August 16, 2019, 08:27:07 PM »
This is getting pretty interesting.

Any chance of time lapse videos of AI versus AI?  :)

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #94 on: August 18, 2019, 02:45:21 PM »
Major Update
I've finally completed the transition to StateSnapshot. This has resulted in a major overhaul of pretty much every part of the mission SDK. Some might call it DotNetMissionSDK version 2.0  ;).

State Snapshot
I needed an immutable, threadsafe state that could be used for AI async processing. Using the live Outpost2 state was not going to cut it.

Behold, StateSnapshot. This is the cornerstone of this update.

StateSnapshot is an immutable class object that is generated at the beginning of every frame. This object contains a wealth of read-only OP2 state information including easy to access player/gaia data, unit lists, unit info, and generated maps.

Units and UnitInfo have been broken into separate derived classes so that it belongs to its correct type. For example, you cannot access objectOnPad from a convec, you must use the SpaceportState object.

The snapshot never changes and exists until garbage collected, which is perfect for performing async operations over time without locks and while maintaining predictability.

Accessing data looks like this:
Code: [Select]
UniversityState university = stateSnapshot.players[0].units.universities[0];
if (stateSnapshot.players[0].commandMap.ConnectsTo(university.GetRect()))
    // university connects to a command center, do something

Game State
The static GameState class is the new access point for live data. The game state contains lookup tables for players and units. The idea is to use StateSnapshot to read data and perform calculations, and then access the live data with GameState when ready to issue commands and modify data.

Accessing and modifying data looks like this:
Code: [Select]
UniversityState university = stateSnapshot.players[0].units.universities[0];
if (stateSnapshot.players[0].commandMap.ConnectsTo(university.GetRect()))
    GameState.GetUnit(university.unitID).DoTrainScientists(Math.Min(stateSnapshot.players[0].workers, 10));

Async Pump
The static AsyncPump class allows for predictable multithreading.

When you want to run an async task, you call AsyncPump.Run from the main thread and pass the amount of TethysGame.Time() you want to wait to complete execution. The first callback parameter runs asynchronously, the second one is called from the main thread at the time requested. If your task finishes early, it waits for the target time. If the time is reached before the task finishes, the main thread will wait for it to complete.

Combined with StateSnapshot, you can achieve a predictable game state every time.

Accessing and modifying data asynchronously looks like this:
Code: [Select]
ThreadAssert.MainThreadRequired();

if (m_IsProcessing)
    return;

m_IsProcessing = true;

AsyncPump.Run(() =>
{
    List<Action> actions = new List<Action>();

    // Do async tasks
    UniversityState university = stateSnapshot.players[0].units.universities[0];
    if (stateSnapshot.players[0].commandMap.ConnectsTo(university.GetRect()))
    {
        // Add command to list for processing on main thread.
        // The ? in the command checks if unit is null before executing DoTrainScientists.
        // GameState.GetUnit will return null if the unit has been destroyed.
        // This may happen due to the Time() difference between the snapshot time and when the command is finally executed.
        actions.Add(() => GameState.GetUnit(university.unitID)?.DoTrainScientists(Math.Min(stateSnapshot.players[0].workers, 10)));
    }

    return actions;
},
(object returnState) =>
{
    m_IsProcessing = false;

    // Execute all completed actions
    List<Action> actions = (List<Action>)returnState;

    foreach (Action action in actions)
        action();
});

Thread Assert
ThreadAssert.MainThreadRequired() is used on various methods to prevent access from async tasks. This helps prevent desync and access violation related issues from multithreading. In other words, these methods are not "thread-safe".

AI Performance
With the new systems above, AI now has a lot of wiggle room when it comes to performance.

First, AI no longer has to perform a complete update on every frame, instead performing its updates over several frames/TethysGame.Time().

Second, AI is now almost entirely performed on separate threads. Each AI manager performs an async update, putting all of its unit commands into a list, which is then executed on the main thread's completion callback.


Upcoming
  • Fixing some AI regression from the new changes, including activating async mode on BaseManager.
  • Finishing ThreadAssert for OP2 API.
  • Breaking up the "god object" UnitEx class.
  • Tons of other AI related tasks from before.


Will post a video of the AI soon for the lazy.  :D

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4798
Re: OP2 Scenario Project for C#
« Reply #95 on: August 19, 2019, 01:47:38 AM »
I'm curious, isn't there a noticeable performance impact when creating snapshots every frame?

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #96 on: August 19, 2019, 02:37:12 AM »
I mean, yes, it does come at a small performance cost, but it is negligible compared to the gains.

A lot of calculations and loops are eliminated by being able to iterate over exactly what you want as opposed to iterating the entire player unit list to find cargo trucks, then again later for convecs, etc. Also, there is room for compiler optimizations now that it is not performing interop for every bit of data access.

Performance Benchmarks
Snapshot time recorded with StopWatch. There are 6 bots building with full tech, all morale buildings satisfied, and combat units. DLLs are set to release mode. Hardware is an AMD Ryzen 5 1600X Six-Core processor.

128x128 map (on6_01.map)
1 ms - Game Start (Land Rush)
2 ms - Mid Game

512x256 (newworld.map)
8 ms - Game Start (Land Rush)
9 ms - Mid Game

Total CPU Breakdown - 512x256 (newworld.map)
27.47% - StateSnapshot
: 18.9% - TileMap > 13.53% - GetCellType > 11.45% P/Invoke
: 7.46% - PlayerState > 5.19% - CommandMap

Mid Game screenshot for reference



Optimization Update
TileMap is now copied entirely on the C++ side in one method call. I couldn't figure out WTF HFL was doing, so it still makes a hundred thousand native function calls, but it is much faster now. Also removed an unneeded clear from PlayerCommandGrid.

512x256 (newworld.map)
1-3 ms - Game Start (Land Rush)
2-3 ms - Mid Game

Mid Game Total CPU Breakdown
12.39% - StateSnapshot
: 6.16% - TileMap > 6.16% - CopyTileMap
: 5.78% - PlayerState > 3.12% - CommandMap > 2.89% - Pathfinder::GetClosestValidTile


Garbage Collector spikes have been eliminated by pooling the top-level StateSnapshot and retaining the maps, opting to clear and reuse instead of reallocating. Inlined HFL method calls in CopyTileMap. PlayerCommandMap has now been merged for all players to a single map, and building processing for it has been delegated to PlayerUnitMap.

512x256 (newworld.map)
Game Start (Land Rush)
0-1 ms - Create
0-1 ms - Release

Mid Game
1-2 ms - Create
0-1 ms - Release

Mid Game Total CPU Breakdown
8.7% - StateSnapshot
: 7.53% - Create
: : 3.44% - PlayerState (All constructors)
: : 2.8% - PlayerCommandMap > 2.8% - Pathfinder::GetClosestValidTile
: : 0.82% - TileMap/CopyTileMap
: 1.17% - Release

Release mode appears to optimize the Create process, so constructors are probably over-represented in the CPU breakdown.
« Last Edit: August 20, 2019, 01:27:56 PM by TechCor »

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #97 on: August 20, 2019, 01:45:13 PM »
Hey Hooman,

Is this enough optimization for ya? Took like 12 hours. I'll send the bill in the mail. ;)

Performance of StateSnapshot is 3-9 times faster, and GC spikes were eliminated.

I bet I could optimize CopyTileMap some more if I could figure out the format to switch from double nested loops to memcpy, but it is a micro-optimization at this point.

1/3 of the cost is from calculating the command map for all players mid-game, so I'd say it's pretty well optimized.

Offline TechCor

  • Jr. Member
  • **
  • Posts: 64
Re: OP2 Scenario Project for C#
« Reply #98 on: August 21, 2019, 08:07:46 PM »
Here's a quick video for 6 bot Land Rush FFA with Tech Level 13.

Outpost 2 AI Test or: How I learned to Stop Worrying and Love the Starflare


Still a lot of work to be done:
Research priorities, earthworker should complete tubes it starts, prioritize defense when enemies have combat units, combat priorities, ESG attacking buildings, etc, etc.

The infrastructure is there, however, and doesn't have any noticeable slowdowns.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 899
Re: OP2 Scenario Project for C#
« Reply #99 on: August 22, 2019, 06:23:08 PM »
Hey, looks pretty good. It looks like you are using the different waypoints to mark AI points of interest for debugging?

I am impressed by the progress!

What is the requirement for this to be embedded in a mission. Is it just the DLL? Does the DLL require a specific .net framework available to work?

-Brett