Loading in Level troubles.

Started by
10 comments, last by Moe 11 years, 11 months ago
So, my team is using a level editor that saves out the level in xml. while trying to read in the level into the game, i get this error message.

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll.

I have gotten the level to load in correctly, but i have to comment out 2 lists that we're going to fill ourselves. the 2 lists being one for our actors in the level and trigger points. once these 2 lists are out of the picture, it loads in like a charm.

any thoughts on why I am having this problem and/or how can I fix it? I've tried google but to no avail.

I'll gladly provide any information requested to help solve this. Thanks in advance!
Advertisement
What happens when you have "Break on all exceptions" turned on in the debugger? Where specifically is it breaking? Is there any additional information in the exception (such as an inner exception)?

Posting the data being loaded and the specifics on how you are loading it could be helpful.
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll
Additional information: There was an error reflecting type 'MayhemOverlord.Utility.Level'.

is the full error message.

it breaks on my load from file function which looks like


public static Level FromFile(string filename, ContentManager cm)
{
FileStream stream = File.Open(filename, FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(Level));
Level level = (Level)serializer.Deserialize(stream);
stream.Close();

foreach (Layer layer in level.Layers)
{
foreach (Item item in layer.Items)
{
item.CustomProperties.RestoreItemAssociations(level);
item.load(cm);
}
}

return level;
}



this is the specific line XmlSerializer serializer = new XmlSerializer(typeof(Level)); causing the crash.

I also turned on "break on all exceptions" and got this:
Managed Debugging Assistant 'BindingFailure' has detected a problem in 'C:\Users\Sneaky123\Desktop\RedBarrel\MayhemOverlord\MayhemOverlord\MayhemOverlord\bin\x86\Debug\MayhemOverlord.exe'.
Additional Information: The assembly with display name 'MayhemOverlord.XmlSerializers' failed to load in the 'LoadFrom' binding context of the AppDomain with ID 1. The cause of the failure was: System.IO.FileNotFoundException: Could not load file or assembly 'MayhemOverlord.XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Your list of items isn't by chance a list of lists, is it?
No sir, just a list of actors and a list of triggers. the actors i believe is self explanatory. and the triggers are points or sections of the level where scripted events will occur.


public List<Actor> Actors = new List<Actor>();
public List<TriggerLevel> Triggers = new List<TriggerLevel>();

for visualization purposes
Would you be able to zip up the code and post it? I might be able to take a look at it tonight.

If you try commenting out/removing portions of each list within the XML, how much are you able to get it to load? For example, if your xml looks like


<Actors>
<Actor>
<SomeVariable1>1</SomeVariable1>
<SomeVariable2>stuff<SomeVariable2>
</Actor>
</Actors>
<Triggers>
<Trigger>
<SomeVariable1>1</SomeVariable1>
<SomeVariable2>stuff<SomeVariable2>
</Trigger>
<Trigger>
<SomeVariable1>1</SomeVariable1>
<SomeVariable2>stuff<SomeVariable2>
</Trigger>
</Triggers>


... what happens when you try to load something like:

<Actors>
</Actors>
<Triggers>
</Triggers>

Does it still choke?

For whatever reason, I'm having a difficult time seeing what could be wrong. The "[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]System.IO.FileNotFoundException" makes me think it could be something completely different, or something as simple as an attribute on a class that's missing.[/background]

[/font]

actually when I comment out the 2 lists, it works perfectly. no crash, level loads and runs smoothly. I just can't fathom a reason why those 2 lists affect the loading in at all because the loader doesn't even touch them. they get filled in my initialization function. as for zipping up the code, I'll try to do so.
ok, Sorry to sound like a noob, but how would i go about posting it up in here?


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using FarseerPhysics.Common;
using FarseerPhysics.Common.Decomposition;
using FarseerPhysics.Common.PolygonManipulation;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using MayhemOverlord.Actors;
using MayhemOverlord.Actors.Humanoid;


namespace MayhemOverlord.Utility
{
enum LevelState
{
Intro,
CutScene,
Playing,
Continue,
GameOver
}
public enum TriggerType
{
Cutscene,
Spawn,
CheckPoint
};

public struct TriggerLevel
{
public string name;
public int primary, secondary;
public Vector2 position;
public Color color;
}

public partial class Level
{
/// <summary>
/// The name of the level.
/// </summary>
[XmlAttribute()]
public String Name;

[XmlAttribute()]
public bool Visible;

/// <summary>
/// A Level contains several Layers. Each Layer contains several Items.
/// </summary>
public List<Layer> Layers;

/// <summary>
/// A Dictionary containing any user-defined Properties.
/// </summary>
public SerializableDictionary CustomProperties;

public List<Actor> Actors = new List<Actor>();
public List<TriggerLevel> Triggers = new List<TriggerLevel>();

public Level()
{
Visible = true;
Layers = new List<Layer>();
CustomProperties = new SerializableDictionary();
}

public static Level FromFile(string filename, ContentManager cm)
{
FileStream stream = File.Open(filename, FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(Level));
Level level = (Level)serializer.Deserialize(stream);
stream.Close();

foreach (Layer layer in level.Layers)
{
foreach (Item item in layer.Items)
{
item.CustomProperties.RestoreItemAssociations(level);
item.load(cm);
}
}

return level;
}

public Item getItemByName(string name)
{
foreach (Layer layer in Layers)
{
foreach (Item item in layer.Items)
{
if (item.Name == name) return item;
}
}
return null;
}

public Layer getLayerByName(string name)
{
foreach (Layer layer in Layers)
{
if (layer.Name == name) return layer;
}
return null;
}

public void draw(SpriteBatch sb)
{
foreach (Layer layer in Layers) layer.draw(sb);
}

public Level Initialize(string FilePath, ContentManager content)
{
AddActors();
return FromFile(FilePath, content);
}

private void AddActors()
{
for (int i = 0; i < Triggers.Count; i++)
{
switch (Triggers.primary)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
}
}
}

public void Update(float dTime)
{
//Update all actors objects
for (int i = 0; i < Actors.Count; i++)
{
Actors.Update(dTime);
}
}

public void Render(SpriteBatch sb, SpriteBatch sbhud)
{
//Draw all level actors
for (int i = 0; i < Actors.Count; i++)
{
Actors.Draw(sb);
}

draw(sb);
}


}


public class Layer
{
/// <summary>
/// The name of the layer.
/// </summary>
[XmlAttribute()]
public String Name;

/// <summary>
/// Should this layer be visible?
/// </summary>
[XmlAttribute()]
public bool Visible;

/// <summary>
/// The list of the items in this layer.
/// </summary>
public List<Item> Items;

/// <summary>
/// The Scroll Speed relative to the main camera. The X and Y components are
/// interpreted as factors, so (1;1) means the same scrolling speed as the main camera.
/// Enables parallax scrolling.
/// </summary>
public Vector2 ScrollSpeed;


public Layer()
{
Items = new List<Item>();
ScrollSpeed = Vector2.One;
}

public void draw(SpriteBatch sb)
{
if (!Visible) return;
foreach (Item item in Items) item.draw(sb);
}

}


[XmlInclude(typeof(TextureItem))]
[XmlInclude(typeof(RectangleItem))]
[XmlInclude(typeof(CircleItem))]
[XmlInclude(typeof(PathItem))]
public class Item
{
/// <summary>
/// The name of this item.
/// </summary>
[XmlAttribute()]
public String Name;

/// <summary>
/// Should this item be visible?
/// </summary>
[XmlAttribute()]
public bool Visible;

/// <summary>
/// The item's position in world space.
/// </summary>
public Vector2 Position;

/// <summary>
/// A Dictionary containing any user-defined Properties.
/// </summary>
public SerializableDictionary CustomProperties;


public Item()
{
CustomProperties = new SerializableDictionary();
}

/// <summary>
/// Called by Level.FromFile(filename) on each Item after the deserialization process.
/// Should be overriden and can be used to load anything needed by the Item (e.g. a texture).
/// </summary>
public virtual void load(ContentManager cm)
{
}

public virtual void draw(SpriteBatch sb)
{
}
}


public class TextureItem : Item
{
/// <summary>
/// The item's rotation in radians.
/// </summary>
public float Rotation;

/// <summary>
/// The item's scale vector.
/// </summary>
public Vector2 Scale;

/// <summary>
/// The color to tint the item's texture with (use white for no tint).
/// </summary>
public Color TintColor;

/// <summary>
/// If true, the texture is flipped horizontally when drawn.
/// </summary>
public bool FlipHorizontally;

/// <summary>
/// If true, the texture is flipped vertically when drawn.
/// </summary>
public bool FlipVertically;

/// <summary>
/// The path to the texture's filename (including the extension) relative to ContentRootFolder.
/// </summary>
public String texture_filename;

/// <summary>
/// The texture_filename without extension. For using in Content.Load<Texture2D>().
/// </summary>
public String asset_name;

/// <summary>
/// The XNA texture to be drawn. Can be loaded either from file (using "texture_filename")
/// or via the Content Pipeline (using "asset_name") - then you must ensure that the texture
/// exists as an asset in your project.
/// Loading is done in the Item's load() method.
/// </summary>
Texture2D texture;

/// <summary>
/// The item's origin relative to the upper left corner of the texture. Usually the middle of the texture.
/// Used for placing and rotating the texture when drawn.
/// </summary>
public Vector2 Origin;


public TextureItem()
{
}

/// <summary>
/// Called by Level.FromFile(filename) on each Item after the deserialization process.
/// Loads all assets needed by the TextureItem, especially the Texture2D.
/// You must provide your own implementation. However, you can rely on all public fields being
/// filled by the level deserialization process.
/// </summary>
public override void load(ContentManager cm)
{
//throw new NotImplementedException();

//TODO: provide your own implementation of how a TextureItem loads its assets
//for example:
//this.texture = Texture2D.FromFile(<GraphicsDevice>, texture_filename);
//or by using the Content Pipeline:
string fileName = HelpfulMethods.FindFileName(asset_name, false);
this.texture = cm.Load<Texture2D>(fileName);
}

public override void draw(SpriteBatch sb)
{
if (!Visible) return;
SpriteEffects effects = SpriteEffects.None;
if (FlipHorizontally) effects |= SpriteEffects.FlipHorizontally;
if (FlipVertically) effects |= SpriteEffects.FlipVertically;
sb.Draw(texture, Position, null, TintColor, Rotation, Origin, Scale, effects, 0);
}
}


public class RectangleItem : Item
{
public float Width;
public float Height;
public Color FillColor;

public RectangleItem()
{
}
}


public class CircleItem : Item
{
public float Radius;
public Color FillColor;

public CircleItem()
{
}
}


public class PathItem : Item
{
public Vector2[] LocalPoints;
public Vector2[] WorldPoints;
public bool IsPolygon;
public int LineWidth;
public Color LineColor;

public PathItem()
{
}
}


///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//
// NEEDED FOR SERIALIZATION. YOU SHOULDN'T CHANGE ANYTHING BELOW!
//
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////


public class CustomProperty
{
public string name;
public object value;
public Type type;
public string description;

public CustomProperty()
{
}

public CustomProperty(string n, object v, Type t, string d)
{
name = n;
value = v;
type = t;
description = d;
}

public CustomProperty clone()
{
CustomProperty result = new CustomProperty(name, value, type, description);
return result;
}
}


public class SerializableDictionary : Dictionary<String, CustomProperty>, IXmlSerializable
{

public SerializableDictionary()
: base()
{

}

public SerializableDictionary(SerializableDictionary copyfrom)
: base(copyfrom)
{
string[] keyscopy = new string[Keys.Count];
Keys.CopyTo(keyscopy, 0);
foreach (string key in keyscopy)
{
this[key] = this[key].clone();
}
}

public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}

public void ReadXml(System.Xml.XmlReader reader)
{

bool wasEmpty = reader.IsEmptyElement;
reader.Read();

if (wasEmpty) return;

while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
CustomProperty cp = new CustomProperty();
cp.name = reader.GetAttribute("Name");
cp.description = reader.GetAttribute("Description");

string type = reader.GetAttribute("Type");
if (type == "string") cp.type = typeof(string);
if (type == "bool") cp.type = typeof(bool);
if (type == "Vector2") cp.type = typeof(Vector2);
if (type == "Color") cp.type = typeof(Color);
if (type == "Item") cp.type = typeof(Item);

if (cp.type == typeof(Item))
{
cp.value = reader.ReadInnerXml();
this.Add(cp.name, cp);
}
else
{
reader.ReadStartElement("Property");
XmlSerializer valueSerializer = new XmlSerializer(cp.type);
object obj = valueSerializer.Deserialize(reader);
cp.value = Convert.ChangeType(obj, cp.type);
this.Add(cp.name, cp);
reader.ReadEndElement();
}

reader.MoveToContent();
}
reader.ReadEndElement();
}

public void WriteXml(System.Xml.XmlWriter writer)
{
foreach (String key in this.Keys)
{
writer.WriteStartElement("Property");
writer.WriteAttributeString("Name", this[key].name);
if (this[key].type == typeof(string)) writer.WriteAttributeString("Type", "string");
if (this[key].type == typeof(bool)) writer.WriteAttributeString("Type", "bool");
if (this[key].type == typeof(Vector2)) writer.WriteAttributeString("Type", "Vector2");
if (this[key].type == typeof(Color)) writer.WriteAttributeString("Type", "Color");
if (this[key].type == typeof(Item)) writer.WriteAttributeString("Type", "Item");
writer.WriteAttributeString("Description", this[key].description);

if (this[key].type == typeof(Item))
{
Item item = (Item)this[key].value;
if (item != null) writer.WriteString(item.Name);
else writer.WriteString("$null$");
}
else
{
XmlSerializer valueSerializer = new XmlSerializer(this[key].type);
valueSerializer.Serialize(writer, this[key].value);
}
writer.WriteEndElement();
}
}

/// <summary>
/// Must be called after all Items have been deserialized.
/// Restores the Item references in CustomProperties of type Item.
/// </summary>
public void RestoreItemAssociations(Level level)
{
foreach (CustomProperty cp in Values)
{
if (cp.type == typeof(Item)) cp.value = level.getItemByName((string)cp.value);
}
}


}






}

ok, Sorry to sound like a noob, but how would i go about posting it up in here?

I was more thinking just upload the entire zipped project to publicly accessible site.

This topic is closed to new replies.

Advertisement