Playing Tribes 2 with 120 bots.

Essentially, I was bored and wondered what would happen if you circumvent the hard coded bot count maximum of 64 in Tribes 2. The result is the video below:



You pretty much just need to patch 5 bytes at 0xA9DD8 of a TribesNext executable to 0x9090909090 which NOPs out the CALL instruction to actually trigger the game halt.

Comments

  • Thanks for the news.
    Maps would require serious rework for handling that many bots, but good news to have for what we do.
  • Is that address supposed to be an offset? Because it doesn't look right.

    0x401000 + 0xA9DD8 = 0x4AADD8 = between functions

    Did you get that address from HIEW or something?
  • Is that address supposed to be an offset? Because it doesn't look right.

    0x401000 + 0xA9DD8 = 0x4AADD8 = between functions

    Did you get that address from HIEW or something?

    It's the offset from the beginning of the file in pretty much any hex editor. I'm rather new to all this so excuse me if I wrote that wrong.

    After locating this in IDA, I found the offset that could be used in a hex editor (I used Bless' go to offset function) as it seems IDA's and Bless' locations were not matching.
  • It's the offset from the beginning of the file in pretty much any hex editor. I'm rather new to all this so excuse me if I wrote that wrong.

    After locating this in IDA, I found the offset that could be used in a hex editor (I used Bless' go to offset function) as it seems IDA's and Bless' locations were not matching.
    I opened Tribes2.exe in HIEW and did a Goto A9DD8 and it took me to
    .text:004AA9D8                 call    PlatformAssert__processAssert
    
    So I'm wondering (without testing) if changing the JGE @ 0x4AA9C8 to a JMP wouldn't accomplish the same thing.

    I don't use hex editors much. I've pretty much fleshed out an IDA database with comments and labels gleamed from comparing it to really old Torque source code, and when I want to patch something I do it in memory after using the Assemble function of OllyDbg to see what bytes I need to change.
  • I mostly just did by searching for the error message displayed and going through to figure out what triggers that error in specific and NOP'd out said call. I'm not entirely too great with assembly to do much more.
  • I once thought about making a T2 video to Smashing Pumpkin's cover of "Clones", using a ton of bots.

    There's probably more you could patch to increase the limit besides just NOPing out the call to processAssert that would make it more stable beyond 120 (which might just be a limit of your machine).

    I'm also curious what would happen if someone else tried to connect to your server that wasn't a local player, and how their unmodified client would react.
  • I've had a friend try it on his own machine the day I did it. Another friend and I was able to connect and play for a little bit but it crashed shortly after we were all in. This was probably due to choice of map, though, as I noticed I that RainDance was one of the maps that wouldn't crash when ran with 120 active bots rampaging everything. Others would induce a crash.
  • This is pretty neat but how many bots have nothing to do? I mean there's only so many tasks go around, and only so many escorts for tasks such as gen raping and capping and so on and so forth.
  • This is pretty neat but how many bots have nothing to do? I mean there's only so many tasks go around, and only so many escorts for tasks such as gen raping and capping and so on and so forth.

    Most of the bots are fighting each other over taking turns with the inventory stations, as outlined in the video. There'd likely have to be a modification built specifically to handle this much AI activity properly. This is assuming that the game is actually stable enough to operate with that many bots. The only known safe configuration is Classic on RainDance with 120 bots, potentially on a Linux machine as well with either WINE 1.4 or WINE 1.6.

    If the bots weren't clustering around inventory stations and were actually out in the field, you won't simply have an idle bot. You'll just have obscene amounts of bots performing the same task at once, such as defending the flag.
  • I have been playing around with the idea, and I still believe that simple map changes will be the only real thing needed after patching the CALL instruction. Granted, I still don't know how to do that or what is needed to.

    Lagg's V3 bots can do more tasks than the original bots, which means it's quite easy to give new and different objectives to all the new bots past 64. Specifically, the numerous vehicle flying/handling objectives can be easily filled by the new bots.

    The problem is that V3 bots don't have the ability to use multiple Vpads efficiently, if at all without other things breaking, so scaling a map like Katabatic to 120 bots with more vehicle usage wouldn't work. It is possible to have more bots doing specific foot patrol routes, sniping, deploying lots of items (pulse sensor map coverage), mortar and missile tasks. Some clever use of tasking can have bots act as mid-field flare deployers to cover bot shrikes and tanks.

    The other major problem is that V3 bots eat up more CPU, and it's already getting choppy on Katabatic RV with 64 on a stock i7 2600k. Tribes 2 doesn't make good use of multi-cores, so 120 bots would be unplayable from the CPU stutter. Would likely need any i7 OCed to 5+ ghz to get somewhere playable.

    120 bots without getting clogged up or stuck near invs can be solved with more invs (spaced specifically), spawn weights and zones, MPB usage, but will eventually hit critical mass for maps never designed for 64 players.

    The good news is maps remain serverside.
  • You simply get a hex editor, such as XVI32 and go to the address 0xA9DD8 in a TribesNext RC2A executable. Starting at 0xA9DD8, you are to overwrite the next five bytes with 0x90 in order to NOP out that call instruction. You know it worked when you can have at least 65 bots without the game giving you an error that looks something like:

    FATAL-ISV
    Out of Dynamic Graph Connections

    If you don't get this error, you are limited to however many bots the game can efficiently handle without being unstable. 120 bots seems to be okay on some maps but a lot of maps will crash. It's recommended you run a mod that has a more efficient corpse and item cleanup. Meltdown 2 for example keeps X corpses active and once you reach that threshold, it starts deleting the oldest corpses first.

    Though as I have noted, this was really only tested on Linux box that's running the game via WINE. There may be slight inaccuracies in how WINE is handling the game that's making this work at all. This can probably be tested with the Linux version of the game as the same patch could probably be applied, albeit at a different location from 0xA9DD8.
  • I apologize in advance for the double and necro post but I finally looked back into all this again and realized why the information I gave initially was wrong. The location I gave initially was a file offset. This should work if you don't want to patch the executable manually:

    memPatch("004AA9D8", "9090909090");
  • Handy.

    Currently looking at new-er Lagg code, but it doesn't run as problem free as I'd like. CPU stutter and device buffer overruns are a lil too common to get something enjoyable.
  • Handy.

    Currently looking at new-er Lagg code, but it doesn't run as problem free as I'd like. CPU stutter and device buffer overruns are a lil too common to get something enjoyable.

    It'd require further patching to eliminate the instability. The patch I gave just removes the 65+ bot count error.
  • One of the other problems is simply with TorqueScript and the engine itself. TorqueScript is "fast", but not optimally fast. There's been numerous topics of discussion over at GG regarding fixes and changes to the scripting language to optimize it, and others who simply wanted to axe it out in favor of a more standardized language, such as C#, Python, or LUA.

    The key problem is that it treats everything as a string, which almost any computer programmer can tell you isn't the fastest of things to work with. Were this functioning swapped out with a more type-friendly approach, things might run smoother. And then you also have the whole concept of JIT compilation which could handle the optimization for you, but TS isn't standardized to work that way.

    I think the only way to see a favorable result lies in Liukcairo's answer of further .exe patching, or by embedding new C++ directly into the .exe to handle the heavy lifting of the AI code for you.
  • I think the only way to see a favorable result lies in Liukcairo's answer of further .exe patching, or by embedding new C++ directly into the .exe to handle the heavy lifting of the AI code for you.

    If enough work was done to be able to provide a workable C++ interface then it should be possible to build some form of AI code into a replacement T2DLL.
  • I think the only way to see a favorable result lies in Liukcairo's answer of further .exe patching, or by embedding new C++ directly into the .exe to handle the heavy lifting of the AI code for you.
    If enough work was done to be able to provide a workable C++ interface then it should be possible to build some form of AI code into a replacement T2DLL.

    If someone were to do that, I'd just overhaul the existing system and use one of those free GG resources to install the Recast navigation system and T3D's AIPlayer class to the engine.
  • I think the only way to see a favorable result lies in Liukcairo's answer of further .exe patching, or by embedding new C++ directly into the .exe to handle the heavy lifting of the AI code for you.
    If enough work was done to be able to provide a workable C++ interface then it should be possible to build some form of AI code into a replacement T2DLL.

    If someone were to do that, I'd just overhaul the existing system and use one of those free GG resources to install the Recast navigation system and T3D's AIPlayer class to the engine.

    It'd take further hacking of the executable to overwrite the hardcoded AI routines (navigation, engagement, whatever happens in the background when you use %bot.stepEngage and such).

    The API I'm referring to would be to read the necessary data and invoke anything it needs directly since it's easily possible to invoke the functions that TS binds to without actually going through TS, all of which can be done without any modification to the executable beyond what it took to run custom C++ code. It's also possible to look at the asm for said TS functions and construct custom C++ routines that don't need to do any of the string -> number conversions to work.
  • Can't the t2 engine be threaded?

    "Thread management - utility classes for creating threads, mutexes and semaphores.
    Standard library functions - all standard library functions are redefined as dFuncname, for example sprintf becomes dSprintf, strcpy becomes dStrcpy, etc."
  • Can't the t2 engine be threaded?

    "Thread management - utility classes for creating threads, mutexes and semaphores.
    Standard library functions - all standard library functions are redefined as dFuncname, for example sprintf becomes dSprintf, strcpy becomes dStrcpy, etc."

    It's possible to run extra threads in Tribes 2 (it uses a handful of it's own, by the way) but I think it would be a bit difficult to get a stable multi-threading system that can work with arbitrary TS and any C++ code running.
  • T2 interpreter is single threaded with callback triggers. The entire language has been designed around that interpreter model. It's similar, in this way, to Javascript engines in web browsers. You can multithread in JS with WebWorkers, but you can only communicate between multiple WebWorkers and the primary execution context through message passing -- there's no simultaneous access support to the primary execution context.

    But, good god... just build a new engine at that point.
  • T2 interpreter is single threaded with callback triggers. The entire language has been designed around that interpreter model. It's similar, in this way, to Javascript engines in web browsers. You can multithread in JS with WebWorkers, but you can only communicate between multiple WebWorkers and the primary execution context through message passing -- there's no simultaneous access support to the primary execution context.

    But, good god... just build a new engine at that point.

    I agree. I just enjoy going back to the game every so often and making it do things that it wasn't meant to do. Nothing long and drawn out.
  • edited August 2014
    I played around since watching your inspirational video. I could not get it to correctly remove the bot limit when launching the game.

    However, I remembered the addbots(int); command and dared the game to UE on me.

    At least I was smart enough not to bet with a game that gets pleasure from people raging at a UE.


    Go to 19:30 if you're curious what 250 bots does to an i7 3770K clocked at 4.2 Ghz does... about the same as most of the computers, TGE is extremely stubborn.

    Edit: Youtube tags are stubborn.
  • I played around since watching your inspirational video. I could not get it to correctly remove the bot limit when launching the game.

    However, I remembered the addbots(int); command and dared the game to UE on me.

    At least I was smart enough not to bet with a game that gets pleasure from people raging at a UE.


    Go to 19:30 if you're curious what 250 bots does to an i7 3770K clocked at 4.2 Ghz does... about the same as most of the computers, TGE is extremely stubborn.

    Edit: Youtube tags are stubborn.

    There was some modified scripts I used to spawn that many bots at server start: http://dx.no-ip.org/files/Tribes 2/My Hacks/NoBotLimit/ (All you need is the .cs files, should work in Classic by replacing the corresponding files)

    With the code, it'd still display a max of 16 bots in the UI but it'd spawn the 120 bots in reality. If you wish to modify the count, refer to aiBotProfiles.cs, line 80:
    for (%i = 0; %i < 120; %i++)
    

    Change the 120 to the number of desired bots.

    By the way, the game doesn't run any of the AI code before the mission starts so you could have some thousand bots spawned and it might be okay -- until the mission starts and the AI code starts running. I'd say roughly 120 is the absolute max, and even then there should be plenty of safety measures taken in code to prevent crashes.

    A good test case to see if it's possible to run T2's bots with just the AI logic in C++ would be to run the bots on as little AI code in Torque Script as possible and to measure the performance. Torque Script is amazingly slow (I wrote a Markov chain implementation in both Torque Script and Python, the Python implementation was visibly faster as Tribes 2 locked up for a few seconds at a time while Python produced results instantaneously) and removing that from the equation should yield a significant performance boost, the downside being that the AI code would need to be written totally in C++ which isn't entirely possible without a lot of reverse engineering of the executable. As Thyth said, everyone is better off if someone just picks up a new engine and built the game (or one like it) on there.
  • edited August 2014
    Thanks Liukcairo, I'll find the loop and modify it and see how far it goes.

    Edit: There are many options out there, but the only thing that truly stands in our way is the conflict of IP. I haven't read too much into it, but Torque 3D or Unity 3D would be great options if there wasn't a brick wall in the way. Although on the side of making it open source, Torque 3D would be the only option as it's not only Torque Script (which Tribal IDE, Eclipse IDE Plugins, etc...) all exist, Unity relies on C#, JavaScript/"UnityScript"/Boo and most of what people use (Including Rust from what I understand) use C#. While it would be no problem for me, if anyone who had grown close to Torque wished to join in, would make it a nightmare starting out as they would have to familiarize themselves with it and grab an IDE that's decent enough to use; Mono can be hectic at times.

    If you've experience with Python, Boo is a route you could take.

    I believe Torque Script (correct me if I'm wrong) is rather similar to Java Script?

    Then the actual engine's source code is another issue. While you almost never need it for Unity, Torque gives it to you with the MIT license to go have fun with.

    Mono screws over here (Go to 1:20 to see it in action):

    Of course it's another Minecraft in Unity3D kind of thing. He falls victim to 2 BSOD's and a power outage. On top of that, Mono kicks out on him a few times.
  • edited August 2014
    This and this may be of some interest to you if you're going down that route.

    Personally, I have been working on bringing back elements of Tribes 2 into T3D as a project for DarkTiger over the past few months. You may want to get a hold of him. He might be up to something along those lines. :)
  • edited August 2014
    This and this may be of some interest to you if you're going down that route.

    Personally, I have been working on bringing back elements of Tribes 2 into T3D as a project for DarkTiger over the past few months. You may want to get a hold of him. He might be up to something along those lines. :)
    My life just got a little happier.

    EDIT: Having looked at the documentation available for Torque and having known about much of what Unity requires, I'll probably look at working on something in Unity when I get the chance.
    While Source for Torque is available, Unity almost never has any situation where you'll need source. MIT is nice and all, but I have no plans to sell whatever would have been made.

    If a community project were to arise, then I'd certainly look at learning TorqueScript in a whole or wait for OMNI to release. DNT may be available, but what I've read on the engine improvements has encouraged me to wait for OMNI rather than look at DNT
Sign In or Register to comment.