Or at least a few hours. It’s easy! Just make a mod with hundreds of classes and give a good 100+ of them names which end in a number! UE1’s method of instantiating these classes ingame or in a level will cause all sorts of broken things to start surfacing years later when you finally figure out what a colossal dumbfuck you were, and the rage will flow freely when you realize you’re going to have to fix all this goddamn bullshit.
Two separate actors. Place them both in a map. Place several of each, actually. Now do this for SludgePlant3, SludgePlant6, and SludgePlant7. Oh, and there’s SludgeTree8 and SludgeTree10 too but fuck that they aren’t relevant for this example.
What happens? You see SludgePlant0, SludgePlant1, SludgePlant2, SludgePlant3, 4, 5, 6, 7, 8, 9, 10, 11, etc. There may very well be hundreds of these things. “But wait,” you say, “there’s no EXU.SludgePlant0!” That’s right, asshole. “There’s also no actor called SludgePlant4 or 5!” Yeah no shit–“or SludgePlant8 or 9 or 10, just SludgeTree8 and SludgeTree10!” ok god damnit shut the fuck up
Anyway, you can see what’s going on here, right? The engine automatically instantiates classes by appending numbers to them as they are spawned. The first instance of any class is always <ClassName>0, and the second is <ClassName>1, and so on. But what fucks up is when your class name ends in a number; the engine gets all retarded and confused and shit and then your class names don’t mean shit in a sea of instances. Instead of doing the smart thing, like, say, SludgePlant1_0 or SludgePlant1-0, you get this clusterfuck of numerical discord that is just a nightmare to wade through if you ever start having problems.
Normally, however, this isn’t a problem, and it technically can still work just fine without causing any sort of crashing or errors. But it’s a pain in the ass to mess with in UED, and the potential for crashes is there, even ingame, if things really go to hell (in EXU2, things “really go to hell” every few minutes). And if you’re in a hyper-optimizing super-obsessive-about-performance mode like I have been for the past few months, you don’t want to leave ANY opportunity for crashes. Which means you gotta fix this fucking buuuuullllshhhhhhiiiiiiiiitttt
In order to undo bad development practices from years back, I took full advantage of the .t3d map export format and Bear Grip I mean Bare Grep, a useful text-searching tool (basically the grep command but for Windows).
Here’s how I went about removing all this garbage!
Step 1: Find all your shitty classes that end in a number.
Step 2: Copy and paste them and rename the new classes (both the filename and the class name in the .uc file itself) so they end in roman numerals or something that’s not a number.
Step 3: Use the might of the Bear Grip to find any classes that reference <ClassName># and replace those references.
Step 4: Subclass your old, numbered classes under your new roman numeral’d classes (this is for purging maps; you can’t delete them just yet).
Step 5: By now, your code should no longer reference any numbered classes, but your MAPS probably still do. Open every single map and export it to .t3d and dump these all into a folder.
Step 6: Search your .t3d files for any references to numbered classes. Find the actors that use them and replace the references. If the classes THEMSELVES are numbered and don’t just contain references to numbered classes, you need to continue.
Step 7: Select all SludgePlant1 (or whatever) in your map. Type set actor bHiddenEd false in the UED console to display shit like InventorySpots and whatevers. Invert selection and delete; don’t save the map. Export the map as something new, like “GodImRetarded.t3d” and then reopen the map. Everything will be back.
Step 8: Open your exported actor list (the .t3d) in a text editor. Delete everything that isn’t a SludgePlant actor (the LevelInfo, Brush, etc). Then do a find/replace for SludgePlant, switching it to SludgePlantI (it’s important you don’t globally replace SludgePlant1 to SludgePlantI, since you run the risk of fucking up tons of instances that are already placed in the level. Replace only the part without the numbers first).
Step 9: You should now have tons of Class=EXU.SludgePlantI1 all over the place. Do a find/replace on this term to change it back to Class=EXU.SludgePlantI. This will keep your instances intact. You should now have a lot of Object=SludgePlantI134 and SludgePlantI23 and stuff. This is good. Save the .t3d file.
Step 10: Now, reopen your map if you decided to be a rebellious little jerk and skip that part of Step 7. Select all SludgePlant1 and delete those bastards. Then go to Import, select your .t3d, and add it to the existing map. Huzzah! All your SludgePlant1 actors are now SludgePlantI actors, and they are in the exact same locations with the exact same properties they had before. Success! Now repeat Steps 6-10 for EVERY OTHER MOTHERFUCKING CLASS THAT ENDED IN A NUMBER. This will take a while.
Step 11: Delete those god damned asshole numbered classes and recompile your shit. Reopen all your maps to make sure you didn’t fuck up and break anything. If you did, undelete the classes UED complains about not finding and recompile, then repeat everything until you root out the last of the little bastards. This step will probably happen at least once. You will probably swear at least thrice.
If you’re done, heave a sigh of relief and move on to whatever the next step in your development hell cycle is, like unbreaking netcode or re-unbreaking other… you know… stuff. Whatever
Anyway, all in all, doing all this has made EXU2’s code base a lot cleaner and more stable and was worth the effort. Most mods out there probably can handle having a few numbered classes here and there without running into any sort of instantiation trouble, but not this one.
EXU2 is a special case, since each map contains hundreds of actors, sometimes almost a couple thousand, and when loads of these actors are basically sharing instance and class numbers, sometimes… things… happen. Plus, EXU2 stresses the engine to its limits (and sometimes even your hardware), so it makes the error potential skyrocket. This is why even minor, seemingly-inconsequential issues like this can wind up being a real pain later on down the road, and that’s why I brutally crush every bug I see as soon as I see it. This probably wouldn’t even be a problem on a modern engine, either, but I’m glad I learned my lesson here and now: Always name your classes so they end with letters!
Also: never, ever, EVER use UED’s copy/paste feature for pawns. Just… don’t.