Now, we have reached a point where it might be useful to place the data that we have on the form into a text file, so that
we can restore this data and we can make lots of different files to create 'levels'.

The file specifications can include a list of rectangle properties (Left, Top, Width and Height or Right and Bottom) for
the Platform, Wall, and Coin.  The coin has a fixed width and height though, so we only need to have Left and Top for coins.
So, let's make the specification:
The first integer in the file will be the number of platforms, and following this integer will be the Left, Top, Right, and
Bottom of each rectangle in the level.  After these rectangle properties, the next integer will be the number of walls, 
followed by its respective rectangle properties (LTRB).  The next integer is the number of coins, and it will be followed by
Left and Top values only.

OK.  First, let's save what we have there.  Of course, we would not want this in the final product so first, we need to set
up some Conditional Compilation definitions.

#Const TESTversion = 1
    'Set this to 1 to allow the testing / editing / debug version of the game.
Close your region back up. Now, let's have a key combination that causes the data on the form to be saved to a file. Let's say Ctrl+S. So, in the KeyDown event.
#If TESTversion = 1 Then  'This code will be hidden from the compiler when TESTversion is set to 0.
        ElseIf e.KeyCode = Keys.S AndAlso e.Control Then
            SaveLevel()
#End If  'The following code will be visible.  Anything between the #If and #End If will be gone when TESTversion is 0.
And now, we can save the map layout in the file.
    Private Sub SaveLevel()
        'First, let's create a binarywriter to write the information to the file.
        Dim FS As System.IO.FileStream = New System.IO.FileStream(Application.StartupPath & "\level.dat", IO.FileMode.Create)
        Dim BW As System.IO.BinaryWriter = New System.IO.BinaryWriter(FS)

        'First, the number of platforms is written to the file.
        BW.Write(Platforms.Count)
        'Next, each platform is written to file.
        For Each Platform In Platforms
            BW.Write(Platform.Left)
            BW.Write(Platform.Top)
            BW.Write(Platform.Right)
            BW.Write(Platform.Bottom)
        Next
        'Next, the number of walls is written to file.
        BW.Write(Walls.Count)
        'Then, each wall is written to file.
        For Each Wall In Walls
            BW.Write(Wall.Left)
            BW.Write(Wall.Top)
            BW.Write(Wall.Right)
            BW.Write(Wall.Bottom)
        Next
        'Then, the coins are written to file.
        BW.Write(Coins.Count)
        'Finally, each coin is written to file.
        For Each Coin In Coins
            BW.Write(Coin.Left)
            BW.Write(Coin.Top)
        Next
        'And we are done.
        'Close the file.
        BW.Close()
        FS.Close()
    End Sub
Now, run the program and press Ctrl+S. Close it and look for a level.dat file in the bin folder. If you see it there and it has a decent file size, then everything is ok. (Mine is 188 bytes)
Now, let's test our loading procedure with some faith: Let's delete all of the platform, wall, and coin initialization code in the load event. That is all of this:
        Coins = New ArrayList(10)
        'Create the coin list and add some rectangles to the list.
        Coins.Add(New Rectangle(200, 530, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(100, 440, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(116, 440, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(132, 440, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(230, 365, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(340, 510, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(20, 490, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(280, 400, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(200, 498, COINSIZE, COINSIZE))
        Coins.Add(New Rectangle(260, 415, COINSIZE, COINSIZE))
        Platforms = New ArrayList(3)
        'Initialize/instantiate the platforms arraylist.
        Platforms.Add(Rectangle.FromLTRB(50, 415, 160, LANDHEIGHT))
        Platforms.Add(Rectangle.FromLTRB(100, 465, 185, LANDHEIGHT))
        Platforms.Add(Rectangle.FromLTRB(150, 515, 210, LANDHEIGHT))
        'Create three platforms.
        Walls = New ArrayList(3)
        'Initialize the wall arraylist.
        Walls.Add(Rectangle.FromLTRB(185, 415, 210, 465))
        Walls.Add(Rectangle.FromLTRB(270, 520, 320, LANDHEIGHT))
        Walls.Add(Rectangle.FromLTRB(320, 540, 370, LANDHEIGHT))
        'Walls are initialized.
And now, we call a LoadLevel() sub that we will complete in a few moments. So:
        LoadLevel()
        'Loads the information for this level.
in place of all of that that was removed. It really can go anywhere in the Load event. Now, for the LoadLevel subroutine.
    Private Sub LoadLevel()
        'We need to create a binaryreader to read from the file.
        Dim FS As System.IO.FileStream = New System.IO.FileStream(Application.StartupPath & "\level.dat", IO.FileMode.Open)
        Dim BR As System.IO.BinaryReader = New System.IO.BinaryReader(FS)
        Dim LV As Integer 'Loop variable.

        Platforms = New ArrayList(BR.ReadInt32())
        For LV = 1 To Platforms.Capacity  'Capacity is the number that you've specified in the New arraylist's constructor.
            Platforms.Add(Rectangle.FromLTRB(BR.ReadInt32(), BR.ReadInt32(), BR.ReadInt32(), BR.ReadInt32()))
            'Read four integers from the file and put it into a rectangle.
        Next
        Platforms.Capacity = 100

        Walls = New ArrayList(BR.ReadInt32())
        For LV = 1 To Walls.Capacity
            Walls.Add(Rectangle.FromLTRB(BR.ReadInt32(), BR.ReadInt32(), BR.ReadInt32(), BR.ReadInt32()))
            'Same for four integers going into wall rectangles.
        Next
        Walls.Capacity = 100

        Coins = New ArrayList(BR.ReadInt32())
        For LV = 1 To Coins.Capacity
            Coins.Add(New Rectangle(BR.ReadInt32(), BR.ReadInt32(), COINSIZE, COINSIZE))
            'Coins only need left and top.  Their width and height are defined by coin size.
        Next
        Coins.Capacity = 100

        'Close the files.
        BR.Close()
        FS.Close()
    End Sub
Looks simple. And now you'll find our level was generated purely from file.
Now, we'll have to go a bit into our editor crates in order to allow platforms, walls, and coins to be added to the form. We'll allow the mouse to be used to select some rectangle on the form. When the mouse is down, we will set one point of the rectangle. When the mouse is released, we will set another point on the rectangle. While the mouse is down, we will draw an unfilled rectangle connecting the mouse coordinates with the initial point. When the mouse is released, a platform or wall will be drawn. A coin will only be placed at the mouse down. We'll use the P, W, and C keys to determine if we are going to draw a platform, wall, or coin. Notice that we cannot use a rectangle, as a rectangle has to have a positive width and height if it is to be drawn. So, we'll use two Points for the mouse coordinates and just use Math.Min and Math.Max to get a decent rectangle from them. Now, let's make our declarations.
    Dim IsMouseDown As Boolean
    'Indicates if the mouse button is pressed.
    Dim InitialPt, FinalPt As Point
    'Stores the mouse's locations for the rectangle setup.
    Dim MDObject As Char
    'Character is P, W, or C for platform, wall, or coin.
Since MDObject is either "P"c, "W"c, or "C"c, it should be initialized to one of these at the beginning.
        MDObject = "P"c
        'Initialize to P for platforms so that mousedown produces platforms at the beginning.
Now, IsMousedown needs to be set to True in the MouseDown event and False in the MouseUp event. In the MouseDown event, the InitialPt is set. In the MouseUp event, the FinalPt is set and the platform, wall, or coin is generated. If we are placing a coin (which will be when MDObject is "C"c, then we don't need the initialpt to try to find a width or a height, since it is predetermined. First, the MouseDown event.
    Private Sub PFMain_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        IsMouseDown = True
        InitialPt = New Point(e.X, e.Y)
        'Set the initial point.
    End Sub
And now, the MouseUp event.
    Private Sub PFMain_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp
        Dim Placed As Rectangle
        'This is the rectangle that we have drawn.
        Dim Mu As Point = New Point(e.X, e.Y)
        'Convert the mouseeventargs's .X and .Y into a Point structure.
        IsMouseDown = False


        Select Case MDObject
            Case "P"c
                Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X), Math.Min(InitialPt.Y, Mu.Y), Math.Max(InitialPt.X, Mu.X), Math.Max(InitialPt.Y, Mu.Y))
                Platforms.Insert(0, Placed)
                'Add a platform.
            Case "W"c
                Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X), Math.Min(InitialPt.Y, Mu.Y), Math.Max(InitialPt.X, Mu.X), Math.Max(InitialPt.Y, Mu.Y))
                Walls.Insert(0, Placed)
                'Add a wall.
            Case "C"c
                Coins.Insert(0, New Rectangle(Mu.X, Mu.Y, COINSIZE, COINSIZE))
                'Place a coin at the point where the mouse was released.
        End Select
    End Sub
And of course, both of those go into an #If TESTversion = 1 Then compilation if block. We need to add some ElseIfs to the keydown event so that the MDObject change between P, W, and C.
        ElseIf e.KeyCode = Keys.P Then
            If Not IsMouseDown Then
                MDObject = "P"c
            End If
        ElseIf e.KeyCode = Keys.W Then
            If Not IsMouseDown Then
                MDObject = "W"c
            End If
        ElseIf e.KeyCode = Keys.C Then
            If Not IsMouseDown Then
                MDObject = "C"c
            End If
That has to go within the #If and #End If in the KeyDown Now, let's add something graphical so that we can see where our new rectangle will go. We'll make a rectangle that connects the InitialPt with the mouse coordinates.
        If IsMouseDown Then
            Dim Outline As Rectangle
            Dim Curse As Point
            Curse = Cursor.Position
            Curse = Me.PointToClient(Curse)
            'Create the cursor's point on the form.
            Outline = Rectangle.FromLTRB(Math.Min(InitialPt.X, Curse.X), Math.Min(InitialPt.Y, Curse.Y), _
                                         Math.Max(InitialPt.X, Curse.X), Math.Max(InitialPt.Y, Curse.Y))
            'Creates the drawing rectangle.  Now to draw it.
            GFX.DrawRectangle(Pens.Black, Outline)
        End If
Like that. That can go near the end of the Artwork subroutine... but it does have to come before the Me.DrawOnForm(). Now, you should be able to customize your levels and add platforms, walls, and coins.