My program doesn't have bugs. It just develops random features.
There are two groups of log warnings, native warnings and script warnings. Script warnings can be generated manually from UnrealScript through the
Script warnings generally have the following structure in Unreal/UT:
ScriptWarning: <name> <object> (Function/State <function or state name>:<adress>) <text>
In UT2003 script warnings begin with "Warning:" like the native warnings described in the next section but still contain name, object, function, etc.
- The class name of the object the warning was generated for.
- The name of the object (complete name with package) the warning was generated for.
- Function if the problem occured in function code, State if the problem occured in state code.
- <function or state name>
- The name of the function or state (with names of the state, class and package) that caused the warning. This refers to the actual function/state name the problem occured in. Note that this could also point to a parent class of the actual class or the parent state of the actual state.
- This is an internal hexadecimal adress and isn't helpful with finding the actual line the warning was generated for.
- A description of the problem. (see below)
Script warnings don't include information about which function called the function that caused the warning. You have to figure that out yourself.
- Accessed None
Probably the most common error message in the log file. This error occurs whenever lines like
Owner.SetPhysics(PHYS_Falling); i = Owner.LifeSpan;
are executed and Owner is set to None.
- Attempt to assigned variable through None
This is less common and always shows up together with an Accessed None warning. If you get this warning look for a line like
Owner.LightType = newLightType;
in the code and check Owner.
Note: First there's the Accessed None warning (for accessing None.LightType)
- Accessed null class context
This error occurs whenever the default value of a class variable is accessed while the class reference is None. If you get this kind of error look for something like
x = aClass.default.Property;
in your code and check why aClass is None.
- Accessed array 'variable name' out of bounds (index/length)
- This warning is generated when you try to access elements of a static or dynamic array with an index greater or equal its length or less than zero.
Native warnings don't have a special structure except that they usually begin with "
Warning:" followed by the warning message. However, not all lines beginning with "
Warning:" actually signal problems, some of those are just status messages. (These are described at the end of this page.)
- Failed to load 'NULL': Can't resolve package name
Failed to load 'object class None.object name': Can't resolve package name
- These two lines appear together and are caused by the
DynamicLoadObjectfunction when trying to load an object from a non-existing package. Object class is the class specified as second parameter of
DynamicLoadObjectand could be e.g. "Class", "Texture" or "Sound". Object name is the actual name of the object that should be loaded. Note that the object's package name is set to "None" because the package could not be loaded. (which caused the first warning)
- Failed to load 'package name': Package 'package name' version mismatch
- The client and server version of the package are different, i.e. one isn't an exact copy of the other. This can be bypassed in UT (not UT2003) by network-conforming the package, but you should first make sure that client and server still understand each other.
- SpawnActor failed because no class was specified
- SpawnActor failed because class classname is abstract
- SpawnActor failed because classname is not an actor class
- SpawnActor failed because class classname has bStatic or bNoDelete
- An object of the specified class could not be spawned. You can only spawn actor classes that are not abstract (see Class Syntax) and have neither bStatic nor bNoDelete set to True.
- RPC bunch overflow
- The engine tried to send a network packet larger than 500 bytes. There are two ways to end up with an overstuffed packet - too many replicated function calls (or Remote Procedure Call) in a single tick, or a property that is being replicated has a value larger than 500 bytes. You are sure you don't have any properties that are that large, you say? Here are some caveats of atomic replication that you may not know:
- Static arrays are replicated atomically. If you change the value of one member of your replicated static array of 10 strings, all 10 strings will be replicated. Ergo the size of your entire static array must be smaller than 500 bytes.
- Structs are replicated atomically. When any value in a replicated struct is changed, the entire struct is replicated.
- Parameters for replicated function calls must all be replicated in the same packet. If you have a replicated function call that takes multiple parameters, the cumulative size of all parameters cannot be larger than ~500 bytes.
- Localization: No localization: property (type)
- This warning means, that the
Localizefunction couldn't find the specified entry in the language file of the given package. Property is the name of a property with the desired package and section name. Type is the requested data type, e.g. int, string, etc.
Harmless Log Lines
Log file lines which begin with
Warning: but aren't real warnings.
- Warning: stage 0: number secs
Warning: stage 1: number secs
Warning: stage 2: number secs
Warning: stage 3: number secs
Warning: Total: number secs
- These lines just indicate that a downloaded package is being decompressed.
Mychaeel: Evolution writes:
Static arrays are replicated atomically. If you change the value of one member of your replicated static array of 10 strings, all 10 strings will be replicated. Ergo the size of your entire static array must be smaller than 500 bytes.
However, Tim Sweeney writes in Networking Architecture:
Arrays are replicated efficiently; if a single element of a large array changes, only that element is sent.
So – what's the deal?
Wormbo: We had a discussion about that on IRC already and we're not really sure. Evolution has this information from Steve Polge. However, Pfhoenix also thinks it's the way Tim Sweeney described it and I did a little testing with an array that should exceed the magical 500 bytes limit (a static array with a length of 128 consisting of structs with one string and one integer value; integers are 4 bytes, aren't they?) and it replicated without problems or log messages.
Evolution: Yeah but what does Tim Sweeney know? :)
Wormbo: Obviously he knows more about array replication than Mr. Polge. Even an array with 512 elements (that's definately more than 500 bytes) replicated fine.
El Muerte TDS: why 500 bytes?
Evolution: I'll verify all this in a few days, at which point I'll remove these comments; most likely it was just a brain fart on Steve's part.
EricBlade: Not sure if anyone ever figured this one out, but I think it's dynamic arrays that are replicated efficiently, and static arrays are not. And it is possible that newer engines may have had some of these restrictions eased/removed.
Wormbo: Not for UT2004 – dynamic arrays aren't replicated at all and static arrays are considered as individual variables for replication.