Foxpaw/Developer Journal
July 5th, 2004
Well, I've integrated the menus all into one, which is neat. I also worked out some accessed nones and revised the gameinfo to allow the level to run before the level is actually "run." That is, there's only the one level that is ever played in, but that level is loaded while the front menu is being displayed. Obviously, you don't want gameplay to begin until after the player has selected some stuff from the main menu.
However, the upside is that the whole thing is really fast. It's kind of neat, but also kind of bad. Specifically, it's kind of bad because it feels unnatural to be dumped into the game when you've barely released your mouse button. Most games have loading screens, and I was expecting to see one when I hit "new singleplayer game."
To remedy this, I've implemented a short delay which is supposed to represent all your ships and stuff coming out of warp space. Basically, you log off by entering warp space, and remain there until you log in again the next time. This greatly simplifies saving and loading to a level manageable from within Unrealscript, since a lot of the "state" is not stored. (projectiles in transit, particle effects, etc. do not need to be preserved in this way.)
Some players would rather have a true "save" and "load" feature on the single-player game, but for the time being that is not practical without native saving and loading support, or large amounts of Unrealscript code to store and restore the state of all objects.
So anyway, I've got the menu flow working. I haven't tried the vehicle editor yet since I changed some of the workings of the menu, but all the other menus seem to work normally so I'm assuming that will to. If anything it should require only minor debugging. With all that working, you can now build stuff, give orders to friendly units, manuever the menu system, shoot at things, get shot at by AI things, and design vehicles. That doesn't leave much left to do. In theory. There will be a lot of polishing and content creation to do, of course.
Also, I still have that cursed problem to solve with the rotations of stuff in the editor. However, I'm confident that the solution will come to me eventually.
July 19th, 2004
It's been a few days without internet access because I had a network cable disconnected and I didn't really get around to reconnecting it. However, I did do some coding, which has been in short supply lately. I got the editor working again alongside the regular level, so you don't have to load a separate level to access the editor anymore. I'm not sure why, but the saving of designs wasn't working anymore so I fixed that too.
Then I added the actual saving functionality, which is cool. It had a few bugs to work out, but in the end, it all worked nifty. So now I can retain a persistent world state without native loading and saving stuff. Also, I added the ability to switch which of your ships you are controlling. I'm pretty excited that both of those things are working. I might change the switching between ships part a bit, but most of that code will remain the same.
Iterestingly, it was not THAT difficult to allow saving of the world state in UnrealScript. Unfortunately, there are a couple of things that can't be saved in this manner - in particular, the progression of an objects state code, or emitter particles, for instance. However, for the most part, stuff can be saved by simply providing a list of variables to be saved. Since Unrealscript can look up variables by their string name, and also read the value in string form and set the value in string form, this was surprisingly easy. Basically, you just have a list of properties that you want saved, each one has a GetPropertyText done on it, and the variable name and value is stored in a relational database. Then, come loading time, all the actors are spawned again, and the tuples of the database are iterated through with SetPropertyText. This allows you to very quickly recreate the world as it was saved.
Of course, some things like references can't be stored in this manner. For that reason and for simplicity, as little as possible is saved. This doesn't cause the exact game state to be stored, but that isn't the intention either. Admittedly, for singleplayer it would be nice to store an exact game state, but that will require native support (to store references and such) which, to my knowledge, is not available in UT2004. (It's not available in UT2003, and I don't have UT2004 yet.)
Wormbo: Save games (like in Unreal) are available in UT2004, the implementation still seems to have a few problems, though.
MythOpus: I've been trying to follow your mod development as closely as possible... I think I have the basic idea put together in my head but correct me here... players will be immersed into an always expanding, always changing world. The player will be in charge of a fleet. He must then build up that fleet, gather resources etc... to eventually wage wars and what not to take control of the persistent world? Okay... now on to another question... will it be multi-player capable (as in online warfare) or do you doubt it... and when a player logs out and 'goes into hyper-space', does the world save everything and pause or does it keep on going if you leave it on? If it keeps on going and you choose to log back in... what would happen if another fleet of ships was right your hyperspace wake? I request to be a beta-tester also
Foxpaw: Well, that's pretty much it. You can control a fleet, or you can dump all your resources into building a small group of ships or a single ship with more exotic (and expensive) weaponry. So it caters to both first person space shooter-type players as well as those who want something more like an RTS/Homeworld kind of play. For the single-player I plan to have a campaign and stuff to keep it a little more interesting. In multiplayer it will be more like an MMO. To facilitate a large number of players, I'm planning a peer-to-peer networking and distributed computing scheme using the IP wrapper classes in the Unreal Engine.
In single player the world will likely be "frozen" when you "log off," (quit the game) and will resume when you return. I have considered the idea of having the game simulate some passage of time when you return, but I haven't decided on that yet. If possible, single player may also have the ability to save the game state as-is and return directly to the action.
For multiplayer, of course, the world will continue while the player is offline. I have considered the possible conflict that could arise if a player tries to log in and other stuff is occupying the space where the player's stuff was when they logged off. I haven't yet decided what to do about that. I have decided that there will be a visual and audio cue when a player is starting to log in. (like when their login has been accepted by the login server and they're connecting to their peers) This would be something like swirling dust or something around the point where a wormhole is about to open.. or something like that. I haven't decided whether the ships should just come through and collide with stuff, encouraging people to log off in less-trafficked areas, or possibly to have them adjust their position so they would warp in clear of any obstacles.
Beta testing is still a while off I think, but I expect when the time comes I'll try to recruit some people for the beta testing both here on the wiki and on BeyondUnreal Forums. (as much as I dislike forums)
Mosquito: I wouldn't recruit off the forums, alot of bad apples their and bunch of people that wont give you useful feedback, select or testers carefully, 5 good testers can be better then 50 bitchy llamas.
NickR: I'd really appreciate the chance to beta test.
T1: Well, I can't resist. I wish to beta test also.
July 26th, 2004
Well, it looks like I might actually have the editor rotation thing down pat. We'll see though. I knew that the solution would be deceptively simple, and the solution that appears to be working is indeed simple, but I'm skeptical. It doesn't feel like it should actually work, though it appears to. I'm hoping that it will continue to work.
So, then, now I can get into singleplayer, have it load up the persistent state, fly around, build stuff I've designed in the editor, and give AI pilots orders to attack and stuff. The AI pilots are a little erratic, but sufficiently effective. So, now I need to make some higher-level AI so I'll have an enemy to play against. Plus a ton of polishing to do. However, I think that the AI is what's needed most at this point.
Simply enough, every ship has it's own AI pilot, which can recieve orders from some external source. AI pilots have limited ability to make decisions and can fight and such on their own. However, they have no knowledge of the larger scale goals and such of their "team." So, for instance, a fighter is smart enough to escort a transport, and a transport is smart enough to travel to a given destination, but neither is intelligent enough to know what needs to be transported or why.
This is where the higher level AI comes in: it does all of the planning and stuff in pursuit of whatever goals that particular AI player has. I've also built in some limited support for heirarchies of AI players.
So for instance, a higher-level AI may preside over a mining base somewhere, and would give "orders" to mining vessels, fighter escorts, and transports to send processed materials to other bases where they may be needed.
Anyways, the higher level AI is likely going to have to be some kind of an RTS AI basically. The problem is that I know very little about how to implement an AI for an RTS game. I have looked at the Homeworld source which was released by Sierra, which may be a good starting point. The problem with that is that the Homeworld AI is a bit crude and has no "political" affinity aside from a predetermined list of enemies and non-enemies. Then it basically builds one of a few loosely defined fleets and launches an attack at what it considers to be the most valuable assets of the target player - usually the mothership or carrier.
I'd like an AI that is a bit more diplomatic, perhaps attacking people only with reason to do so and such. However, now that I mention it, a mining base is probrably the perfect test-bed for developing the AIs, since it has a pretty straightforeward motive. I think I'll give that a shot.
September 3rd, 2004
I'd been holding off on buying any new games until I got a new video card, since I would possibly get a sub-par gaming experience with my integrated graphics. Shortly before my last update I got an X800 Pro and I've been mostly playing games since. Unfortunately, I haven't been doing any work on my own mod.
I was going to make a mining base as a platform to develop the AI further, but then I realized that building a base was going to require me to make new meshes for the base parts, since I couldn't really build a base out of fighter parts.
The editor rotation thing does seem to work, but another part that seemed like the easier part of that problem doesn't seem to. This I find wierd because it's essentially the same code as the turrets, which seem to work. This has raised an unsettling feeling that maybe the turrets actually don't work, and they only appeared to work because of some coincidence in the way that I tested them. ...
Actually while I was writing that I realized that the turrets work because their axis of rotation is always the same relative to the turret's own internal coordinate system, (it can be anything in relation to the rest of the ship) but when rotating components in the editor the axis of rotation is dependant on how the component has been attached. To facilitate proper rotation I'm probrably going to have to make some of the turret code global to all ship parts, in that the rotation of a given part will be expressed as an axis of rotation and a rotation around that axis, instead of just a straight rotation relative to it's parent component.
That's reminded me of an interesting point: explaining things to people seems to be a good method of gaining new insight into those things. I've noticed this before, but never really written or said anything about it. However, it seems to hold true - many times I've been writing about a problem or telling someone about it when mid-explanation I'd have an epiphany. Sometimes I even have mock "Q & A sessions" with myself when noone is around. (They might think I was crazy if they realized I was conversing with myself.)
At any rate, I'm hoping to get back into programming soon.
MythOpus: Talking to myself always helps me figure out all my problems too. My family usually thinks I'm talking to them though. Anyhoo, how is the mod coming along?
Foxpaw: Well, as mentioned above it's somewhat stalled for the time being due to the editor rotation shenanigans. It's pretty much the only major coding hurdle that I can see still remaining to be surmounted.
Completion of the editor is essential to the creation of the game world, which is going to be required to experiment with a few more things.
Once I have the editor done I can start building up the game world, and then do some quasi-fun AI stuff.
September 16th, 2004
Well then, I actually did a bit of coding patching up a few minor issues. Now I'm thinking I want to change some of the lower-level workings of the ships, but I'm uncertain as to the best way to go about doing so.
Basically each ship is a heirarchy of parts. The part at the very top of that heirarchy keeps track of ship-specific stuff like the center of mass of the whole thing, the pilot, resources stored on-board, etcetera. However, every part has the capacity to store this information, but only the top part does. This is a waste of RAM. Further, it slows down run-time execution somewhat and complicates the AI system. Lately I've been noticing some oversights that have resulted from working with this system.
So, now I want to have a central "ship" actor, which will still have it's parts, but instead of the topmost element in the heirarchy holding the ship-specific data, the "ship" actor itself will store ship-specific data and handle the camera and such. It will also handle some of the AI which I want to simplify. Originally I was using a controller sort of system kind of like the system used by UT2003/UT2004. However, this system no longer makes sense to me, as every ship except for one is going to have an AI controller. (Barring network stuff, of course, but that's handled differently.) Then, every time a player leaves the control of their ship to go to a menu or something, an AI has to be created to take over, and then has to get destroyed for the player to come back in.
Instead, I'm likely going to have an AI built into the "ship" actor which will simply be overridden by the player. This also has the added advantage of having some continuity - that is, if a player takes over control of one of their ships temporarily and then leaves, it won't be replaced with a new, "clueless" AI. This should also simplify the code so I won't end up with oversights like stray cameras and AIs that didn't get cleaned up due to some anomalous condition.
However, I'm not really sure how to go about implementing a centralized "ship" actor - there are many ways that a ship can be created, and frankly I'm not sure that I remember them all. I'll take a stab at it later and see what I come up with though.
Well, now it's about 5 hours later, and it was easier to change than I expected. I came up with a clever scheme of just changing the name of the ship part class and then creating a new ship class to hold the per-ship data. Then I just caught all the errors tossed at me by the compiler to find all the places where the two classes were referenced. It ended up being relatively simple to change, because most places where a ship part was being referenced, it was either accessing per-ship data, or per-component data, and rarely were the two mixed. In fact, I had only two major bugs after recompiling and testing, which I'd say is pretty good for splitting a 29KB class into two.
Let me take this opportunity to curse Microsoft's Multimedia Keyboard, upon which the decision was made that people don't really use insert so it should be removed as a key and instead added as a third function of the print screen/system request button. Of course, no indication is made as to how to activate that feature, so when I accidentally enable insert somehow I now can't disable it.
Anyway, back to what I was saying: the new structure seems better and allowed me to remove several if checks, some recursion, and other assorted stuff. It also allows me to standardize ship controls a little more, which I guess is a good thing. It's faster at runtime, which is good. I've taken advantage of the speed increase to implement a more flexible resource system, though the most critical resources on a ship, energy and fuel, will remain with the older system as it is faster - so the things using the more complex system will be more like cargo and unrefined stuff that's been mined or whatever.
September 17th, 2004
So, I've been coding up a storm, but I've hit a roadblock and I'm stumped. Normally I can deduce my way out of any error, especially one as tame as an Accessed None, but so far I'm unable to overcome it. The reason being that I can't figure out what's going on. It seems I have an object reference that is None, but at the same time it's not None. How is this possible you say? Err.. well I don't know. But the following bit of code:
if ( Parts[0] == None ) DebugMSG( Parts[0]$" is teh none!" ); else DebugMSG( Parts[0]$" exists." );
reliably generates the message "World.ShipPart is teh none!" which doesn't make any sense. Clearly, Parts[0] == None since it would have to pass the check to display that message. However, the very fact that the object's name, World.ShipPart, shows up in the message, means that Parts[0] can't be none.
I'm going to continue working on this bug and perhaps try some more deductive methods of finding out what's wrong, particularly finding out what's causing this anomalous condition. I'll post an update if I figure it out, though it might take a while due to the apparently impossible nature of the bug. (My suspicion is that perhaps somehow I have accidentally foiled the garbage collection system, but I'm not sure how I could have done so as ShipPart is a subclass of actor)
UPDATE: Okay, I was close. I also caught a fleeting glimpse into the garbage collector. Apparently, the Parts[0] WAS none, but whether it's "none" or not appears to be based on some flag stored in memory, as opposed to an actual value stored in the reference. This means that evaluating == None returns true, but casting to a String gets passed the "accessed none" checks and uses the region of memory that previously held a valid object. This condition persists for only a short time, and this memory appears to be reused after a short time. A most interesting bug to have.
Mychaeel: That flag you're talking about is probably bDeleteMe
. Its consequences are mentioned already in the comments to the entry of May 31, 2004 on Mychaeel/Developer Journal.
Foxpaw: Possibly - but I think it might be a native bit. It could be bDeleteMe, but this isn't an instance where something has been deleted but still has bDeleteMe set - if you tried to access bDeleteMe in this case you would just get an accessed none. The ability to get the name of the objects by casting to a string persisted for several seconds after the reference was None, which is not (to my knowledge) the use of bDeleteMe. It was my understanding that bDeleteMe is only intended to be used to test if an object had been destroyed earlier in that Tick.
Mychaeel: No. bDeleteMe
is set for any destroyed actor until it is garbage-collected – and that usually takes until the next match starts.
Earlier engine versions just set the bDeleteMe
flag, removed the actor from the actor list (and put it in the "just-deleted chain" of actors which is maintained via the Deleted
reference defined in Actor) and set any references to it to None
.
Newer engine versions also check the bDeleteMe
flag whenever an actor is accessed in UnrealScript (as in the "==" operation or when accessing any member of it) and return None
instead of the actual actor reference if it is set. (In earlier versions, you could access a just-destroyed actor without problems as long as you had a reference to it – that's not possible anymore.) It might be that casting an actor reference to a string as it is done in those log statements of yours doesn't do that bDeleteMe
check, so you'd get an object name there even though comparing the reference to None
will yield "true."
I've had some problems with accessing destroyed actors of my own when I assumed that destroying an actor would effectively set all references to it to None
– that's apparently not the case, for instance when you've referenced an actor from a "static variable" (i.e. the default value of a variable).
September 18th, 2004
Well, I finally knuckled under and did the grunt work of implementing the component editor. It actually ended up being less of a nasty hack than I had expected, though it could still use some improvement.
At any rate, I can now use all parts of the editor so I can fabricate ships from start to end and build them in hangars. Previously I had manually edited some stuff to make the components, and then used the vehicle editor to just assemble them. The component editor was a complex part to implement because although it didn't involve anything particularly fancy, it involved a large number of variables that could be set, and which variables would be available for setting was dependant on what type of component it was. A mechanism for changing what type of component it is was also needed.
Anyways, now that that's done, there should be at least one new screenshot coming soon. I know I said that a long time ago, but I got kind of sidetracked. Unfortunately, I've been had by Sierra and the sample textures included in their Homeworld 2 SDK don't actually line up, although they look like they should. Further examination showed that the diffuse channel of the background in the level of Homeworld 2 that the sample textures are from is slightly different from the actual sample textures provided. The "star mask" appears to be the one from the production game, while the diffuse channel was perhaps modified prior to shipping.
What this means is that there are a few wierd artifacts where the alpha channel doesn't agree with the diffuse channel. I'll try to take screenshots that hide this anomaly. I have improved the backdrop code somewhat so it looks much nicer now too. This should be obvious when I upload the screenshots. Unfortunately, JPEG will probrably have something to say about the quality of the screenshots, but we'll see.
September 29th, 2004
First off, let me take this moment to thank Epic for making classes with very generic names, and then putting them in Engine so they effectively reserve the word into perpetuity. I really appreciate writing a lengthy but relatively straightforeward class only to find that it won't compile because Epic felt like they should include a class called VehiclePart that isn't even used at all and, though native, provides no apparent functionality. It's like finding a prize in your cereal, only instead of a prize, it's a broken bottle of arsenic. Ruins the whole bowl. I, of course, had the good fortune of naming a struct that and then writing a class using it I had to change it to something else, which was not as simple as search and replace as that particular string was also a substring of some other stuff that I didn't want changed. I actually knew about this class and thought it would work anyway, since, in most cases it does. However, the behaviour in this case appears to be somewhat inconsistent, so certain sorts of declarations used the struct, while others tried to use the class. This allowed me to pretty much finish the class before discovering this lovely surprise. Of course, since tons of stuff that is unrelated to the engine is stored in the Engine package, which you can't really exclude from your compilation, there's no way to really escape these generic "reserved classes."
Mychaeel: You can always fully qualify any class with its package name: "MyPackage.VehiclePart".
Foxpaw: Yes, but this is a struct interfering with a class, not a class interfereing with another class. Does the same apply for structs?
Mychaeel: You can fully qualify a struct name with its class name: "HudBase.SpriteWidget", or "XInterface.HudBase.SpriteWidget".
Anyways, now that I've said that, the class I was mentioning was the one that stores your various ship blueprints and stuff. I wanted to change this for two reasons. Number one was that for some reason saving a ship would sometimes wipe out all of your saved component designs, and sometimes saving a component would wipe out all your ship designs. Bad news. I think I found the cause of that while doing a complete rewrite of that class, but I wanted to rewrite it anyway. Previously, the vehicle "catalog" that stores your designs was a subclassed "persistant state" that stored only your components and ships that you had designed and never actually got loaded into the game wholesale. I decided to change this for one main reason:
When I originally wrote the class, I thought that that system would be good. Ships, once designed, would retain all of their properties, so if you changed a component design, ships already designed with that component would not be affected. At the time I considered this to be a good thing, as it would allow you to keep your older designs without having their parts cluttering up the part designer. I've changed my mind on this though, as I think it might be inconvenient for players to redesign all of their ships if they wanted to change some of the stats of a weapon or something. So now, ship designs just reference the components they are made from instead of making their own copies. This neccessitated a separate "catalog" class and not just a subclassed "persistent state." With the new system, changes made to components after a ship was designed will affect all ships that have that particular component on them somewhere, but only ships built from that point onward. For the time being, there is no mechanism to retrofit existing ships, though I might be able to implement something like that by having it compare the components of your ships to find the closest component and retrofit to that. No reference to the original component templates used is stored in the components, so I would have to find some scheme to figure it out based on which component template was the most similar.
I also found a small bug that I'm amazed eluded me for so long. If a ship takes enough damage to certain areas it can be severed into two or more independant parts. This is done automatically in the function that causes a ship to remove components from itself. What I didn't realize was that when I remove a component from a ship so that I can put it on another ship, I was "severing" it off of ship A to put it on ship B, but the act of "severing" it from ship A caused it to be made into a fragment, a member of the new "ship," ship C. Then it merrily went about adding it to ship B, (having passed the check to see if it's part of a ship already, and severing it if it is) and thus ended up as a member of TWO ships. This was causing wierd rotation issues that would be fixed by saving and reloading. (As the saving code will only recognize one of the two ships as the actual owner of the component.) I suspected it was something like that, but I was having difficulty finding out where in the code that was happening as all of the references from the component to it's parent ship pointed to ship B, but ship C was sitting inconspicuously in RAM with references to the component.
Also, in addition to my earlier rant, I'd also like to express my feelings for the changes made to the broadcast system for UT2004. How could this be a problem, one might say? Here's how: UT2003 had a queue of up to a thousand messages in the console window. (Though I don't think it would actually display that many.) It did so with little performance overhead. UT2004 has a queue of a hundred. How is this bad, you might ask? Well, despite having a queue 1/10th the size, if you pump a lot of messages into it fast, it slows down the game enormously. I first noticed when I spawned a UniversalThingTally. (a debugging tool I made which does an allactors and reports back a count of each type of actor existing in the world, and it does this every tick. I use it to find things that aren't getting cleaned up like they should.) Now, a UniversalThingTally puts a LOT of messages on the console. It caused a minor slowdown in UT2003. But in UT2004, it drags my system from a peppy 200fps to 20 as soon as it's instantiated, and over the next few seconds, it goes down to 5, then to 2, then to 1, then I hit tilde, type in "exit" and hit enter, wait a few seconds, then shout some profanities.
I fail to see how the changes made to the broadcast system are an improvement. I copy and pasted UT2003s code into a subclass of ExtendedConsole and all was well.
I recently ported the code for the mod over to UT2004, by the way. I suppose I didn't explicitly mention that. The mod directory structure is cool, and the fact that saved games are supposed to work in UT2004 is cool too. Most of the other code changes (low-level packages like Engine, IPDrv, etc. only - I can't speak for the UT2004 game stuff) are of questionable value.
September 30th, 2004
Turns out that I actually didn't have the problem fixed that I thought I had fixed. Now, I have found the problem. It's certainately devious. As you likely know the contents of structs are stored if a variable of that struct's type is declared as a config variable. What you may or may not know is that elements of the struct declared as transient are not saved. This is obvious when you think about it, and is desired behaviour.
However, what I've rudely discovered was causing me so much grief, is that transient elements are not only not saved, but they are reset to zero/null/empty array when you save the struct using SaveConfig() or StaticSaveConfig(). This seems like a most bizarre behaviour and was likely not intended by Epic. What probrably happens is it writes out the data, then reads it back in. Reading no value for the transient members of the struct, they are set to their appropriate initialization value.
Also, the cool Homeworld-esque trail system I made seems to have been antiquated by the behaviour of TrailEmitters being changed. Although TrailEmitters are inferior to my system (you can see some visual artifacts if they are viewed from certain angles) I'm going to switch due to the increased performance of the native trailemitters.
To top that all off, I got some high-poly models up and running, which has upped the visual quality. (Screenshots are on the [/Cosmic Fury] page.) I've actually gotten a surprisingly large amount of stuff done today, though granted I only had one and a half hours of class today so I spent a lot of time on the mod. I've got almost all the bugs worked out, except for some reason the vehicle editor crashes sometimes when you try to save. Oddly enough, the longer you go between saves, the more likely it is to save when you eventually do do the save. This seems bizarre, but I have no idea what could be causing it. It's crashing in a static function, I know that much from the stack trace, but the whole vehicle "catalog" is static functions, so, err.. yeah. If it becomes a big enough problem I'll try instantiating the catalog and see if the stack trace gives me some more useful output then.
October 4th, 2004
Today I mucked around with some special effects stuff, but I don't have much to show for it. First I made bullets that looked more like carrots, but I was eventually able to improve them so they look more like tracers and stuff in flight. I also worked on my generic explosion effect which was dandy. I'm still not quite happy with the effect, but it's not bad.
I did, however, implement a proper "turret cam" which greatly helps when using the space station I made. The annoying thing that was going wrong with that was, any combination of pitch and yaw will result in some roll. (Assuming you don't use a fixed coordinate system.) Normally this isn't a problem. Your ship just rolls and your camera is "upright" before you even notice that you rolled slightly. However, since the space station has no form of mobility, and as such CAN'T roll, those little rolls start to add up and next thing you know you can barely control your crosshairs. The new turret cam puts your view squarely behind a turret of your choice, (pressing a button cycles through all available turrets and then back to the ship view) and all rotations are in the reference frame of the turret. Further, all roll control is negated in this mode, allowing you to aim more easily with turrets. This actually ended up being more complex implementation-wise than I had expected, because of course, the reference frame of a turret changes as it rotates.
Mosquito: you should consider implementing a master turret control, which you can select targets that all turrets in line of sight shoot at. It would be a pain to only use individual turrets while all the others idle.
Foxpaw: The turrets are actually already linked, and can fire in four modes - if they have their own target, they auto-aim at that target; if they have a human pilot with nothing targetted they all aim parrallel in the direction the pilot aims (either from the ship view or any turret's view); if the human pilot has targetted something the turrets aim so that their shots will converge at a distance equal to the distance from the ship to the target. (so the shots converge on the target, but you can still lead); and, if the ship is being flown by an AI pilot the turrets autoaim at the AI pilots' target.
October 5th, 2004
Since introducing some non-low poly models, things have been looking much better eye-candy wise. I keep taking screenshots that I want to post up but I know that I'll have better ones in a few hours anyway, so I've been holding off entirely.
I noticed that the fighters are very difficult for the AI to hit. (likewise for humans, but.. ermm.. I'm sure that's just me) This I attribute to a slight fault in the bit of code that does the lead-in calculations. Unfortunately those calculations are fairly complicated as it has to take into account movement of the ship firing, movement of the ship being fired upon, and of course the muzzle velocity of the weapon. The trick, however, seems to be that by adjusting the aim to lead the target, this subtly changes the distance before impact, which subtly increases the amount of time it will take for the projectile to impact, which subtly increases the amount of lead-in required. This seems to be pretty much a neverending cycle, which causes the AI to just barely miss most of the time. This problem is not particularly prevalent on larger targets, such as capital ships and space stations. To this end I think that I might either need to implement some sort of iterative system whereby the aim is repeatedly refined, or maybe I could just leave the lead-in calculations as they are on the premise that, as mentioned, hitting other fighters isn't that easy to do anyway.
MythOpus: Homeworld (I think) uses the repeadtedly refining method. The AI usually misses fighters for the first two shots but then starts getting closer and closer to hitting them. I think it works rather well, but you should inkorporate some sort of randomness.
Foxpaw: Heh, I was writing that I had finished implementing it while you were writing in support of it. I actually haven't looked at how Homeworld does it, though I do have the source to Homeworld, so maybe I'll look there and see if they have a more efficient method.
Okay, so I implemented the iterative lead-in system, which resulted in fairly frightening accuracy on the part of the bots. This is good as I was hoping I could achieve this - if the bots have the ability to hit unerringly, then I can just factor in mistakes for them on lower skill settings. This way though, they have the code capability to be truly "godlike." This took less time than I thought and uses amazingly few iterations. I was concerned about the performance implications since lead-in calculations are done fairly frequently - once per weapon on an AI controlled ship and sometimes once for the AI itself. However, it turns out that the iterative lead-in actually only goes for 2-4 cycles to get 1/1000th of a second resolution.
Also, now that everything's working pretty decently, I've been trying to arrange some larger battles betwen AI units. It's now that I've decided some optimization is needed. The framerate is still decent in a larger battle, but I can tell that at it's current performance it will not be able to handle a game world considerably larger than what I have now at acceptable framerates. So, unfortunately, I have to optimize, which is not very entertaining. That is of course, unless you like watching tons of numbers scroll by in the console and looking for ones that are abnormally high.
Fortunately, I wrote it with some optimization hooks so I can easily time to see which actors are whiling away all my precious milliseconds. The main culprits are turrets, and the master ship actor. The master ship actor is spending about 0.30 ms average in it's physics simulation, and about 0.20 ms doing AI. The other primary culprit is turrets, which consume about 0.22 ms each.
Interestingly, the physics simulation uses very little time most of the time but occasionally "spikes" every few frames. I've isolated this down to a few lines of code, all of which seem to spike similarly often. One of them performs a matrix multiplication, which should be somewhat time consuming, but strangely it is pretty fast for most executions - only spiking up once every few frames. Another line is simply a setlocation call. This I can't do much about except hope that perhaps some tweak in the next patch will eliminate the sporatic spiking. The third does another matrix multiplication, and a setrotation. I haven't dissected that yet to see which of the two are spiking, or if it's both.
Well, I couldn't figure out what was causing the spikes, so I optimized as much as I could and left it. The turrets were optimized simply by reducing their resolution a bit. (Resolution in this sense meaning the minimum amount that the turret must turn before it will go to the trouble of updating all of it's physics and such) This helped because the AI tends to have a slight "jiggle" which is too small to be noticeable on screen but was still stressing the turret physics more than was neccessary. I optimized the AI by implementing an "awareness" feature - basically, the less aware the AI, the less frequently it scans for targets, etc. The awareness of a given AI is based on it's current activities, so an AI with no orders or a simple movement order is the least aware, AIs with defensive orders like escorting another ship or holding a blockade are more aware, and AIs actively engaged in combat are the most aware.
October 10th, 2004
I finally implemented the last part of the physics system for the spacecraft. Previously I had most of the physics in, but applying an impulse could only give a linear velocity, and not "spin" you around. I changed that over the course of today. This actually proved to be trickier than it sounds, because you have to take into account both the location of the impulse relative to the center of mass of the ship, as well as the direction of the impulse. After puzzling for a while on tangents, planes, and a derivative or two, I eventually got a solution using cross products. The derivatives were eliminated by putting a simple constraint on the system, that a force could only be at maximum the approximate radius of the object around. So, for instance, a force can only be applied to an object from within that object somewhere. (or on it's outer surface) Forces with a "location" outside of the object are treated as if they were right on the surface of the object.
I'm somewhat surprised that companies actually get paid good money to develop physics systems, but mine only took 2-3 pages of UnrealScript and a couple of days to implement.
MythOpus: Instead of making physics systems that Epic will no doubt steal from you anyways... get a job from Epic to work specifically on physics systems :O
Mychaeel: Physics are simple as long as you have a single, solid body which is exposed to simple forces. It gets interesting as soon as you have that body interact with another one in a non-trivial manner (i.e. have a barrel fall on a floor, or have a body with arms and legs attached by joints collide with a barrel). Just maybe that might be the reason real physics systems take months or years to be developed and loads of money to license.
October 11th, 2004
Not much today - I spent most of the day mucking around with the AI to try to get it to aim a little better. Unfortunately I didn't have much success with that, though I did confirm that my aiming routines were mostly working, for some reason there is a slight difference from the direction the bot is "aiming" and the direction that it's guns actually end up pointing. I'm not sure yet why that is occurring, but I'm sure I'll figure it out eventually.
I also implemented some nifty view shake which was surpringly effective. I had intended it just as a "nice touch" but it seems to add a lot of energy to the game and also serves as a semi-useful feedback device to let you know when you are hit, and gives a satisfying rumble when you fire weapons with a lot of recoil.
Unfortunately, the AI's movement seems to be messed up somehow. They used to fly off into space seemingly randomly when given a movement instruction, but they worked fine when fighting. Now, however, they seem to fly off when instructed to attack as well. So, I'm going to have to figure out what's causing them to fly off like that. I suspect it's something simple, but it seems like it might be difficult to diagnose.
All right, that took me all of 5 minutes to fix. I feel kind of silly for not noticing that I was referencing the AIs rotation and velocity, when of course the AI doesn't actually move, only it's ship moves. I must have let that slip in while I was optimizing some code or something.
OCtober 18th, 2004
One week later, so what have I accomplished? Well, err.. I, umm. Yeah. Not much. I think I spent most of the week thinking about girls, playing Far Cry, and I'm pretty sure I did some other stuff that I'm sure was productive or something.
However, I did have a potentially valuable insight. While I was pondering more stuff for an operating system that I may write someday. (I haven't really gotten started besides a simple "Hello World!" OS, as I'm not really sure where to begin.) Anyways, I was thinking about optimizing for performance (as I often do) and I was thinking about arrays. Then I started thinking about Unrealscript, and how I had a lot of arrays in my mod. It wasn't until a couple of days ago that I realized that a linked list would probrably be a lot faster than an array. The reason being, almost all of the accesses to the arrays are iterative ones inside a for loop. Every time I access the ith array element, that involves a multiplication, which takes over 30 cycles to complete, not to mention the additions and other operations necessary to find and return an array element. This as compared to a linked list, which involves an assignment, an addition, possibly another addition, and one memory access. (In theory, in practice, references are probrably more like pointers to pointers, so add in another memory access and possibly another addition.) Anyways, the point is, now I'm wondering if linked lists might be a lot faster than the arrays I'm using, since accessing arbitrary elements is rarely necessary and almost all of their use is iterative. I'll do some tests and post the results up here later.
Hmm, well, my first results showed linked lists to be much faster. However, it turns out that that was because there was a bug in the code. So I fixed that, and linked lists still appeared to be faster. Then I noticed another bug, so I fixed that one too. Now that the whole test seemed to be running properly, both linked lists and arrays gave comparable results - however arrays were given the benefit of going second in the simulation and so may have benefitted from some caching. Linked lists took ever-so-slightly more time to create, (~2.3% longer) but took considerably less time to destroy than dynamic arrays. (~30% faster) The times for both included the time to actually spawn or destroy an actor, however, so the differences would be more pronounced if this factor was not included. Time spent iterating through the list was inconsistent and varied considerably from run to run. 400 - 650 ms to iterate 1000 elements for dynamic arrays, and 500 - 800 ms to iterate 1000 elements in the linked list. In most of the runs the dynamic arrays were faster.
These results seem a bit illogical but probrably result from the array lookup being primarily native code while the linked list operates primarily in Unrealscript - though I'm only speculating on the actual cause.
It would be nice if UnrealScript had a mechanism to iterate a given dynamic array, without having to do a multiply on the index for every element though.
Wheeeee! I finally figured out what was causing the turrets to aim imperfectly. Turns out I had a == None where I should have had a != None. Thus, the turret believed that it was not equipped with any functional weapons and so used the fallback (less accurate, but much faster) aiming calculations. The AI hits almost all of the time now. It still misses occasionally, but I'm not sure what this is caused by.
Now I need to code in a system whereby lower skilled AI pilots will deliberately miss sometimes. I'm not really sure how the best way to do that is though. I can't just add a random offset to their aim, as it takes time to turn and so the offsets would end up averaging out to cause very little loss in aiming ability. (Not to mention that there might be a noticeable "wobble" if a ship was deliberately throwing off it's aim randomly.) Instead I think that I need some method of having the AIs aim "zero in" on the target over a certain amount of time, effectively interpolating between it's current aim and the aim it should have. However, the amount of interpolation will have to go down the longer it's been aiming, otherwise with even a little interpolation it's aim will always lag behind a fast-moving target.
October 26th, 2004
Well, I made some asteroids. I'm still having some difficulty having them look right. My plan for how the asteroids and harvesting of them will work is, you damage the asteroids which causes them to break into smaller pieces, much like in the game, Asteroids. When they're small enough, a "harvester" part will suck in the pebbles like some kind of space vacuum-cleaner. This seems simple enough and doesn't appear to cause any performance issues. (I was concerned that having tons of little pebbles being simulated might mean a performance hit.)
The issue that I'm having with that is that it looks funny when an asteroid suddnly turns into 5 or so much smaller asteroids. I had planned to cover this up by having a big "burst" of dust come out of the spot where it "cracked open," thus making an opaque cloud of dust so you couldn't see one asteroid transform into five or so smaller ones. Unfortunately, I haven't had much success making a believable dust effect. The dust effect has to appear quickly enough to hide the asteroid breaking apart, and be big enough to cover it. So far, I haven't been able to make it look natural enough when it appears, but I'll figure something out originally. Alternatively, I might make a completely different system of mining asteroids, whereby you just "suck them dry" but the asteroid doesn't actually disappear - it just gets "depleted." I'll have to think about that over the next little while.
In other news, I finally made that mining base AI I was planning to. So far it can float defiantly, mass-producing waves of fighters. The AIs production capabilities have made for larger battles than I'd had previously, and I'm noticing more and more that space is getting littered with garbage. I'm not sure how to go about fixing that yet.
The thing is, a ship can easily be disabled without being completely wiped out. For instance, a fighter who's midsection has been sufficiently damaged could bust in twain along it's midsection, leaving a drifting cockpit with chin guns, and an uncontrolled thruster/fins/some other junk. Both parts are effectively just useless debris, so presumably I could just make them explode and maybe leave behind a single static mesh which would have less processing overhead. (So the remains can still be salvaged for resources.)
However, that poses a problem: what if a ship is redered derelict, but a player is planning on sending out something to repair it or salvage it as is? (Not just salvaging the wreckage for resources, but repairing it and making it operational again.) This could make sense as it might save build time or something. I don't really know of any specific case where it would be useful, but I'm fairly confident that there are reasons why a player might want to repair their derelict ships, or capture fragments of an enemy ship.
Another problem arises if the computer's definition of a derlict ship may differ from that of the player. For instance, a drifting cockpit with only a chin gun atttached is not particularly valuable. However, it could still be used to keep an eye on something, and it's gun might be useful if something should unwittingly stray past it. On the other hand, there has to be some point at which a ship is deemed derelict, because the buildup of half-ships from any protracted conflict soon escalates to the point where performance takes a big hit. The question of "what makes a ship" is also of some consequence here: For instance, some kind of gun platform may appear to be quite derelict, as it is pretty much just a cockpit and a gun. (and likely some turret mechanism) Some stationary facilities with no guns might also end up being mistakenly shuffled into the category of "derelict" ships, even if they are in good condition. Unfortunately health isn't really an option as a ship could be severely crippled even by a relatively small amount of damage, (if applied in the right place) and effectively be debris despite being in relatively good health.
So now what I'm thinking is that I'll have a slow decay on ships that are fragments. When part of a ship breaks off, one part becomes a "fragment" while the other retains recognition as the ship in question. Anyways, the fragment will lose health over time and eventually be destroyed completely. The other part, that isn't a fragment, is going to stay as-is, as it will still be targetted by enemies so hopefully will get cleaned up eventually.
Octover 28th, 2004
For a long while I was dreading making the master "player" AIs to manage fleets of AI ships, as it seemed like it would be extremely complex and I didn't really know where to begin. However, once I got going things actually went pretty smoothly. Firstly I wrote a couple of hooks for the AI, notifications when one of it's hangar has completed a ship, etcetera. Then I wrote a simple routine that just made the AI build a certain type of ship non-stop. (It queues up a new one every time it gets the "ship completed" notification.)
Then I had it organize the ships into an array and when the array reached 5 in length it would give all the ships an order to attack and clear the array. That was pretty simple and reasonably useful in the limited test environment. Then, I altered the setup to instead store an array of "wings," each of which contained an array of ships and some information about that wings objectives. The same array storing recently built ships was used, and when 5 ships were built they were added to the "wings" list as a new wing of fighters. Then, I just added a timesliced function to check (every 10 ticks) all of the fighter wings and see if any is idle (target was destroyed, etc.) and also to reorganize the wing if necessary. (if members were lost, etc.)
That worked pretty good. In fact, I was quite impressed with how well it worked, as the fighter wings all got the same attack orders at the same time so they ended up fighting in little clusters. Previously I made an edit saying that I didn't see the tactical value in formations, but I could see when they fought in clusters they were a lot more effective when they "ganged up on" enemies.
So, I decided to revisit the formal formation code that I had written previously. It was old and decrepit, and out of date with changes that I had made elsewhere. However, it didn't take that long to get working, and it worked surprisingly well. The most time consuming part was probrably writing and debugging the portion of code that determines each fighters placement in the formation, which sounds easy, but it was difficult to debug due to a small oversight I had made. At first the formations were kind of "loose" as the formation leader would take off and have a "head start" on his formation members. I was able to relatively easily rectify this by having the formation members request the formation leader to slow down if they are having difficulty keeping up. Though I don't really feel quite right about that (as it means that a formation doesn't move quite as quickly as individual fighters during turns, etcetera) it seems to work pretty decently.
Soon I'll add some scheme for making different types of wings, and have it build resourcers and stuff. Unfortunately, my original control scheme probrably isn't going to work out, as the number of possible instructions has grown somewhat. However, I can probrably work around that by having more submenus on the "smart menu" and relegating some of the things currently on the "smart menu" to their own key on the keyboard for lesser used instructions, like ram, kamikaze, and scuttle.
T1: Have you tried pie menus? Like in the sims? Harder to code than normal menus, but easier to use, since all the options are equally easy to reach.
Foxpaw: Hmm, I haven't played the Sims, so I don't know if that would work or not. The menus that I'm using are keyboard based menus, like the UT2004 voice menu. The mouse is needed elsewhere during play.
T1: Oh yah, I forgot about the mouse being needed... In that case pie menus just look graphically different but are used the same. Neverwinter Nights also uses pie menus. That's the only other example I can think of. Hmmmm... You could make the menus user configurable/rearrangeable.
Hrmm. I've run into a slight problem with having swarms of fighters. Well, two problems. Both are performance issues. Although the use of formations reduced the performance hit from loads of fighters somewhat, once you get into the range of about 60 AI controlled fighters in a massive dogfight the time spent doing AI and physics calculations on the fighters start to add up, plus the polygon load starts straining the video card with that many fighters (plus the space stations launching them) onscreen. I can optimize some by cutting back the particle effects, but many of the models I'm using now are low-poly so when they are replaced with high-poly versions, that's going to introduce more strain, resulting in no net gain. (Though if I use rigidized skeletal meshes with LOD that might help some.)
I also don't know how much more I can optimize the fighter AI. It may be that massive fleet confrontations are not something that modern hardware can really handle. (Technically I suppose Homeworld and Homeworld 2 have big battles, but they also have a massively simplified flight model and they also don't have 20,000+ poly battlestations on screen.)
So, I'm going to have to do something about that. As it stands right now, fighters are of questionable effectiveness against larger targets due to their relatively small weapons and relatively light armor. Their only redeeming quality is an ability to be disgorged en masse towards a foe. I need to either find a way to have large numbers of fighters without a serious performance hit, or find a way to make fighters more powerful without breaking obvious logical rules.
In lots of games this is worked around by having fighters have amazing power for their size. Capital ships, despite being much larger and theoretically being capable of mounting entire arrays of fighter weaponry, are often armed with weapons only a couple of times more powerful than the fighter's weapons, though said weapons take up tens or even hundreds of times as much space. How does this make sense?
I don't really want to implent a system whereby fighters have such a rediculous advantage, plus it would not be technically feasable as players get to design their own ships, so it wouldn't take long to figure out that they could make their ships a lot more powerful if they just use clusters of fighter weaponry instead of larger weapons. So, I can't give fighters an artificial boost statistically like that.
Unfortunately, the strategic role of fighters in a real-life situation is somewhat limited. Though they definately have uses, the sort of science fiction view of fighters is highly unrealistic so I'm not really sure how I can work it in. Previously the fighters had a useful edge even in small numbers because they were small and fast, and hence very difficult to hit. However, improvements to the AI aiming routines have removed that advantage from fighters as turrets armed with trace-fire weapons or explosive projectiles (think flak) can make short work of them.
Also, it's not really feasable for me to just ignore it, as that will likely lean towards a bigger-is-better philosophy where instead of fleets it will just be individual behemoths roaming about and having 1-on-1 slugfests.
The only feasable solution I can think of is to artificially inflate the price of turrets, which would make countering fighters with fast-tracking powerful turrets inadvisable. Err.. but then people will just built huge quantities of fighters. Unless I was to artificially cap the maximum "crew" a player could have, and have different classes of ship (the player's designs are classified automatically based on speed, firepower, etc. so the AI can fight more effectively) require different amounts of "crew" to function.
Hrmm. I kind of like that idea, actually. Fleets could still grow in strength because the stats (and hence cost) of the ships could still be built up, but the QUANTITY of ships (and hence, the processor and video card load) would not go up.
The downside is then to have large "empires" (AI Controlled) you would need to have a bunch of AIs that would just be allied, which is questionably realistic as then you would have to orchestrate "diplomacy" between the AIs...
It's an idea though. Maybe having a "crew cap" would be good for the gameplay. Though 60 fighters is kind of a low cap. Hrrmmm.
Mosquito: let me just dig up some old crap: Mosquito/notebook
Some old idea from like 2 years ago, but why not instead of having millions of complex fighters, wouldn't it be much more... epic if it was 60 massive complex battleships? Fighters could be very simple construction and in large numbers, while afew dozen juggernaughts slug it out, I was still poundering doing something with my idea, but I'm really not doing anything with it. I just can't get much inspiration in level design for just big ships floating around in a void.
T1: You could make fighters require an "owner" ship and have a limited number of fighters per ship (more fighters for bigger ships).
Foxpaw: I don't see how that would help the situation - the problem isn't that fighters are too good and need to be limited for balance sake, it's that the system can't handle enough fighters to be practical. Hence, if people can't build enough fighters to stand a decent chance against larger ships, they likely won't build them at all. (which is what I want to avoid.)
DJPaul: What about creating a mesh that is a bunch of fighters? You'd have one mesh for a group of ten fighters (flying in formation). When something required responses from indidivudal ships, you could destroy the group ship mesh and spawn ten individual fighters. I imagine this might also make the part of your AI code that controls ships flying in formation easier.
Foxpaw: Err, hmm. I did sort of consider that idea at distance, but even if I did do that it would still be pure fancy without having access to C++ code. Since the fighters are designed during play by the players, there would be no way for me to make a mesh containing multiple fighters, when there's no way of knowing what those fighters will even look like until the player designs them.
Ryan: I don't know how this would affect your gameplay, or even if it is possible in the Unreal engine (newbie Unreal scripter). Could you use some sort of proxy mesh for an individual fighter which maybe suggests that it is partially cloaked, which then changes to the high poly mesh when it attacks. You would get the feel of large numbers of fighters with quite a lot of action with them uncloaking and cloaking. The tactical aspects might be more complex if aiming at cloaked vehicles was more difficult, a chance for the turret ai to show it's mettle.
DJPaul: Hmm. How "dumb" are non-leader fighters when they are in a formation?
Foxpaw: I suppose I could use a different mesh to represent the fighters when they aren't in combat, but I'd rather not do that. I think that that might adversely affect the visuals, and maybe make the combat kind of confusing to watch.
As for how dumb the non-leading fighter are in formation, they aren't really "dumb" per se, more so "oblivious." They do pretty much all of the same things as the leading fighter does, with the notable exception of scanning for targets. Though presumably the formation members wouldn't have to compute flight paths and stuff, they still do in order to stay in formation.
November 2nd, 2004
Well, I found one place that I can save a lot of polygons. I have nifty space dust floating around, which I was considering to have a negligible impact on performance. However, I noticed that the performance imapct was not so negligible. For some reason, the space dust was not getting cleaned up properly so when I called up my "thing tally" (which is just a debugging tool that generates a list of all classes of object in existance and how many of them there are) I found that for some reason I had 4 times the amount of dust particles as usual. This was of course a bug, which was quickly fixed.
However, it got me thinking - surely even 3000 of the dust particles couldn't have dragged down my X800 that much, could it? So I looked into it. Admittedly I'd never done the math. Surely 750 dust particles at 48 triangles each couldn't be that many polygons, could it? I busted out the calculator and my worst fears were confirmed. 36,000 polygons. That's one heavyweight particle effect. Granted, not all of those were on-screen at a time, but still, it was a lot of polygons to render and light just for the space dust effect. Now, I do want to keep the space dust effect - it's very handy to provide some reference frame for which direction you're drifting in and how fast you are drifting. Plus it's got the "ooh ahh" factor when you whiz close by a chunk of dirt and see it's all lit properly and even has smoothing groups on it.
Unfortunately, the polygon load is too high. So, I'm going to toy with the 4 parameters for the space dust and see what I can do with less particles. I suspect that I can achieve a similar effect with a lot less particles, as I have a hunch that most of the particles are too far away to be noticed. I can reduce the number of particles while reducing the size of the effect to keep the particle density the same. I'll play with that and see what I come up with.
I'm also considering making an "abridged" version of the older stuff in my developer's journal, and maybe making it into some tutorials or something. It's really big, and the wiki doesn't seem to like extremely large pages, so I've had to trim some stuff off of it. (This is probrably a timeout issue with uploading all of the text.) That stuff is still on my hard drive, but I'd like to keep it up here, though admittedly most of it is pretty ancient Gen 3 stuff.
November 2nd, 2004
Ahoy! It's time for me once again to squel with delight having spotted another area for improvement. I've massively improved the fine manuevering ability of the AI fighters. Gather round, ye all, to hear another long-winded tail of my train of thought and how it led me to this improved system.
Today as I was bored in class, I started scratching out a flow chart of a much more advanced docking system from what I had currently implemented. Previously fighters that wanted to dock would simply fly to within a certain proximity of the hangar they wanted to dock with, and wait. The problem with this method is they were often in the path of fighters launching, approaching the hangar at an awkward angle and running into something, or other such mayhem. The second one, I realized in class, was super easy to fix, all I had to do was have them approach at a certain fixed angle, relative to the hangar. (the direction of it's opening, of course) I'm not really sure why I didn't think of that before.
Anyways, that of course posed a new problem. If all incoming fighters were trying to come in at the same angle, obviously they would crash into each other. Easily solved, I thought, by simply having them wait in a queue like holding pattern. Of course, to prevent colliding with the fighters that might launch from the hangar, I'm then going to have to have the holding pattern be out of the way somewhat, in a direction that launching fighters are not likely to travel in. (Collision prediction is disabled presently for performance reasons, but it's suspended during launch and docking anyway to prevent craft from panicking as they close in on the hangar.)
So I have to have a queue of fighters, all maintaining a safe distance from each other and from the hangar, proceeding in an orderly fashion toward the hangar, and they can't be aligned with the hangar because that would block the launch of other fighters, so I now need some kind of controller to make sure that a fighter positions itself at the correct approach angle before launch... phew, better draw a diagram. Hence, I drew the first flow chart that I've made of my own free will. Normally I despise the things, as I'd rather hammer it out in code. However, I was stuck in class, and the professor was droning on about the influence of parenting styles on adolescent development or something, so I drew out the flow chart. The first one was sub-par, so I started with a fresh sheet and ended up using the whole sheet of paper for this flow chart, but alas, the whole process was planned out.
So, I go home, implement everything on the chart, and low and behold the fighters are positioning themselves all over the place, screaming into the hangar at full speed when it's already occupied, and other assorted mayhem. I briefly consider why I trusted a flow chart in the first place, but then set about getting the code working. A few oversights and typing mistakes later, the fighters are now lining up really sloppy, and ramming each other as they tried to settle into position. A short while later, I had it good enough that they no longer rammed each other (often) but had difficulty aligning themselves to the hangar and going in straight. Simply enough, their momentum was too great as they lined themselves up, and they didn't end up going straight into the hangar.
So I thought about this. The manuevering code had something in it to control drift (undesirable momentum) but it was commented out because I had inadvertantly coded it so that it also misinterpreted slight strafing movements as drifting. After enabling it, the fighters were flying all crazy, so while examining the function and trying to figure out why, I started to puzzle. Why did I have the cancellation of undesirable momentum and the application of desirable momentum handled separately? Surely I could just figure out what momentum I wanted based on the functionality I already had for computing acceleration/deeleration and figuring out, based on distance and acceleration/deceleration rate, the ideal speed to travel at.
It dawned on me quickly that I could make a simpler function that worked better if instead of finding an optimum speed, I simply find an optimum momentum, then I could compare it to my current momentum (desirable and drift) to find the change in momentum that would be required, and apply thrust based on this. I implemented that system and was very impressed. The AI pilots can now make tight manuevers much less recklessly and they are also a lot better at predicting their coasting and such when they decelerate to a halt. I haven't tried building any formations of fighters since implementing the new system, but I suspect that the fighters will fly in a much "tighter" formation with the new manuevering code.
So ends another trilling tale of intrigue from the dark corridors of my mind. Hrmm, actually that ended up being a lot longer than I thought. Maybe I should be a novelist.
November 9th, 2004
It appears that I've finally wrapped up the second "rotation in editor" issue. The solution was deceptively simple. I was trying lots of stuff with matrices and trig to try and figure out the rotation, but that wasn't working very well. Eventually I realized that instead of trying to artificially adjust the rotation of the components attached via sockets, I could just rotate the socket itself. Since the sockets don't normally use their roll for anything, and altering the roll would cause exactly the effect I wanted, I did that. I'm not sure why I didn't think of that before, but it's probrably because back in third gen I was using vectors for that which couldn't be rolled, obviously, so I probrably had the mindset that changing the socket was not an option.
November 10th, 2004
I'm so excited. Not only do I have a five day weekend starting today, but I spent most of the time I was in class today scheming and plotting. It seems I've found a way to build a 2-to-1 multiplexer that's twice as fast, a 4-to-1 multiplexer thats thrice as fast, an adder that's twice as fast, and a logic unit that's almost 5 times as fast. (one fifth the transistor depth, plus one transistor) It seems that the overly modular design of modern computers has resulted in much waste. Also I noticed how you can take two of the 2 to 1 multiplexers in the function unit and turn them into a dedicated combinational circuit that would be faster and use less transistors.
Unfortunately I have a relatively small selection of transistors at my house, and I don't want to pay the exorbitant prices at Radio Shack, so I'll have to contact my neighbor who teaches electronics at a high school and see if he has some I can borrow to see if the circuits I've designed actually work. If that doesn't pan out I'll see if the Verilog HDL has any syntax for specifying individual transistors and maybe I can do something with that. That's a last resort though, as the software I use for Verilog simulations (ModelSim) seems kind of shifty.
November 14th, 2004
Blech. Bugs seem to be coming out of the woodworks for no apparent reason. Code that was previously stable is now spitting out loads of accessed nones and other chicanery. One annoying bug turned out to be caused by things getting destroyed due to collisions mid-physics-simulation. Interestingly Karma suffers from the exact same bug. Some other accessed nones still remain, which I'm trying to figure out now.
In other news, I made a different fleet AI which was quite fancy. Unfortunately, it's much more processing intensive than the one I had before, and mysteriously causes GPFs. At first I put this down to using some things derived from Object to save memory, but when converted to Actor subclasses there were still GPFs. GPFs of course are the most annoying bug one could possibly have, as log statements leading up to the GPF don't get printed (they are still in the log buffer, which doesn't get flushed in the event of a GPF) and your options for debugging are fairly limited.
Well, that's that. I figured out why all the accessed nones were appearing now. At first it was quite strange as a new AI was causing accessed nones in the physics system, which seemed completely unrelated. Turns out that the flaws were in the physics system all along, but the new AI was smarter than the old one, and realized that blowing up ships while they are docked is easier than trying to blow up ones that shoot back. While docked, the ships are in an anomalous state where they are actually part of two ships simultaneously. (Themselves and the ship they are docked with.) When parts of them were dismembered, they were being removed from one ship, but not both.
So then, with that figured out I got back to work on the new AI. It's turning out to be a lot more complicated than I thought it would be - but seems like it should have good potential. The first system that I used built ships on a ratio basis, and periodically scanned it's squadrons to find idle ones, then found jobs for them to do. This ended up being relatively simple to implement and created a good illusion of the AI actually attempting to accomplish something.
The new system that I'm trying to implement is more or less the opposite: an objective manager determines things that it wants done, and the importance of each objective. This will probrably eventually become heirarchial, with subobjectives being determined to complete higher level objectives. Anyways, the squadron manager then has to rate the effectiveness of all of it's squadrons, and determine appropriate assignments, so the most important objectives will have the most "effectiveness" worth of ships dedicated to that task. Then, the construction manager looks at the assignments made by the squadron manager, and "fills in the gaps" by building ships appropriate to the objectives. For instance, if there was a lot of things that needed harvesting, and not many ships available for harvesting, harvesting squadrons would have priority for being built first.
The reason why this is complicated may be obvious at this point - you have an objectives manager, squadron manager, and construction manager working in concert, and objectives and squadrons have to be frequently reevaluated for changing importance or effectiveness. AI is also notoriously difficult to debug. However, I'm confident that the end result will be worth it.
November 16th, 2004
Hrmm. I haven't done anything with the mod in the last couple of days. I got laid off about 4 months ago. This coincided with my return to school, which was convenient. My original plan was to collect employment insurance while I was going to school, which I understood was a legitimate use of a program that I've paid out the hiney for since I started working at the tender age of 14. Apparently, however, employment insurance is all about ensuring employment for the workers at employment insurance office. (I'm aware that insure and ensure are completely different, but I like the way it sounds anyway.) Apparently, they accomplish this by explicitly advising people who have been advised of an impending layoff to wait until they have finished working, then 4 weeks after they've made an application and are under the guise that they are eligible for benefits they get a phone call notifying them that they are ineligible because they did not submit form X prior to the layoff. As a final insult, they send you a letter notifying you that any monies recieved at your termination, such as vacation pay for the portion of the year that you've worked, is not only not eligible for benefits, but actually gets directly deducted from the benefits that you aren't recieving.
So anyways, plan B was to live off of savings. As I'm frugal, I figured I should have no difficulty living for roughly a year on three thousand dollars. This budgets for car payments and car insurance, while leaving some left over for surprise expenses. Unfortunately, my grand plan did not compensate for the fact that so many games that I wanted would be released, nor had I considered that Christmas was going to happen.
So now I have to find work. At this point, you might be asking yourself, what, is this a blog now? What does this have to do with journaling development? Well, I have to do school work. On top of that, I have to find actual work. Unfortunately, this is not exactly prime time for finding work - apparently my options are babysitting, taking care of senior citizens, delivering pizza, shampooing carpets, telemarketing, or joining the army. Err.. yeah. You may have heard the term "overqualified." When I was younger, I didn't see how being "overqualified" could possibly be a bad thing, but it makes work a lot less fun. You show up, and work for a couple of hours before the manager is dropping a log because you're already better at your job than the rest of his staff, so you get promoted a few times your first day and all of a sudden everyone resents you because you came out of nowhere are usurped the promotion they were hoping for your first day. However, because you haven't yet had a chance to become acclimatized to the immense amounts of BS present in any corporation, from your elevated perch you can clearly see that the company you're working for totally blows and working there sucks.
Now, you might be thinking: Foxpaw, you didn't even answer the question. What does this have to do with you mod? Okay, I'll cut to the chase. Most of those jobs I'm ludicrously overqualified for. So I narrowed it down to: pizza delivery, because then I'll at least get to drive my fancy car and listen to my own music, plus I won't have to deal with as much corporate BS, and I'll get tips; or, the army, because then I'll get to play with guns and make explosions. Tomorrow I have an interview at Pizza Express, which is a less popular pizza place (my conjecture being that the more obscure the pizza joint, the less likely they are to have those things that go on your window or roof, as I don't want to risk damaging my $50,000 car so Dominos can advertise. I also have an interview with a recruiter for the 26th field regiment tomorrow. Although artillery is probrably the most boring of all the combat roles, it requires the least training and it also has the shortest commute.
So, now you might be saying: Foxpaw, you just dodged the question again. Okay, okay. I would prefer the army to pizza delivery. The army is not known for short shifts or lots of free time. I also have school work to do. Plus my family has sold their house so I have to move. I also have a purebred cat that I have to find a home for, and I just realized that end of term is like two weeks away and I haven't started a term paper in adolescent psychology which I'm doing crappy in so I can't afford to bomb on the paper. This paper is based on a book that I had to pick from a reading list that was supplied. Unfortunately, now that I've read the book I've come to the realization that it doesn't have any major adolescent characters so I'm going to have to fudge the whole essay, while making it sound good enough to get a decent mark so I won't get a lousy mark in the course.
So, I've got a lot of stuff to do for school, and I have to fit moving and finding a home for my cat in there. All of this stuff has deadlines, and I have to do that stuff while still going to class and likely spending at least 5 hours a day making craters. Plus I still have to fit in going to the gym. Weekends are also going to be busy as I'm trying to con, err.. I mean, convince my friends sister into going out with me. Hence, I have to spend all of my time on my growing "to-do" list, and I can't afford to spend any time on modding. So, there might not be many updates for a while. I'll probrably still pop into the wiki on a fairly regular basis, but I don't have any time to spend writing and debugging any code of my own.
The soonest I can foresee things cooling down is, like.. a month from now, when exams are over. Except.. errr.. well, crap. I just remembered that when exams end, we're moving, I have no idea where I'm going to be living for about a month, then we move into our new house, but for reasons I won't elaborate on too much I won't have Internet access until, like, the spring at least. I might be able to sneak in an update from the University, but there likely won't be any screenshots or any sort of media for a while.
I should have internet again in the spring. Hopefully the mod will be something that I can call "done" at that point. I've so far seemed to be suffering from some kind of compulsion: I have a vision of what the mod will be when it's "done." However, once I reach that point, my vision has grown to something larger. At first it was relatively simple, to have existing gametypes playable on spacey maps with customizable space craft. Once I had that, I wanted organized, custom gametypes where other ships would be objectives and stuff (like the "Carrier Assault" gametype I had planned.) Once I had that, I wanted it to be like an action/rpg/strategy kind of deal. It's like I'm never satisfied.
Anyways, we'll see. I just thought I should post so as to avoid postulation that the whole thing is "vaporware" or other such chicanery.
Mosquito: I'm nearly to grief stricken to comment! You're one of more innovative and intelligent minds in the whole of the unreal modding community! Real life sucks, but I guess you gotta set your priorities. I wouldn't recommend military though, unless you live in canada, because most other industralized nations are pretty engaged in conflict. Unlike canada, who would really like to do stuff, but just can't afford to send or return troops and equipment.
Foxpaw: I do live in Canada, but regardless, since I would be working only part time that would more or less disqualify me from service overseas.
Mosquito: Join the reserves, I know afew people in it and its not too bad. Its good money. Where abouts canada anyway, I don't know why, but I though you were english.
Foxpaw: I live in Manitoba. I went to see a recruiter yesterday, who gave me a stack of paperwork as thick as the Bible and told me that once I had filled it out I can expect a call within 1-6 months. Silly me, I had assumed that since they had a sign in front of the armoury looking for part time workers that meant that they were looking to hire people sometime this century.
T1: That sucks... to say the least. Good luck in getting a job you like. Hmmm... Have you thought of letting some other people to try to continue the development of the mod? But then again, I understand your dislike of working with other people.
MythOpus: Good luck with everything man! And I live in Canada Too. YAY CANADA!
Graphik: I know what you mean about never being satisfied with a mod. Just decide on a milestone, reach it and release. Then consider going further.
I have no advice for Real Life... it's so difficult to mod.
Mr.Mitchell: Sorry to hear about the problems you are facing. I never dropped a note in the journal, but I loved reading it. I wish you good luck with reallife.
December 31st, 2004
It turns out that fate has smiled on me, somewhat. The plans with regards to moving have changed somewhat so now I'm housesitting for the next three months, which means I have internet access. I'll also have internet access at the new house when it's built, as my parents have changed their mind about the wireless connection they were planning to get, which could not be set up until spring.
So I have internet until further notice. I don't know how much work I'll be doing on the mod though as the bedroom that I have the computer set up in is quite small and the computer is set up on the floor next to the bed which is not the most comfortable position.
I think that any modding I do in the next short while will probrably be rewriting some internal stuff. Circumstances resulting in the corruption of the test level have only recently been rectified. During the time when it was out of commission I wasn't able to work on the mod, but I did take some of the base classes and use them to make a mini-mod of a different type, the purpose being to test how abstract my abstract base classes were. This has improved my base classes somewhat, which will require minor tweaks to incorporate back into the main mod.
January 14th, 2005
Well, I haven't worked on the mod much at all. I'm considering rewriting some stuff but I don't want to do a complete rewrite again, so I'm a bit stuck at where to begin. I've decided that I want to separate the in-game physical representation of ship parts from their workings. This will require a lot of modifications.
The intent of this is so that I can have ships with no physical representation in the world, such as those harbored inside another ship. Right now the only kind of docking I can really do is to have a ship occupy a hangar, which is more realistic, but also somewhat problematic and much more resource intensive.
I'm also considering using objects instead of actors for a bunch of stuff but I don't know if that's a good idea or not. Objects seem to be kind of crashy even if you are careful not to leave any dangling references. However, the WeaponFire classes for UT2004 are objects, and they seem to work, so maybe I'll give it a try. I suspect that I may regret this decision, however.
On the plus side I realized that if I were to insert a few hacks I could probrably make a simple gametype using the stuff that's already implemented... so maybe I'll do that. I haven't decided yet. I've been pretty busy lately but I might have a few hours after work today, so maybe I'll see if I can hack together a gametype and maybe polish some things.
Also I had a couple of neat ideas for the HUD, particularly the radar, which I'll write more about when I have the ideas more finalized.
January 24th, 2005
I haven't made much progress. I've been pretty frustrated and unfortunately it looks like I might do another rewrite from scratch because I'm speculating that that might be simpler than retrofitting the existing code. Unfortunately, simply getting sufficient code updated so it will compile has been an exercise taking up several days. Seeing as it only took about 3 days to do a complete rewrite before, I might do that again.
I don't really want to though, as it means lots of work for little apparent gain. However, the changes must be made, so I think I may have to "bite the bullet" so to speak.
NickR: Any chance we might see some of your previous versions? Maybe the source code to those previous versions aswell? It would be cool to see exactly what you are trying to do.
MythOpus His previous versions (screenshots at least) are here > Foxpaw/Cosmic Fury As for his source, that's up to him.
Foxpaw: Err.. sorry, I don't have the source code to my previous versions, as per below:
March 3rd, 2005
It's been a while since I've updated here. I unfortunately haven't done much coding. I've been highly unmotivated to work on a new iteration of the code and I've been unable to decide between redoing it or finishing the stuff I had. Tonight I decided that maybe I'd finish what I had, but that was followed by the stark realization that that version was archived on my parent's PC. I recently formatted that PC for my parents. Although I backed up their stuff, I had forgotten that I had my own backups on there.
So, I'm stuck forging ahead with some redoing. Unfortunately, there's another fly in that ointment. Not sure if I updated this or not, but I now have two jobs. I'm working as a research assistant on a project involving spiritual interactions through machines.. or something. I haven't really payed too much attention to the theory behind it, as I'm taking the whole thing with a grain of salt. Regardless, someone got a research grant to do this, and it'll look good on my resume. My title of "Research Assistant" also seems to impress the ladies.
Anyways, I'm also working part time at McDonalds, which is sweet because I get food at half price, but more importantly there's tons of foxy ladies there. In light of the abundance of ladies this mod has had some difficulty competing for my attention, particularly as I've already figured out all the "fun" stuff. Presently the part I have to re-implement is the saving/loading code, which is rather dry programming, which hasn't helped either. I'm confident that I'll update eventually.
CIpen: Perhaps I missed it? Perhaps I didn't look or read enough? Was there ever any sort of release of your (Foxpaw/Cosmic_Fury) mod? Pictures at the Cosmic_Fury link is all that I discovered. I keep thinking I'm missing something that everyone else has
MythOpus: Sadly... there was no release. Nor was there even a beta (not to my knowledge anyway). He kept redoing the code when he got it to work hehehe. I say, we kidnap him and tie him up with a computer infront of him and force him to finish the mod. Then WE can steal it and say we programmed it. He won't be able to do anything about it because we would either have him still tied up.. or we would find some blackmail thing agaist him muhaha. HAH.
CIpen Hehe, MythOpus But why take so long? Why keep redoing it? I mean, there is a reason something might be messy. Either you just don't have time or it is just to many lines of code. If you write something from scratch normally you have it well organized. That stick shift car class I did is rather a good example of what BAD coding looks like, on the other hand you prolly wouldn't think it was me that coded the sun/moon package I did (uses an emitter for the sun and moon and lets you set the hours/colors of them at different times you specify). Well, my two cents is this: what's the use of a well oiled machine if it just sits around?
Foxpaw: I haven't had too much time to work on it lately, as I've been pretty occupied with other stuff. The intent of redoing stuff was to make it perform better and to expand the possibilities of what I could do. The first iteration was using UT, and the code kind of got messed up somehow. The second one was a very evolutionary sort of design that wasn't really planned out from the start and hence, wasn't very flexible. The next one was planned out, and worked, but had poor performance and some annoying issues with Karma that I couldn't work around very elegantly. Because of the poor performance, it was limited to about a dozen ships at a time, which was far too few for what I wanted to do. There was also things that didn't seem like they were going to work at all, such as having ships existing "outside" the map in other sectors and such. The next one had support for stuff in other sectors, and had persistent state loading/saving, and performed well enough to have scores of fighters flying about without a heavy performance hit. However, some things were starting to get a little hackier than I liked, and I saw room for some substantial improvements in performance (both computer wise and AI wise) that could only be realized with some changes to the code design. The rewrite shouldn't take a lot of "man-hours" to do, but time to work on it has been scarce as I've been occupied with other stuff.
I'm hoping this iteration will be the last as each successive iteration went much further than it's predecessor. The version before the current one had basically everything except for network code and a facility to have a "hangar" on a ship. (Ships could dock, but only external "docking" like a modern aircraft carrier was possible.) The new code has functional hangar code so that is at least settled. The rest is mostly just porting code over from the last iteration.
June 11th, 2005
I've been spending more time on this, so I've elected to finally make an update. Previous iterations of the code had some amount of "drag" on the ships so they effectively had a maximum speed. I've decided to get rid of that for more realism, to speed up physics calculations, and to improve the accuracy with which the AI can plan out manuevers.
This posed a problem of it's own. Without a max speed, I ended up going way faster than I had intended, and easily attained uncontrollable speeds. This was less than ideal and the great amount of momentum I accumulated made it very difficult to make quick manuevers to dodge fire, etcetera. I tried fixing this by reducing the power of the ship's engines, but that didn't quite work out. The ships went slower, but were not very responsive.
To solve this problem, I've implemented a "combat speed" setting. Basically, you have two controls for your speed, a boolean throttle control and the "combat speed" control. The "combat speed" can be adjusted to whatever speed you like, and represents the speed that you want the ship to travel. The ship applies full thrust when you have the boolean thrust control active and your speed is less than the combat speed you have chosen.
This allows you to keep the throttle control pinned all the time during battle without accelerating beyond your chosen speed. This has proven very helpful as it removes the need to attain speed, then "coast" at that speed until you need to change direction, at which point you must engage the thrusters again, etcetera. A ship that accelerates more quickly, of course, can have a higher combat speed while maintaining the same agility as a craft with slower acceleration, or keep the same combat speed and enjoy more responsive changes in direction. With the combat speed set to about what you can accelerate to in 2-3 seconds, you have good speed with good manueverability, or if the combat speed is at the speed you can attain after about a second of acceleration you can adjust direction quickly enough to evade incoming fire.
The other major thing is a new implementation idea for fighters. Previously, I was planning to have fighters be the same as any other ship, but they would be carried in carriers and spill out on demand to wreak havoc. While experimenting with carrier code, I had carriers that auto-generated fighters within their hangars. I had intended this only for testing, but it turned out to be really cool to watch. When I went to carriers that only carried existing ships, the battles were much less exciting as one fighter group would eliminate the other after a short time, and then the fighter-less carrier would be ganged up on by the fighters until it was destroyed. This turned out to be much less fun to watch than a carrier constantly pumping out fighters and being taken out through attrition against another carrier.
So, my plan is to have fighter carrying carriers as before, but to also have "drone carriers" that construct and launch flimsy drone fighters during battle. This is similar to using regular fighters in terms of combat effectiveness, but is far more entertaining. Drones have the advantage of requiring less micromanagement and requiring no resources, other than energy, to construct. Full size fighters retain the advantage of being many times as durable, having more powerful weaponry, and being able to use equipment such as warp drives and cloaking devices.
MythOpus: Foxpaw, you always seem to amaze me. I do need a bit of clarification on something though. Is this an RTS, a first person space ship shooter, or a combination of both? Who commands the heavy ships in the fleet (i.e. the carriers etc...)? I can't wait to see what this looks like. I want to warp into an area full of big ship, with a few backup fighters on my 6ix, and activate our cloaking devices and lay mines across the hulls of all the big ships and blow them all to hell
Foxpaw: It's kind of a mix.. Have you ever played the game Battlezone, or the distantly-related sequel, Battlezone II? Battlezone was an RTS played from first person - kind of like Tribes but you can build buildings and harvest resources and stuff too. Of course, you can also go into combat in any of your vehicles too.
This mod is kind of like that. It's sort of like Battlezone, but in space. So, you can fly any of your ships in first person view with a joystick or mouse or whatever peripheral you prefer. Any ships that you aren't directly controlled by a human are AI controlled and can be given various wingman-like orders: attack my target, escort my target, etcetera.
Multiplayer I expect to be a fairly free-form space sim with economic and combat elements. Single-player will probrably be a little more focused toward combat, but I haven't worked out the details of what sort of story that will have.
June 12th, 2005
Today I had to use Calculus to figure out a formula. Interestingly, I had to use Calculus II, which I've only just completed. Perhaps if I had not procrastinated so much I might have ended up frustrated at this problem. The issue at hand was having the AI decide what ships are best against what other ships. The formula for this was straightforward: it takes the attacker's tracking ability and divides it by the targets agility, then takes that and divides it by the estimated time it would take for the attacker to destroy the defender assuming the use of all weapon systems. Travel time to the defender is also added to the "time to kill," and the "time to kill" is limited to a tenth of a second to prevent needless overkill.
That part was pretty straightforward, but what wasn't so simple was determining the tracking speed. Tracking speed for turrets was simple enough - they have a max rotation speed already. Factoring the ship's own ability to turn was much trickier. Ships don't really have a fixed rotation rate but rather a certain rotational acceleration. So, I had to compute an average turn rate given the rotational acceleration. The average turn rate depends on the acceleration and the amount of time spent accelerating, and the amount of time spent accelerating depends on the distance being rotated and... the average turn rate.
Fortunately I remembered that a derivative essentially represents a rate of change - so the turn rate is essentially the rate of change of the ship's rotation, and the acceleration is the derivative of the turn rate. So all this involved was a couple of quick integrations, then a pile of algebra, and I eventually ended up with the average turn rate, assuming a 32768 URU turn, being:
(32768 / sqrt((2*32768)/RotationalAcceleration))/2
In-game testing suggests that this is accurate, as 32768 divided by the number given by that formula seems to be the number of seconds spent on a 180 degree turn.
MythOpus: That was so over my head it's not even funny = | That's okay though. I wish coding could be a lot simpler where math came into the picture. I wish you could just explain what you need done, like you did before... this and this ned to be taken to the twelth power but only if it is above this number and if it's this number than make it destroy that other ship. Ugh. Even that made my head hurt
June 13th, 2005
Well, I've been fairly active on this, so with any luck mod production will be back in full swing again. I've hit a minor setback today that I'm not sure what to do about.
Using objects instead of actors and various clever optimizations, I've been able to increase the number of ships that can be flying around doing stuff simultaneously. Increased significantly, in fact, so literally hundreds of ships can be in play at a time. I haven't stress tested to see how high it can go before the framerate starts to drop.
However, I've hit a minor snag: the physics, etcetera seems to be able to handle tons of ships everywhere without a hitch, but the "fleet command" AI hasn't been so friendly. The fleet command AI operates using a list of objectives, and a list of squads. Each target that needs to be waxed has a "destroy" objective associated with it, each harvestable resource a "harvest" objective, etcetera. Periodically, the AI generates a table of the effectiveness of each squad with regards to each objective. It then uses this table to pick the best squads for the given job, and how many forces are needed to win a given battle, etcetera. All in all it gives quite intelligent behaviour. Different fleet behaviours can be elicited by modifying the relative importance of different objectives, which is factored into the effectiveness table.
The problem with that is that it grows exponentially. So, for instance, 10 friendly squads versus 10 hostiles creates a table with 100 cells. 30 friendlies versus 30 hostiles, however, creates 900 cells. The number of entries in the table quickly escalates as the number of ships and the number of targets goes up. As a temporary fix, I have limited the frequency of squad redistribution to a function of the number of squads and objectives. So, basically, as the table grows, the time between updates grows at the same rate, causing the processing time used by the AI to be fixed regardless of fleet size or target numbers.
However, I can see how that might become a problem, if the frequency of updates gets too long, the fleet will have sluggish responses which will prevent fighters and drones from fighting effectively. It would also make AIs somewhat susceptible to swarming by drones, as a large number of targets could make the frequency of updates too slow for efficient targetting.
Since the vast majority of squads that the AI controls are drones, I have considered having drones and turrets use a separate, more crude targetting method. that will remove a lot of the squads from an AI player, but unfortunately does nothing to reduce the number of targets. It also has the disadvantage of having drones fight less intelligently, which is definately less than ideal.
I could also reduce the problem by reducing the number of drones and increasing their power. I'll toy with the drone maximums and see what kind of results I can get. I'm a bit concerned that having too few drones will remove the fireworks show that occurs between battling carriers. I'll try it out and see how it goes, however.
June 14th, 2005
I've reached a sort of temporary solution by implementing a "performance throttle." This is an idea I had used before for graphical elements to scale back particle effects when the framerate starts to dip. Basically, the higher the framerate, the more frequently the AI updates. If the load on the scripts gets too high, the AI will update less frequently to compensate, which is handy.
The only slight snag with that is that the AI, if it has enough ships and objectives, can still cause a noticeable "jerk" on the frame that it does update on. I'll have to see what optimizations I can make to speed this up.
June 15th, 2005
Today I was playing around with MeshSpawning on Emitters. I had the clever idea of using MeshSpawning on arbitrary meshes, then extracting the locations of the spawned particles, to in effect extract vertex information from the model. I got some good results with this, but not as good as I had hoped. I had envisioned collecting vertex information, and sorting by distance from the point of impact of some weapon, to have a shield effect whereby the shield "haze" would spread across the hull of the ship from the point of impact outward.
Unfortunately, I needed to collect and sort about a thousand vertices to make the effect move smoothly over the hulls, and the amount of processing involved in collecting those vertices and sorting them caused a "hiccup" every time it was performed. I may still make use of this for effects requiring less smoothness, like perhaps lighting arcing over the hull away from the point of impact of some EMP weapon or something like that. That would require a lot less vertices to make a nice effect.
MythOpus: I think a shield effect that would require less amount of processing power is the shield system found in good old Homeworld: Catyclysm. The sentinels shields are simple, and not very flashy, but if you were able to modify it but keep the basic principle, you might not have to go through all this vertices sorting and what not. You could flash up the shield effect and make it appear only after the ship was hit or something.
Foxpaw: It's been a while since I've played that. I don't remember what that effect looks like, so.. I don't really have much to say about that, but I thought I'd respond so you didn't think I was ignoring your comment.
June 16th, 2005
Well, I optimized the vertex collection and sorting a whole bunch, to the point where it might be feasable for some use, so long as it's not used heavily. Once I had a shield effect working like I had envisioned it, I decided that I didn't want it. It was rather slick and high-tech looking, which made it look quite out of place amidst the backdrop of fire, smoke and dust provided by exploding drones, missiles, and cannon fire.
I also made some optimization to the fleet AI.. unfortunately it's only about 12% faster, but on the plus side the optimized code actually ended up with less lines of code and fewer variables required, so the code is a bit cleaner from that.
June 18th, 2005
I put together a cruiser to test out some stuff yesterday. Other than that I was making minor tweaks. I have noticed something interesting with the capital ships, however. All ships have access to automation on various components. AI players use all of the automation options, and then provide a little additional guidance. I've found that this is the most effective way to fight for humans too.
Since the majority of weapon systems on a capital ship are turret mounted, or guided missiles, the tracking computer and targetting computer end up doing most of the fighting for you. Of course, you can do these things manually, but it doesn't make a lot of sense. The tracking computer can track more precisely and with faster response time, and the targetting computer can consider many more targets in a given time span than a human could, and make very good decisions about whom to attack and with what weapons. In effect, the automatic tracking and automatic targetting greatly exceeds the capabilities of any human.
I'm not sure what to think of this. The fighter combat is highly technical - aiming and manuevering which relies on one's hand-eye coordination and quick thinking. The capital ship combat stands in sharp contrast to this. The capital ship combat is far removed from one's technique. Since your turrets can target, track, and fire on their own, and given the ponderous pace of capital ships, the combat ends up being much more strategic and based on planning and shrewd strategic decisions rather than split-second decisions and precise handling of the controls.
I've found this to be an interesting way to fight in a space sim. You can turn to bring the target into the range of motion of as many turrets as possible, or turn to present a less damaged side of the ship to the enemy at a cost of preventing some of your turrets from hitting the enemy. You can close with the enemy to bring more weaponry into range, or try to keep the enemy at range to minimize the number of weapons they can bring to bear on you. You can target a specific enemy, forcing more turrets to fire on that target - allowing you to concentrate your fire at some cost of efficiency. (Your turrets will automatically target the ship that they can eliminate the most quickly without overkill, so anything that you manually target is a "worse" target than the ones your turrets are already attacking.) Other ships can also be given orders to attack or protect certain targets. (Though again, they generally fight more efficiently by themselves, but there are cases where their judgement may not be the best.) The role of the human player in a capital ship, then, is more like a general or an admiral rather than the bridge commander of a ship.
June 19th, 2005
I made a major optimization to the fleet AI today. Originally, the different combat arrangements were sorted using QuickSort and then the best one was taken off the top. The list was then stripped of all assignments that required the use of that squad, the tactical value of targets that the assigned squads were attacking was reduced (as they are already being dealth with, so the rest of the fleet can engage elsewhere) and the assignments involving that target were then reinserted appropriately into the list. This process was then repeated so that the lesser squads could get assignments without affecting the movements of the most major squads. I later optimized this as I found that QuickSorting the entire list again was faster than reinserting the modified members. This is the 12% speed increase noted above.
Today, I tried something different. I was trying to get more speed by trimming the list - not including assignments that would not get picked anyway, to make less work for the sort. Then I thought, maybe I can get away without doing the sort at all. To this end, I tried using a linear search to find the best tactical arrangements instead of sorting them. This seems to be far faster than sorting the list and going in order. I suppose sometimes the cost of being disorganized is not high enough to justify cleaning up. Unfortunately I don't think many spouses would go for that explanation.
I also did some relatively boring bug-hunting. Oddly, I had a division-by-zero that was crashing the engine. I found this quite peculiar as I understood that the engine gracefully handled division by zero by returning the maximum integer or maximum floating point value. (as the case may be) This one took a long time to figure out since the engine was crashing, leaving me without the benefit of logs to find the problem.
Now, with the bugs cleared out, all the stuff for combat is basically hammered out and some of it has been minorly polished. There's things I still plan to implement, but the stuff required to have a scrap is in place and working.
Hence, I have elected to focus on the economic side of the game - gathering of resources, construction of ships, pillaging helpless convoys, the usual. I'll probrably set up a testbed area for this tomorrow.
June 20th, 2005
So freighting stuff around, docking, undocking, and fleet AI coordination of such is all working. Economic stuff turned out to be way less action-packed than fighting. Then I thought it would be neat if there was pirate ships to harass the stations. Then I thought it would be better if the pirates had a fleet of ships. To counter this, I gave the trading group a fleet of ships too. At this point the economics stuff kind of went out the window and I was focusing on combat again.
I expect that I will do more economy-based stuff later. I still have to make mining stuff and something to deal with ship construction. However, I've become slightly sidetracked with the combat stuff.
Combat wise, I've made the missiles follow a drunken path, which seems like a good idea, as a missile following a drunken path would be basically impossible to intercept with another missile. It also looks much cooler. When a ship launches multiple missiles, it looks kind of like the "swirl" thing on the UT2004 rocket launcher, but much sweeter. The drunken missile code was fairly simple, basically I take the sine of the distance to the target multiplied by a random constant. This constant is determined at fire time. The sine is then applied to one vector perpindicular to the missile. Another sine with a different constant is applied to a vector perpindicular to the velocity and the first vector. So the path isn't truly random, but it is still much more complex. I'm considering having the constants change in flight randomly which would give a truly drunken path.
Presently the fleet AI functions at roughly the level of an English Admiral, circa 1600 AD. At this point, ships are moving to combat individual targets based on an assessment of target capabilities and their own capabilities. Their strategic sense is excellent in this sense, but it causes the ships to get somewhat "mixed up" as they close on each other. Shortly after the 1600s Robert Blake developed the "line of battle" tactic, whereby powerful, tough ships would line up to broadside an enemy fleet. Positioned end-to-end, friendly fire was eliminated, which was a problem with the previous tactic of squaring off with individual targets.
My ships don't have a problem with friendly fire. This is because they are fairly good shots and the three dimensional nature of space combat means that the lines of fire rarely cross a friendly ship, even when the target is surrounded. For this reason I'm not sure that I want to implement "line of battle" tactics. Artificially restricting the movement of the ships might make them less effective. On the other hand, it would make for a gap between the battling sides, which might be more visually pleasing, and it would also prevent the occasional case where two ships, battling back and forth, end up manuevering quite far away from the main conflict.
A third possibility is the tactics popular today, the so called "battle group" tactic. The "line of battle" fell out of popularity near the end of world war II as a bunch of battleships end-to-end in a straight line were an amazing target for bombers. (SAM systems did not exist at this point) The "battle group" tactics basically has one large ship supported by other ships. So, an aircraft carrier, for instance, would move about, and a number of cruisers, destroyers, frigates, and submarines would follow in formation, providing anti-air, anti-submarine, and anti-torpedo support. The main disadvantage of this tactic is that a lot of your firepower is wasted as the destroyers, etc. are not in range of the enemy battle group, so they spend a lot of their time screwing around.
In other news, there MIGHT be a video coming soon. The combat is looking fancy, but screenshots seem to turn out a bit stale looking so I'd like to produce something in motion. However, a video takes a lot more time to prepare, what with video editing and such involved. I've included some screenshots in this journal entry even though they don't really do the mod justice in my opinion.
(a) (c) |
(b) (d) |
(a) These missiles are drunker than a teenager at a grad party.
(b) Naval Combat, circa 1600 AD.
(c) "Line of Battle," circa 1700 AD.
(d) Sucks to be that guy.
Bonehed316: This sounds really cool. The pictures dont look as cool as the idea sounds, but I'm sure it looks much better in person. For your missiles, I have an algorithm that sends missiles to a "midpoint" location, which is located somewhere between the weapon (or whatever is firing the missile) and the target, then offsets it so that the missiles all spread outward, once they reach that point, or travel in that direction for a specific amount of time (determined by the distance between the two objects), they then switch "target location" to the actual target's location. The result is a more interesting flight pattern, and is very useful for multiple missiles fired at once. The only problem I forsee with a drunken pattern is it might increase the possibility of missing your target.
Foxpaw: Ah, the missiles don't fly a random pattern, as it appears they do. Since their offset is a function of the sine of the distance to the target, when they reach the targets location the distance is zero, so the sine of the distance is zero, hence the offset is zero. For that reason, the "drunken" flight pattern is actually just as precise as a straight flying missile.
June 26th, 2005
Today I implemented some mining stuff. Mining lasers, asteroids, and a technical means of storing these as cargo without using tons of resources were implemented. I plan to implement a few other means of mining, specifically I want to have mining drones, and mining bases that you could deploy onto asteroids.
To coordinate this I had to expand the AI somewhat to have an economic controller. Previously I already had a means to coordinate freighters' pickups and dropoffs. The economic controller generates the "work orders" for the freighter management. It also generates "work orders" for resourcing vessels, and decides when they should drop off the stuff they've mined and to where.
So presently the testbed area contains a cluster of asteroids, a mining station, mining ships, freighters, and a space city. The miners mine from the asteroids, drop that off at the mining station, then the freighters load up at the mining station and carry haul the minerals or whatever to the space city, which is some distance away.
Speaking of some distance away, that blasted 60,000 UU render distance is giving me trouble again. I scaled everything down to get rid of that the first time, which worked good at the time, but as things have gotten bigger, it's creeped up on me again. The space city and the mining station cease to be rendered before they shrink away to nothingness, causing undue ugliness when they pop into view. I could rectify this by scaling everything down again, but I don't really like that idea, as it means I would have to scale down all the special effects and sound and light radii, which would take a while to get nicely balanced again. I may have to reinstate the "imposter" system used in the third generation to deal with this thorn in my side.
Mosquito: why not just use distance fog that makes the large city fade away into the backround before it could ever stop rendering?
Foxpaw: I have been using the distance fog but the two problems with that is firstly that it fades to a fixed color, and the backdrop behind it is not one constant color, so you can see a "silhouette." The other problem is that at the distance where it stops rendering (the point at which it is completely fogged) is still close enough to the player that it's sort of unrealistic to have it disappear from the screen.
Mosquito: What about fading it Alpha wise?
O-GL Very interesting reading all your recent updates Foxpaw. I guess the imposter system would be best for this problem. Hopefully the imposter system doesn't use too much processing power. Alot of games with such large view distances have things popping into view or have them popping in with a silhouette. Of course, it isn't optimal for the game experience to have any 'popping' at all – but as long as the player can play the game with the opportunity to interact with all targets, that is all that matters.
I haven't updated my wiki page for a few years, but your efforts here are really motivational for me. One question: what changed in your life so that you could work so much on your mod?
Bonehed316: In homeworld, for example, they explained the "popping" with sensor distances. When a ship wasnt in any of your fleet's sensors, it wouldnt get drawn. This isnt so easy for you, but it IS possible. You simply need a "sensor" object, and use its collision cylinder to detect when pawns (or whatever you use) touch it, but is not a projectile target so things wont shoot it. Any actor will of course trigger the Touch/UnTouch events for the sensor object, which can then unhide other actors, or whatever so they are drawn. But that may not be what you have in mind, but it is one solution.
OR you can borrow an idea from Angel Mapper and rig the materials on the ships that come into view with a material and adjust the transparency.
Foxpaw: I have considered the "sensors" thing but I'm not sure if I like that idea or not. The major issue that I see with it is that one would expect your sensors would have a farther reach than your visual range.
I've been working on the mod much more lately, though I'm not entirely sure what has given me more time. I think I might just be procrastinating less.
O-GL: Do you have a part-time job? What job did you end up getting and how much time does it take up?
Foxpaw: I'm working as a research assistant at the University and at McDonalds part time. McDonalds is about 20 hours a week, at the University, it's supposedly full time but in reality there is a fair bit of downtime when meetings have to be scheduled around other people and stuff.
Switch`: The far clipping plane is at 65536uu, you can change it by editing Core.dll, in 3355 it's a float at offset 0xAD96C.
July 6th, 2005
I mostly only have technical stuff to report. I've been making various improvements all around, until today when I did some meatier stuff. I noticed there was some slowdown that was occurring when I tried a pirate spawning test.
In this test, pirate ships randomly spawn around the area where mining or freighting operations are taking place. This is in place of a proper pirate faction with it's own AI and other such goodies, which will be in place eventually. Although the ships spawned more quickly than I had intended, this does not appear to be the cause of the slowdown as the number of ships spawning was not great.
To track down the problem, I started profiling code. This was rather easy as I had previously made my own code to tick my ships and parts and stuff. I hadn't written about this earlier, but it's quite nifty. I can control the order in which things are ticked, making the AI more accurate. First, ships move, then AIs adjust their movement controls and aim. Then, turrets get ticked, allowing them to move to the new directions desired by the AI. Finally, weapons get ticked. (There is other stuff in between too.) This order allows turrets to hit targets at their new position instead of sometimes being a tick away. (Depending on the order in which they are spawned.)
Isolating the ticks like this also allows for some super nifty stuff, like having ships get more or less delta in a given cycle to have time dilation or stasis effects without any hacks. Another very useful possibility is that it will allow me to tick ships that are very far away from the player or in other systems less frequently (with a higher delta) to reduce computer resources dedicated to them.
As a side effect it also makes it easier to find where optimizations can be made. First I discovered an oversight in the turret code that was making it use far more resources than were necessary. With a few changes I cut their running time to a tenth of what it was before. The other big user of tick time was the ships themselves - most specifically their physics.
While optimizing the ships physics things didn't go so well. I accidentally introduced a bad bug that I had a very hard time tracking down because I introduced that bug in a very commonly used part of my math library, so it was producing odd behaviours and using WinDiff between current versions and backups of the files that I thought were the relevant classes revealed no changes. I also found something else problematic.
When looking over the physics code I found a place where there was a possibility of parts maintaining some physics related references to parts on a different ship, if those parts had been on the same ship but had been separated by damage. I hadn't caught on to this because the design of the ships I've made is prone to having all the small bits stripped off before any major structural components are destroyed.
This turned out to be somewhat difficult to solve. To do this cleanly I was going to have to break apart the entire ship, maintaining all heirarchial information, and then reassemble it. The reassembly would correct all physics references. To maintain the heirarchy, I tried using a struct. This struct contained a reference to one part, and a dynamic array of more such structs. It was, essentially, a tree structure.
Unrealscript didn't like this. I don't know if it was the tree-ing of structs that it didn't like, or simply the referencing of Objects from within said tree. I'm inclined to think the latter, given Unrealscript's general attitude toward Objects. I was getting wierd behaviour like a GPF if I tried to assign anything to any element of the dynamic array, except the first element. I ended up solving this using Objects instead of structs. I was a bit apprehensive about using Objects for this as I suspected that they would be more prone to crashing than structs. It appears my concern was unwarranted in this case.
With all that I never did get around to figuring out the source of the slowdown with the pirate spawning. I'll probrably get to that soon.
July 27th, 2005
I haven't written an update in a while, but I have been doing stuff. Mostly technical improvements, so there hasn't been much to say. I don't have much to say about that since a large problem has come up.
Tragedy has struck. Though I may never know how a piece of software operating in protected mode can cause permanent damage to hardware, it seems possible. While extracting some files from an archive using WinRAR, the computer froze up and the hard drive was making a funny noise. So I rebooted without incident and breathed a sigh of relief as no data seemed to be damaged. (My backups had somewhat recently been erased as the computer they were on was reformatted.) Assuming this was some wierd fluke, (I had another idea about what might have gone wrong, but I won't go into the boring details) I tried extracting the archive again, with the same results. A lockup, accompanied by a wierd noise from the harddrive.
So I tried rebooting again. Wierd noise from the harddrive on startup this time, and the disk isn't autodetected by the BIOS. My harddrive has a jumper setting which stops the platter from spinning, and the drive autodetects in this setting, but for obvious reasons it does not function. The wierd sound that the hard drive is making sounds like one of the heads is continuously sliding back and forth between the extents of it's travel. The drive makes this sound even with the IDE cable disconnected, so it appears there is damage to the harddrive and not to the BIOS.
Tomorrow I plan to look into my options. If the head can be repaired without destroying the data, I may be able to recover the data. However, if the head has contacted the spinning platter (which seems plausable given it's obvious hardware malfunction) all the data will be lost. If that is not the case I may be able to transplant the platter into an identical drive and get at the data that way. Though I believe I have the tools and the know-how to prevent dust from getting into the drive and possibly to perform a successful transplant, it will require endangering a brand new hard drive, so I'm not too keen on that idea. On the other hand, losing all the data would be the pits, as I had an important database, and of course the mod and the operating system that I had more or less completed on the drive.
So I'm going to look into my options tomorrow and play it by ear for now. Since this coincides very badly with the loss of the backups, it might mean a start from scratch if all the data has been lost. That would be very unpleasant since this iteration of the code is the first for which I did not see any way in which I could improve upon it if I did it again.
We'll see how things unfold from here.
Graphik: Online file storage = good.
July 30th, 2005
It appears that I have little recourse with the failed harddrive, so all my data is lost. This is quite unfortunate.
As far as the mod goes, I could remake everything from scratch, creating yet another iteration, but I'm not sure that I want to do that. I don't see any way that I could improve upon the previous iteration, so redoing everything would be kind of boring. On the other hand, I've worked on this a long time and it would be a shame if I end up with nothing to show for it. I also don't want to disappoint those people who may have been eagerly awaiting a release. I also quite like the idea but I doubt it's mainstream enough that a commercial game studio would ever tackle it, so if I ever hope to play such a game I may have to make it myself.
I might try doing a completely different style of mod instead. I'm not really sure at this point. For now my plan is to play some games, and see if I get any ideas or if perhaps an unmodable game with no sequel on the horizon cries out for more. (like Manhunt)
T1: You know, the only thing I've been wanting to play more than this mod is coding for Unreal Engine 3 (not the actual games...) and TES4: Oblivion.
September 2nd, 2005
I've decided to try to write a compiler. This is detailed on the root of my personal page, Foxpaw. That specification will likely be moved out to a different location at some point. Most of the functionality is complete at this point, but using it to compile a mod is as yet not possible because I don't have everything for inheriting from classes in other packages working.
My original vision was to make a compiler that is completely compatible with Unrealscript, and then add functionality to it. However, I'm no longer sure if that's what I want it to be. Writing a compiler for UnrealScript is turning out to be more complicated than I had expected, as the syntax of the language has many exceptions to it. Unrealscript also has many language features that I have very little interest in, and some features that I would like to implement would require adding yet more exceptions to the language.
Now I'm wondering if I should instead try to standardize a little bit and instead of making exceptions in the compiler to handle nuances of UnrealScript, I could instead modify UnrealScript for more straightforward compilation. I could make more powerful language features from within a more straightforward language.
However, compatibility with Unrealscript was a fairly central part of what I was trying to do, so I'm not keen on changing that. I'll make some decision on what to do, maybe in a few days. I haven't been spending much time on this, so it might be a while before I can release anything.