• 0

An error occurring during compiling


Question

i'm building an Hide and seek game using csharp here is the code, it has 2 interfaces , 2 independent classes, 6 other classes which inherit from the interface and the other 2 classes, the code has zero errors and runs when pressed start. But some times during execution the code starts running and give me this error it pints to the line currentLocation.Exits.Name

 

So hears the cod for the entire program

  interface IHasExteriorDoor
    {
        string DoorDescription { get; }
        Location DoorLocation { get; set; }
    }
 interface IHidingPlace
    {
        string HidingPlaceName { get; }
    }
abstract class Location
    {
        public Location(string name)
        {
            this.name = name;
        }
        public Location[] Exits;
        private string name;
        public string Name
        {
            get { return name; }
        }
        public virtual string Description
        {
            get
            {
                string description = " You're standing in the " + name + ". You see exits to the following places:";

                for (int i = 0; i < Exits.Length; i++)
                {
                    description += "" + Exits[i].Name;
                    if (i != Exits.Length - 1)
                        description += ",";
                }
                description += ".";
                return description;
            }
        }
    }
class Opponent
    {
        private Random random;
        private Location myLocation;
        public Opponent(Location startingLocation)
        {
            myLocation = startingLocation;
            random = new Random();
        }
        public void Move()
        {
            if (myLocation is IHasExteriorDoor)
            {
                IHasExteriorDoor LocationWithDoor = myLocation as IHasExteriorDoor;
            
            if (random.Next(2) == 1)
                myLocation = LocationWithDoor.DoorLocation;
        }
        bool hidden = false;
        while(!hidden)
            {
            int rand = random.Next(myLocation.Exits.Length);
            myLocation = myLocation.Exits[rand];
            if(myLocation is IHidingPlace)
            hidden = true;
            }
        }
        public bool Check(Location locationToCheck)
        {
            if (locationToCheck != myLocation)
                return false;
            else
                return true;
        } 
    }
 class OutsideWithDoor : Outside, IHasExteriorDoor
    {
        public OutsideWithDoor(string name, bool hot, string doorDescription): base(name, hot)
            {
            this.doorDescription = doorDescription;
            }
        private string doorDescription;
        public string DoorDescription
        {
            get { return doorDescription; }
        }
        private Location doorLocation;
        public Location DoorLocation
        {
            get { return doorLocation; }
            set { doorLocation = value; }
        }
        public override string Description
        {
            get
            {
                return base.Description + "You see " + doorDescription + ".";
            }
        }
    }
 class Outside : Location
    {
        private bool hot;
        public bool Hot { get { return hot; } }

        public Outside(string name, bool hot) : base(name)
        {
            this.hot = hot;
        }
        public override string Description
        {
            get
            {
                string NewDescription = base.Description;
                if (hot)
                    NewDescription += "It's very hot.";
                return NewDescription;
            }
        }
    }
 class OutsideWithHidingPlace : Outside, IHidingPlace
    {
        public OutsideWithHidingPlace(string name, bool hot, string hidingPlaceName) : base(name, hot)
        { this.hidingPlaceName = hidingPlaceName; }

        private string hidingPlaceName;
        public string HidingPlaceName
        {
            get { return hidingPlaceName; }
        }
        public override string Description
        {
            get { return base.Description + "Someone could hide" + hidingPlaceName + "."; }
        }
    }
class RoomwithDoor: RoomWithHidingPlace, IHasExteriorDoor
    {
        public RoomwithDoor(string name, string decoration, string hidingPlaceName, string doorDescription):base(name, decoration, hidingPlaceName)
        { this.doorDescription = doorDescription; }
        private string doorDescription;
        public string DoorDescription
        {
            get { return doorDescription; }
        }
        private Location doorLocation;
        public Location DoorLocation
        {
            get { return doorLocation; }
            set { doorLocation = value; }
        }
    }
class Room: Location
    {
        private string decoration;

        public Room(string name, string decoration):base(name)
        {
            this.decoration = decoration;
        }
        public override string Description
        {
            get
            {
                return base.Description+"You see " + decoration + ".";
            }
        }
    }
 class RoomWithHidingPlace : Room, IHidingPlace
    {
        public RoomWithHidingPlace (string name, string decoration, string hidingPlaceName): base(name, decoration)
        {
            this.hidingPlaceName = hidingPlaceName;
        }
        private string hidingPlaceName;
        public string HidingPlaceName
        {
            get { return hidingPlaceName; }
        }
        public override string Description
        {
         get { return base.Description + "Someone could hide" + hidingPlaceName + "."; }
        }
    }
public partial class Form1 : Form
    {
        int Moves;
        Location currentLocation;

        RoomwithDoor livingRoom;
        RoomWithHidingPlace diningRoom;
        RoomwithDoor kitchen;
        Room stairs;
        RoomWithHidingPlace hallway;
        RoomWithHidingPlace bathroom;
        RoomWithHidingPlace masterBedroom;
        RoomWithHidingPlace secondBedroom;

        OutsideWithDoor frontYard;
        OutsideWithDoor backYard;
        OutsideWithHidingPlace garden;
        OutsideWithHidingPlace driveway;

        Opponent opponent;

        public Form1()
        {
            InitializeComponent();
            CreateObjects();
            opponent = new Opponent(frontYard);
            ResetGame(false);
            MoveToANewLocation(livingRoom);
        }
        private void MoveToANewLocation(Location newLocation)
        {
            Moves++;
            currentLocation = newLocation;
            RedrawForm();
        }
        private void RedrawForm()
        {
            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++)
                exits.Items.Add(currentLocation.Exits[i].Name);
            exits.SelectedIndex = 0;
            description.Text = currentLocation.Description + "\r\n(move #" + Moves + ")";
            if(currentLocation is IHidingPlace)
            {
                IHidingPlace hidingPlace = currentLocation as IHidingPlace;
                exits.Text = "Check" + hidingPlace.HidingPlaceName;
                exits.Visible = true;
            }
            else
                exits.Visible = false;
                if (currentLocation is IHasExteriorDoor)
                    goThroughTheDoor.Visible = true;
                else
                    goThroughTheDoor.Visible = false;
        }
        private void CreateObjects()
        {
            livingRoom = new RoomwithDoor("Living Room", "an antique carpet","inside the closet", "an oak door with a brassknob");
            diningRoom = new RoomWithHidingPlace("Dining Room", "a crystal chandelier", "in the tall armorie");
            kitchen = new RoomwithDoor("Kitchen", "stainless steel appliances","in the cabinet", "a screen door");
            stairs = new RoomwithDoor("Kitchen", "stainless steel appliances", "in teh cabinet", "a screen door");
            hallway = new RoomWithHidingPlace("Upstairs Hallway", "a picture of a dog", "in the closet");
            bathroom = new RoomWithHidingPlace("Bathjroom", "a sink and a toilet", "in the shower");
            masterBedroom = new RoomWithHidingPlace("Master Bedroom", "a large bed", "under the bed");
            secondBedroom = new RoomWithHidingPlace("Second Bedroom", "a small bed", " under the bed");

            frontYard =new OutsideWithDoor("Front Yard", false, "a heavy-looking oak door ");
            backYard = new OutsideWithDoor("Back Yard", true, " a screen door");
            garden = new OutsideWithHidingPlace("Garden", false,"inside the shed");
            driveway = new OutsideWithHidingPlace("Driveway", true, "in the garage");

            diningRoom.Exits = new Location[] { livingRoom, kitchen };
            livingRoom.Exits = new Location[] { diningRoom, stairs };
            kitchen.Exits = new Location[] { diningRoom };
            stairs.Exits = new Location[] { livingRoom, hallway };
            hallway.Exits = new Location[] { stairs, bathroom, masterBedroom, secondBedroom };
            bathroom.Exits = new Location[] { hallway };
            masterBedroom.Exits = new Location[] { hallway };
            secondBedroom.Exits = new Location[] { hallway };
            frontYard.Exits = new Location[] { backYard, garden, driveway };
            backYard.Exits = new Location[] { frontYard, garden, driveway };
            garden.Exits = new Location[] { backYard, frontYard };
            driveway.Exits = new Location[] { backYard, frontYard };

            livingRoom.DoorLocation = frontYard;
            frontYard.DoorLocation = livingRoom;

            kitchen.DoorLocation = backYard;
            backYard.DoorLocation = kitchen;
        }
         private void ResetGame (bool displayMessage)
        {
            if (displayMessage)
            {
                MessageBox.Show("you found me in" + Moves + "moves!");
                IHidingPlace foundLocation = currentLocation as IHidingPlace;
                description.Text = "you found your opponent in " + Moves + "moves! He was hiding" + foundLocation.HidingPlaceName + ".";
            }
            Moves = 0;
            hide.Visible = true;
            goHere.Visible = false;
            check.Visible = false;
            goThroughTheDoor.Visible = false;
            exits.Visible = false;
        }

    

        private void goHere_Click(object sender, EventArgs e)
        {
            MoveToANewLocation(currentLocation.Exits[exits.SelectedIndex]);
        }

        private void goThroughTheDoor_Click(object sender, EventArgs e)
        {
            IHasExteriorDoor hasDoor = currentLocation as IHasExteriorDoor;
            MoveToANewLocation(hasDoor.DoorLocation);
        }

        private void check_Click(object sender, EventArgs e)
        {
            Moves++;
            if (opponent.Check(currentLocation))
                ResetGame(true);
            else
                RedrawForm();
        }

        private void Hide_Click(object sender, EventArgs e)
        {
            hide.Visible = false;
            for (int i = 1; i <= 10; i++)
            {
                opponent.Move();
                description.Text = i + "...";
                Application.DoEvents();
                System.Threading.Thread.Sleep(200);
            }
            description.Text = "Ready or not, here i come!";
            Application.DoEvents();
            System.Threading.Thread.Sleep(500);

            goHere.Visible = true;
            exits.Visible = true;
            MoveToANewLocation(livingRoom);
        }
    }

Although this program contains 0 errors the program stops compiling sometimes and points towards the line current.Exit.Name and give a pop up saying Null reference  exception was handled.

 

Here's how the form looks like FORM

Link to comment
https://www.neowin.net/forum/topic/1323070-an-error-occurring-during-compiling/
Share on other sites

7 answers to this question

Recommended Posts

  • 0
Location currentLocation = null;
// Or
Location currentLocation.Exits = null;

The error is caused because the value is null, this can be caused by either the whole currentLocation to be null or the Exits attribute to be null.

 

If I would have to guess:

 

You start at Location A which has exits B, C and D.

Then you go to exit Location C which has no exits, the attribute "exits" is null, this causes an error in the for loop which expects at least an empty array instead of null.

 

The NullReferenceException is the most common exception I've ever seen in a C# application :p

 

TL;DR

 

Always initialize your arrays/lists or check if they aren't null before using a loop.

 

Also this is not an compilation but an execution error, which means that the code will compile fine and can be distributed to the users which will see their application crash. Therefore it's always recommended to test all scenarios (0, 1 or multiple exits) for bugs before shipping the code.
 

This can be done manually or automated (recommended) with unit tests: https://www.youtube.com/watch?v=rW6LvPP4VvA

 

 

  • 0
  On 21/02/2017 at 12:51, Ch33f said:

Although this program contains 0 errors the program stops compiling sometimes and points towards the line current.Exit.Name and give a pop up saying Null reference  exception was handled.

Expand  

First, this is not a compile-time error! It does not happen while the program is compiling, it happens while the program is running, i.e. after compilation. If you have any confusion about compile- vs run-time you need to clear that up ASAP. The compiler turns your text files (*.cs) into executable files (*.dll, *.exe), which can then run inside an operating system process. Exceptions happen at run-time when your program is legal C# so it compiles, but it still manages to do something wrong (like in this case, dereferencing a null).

 

As @Seahorsepip mentions, if `currentLocation.Exits.Name` throws NullReferenceException then either currentLocation is null or currentLocation.Exits is null. Why are they null? What could you do to make them not null? That's yours to figure out.

 

 

  • Like 1
  • 0

After reading the code, it appears to me your problem is very simple...

 

abstract class Location
    {
        public Location(string name)
        {
            this.name = name;
        }
        public Location[] Exits;

you did not initialize Exits in the base constructor, nor did you initialize it in the inherited constructors as well.

Seems to me somewhere you should have this line somewhere in your constructors.

Exits = new Location[ExitCount];  //Where ExitCount is an integer

 

  • 0
  On 21/02/2017 at 18:19, Seahorsepip said:

The NullReferenceException is the most common exception I've ever seen in a C# application :p

Expand  

For me it's the "Object reference not set to an instance of an object" error (I've caused this in my apps forgetting to set it correctly), and the division by zero errors. I'm working on a C# GTA soundboard, and when I'm tired the object reference error happens a lot :) Caffeine normally helps :)

  • Like 1
  • 0
  On 21/02/2017 at 23:08, sao123 said:

After reading the code, it appears to me your problem is very simple...

Expand  

The exits are given a value in CreateObjects():

See Form1 constructor:

MoveToANewLocation(livingRoom);

Which sets currentLocation to livingRoom (which is generated by CreateObjects() and has the exits value diningRoom and stairs).

So exits don't need to be initialized in the Locations class itself to work but imagine what happens when the following method is called:

MoveToANewLocation(stairs);

And the stairs exits array attribute is not initialized in CreateObjects()?

 

Then it tries to for loop trough null instead of an array and we end up with a NullReferenceException :)

 

So initializing every array in the classes is a quick fix that does indeed solve the NullReferenceException issue in most cases but might not solve the underlying issue, maybe a Location should always have at least 1 exit as example.

 

As I said before it's saves a lot of work when unit tests are made for all use case scenarios(values, actions etc). Then it's directly clear when something stopped working that worked before.

 

  On 21/02/2017 at 23:33, Tidosho said:

For me it's the "Object reference not set to an instance of an object" error (I've caused this in my apps forgetting to set it correctly), and the division by zero errors. I'm working on a C# GTA soundboard, and when I'm tired the object reference error happens a lot :) Caffeine normally helps :)

Expand  

I always get StackOverflowExceptions since I have a habit to write a lot of recursion logic lately :p 

  • 0
  On 21/02/2017 at 23:33, Tidosho said:

For me it's the "Object reference not set to an instance of an object" error (I've caused this in my apps forgetting to set it correctly), and the division by zero errors. I'm working on a C# GTA soundboard, and when I'm tired the object reference error happens a lot :) Caffeine normally helps :)

Expand  

Try F# - no nulls (mostly) among other benefits ;)

  • 0

Thank You for the feedback, i got the program working, exits is the name given to the combo box and its has been initialized in Location class here is the edited version of form.

public partial class Form1 : Form
    {
        int Moves;
        Location currentLocation;

        RoomwithDoor livingRoom;
        RoomWithHidingPlace diningRoom;
        RoomwithDoor kitchen;
        Room stairs;
        RoomWithHidingPlace hallway;
        RoomWithHidingPlace bathroom;
        RoomWithHidingPlace masterBedroom;
        RoomWithHidingPlace secondBedroom;

        OutsideWithDoor frontYard;
        OutsideWithDoor backYard;
        OutsideWithHidingPlace garden;
        OutsideWithHidingPlace driveway;

        Opponent opponent;

        public Form1()
        {
            InitializeComponent();
            CreateObjects();
            opponent = new Opponent(frontYard);
            ResetGame(false);
            MoveToANewLocation(livingRoom);
        }
        private void MoveToANewLocation(Location newLocation)
        {
            Moves++;
            currentLocation = newLocation;
            RedrawForm();
            
        }
        private void RedrawForm()
        {
            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++)
                exits.Items.Add(currentLocation.Exits[i].Name);
            exits.SelectedIndex = 0;
            description.Text = currentLocation.Description + "\r\n(move #" + Moves + ")";
            if(currentLocation is IHidingPlace)
            {
                IHidingPlace hidingPlace = currentLocation as IHidingPlace;
                check.Text = "Check" + hidingPlace.HidingPlaceName;
                check.Visible = true;
            }
            else
                check.Visible = false;
                if (currentLocation is IHasExteriorDoor)
                    goThroughTheDoor.Visible = true;
                else
                    goThroughTheDoor.Visible = false;
        }
        private void CreateObjects()
        {
            livingRoom = new RoomwithDoor("Living Room", "an antique carpet","inside the closet", "an oak door with a brassknob");
            diningRoom = new RoomWithHidingPlace("Dining Room", "a crystal chandelier", "in the tall armorie");
            kitchen = new RoomwithDoor("Kitchen", "stainless steel appliances","in the cabinet", "a screen door");
            stairs = new Room("Stairs", "a wooden bannister");
            hallway = new RoomWithHidingPlace("Upstairs Hallway", "a picture of a dog", "in the closet");
            bathroom = new RoomWithHidingPlace("Bathjroom", "a sink and a toilet", "in the shower");
            masterBedroom = new RoomWithHidingPlace("Master Bedroom", "a large bed", "under the bed");
            secondBedroom = new RoomWithHidingPlace("Second Bedroom", "a small bed", " under the bed");

            frontYard =new OutsideWithDoor("Front Yard", false, "a heavy-looking oak door ");
            backYard = new OutsideWithDoor("Back Yard", true, " a screen door");
            garden = new OutsideWithHidingPlace("Garden", false,"inside the shed");
            driveway = new OutsideWithHidingPlace("Driveway", true, "in the garage");

            diningRoom.Exits = new Location[] { livingRoom, kitchen };
            livingRoom.Exits = new Location[] { diningRoom, stairs };
            kitchen.Exits = new Location[] { diningRoom };
            stairs.Exits = new Location[] { livingRoom, hallway };
            hallway.Exits = new Location[] { stairs, bathroom, masterBedroom, secondBedroom };
            bathroom.Exits = new Location[] { hallway };
            masterBedroom.Exits = new Location[] { hallway };
            secondBedroom.Exits = new Location[] { hallway };
            frontYard.Exits = new Location[] { backYard, garden, driveway };
            backYard.Exits = new Location[] { frontYard, garden, driveway };
            garden.Exits = new Location[] { backYard, frontYard };
            driveway.Exits = new Location[] { backYard, frontYard };

            livingRoom.DoorLocation = frontYard;
            frontYard.DoorLocation = livingRoom;

            kitchen.DoorLocation = backYard;
            backYard.DoorLocation = kitchen;
        }
         private void ResetGame (bool displayMessage)
        {
            if (displayMessage)
            {
                MessageBox.Show("you found me in" + Moves + "moves!");
                IHidingPlace foundLocation = currentLocation as IHidingPlace;
                description.Text = "you found your opponent in " + Moves + "moves! He was hiding" + foundLocation.HidingPlaceName + ".";
            }
            Moves = 0;
            hide.Visible = true;
            goHere.Visible = false;
            check.Visible = false;
            goThroughTheDoor.Visible = false;
            exits.Visible = false;
        }

      /*  private void MoveToANewLocation(Location newLocation)
        {
            currentLocation = newLocation;

            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++) 
            exits.Items.Add(currentLocation.Exits[i].Name);
            exits.SelectedIndex = 0;

            description.Text = currentLocation.Description;

            if (currentLocation is IHasExteriorDoor)
                goThroughTheDoor.Visible = true;
            else
                goThroughTheDoor.Visible = false;
        }*/

        private void goHere_Click(object sender, EventArgs e)
        {
            MoveToANewLocation(currentLocation.Exits[exits.SelectedIndex]);
        }

        private void goThroughTheDoor_Click(object sender, EventArgs e)
        {
            IHasExteriorDoor hasDoor = currentLocation as IHasExteriorDoor;
            MoveToANewLocation(hasDoor.DoorLocation);
        }

        private void check_Click(object sender, EventArgs e)
        {
            Moves++;
            if (opponent.Check(currentLocation))
                ResetGame(true);
            else
                RedrawForm();
        }

        private void Hide_Click(object sender, EventArgs e)
        {
            hide.Visible = false;
            for (int i = 1; i <= 10; i++)
            {
                opponent.Move();
                description.Text = i + "...";
                Application.DoEvents();
                System.Threading.Thread.Sleep(200);
            }
            description.Text = "Ready or not, here i come!";
            Application.DoEvents();
            System.Threading.Thread.Sleep(500);

            goHere.Visible = true;
            exits.Visible = true;
            MoveToANewLocation(livingRoom);
        }
    }

 

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • I was going to say that search engines and such, have been scraping everyone's copyright, IP and data, since the beginning of the internet.
    • Microsoft is officially making the Xbox app on PC a universal launcher by Pulasthi Ariyasinghe It was earlier this year that an image mockup from Microsoft showed the Xbox app on PC with an interesting change: including support for other PC stores on the app, teasing that it may be becoming a universal launcher like GOG Galaxy or Playnite. Considering the company's new handheld initiative that will house a brand-new gaming-focused version of Windows, it was clear that this feature was on the way. And now, Xbox Insiders have access. Announced today as the 'aggregated gaming library' feature, it's poised to land this holiday on the ROG Xbox Ally and ROG Xbox Ally X to easily manage all their installed games from a single place. But before that, Xbox Insiders on PC can have a crack at it to see how it functions and provide feedback to Microsoft. In its current state, Microsoft says that the feature now supports Xbox, Game Pass, Battle.net, and "other leading PC storefronts," all handled via the Xbox PC app. The company did not detail what these other storefronts are, but Steam, Epic Games Store, Ubisoft Connect, and EA Play apps seem likely candidates. "Whether you’re on a Windows PC or a handheld device, your Xbox library, hundreds of Game Pass titles, and all your installed games from leading PC storefronts will now be at your fingertips," said the company. When a game from a supported store is installed on a PC, Insiders should now see it appear on the Xbox app in the My Library and Most Recent sections for easy access. "And this is just the beginning," adds Microsoft. "We’ll continue rolling out support for additional PC storefronts over time." Insiders can also disable this functionality and hide games from specific stores if needed from the Settings > Library & Extensions menu. Anyone interested in testing out the new 'aggregated gaming library' update can use the Xbox Insider app on PC to enroll in the ongoing Insider Previews.
    • Get this powerful mini PC with Core Ultra 9, 32GB RAM, and 1TB SSD for just $799 by Taras Buria The ASUS NUC 14 Pro+ is a powerful mini PC with capable hardware, and right now, you can get it on Amazon with a big discount. At just $799, this computer offers a Core Ultra 9 processor, 32GB of memory, and a 1TB SSD. The NUC 14 Pro+ features a low-profile aluminum chassis, which can be opened without removing rubber feet or undoing any screws. Its toolless design lets you access the storage without a screwdriver. The computer also has a rich set of ports. On the front side, you will find two USB 3.2 Gen 2 Type-C, one USB 3.2 Gen 2x2 Type-C, and a power button. Unlike the Mac mini, which has a frustrating power button placement, the power button in the NUC 14 Pro+ is located where it should be. The back of the NUC 14 Pro+ has a DC-in port, two Thunderbolt 4 ports, one 2.5G Ethernet port, one USB 3.2 Gen2 Type-A, one USB 2.0 Type-A, two HDMI 2.1, and a Kensington lock. Finally, there is a VESA mount, which lets you place the device on the back of your monitor for a cleaner desk. The computer is powered by Intel's 14th-gen Core Ultra 9 185H processor, 32GB of DDR5 memory, and a 1TB PCIe Gen4 NVMe SSD. Windows 11 Home is preinstalled, so you do not need to bring your own drive, memory, or Windows 11 license. ASUS NUC 14 Pro+ Core Ultra 9 185H, 32GB RAM, 1TB SSD - $799.99 | 27% off on Amazon US This Amazon deal is US-specific and not available in other regions unless specified. If you don't like it or want to look at more options, check out the Amazon US deals page here. Get Prime (SNAP), Prime Video, Audible Plus or Kindle / Music Unlimited. Free for 30 days. As an Amazon Associate, we earn from qualifying purchases.
    • This guy is just salty that Waymo is about to get buried by a company with cars that cost significantly less, charge significantly lower fares, and will soon dramatically outnumber their fleet. Waymo made the mistake of not reducing their vehicle cost quick enough and not overcoming their route limitations. Unless they start allowing their cars to use the freeways and have significantly wider geofencing, they're going to soon join the list of discontinued Google products. If Tesla wasn't the one to make them irrelevant, somebody else soon was. There's a long list of companies designing robotaxis right now.
    • LOL. Hard to believe people still fall for this. If you are having some sort of issue, I would work on fixing that instead turning off these settings.
  • Recent Achievements

    • Week One Done
      fredss earned a badge
      Week One Done
    • Dedicated
      fabioc earned a badge
      Dedicated
    • One Month Later
      GoForma earned a badge
      One Month Later
    • Week One Done
      GoForma earned a badge
      Week One Done
    • Week One Done
      ravenmanNE earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      651
    2. 2
      Michael Scrip
      226
    3. 3
      ATLien_0
      218
    4. 4
      +FloatingFatMan
      146
    5. 5
      Xenon
      137
  • Tell a friend

    Love Neowin? Tell a friend!