Gaming for the Original SWBF1 and SWBF2/other games => The Walking Dead Campaign by Phobos Public Board => Topic started by: Phobos on June 28, 2016, 03:22:55 AM

Title: SWBF Engine Limitations for TWD Mod
Post by: Phobos on June 28, 2016, 03:22:55 AM
Star Wars Battlefront - Client/Server Engine Limitations
The modification of zombie behavior is one of the biggest SWBF limitations, as AI behavior programming is hard-coded into the game EXE, which the modding community does not have the source code for. So this means zombies will flinch from grenades and other 'delayed explosives', and will chase command post objectives rather than hunting down players from a distance. This is perhaps one of the biggest limitations of the mod concerning zombie survival realism, but the structure of each mission is being optimized in a way that balances out the bugs as much as possible with other gameplay elements.

In more detail: there are several limitations in the SWBF Zero Engine that can't be changed, unless either
- Psych0fred released the source code for Star Wars Battlefront v1.2, which he told us is not possible
- An advanced hacker/modder figured out a way to modify the memory or discovered a hex edit to fix the limitations

There are 6 main limitations which cause bugs with the realism of The Walking Dead mod's gameplay.
1) AI are programmed to suicide after ~15 minutes of being spawned if their reinforcements are below a certain threshold. This means for example on boss maps if you just hide in a glitch and speedhack or go AFK, the game will give you a cheat win.
2) AI always flinch and stop attacking from certain weapon classlabel, such as "sticky" and sometimes "melee". Sticky is used for grenades, molotovs, and other delayed explosive weapons. Zombies should not flinch from anything so this is an annoying bug.
3) Only 2 AI on your team can follow you at once. Although you can command more to stand still, or get in a vehicle, they won't always stay in the vehicle (as noted below)
4) SWBF AI are programmed to instantly exit vehicles and go for command posts after your team drops below 25 reinforcements. The AI will forcibly auto-evacuate every vehicle at this point. If you command them to get back in, they will continually exit as soon as they enter.
5) AI cannot be coded to target players from any distance unlike in most other zombie games. This should be possible in theory with the source, by assigning the code AI use for targeting command posts to enemy units instead.
6) The model memorypools for units are quite low in MP, they are higher in SP but still limited. This means most units will be invisible at long range when dozens of zombies are spawned at once, and this handicap is much more noticeable in the server. Zombies units without true low poly models might be removed if this is too much of a problem.
6B) The sound memorypools are also low for SP and MP, due to this several zombie classes must be 'silent' or groan only when attacked/targeting enemies, or else other sounds such as gunshots and tactical voiceovers get muted.

1) No workaround discovered yet: Adding extra henchmen to protect the main enemy boss still won't protect the boss from suiciding after ~15 mins once the reinforcements are below 25
2) Partial workaround: Explosives such as molotovs/grenades can be changed to another classlabel for instant explosion, but they won't throw with the same special curved angle as the stock grenades.
3) No workaround discovered yet
4) Partial workaround: Higher reinforcements added for some maps that require AI to use vehicles, along with 4 playable main characters that spawn once there would be a henchman/soldier class.
5) No workaround discovered yet
6) No workaround discovered yet: Gistech has spoken with Psych0fred about ideas for possible hex-edit based workarounds. I think Gistech is still investigating possible solutions.
Title: Re: SWBF Engine Limitations for TWD Mod
Post by: Gistech on June 28, 2016, 05:23:36 AM
As it was explained to me, the model memory appears to be set several times within the source code itself suggesting more than one memory pool. It seems there are two limits. The first is a lower limit which appears to be 16MB. This 'lower limit' is what triggers the model flips to low-res. The higher, absolutely-must-not-be-breached limit appears to be 32MB.

If this is of any use to you, here is what I got sent:

There are many memory pools set at various point throughout the gameand in different files. The best I can figure is the 16 and 32 represent the integer size of the value. For example:

Code: [Select]
uint16 mCount; // Count in pools
uint16 mBin; // which bin it is, byte size = (mBin << BIN_SIZE_SHIFT)
uint32 mTotal; // Total count (may be higher than pool count)

These are set and reset many times throughout the game.

There was a file called GameMemory.cpp which specified memory allocations at various points in the game (boot, entering shell, metagame, levels, gamespy, etc.  Here's some snippets that may help.

Code: [Select]
namespace GameMemory
         // Setup function, should be called only once. Sets the ranges for
         // memory usable by the game.
         extern void InitApplicationMemory(char *arenastart, char *arenaend);
         // [Re]builds the various heaps usable by the game. Should be done
         // each time on entering shell/mission. bForShell is a hint that the
         // shell is going to be used next.
         extern void BuildHeaps(bool bForShell);
         // Frees the temporary load memory. Should be done at end of load,
         // and the temp heap MUST be free.
         extern void ReleaseTempHeap(void);
         // For building/releasing the Temp gamespy heap
         extern void BuildTempGamespyHeap(void);
         extern void ReleaseTempGamespyHeap(void);
         // Returns whether it's allocated or not.
         extern bool IsTempGSHeapAllocated(void);
         // ------------------------- Varbs
         // Permanent memory. Shouldn't have allocations/deallocations after
         // initial boot.
         extern RedHeapHandle ApplicationHeap;
         // Memory for Gamespy (if appropriate). Not blasted between shell and
         // game
         extern RedHeapHandle GamespyHeap;
         // Memory for Gamespy (if appropriate). Used as a temp place for
         // server browsing.
         extern RedHeapHandle TEMP_GamespyHeap;
         // Memory for Lua. Larger in the shell (where we do more)
         extern RedHeapHandle LuaHeap;
         // Main block of memory for items
         extern RedHeapHandle RunTimeHeap;
         // Main block of memory for artist's items (terrain, textures, models)
         extern RedHeapHandle ArtistHeap;
         // Temporary memory for loading. MUST be empty at end of load, released
         // into RunTimeHeap at the end of the load
         extern RedHeapHandle TempLoadHeap;

const uint32 GAMESPY_HEAP_SIZE        = 2 * 1024 * 1024; // lots, just because we can
const uint32 GAMESPY_BROWSE_HEAP_SIZE = 0 * 1024; // part of regular heap!
const uint32 APPLICATION_HEAP_SIZE    = 15 * 1024 * 1024 + 256 * 1024;
const uint32 SHELL_LUA_HEAP_SIZE      = 16 * 1024 * 1024; // Lots for modders
const uint32 GAME_LUA_HEAP_SIZE       = 16 * 1024 * 1024; // Lots for modders
const uint32 TEMP_LEVEL_HEAP_SIZE     = 2 * 1024 * 1024; // for loading
const uint32 ARTIST_GAME_HEAP_SIZE    = 8 * 1024; // NOT USED on PC/XBOX
const uint32 ARTIST_SHELL_HEAP_SIZE   = 8 * 1024; // NOT USED on PC/XBOX

You may also want to look for gArenaStart and gArenaEnd and arenastart and arenaend.

Code: [Select]
void GameMemory::InitApplicationMemory(char *arenastart, char *arenaend)
         gArenaStart = arenastart;
         gArenaEnd = arenaend;
         gArenaStart = (char *)RedInitHeap(gArenaStart, gArenaEnd, MAX_REDMEMORY_HEAPS);
         if(ApplicationHeap) {
                 ApplicationHeap = 0;
         // allocate defined application memory
         char *LevelHeapstart = gArenaStart;
         char *LevelHeapend   = LevelHeapstart + APPLICATION_HEAP_SIZE;
         ApplicationHeap = RedCreateHeap(LevelHeapstart, LevelHeapend, 16, "Application");
         // allocate Gamespy memory
         GamespyHeapstart = LevelHeapend;
         GamespyHeapend   = GamespyHeapstart + GAMESPY_HEAP_SIZE;
         GamespyHeap = RedCreateHeap(GamespyHeapstart, GamespyHeapend, 16, "Gamespy");
         gAppHeapEnd = GamespyHeapend; // store where available memory lies.

These are just two fragments of many functions that manage memory.