<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>Mistakes and All - Bryan Bedard&apos;s Blog</title>
    <link>https://www.highwaynorth.com/blogs/bryan/rss</link>
    <description><![CDATA[In this blog I will share my adventures in software development. Throughout my life I have been on an unending journey of learning. When it comes to software, there is always something new to learn and no matter how much experience I have, I still make plenty of mistakes along the way. Hence, the title of the blog. I intend to share my experiences, "mistakes and all." I don't always get it right the first time and hopefully by sharing my mistakes it will save you from making the same ones.]]></description>
    <item>
      <title>Handling Touches in 2D Unity Games</title>
      <link>https://www.highwaynorth.com/blogs/bryan/handling-touches-in-2d-unity-games</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/handling-touches-in-2d-unity-games</guid>
      <pubDate>Tue, 14 Jan 2025 03:38:51 GMT</pubDate>
      <description><![CDATA[<p>The Unity <a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/QuickStartGuide.html" target="_blank">input system</a> is powerful, flexible and easy to use. It allows you to separate the logical meaning of an input (e.g. move) and the device-specific controls (e.g. key press, game stick). It supports mapping <a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.5/manual/Actions.html" target="_blank">Actions</a> to multiple input devices such as mouse, keyboard and touch. This short article shows how to handle touches. It is not a guide to touch input in general, just the basics of how to handle a touch press on the screen.</p>

                    <p>As of this writing, when you create a new Unity project, an input action asset is created with pre-defined action maps for player and UI actions. These action maps may meet your needs out of the box.</p>

                    <p>To handle touches on the screen and detect the position that was touched, you will need to add an action to an action map. Follow these steps.</p>

                    <h3>Step 1: Open the Input Actions Asset</h3>

                    <p>Double-click the input actions asset to view and modify the action maps. The default generated input actions file is located in the root of the Assets folder and should be called InputSystem_Actions.inputactions</p>

                    <a href="../../static/0007/01-default-input-system-actions.png" target="_blank"><img src="../../static/0007/01-default-input-system-actions.png" alt="Screen shot of default input system actions asset" class="Screenshot" /></a>

                    <h3>Step 2: Add an Action to the Action Map</h3>

                    Right-click the Actions box and click Add Action. Name the new action AttackPosition. Right-click the new action and click Add Binding. Select Touchscreen > Position for the Path setting of the binding.

                    <a href="../../static/0007/02-touchscreen-position-action.png" target="_blank"><img src="../../static/0007/02-touchscreen-position-action.png" alt="Screen shot of action maps with AttackPosition action added bound to touchscreen position" class="Screenshot" /></a>

                    <p>With the Position [touchscreen] binding selected, check the box for Touch in the Use in control scheme section. Click on the AttackPosition action and set Action Type to Value and Control Type to Vector 2. This will configure the action to reeturn a Vector2 value.</p>

                    <h3>Step 3: Add a Player Input Component to the Player GameObject</h3>

                    <p>The <a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.5/manual/PlayerInput.html" target="_blank">PlayerInput</a> component represents a single player and that player's associated Input Actions. Select the player GameObject in your scene that you want to add touchscreen position input to. Click Add Component in the Inspector window and choose Input &gt; Player Input. Choose InputSystem_Actions for the Actions property of the Player Input component. Leave other properties set to their default values.</p>

                    <a href="../../static/0007/03-player-input-component.png" target="_blank"><img src="../../static/0007/03-player-input-component.png" alt="Screen shot the player input component" class="Screenshot" /></a>

                    <h3>Step 4: Add a Script to the Player GameObject to Handle Touch Input</h3>

                    <p>Add a script component to the player GameObject. Edit the script and subscribe to the performed event in the OnEnable method. To subscribe to the event, get a reference to the PlayerInput component and add an event handler to the performed event on the input action named AttackPosition:</p>

                    <pre>
private void OnEnable()
{
    var playerInput = GetComponent&lt;PlayerInput&gt;();
    playerInput.actions["AttackPosition"].performed += AttackPosition_performed;
}                    
                    </pre>

                    <p>Unsubscribe from the event in the OnDisable method:</p>

                    <pre>
private void OnDisable()
{
    var playerInput = GetComponent&lt;PlayerInput&gt;();
    playerInput.actions["AttackPosition"].performed -= AttackPosition_performed;
}                
                    </pre>

                    <p>Implement the event handler. This example shows how to get the raw touch position in screen coordinates by calling the ReadValue() method on the action named AttackPosition. After reading the value in screen coordinates you can convert to world coordinates if needed:</p>

                    <pre>
private void AttackPosition_performed(InputAction.CallbackContext context)
{
    var playerInput = GetComponent&lt;PlayerInput&gt;();
    var attackPositionScreen = playerInput.actions["AttackPosition"].ReadValue<Vector2>();
    Debug.Log("Attack Screen: (" + attackPositionScreen.x + ", " + attackPositionScreen.y + ")");

    var attackPosition = Camera.main.ScreenToWorldPoint(attackPositionScreen);
    Debug.Log("Attack World: (" + attackPosition.x + ", " + attackPosition.y + ")");

}                                            
                    </pre>
                    
                    <p>Use the touch coordinates to take action in your game as desired.</p>]]></description>
    </item>
    <item>
      <title>How to Debug Android Games in Unity With logcat</title>
      <link>https://www.highwaynorth.com/blogs/bryan/how-to-debug-android-games-in-unity-with-logcat</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/how-to-debug-android-games-in-unity-with-logcat</guid>
      <pubDate>Tue, 14 Jan 2025 02:08:57 GMT</pubDate>
      <description><![CDATA[<p>The debugging experience with the Unity player inside the Unity editor is quite good. Many developers use Visual Studio as their script editor for Unity. In Visual Studio you can attach the debugger to Unity and you can set breakpoints in your scripts, step through code and inspect variables. For most testing and debugging it is sufficient to test within the player, even if the game is being built for other platforms such as Android or iOS. However, sometimes the game behaves slightly differently on a particular platform and you may need to test and debug on that platform directly, such as on a mobile device. For Android games, you can connect a device to your development machine with a USB cable and use logcat to inspect debug log output. While not as powerful as being able to set breakpoints, this is a simple way to get visibility into what is happening at runtime in your game.</p>

                    <p>This article does not cover how to enable debugging on your Android device but you can find other articles easily such as <a href="https://developer.android.com/studio/debug/dev-options" target="_blank">Configure on-device developer options</a> on the Android developer site.</p>

                    <p>Once you have USB debugging enabled on your device and the <a href="https://developer.android.com/studio" target="_blank">Android development tools</a> installed on your development machine, connect your Anrdoid device with a USB cable, open a terminal window and run the Android Debug Bridge (ADB) with these parameters to run logcat on the Android device and output only log messages from Unity:</p>

                    <pre>
adb logcat -s Unity
                    </pre>

                    <p>To run adb from any folder on Windows, add the Android platform-tools folder to your PATH <a href="https://stackoverflow.com/questions/9546324/adding-a-directory-to-the-path-environment-variable-in-windows" target="_blank">system variable</a>.  The path to the platform-tools folder will vary depending on where you installed the Android SDK, however it should be something like C:\Users\(YOUR WINDOWS USER NAME)\AppData\Local\Android\Sdk\platform-tools.</p>

                    <p>In your code, output messages and values of variables to help you debug using the Debug class like this:</p>

                    <pre>
Debug.Log("This is a debug message. The value of the name variable is " + name);
                    </pre>

                    <p>Messages output by Debug.Log() will be tagged with an 'I' to indicate that it is an informational message. The Debug class also has methods for LogWarning() and LogError() that are tagged with 'W' and 'E' respectively. Output from logcat can be filtered further to only show the level of logging that you are interested in seeing.</p>

                    <p>With your device connected and adb logcat running, run the game on your phone and watch for log messages to appear in the terminal window.</p>

<p>Update: After writing this article I found a similar <a href=" https://docs.unity3d.com/6000.0/Documentation/Manual/android-debugging-on-an-android-device.html" target="_blank">article</a> in the Unity documentation.</p>]]></description>
    </item>
    <item>
      <title>Think of Me and Angel of Music</title>
      <link>https://www.highwaynorth.com/blogs/bryan/think-of-me-and-angel-of-music</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/think-of-me-and-angel-of-music</guid>
      <pubDate>Sun, 07 Jun 2020 21:59:48 GMT</pubDate>
      <description><![CDATA[<p>I recorded a couple more songs from Phantom of the Opera. I have been experimenting with different settings such as mic placement, gain level on the microphone, audio input level etc. I have also been trying different things to clean up the recordings with CyberLink AudioDirector. Previously I was using the "remove hiss" tool but I found that while it was nice to remove the background hiss, the piano sound became muffled and warped in some places. So, for these I kept the hiss. I am also applying equalizer settings that I came up via some experimentation to try to make the piano sound more natural. Not sure if that is working out but still learning. You be the judge. I will share my recording setup and process for editing the videos in an upcoming blog post.</p>

                    <h2>Think of Me</h2>
                    <p>Think of Me turned out pretty good overall. I recorded two versions, one is a bit slower than the other.</p>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/fw8fP-LmdCE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/wkkqyB17GKc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

                    <h2>Angel of Music</h2>
                    <p>I was really digging how this one sounded until the very end. Hit a few bad notes in the final chords. You can see my frustration in my facial expressions in the video. Oh well, the blog is called "mistakes and all" right?</p>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/vTYyoW4gKfI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>Re-introduction Etudes</title>
      <link>https://www.highwaynorth.com/blogs/bryan/re-introduction-etudes</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/re-introduction-etudes</guid>
      <pubDate>Sun, 07 Jun 2020 04:51:55 GMT</pubDate>
      <description><![CDATA[<p>A little over a year ago my wife bought me piano book called <a href="https://www.chillygonzales.com/books/re-introduction-etudes/" target="_blank">Re-introduction Etudes</a> by <a href="https://en.wikipedia.org/wiki/Chilly_Gonzales" target="_blank">Chilly Gonzales</a>. It's geared towards people who took piano lessons when they were young and want to get back into playing. I got back into playing several years ago but I still thought the book would be useful to me. I really enjoy playing these pieces and I like the way Chilly explains the techniques and the structure of the songs.</p>

                    <p>I recorded the first five songs. Historically, I have never been good at memorizing songs on the piano. As I work through the Re-introduction Etudes I am making a point to memorize each song to try and get better at this. The recordings are all from memory. I think playing from memory forces me to concentrate a bit more which leads to less mistakes.</p>

                    <h2>Five Spot</h2>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/ix_IesosrjY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>                    

                    <h2>Pavane</h2>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/nvirJ01mV0o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
                    
                    <h2>Pleading the Fifth</h2>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/nvirJ01mV0o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>                    

                    <h2>Mansbridge</h2>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/EVv39hWnqHg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
                    
                    <h2>Red Thread</h2>
                    <iframe width="560" height="315" src="https://www.youtube.com/embed/nvj6KHun-pU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>Modifying Animations for Prefabs in Unity</title>
      <link>https://www.highwaynorth.com/blogs/bryan/modifying-animations-for-prefabs-in-unity</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/modifying-animations-for-prefabs-in-unity</guid>
      <pubDate>Wed, 27 Dec 2017 22:02:43 GMT</pubDate>
      <description><![CDATA[<p>It was not obvious to me how to go about adding an animation to an existing prefab or modify animations associated with an existing prefab. This forum <a href="https://forum.unity.com/threads/help-with-animations-and-prefabs.11042/" target="_blank">discussion</a> led me to the right answer but I wanted to write a short blog post so I can easily find my way back to this answer in the future when my memory of it becomes foggy.</p>

                    <p>You can’t directly add animations to a prefab nor modify animations it already has. The only way to do it is to follow these steps:</p>

                    <ol>
                        <li>Create an instance of your Prefab. (e.g. drag it onto the scene)</li>
                        <li>Add/modify animation clips on the instance.</li>
                        <li>When finished, drag the instance on top of the original Prefab to replace it with the enhanced object that includes the new or updated animations.</li>                        
                    </ol>]]></description>
    </item>
    <item>
      <title>Relative Position Animation in Unity</title>
      <link>https://www.highwaynorth.com/blogs/bryan/relative-position-animation-in-unity</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/relative-position-animation-in-unity</guid>
      <pubDate>Wed, 27 Dec 2017 22:01:43 GMT</pubDate>
      <description><![CDATA[<p><a href="https://unity3d.com/" target="_blank">Unity</a> has a powerful animation editor. The concept is that you attach an <a href="https://docs.unity3d.com/ScriptReference/Animator.html" target="_blank">Animator</a> component to a <a href="https://docs.unity3d.com/ScriptReference/GameObject.html" target="_blank">GameObject</a> and then attach an <a href="https://docs.unity3d.com/Manual/class-AnimatorController.html" target="_blank">Animator Controller</a> to the Animator. An Animator Controller allows you to arrange and maintain a set of <a href="https://docs.unity3d.com/Manual/AnimationClips.html" target="_blank">Animation Clips</a> and associated <a href="https://docs.unity3d.com/Manual/class-Transition.html" target="_blank">Animation Transitions</a> for a character or object. An Animation Clip lets you define animations to GameObject properties along a timeline of keyframes.</p>

                    <p>I ran into a snag when I tried to animate the <strong>Transform.Position</strong> property of a GameObject. This works well for an instance of a GameObject in a specific location. However, a problem arises if you try to re-use the animation as part of a prefab or if you move the GameObject to another position. The problem is that the position values stored in the animation clip are absolute, meaning the object will move to the position recorded in the animation (world coordinates), instead of applying the animation relative to the current position of the GameObject prior to starting the animation (local coordinates).</p>

                    <p>This video <a href="https://youtu.be/4OvTLXA1Ark" target="_blank">tutorial</a> by <a href="https://www.youtube.com/channel/UCianwNdo8CMKIZm-vn8AGLA" target="_blank">Erwin Broekhuis</a> explains the simple fix for this, which is to wrap the animated object in a parent object and attach the Animator to the parent instead. However, the video is using the Animation component which has been <a href="https://www.reddit.com/r/Unity3D/comments/2i2pk6/in_terms_of_animations_is_the_animation_control/" target="_blank">deprecated</a> in favor of the newer Animator component. It took me a couple attempts to get it working properly so I decided to write this blog post with updated screen shots and steps with Animator.</p>

                    <h3>Step 1: Create the Parent Object</h3>

                    <p>Create an empty object off the root of the hierarchy. You can name the parent whatever you like, here it is called <strong>Parent</strong>.</p>

                    <a href="../../static/0006/01-create-parent.png" target="_blank"><img src="../../static/0006/01-create-parent.png" alt="Screen shot of Create Parent" class="Screenshot" /></a>
                    
                    <h3>Step 2: Add the Child Object</h3>

                    <p>Add the child object under the parent. In this walkthrough, we are simply adding a Cube 3D object. The child object should default to transform.position (0, 0, 0), which is a local coordinate position relative to the parent. You can name the child whatever you like, here it is called <strong>Cube</strong>.</p>

                    <a href="../../static/0006/02-create-child.png" target="_blank"><img src="../../static/0006/02-create-child.png" alt="Screen shot of Create Child" class="Screenshot" /></a>

                    <h3>Step 3: Add the Animator Component to the Parent</h3>

                    <p>Add an Animator component to the parent object. The Animator component is found in the miscellaneous category.</p>

                    <a href="../../static/0006/03-create-animator.png" target="_blank"><img src="../../static/0006/03-create-animator.png" alt="Screen shot of Create Animator" class="Screenshot" /></a>

                    <h3>Step 4: Create an Animator Controller</h3>

                    <p>We need to create an Animator Controller to manage the animation clips and state transitions. I suggest creating a folder named Animation to store your animation controller and animation clips. In the Project window, right-click on the Animation folder and choose <strong>Create &gt; Animator Controller</strong>. You can name the controller whatever you like. Here it is called <strong>CubeAnimatorController</strong>.</p>

                    <a href="../../static/0006/04-create-animator-controller.png" target="_blank"><img src="../../static/0006/04-create-animator-controller.png" alt="Screen shot of Create Animator Controller" class="Screenshot" /></a>

                    <h3>Step 5: Attach the Animator Controller to Animator</h3>

                    <p>Attach the Animator Controller to the Animator by dragging it onto the Controller property of the Animator. To do this, start by selecting the <strong>Parent</strong> object in the hierarchy then click on the Animation folder in the Project window. Drag <strong>CubeAnimatorController</strong> from the Animation folder onto the empty Controller box under Animator in the Inspector window.</p>

                    <a href="../../static/0006/05-attach-animator-controller.png" target="_blank"><img src="../../static/0006/05-attach-animator-controller.png" alt="Screen shot of Attach Animator Controller" class="Screenshot" /></a>

                    <h3>Step 6: Create an Animation Clip</h3>

                    <p>If it’s not open already, open the Animation window by choosing <strong>Window &gt; Animation</strong> from the Unity Editor menu. You can place the Animation window anywhere you like. Personally, I like to position the Animation window in the same group as my Project window in such a way that the Scene window is visible at the same time as the Animation window.</p>

                    <p>Select the <strong>Cube</strong> object in the Hierarchy window. Click on the Animation tab so that the Animation window is visible. You should be prompted to create an animation clip.</p>

                    <a href="../../static/0006/06-create-animation-clip.png" target="_blank"><img src="../../static/0006/06-create-animation-clip.png" alt="Screen shot of Create Animator Clip" class="Screenshot" /></a>

                    <p>When you press the button to create an animation clip a dialog will open prompting for the location to save the animation clip. I suggest saving it in your Animation folder where you saved the Animator Controller. Name the animation Clip <strong>CubeMove</strong>.</p>

                    <a href="../../static/0006/07-animation-clip-properties.png" target="_blank"><img src="../../static/0006/07-animation-clip-properties.png" alt="Screen shot of Animation Clip Properties" class="Screenshot" /></a>

                    <p>Note that creating the animation clip also adds a corresponding state for it to the <strong>CubeAnimatorController</strong> you attached to the Animator. This blog post does not cover anything related to the Animator Controller or state transitions.</p>

                    <h3>Step 7: Add the Cube’s Transform.Position Property to the Animation Clip</h3>

                    <p>In the Animation window, with the <strong>CubeMove</strong> clip (state) selected, click the Add Property button. Do not select the root Transform object but instead expland Cube and choose <strong>Cube &gt; Tranform &gt; Position</strong>.</p>

                    <p>At this point, you will see the Cube Position property in the Animation window with two keyframes added to the timeline, one at 0:00 and one at 1:00. These times refer to the frame number. By default an animation has 60 samples and will last 1 second at 60 frames per second.</p>

                    <a href="../../static/0006/08-cube-transform-position-property.png" target="_blank"><img src="../../static/0006/08-cube-transform-position-property.png" alt="Screen shot of Cube Transform Position Property" class="Screenshot" /></a>
                    
                    <h3>Step 8: Add a Keyframe to the Animation</h3>

                    <p>Click on the timeline at position 0:30 then click the button in the Animation window to add a keyframe. You will notice that the Animation editor will enter “record” mode with a few visual cues:</p>

                    <ul>
                        <li>The record button will be depressed</li>
                        <li>The game Play/Pause buttons at the top of the Unity Editor will be colored red</li>
                        <li>The Transform.Position property attributes in the Inspector for the Cube will be colored red</li>                        
                    </ul>

                    <p>Change one of the Transform.Position property attributes. For example, change X from 0 to 2.</p>
                    
                    <p><strong>Note: At this point you may see that both the Parent and the Cube objects are selected in the Hierarchy window and that a Transform.Position will be added to the animation clip for both of them. If this happens, right click the Parent Transform.Position and choose to remove the properties from the animation. This is key to ensuring that the animation remains relative to the parent object’s current position.</strong></p>

                    <a href="../../static/0006/09-add-keyframe-to-animation.png" target="_blank"><img src="../../static/0006/09-add-keyframe-to-animation.png" alt="Screen shot of Add Keyframe to Animation" class="Screenshot" /></a>
                    
                    <p>Click the Record button in the Animation window to stop recording.</p>

                    <h3>Step 9: Test the Animation</h3>

                    <p>Press the Play button in the Animation window to test your animation. You should see your Cube sliding 2 units along the X axis from its start position then return back.</p>

                    <h3>Step 10: Move the Parent Object and Repeat Test</h3>

                    <p>To confirm that the relative position animation works as expected, move the <strong>Parent</strong> object somewhere else in the scene then click the Play button in the Animation window again. If everything is configured correctly, the animation should begin from the new location of <strong>Parent</strong> and animate 2 units along the X axis and back. It should <strong>not</strong> jump to the location where the animation was originally recorded.</p>]]></description>
    </item>
    <item>
      <title>The Music of the Night on Piano - Blue Yeti</title>
      <link>https://www.highwaynorth.com/blogs/bryan/the-music-of-the-night-on-piano---blue-yeti</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/the-music-of-the-night-on-piano---blue-yeti</guid>
      <pubDate>Tue, 29 Aug 2017 03:56:50 GMT</pubDate>
      <description><![CDATA[<p>I bought a <a href="http://www.bluemic.com/products/yeti/" target="_blank">Blue Yeti</a> USB microphone this weekend and I absolutely love it. I got the Blackout version and it looks very sexy :)</p>

                    <img src="../../static/0005/01-blue-yeti-microphone.jpg" alt="Blue Yeti Microphone" class="Screenshot" />
                    
                    <p>To test out the new mic, I re-recorded The Music of The Night on piano. It sounds SO much better than my <a href="https://www.highwaynorth.com/blogs/bryan/my-first-piano-video---the-music-of-the-night">original recording</a>.
                        I used Cyberlink <a href="https://www.cyberlink.com/products/powerdirector-ultra/features_en_CA.html?&r=1" target="_blank">PowerDirector</a> and <a href="https://www.cyberlink.com/products/audiodirector/features_en_CA.html" target="_blank">AudioDirector</a> to edit the video and cleanup the audio, but the mic is so good I really didn't
                        have to do much to the audtio at all. Eliminated a bit of room noise (really wasn't much) and bumped the volume up a tad.</p>

                    <iframe width="560" height="315" src="https://www.youtube.com/embed/KZTVmdbq4B0" frameborder="0" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>All I Ask of You on Piano</title>
      <link>https://www.highwaynorth.com/blogs/bryan/all-i-ask-of-you-on-piano</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/all-i-ask-of-you-on-piano</guid>
      <pubDate>Mon, 10 Jul 2017 03:27:23 GMT</pubDate>
      <description><![CDATA[<p>Me playing All I Ask of You from Phantom of the Opera on piano.</p>

                <iframe width="560" height="315" src="https://www.youtube.com/embed/1MX1CXSF-Nw" frameborder="0" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>Happy 10th Anniversary TerraClues!</title>
      <link>https://www.highwaynorth.com/blogs/bryan/happy-10th-anniversary-terraclues-</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/happy-10th-anniversary-terraclues-</guid>
      <pubDate>Wed, 22 Feb 2017 03:30:17 GMT</pubDate>
      <description><![CDATA[<p>In celebration of 10 years since the launch of <a target="_blank" href="https://www.terraclues.com">TerraClues</a>, we are excited to re-launch the site with a modern look and feel. The best part of the new design is that it is mobile friendly and works great on touch devices of any size. Help us celebrate by grabbing your tablet or phone and curl up on the couch and enjoy solving a few hunts.</p>

                    <a href="/static/0004/01-terraclues-home.png" target="_blank"><img src="/static/0004/01-terraclues-home.png" alt="TerraClues home page" class="Screenshot" /></a>

                    <p>In addition to the new look and feel, there are a couple new features. Easily share hunts with friends on Facebook and Twitter. Check out the new Stats page to understand how far people are making it into your hunt before getting stuck.</p>

                    <a href="/static/0004/02-terraclues-features.png" target="_blank"><img src="/static/0004/02-terraclues-features.png" alt="TerraClues features" class="Screenshot" /></a>

                    <p>It’s now easier than ever to find interesting hunts to play. Click tags in hunt listings to quickly see other hunts with the same tag. Tags are available for categories, difficulty levels and more. Be sure to tag your hunts when create new ones or circle back and add tags now to hunts you created before.</p>

                    <a href="/static/0004/03-terraclues-tags.png" target="_blank"><img src="/static/0004/03-terraclues-tags.png" alt="Hunts tagged in hunt lists" class="Screenshot" /></a>

                    <p>TerraClues has always been popular in schools and teachers around the world use it as a fun and educational game in their classroom. To make it easier for students to jump in and play, we simplified the Schools area. Hunts have been carefully selected by our team of moderators and tagged as educational and appropriate for use within a classroom setting.  Additionally, hunts are tagged for specific grade levels or subjects. Browse available hunts using the tags on the <a target="_blank" href="https://www.terraclues.com/Schools">Schools</a> page Tap into students' creativity by challenging them to create their own hunts too. A free account is required to create hunts.</p>

                    <a href="/static/0004/04-terraclues-for-schools.png" target="_blank"><img src="/static/0004/04-terraclues-for-schools.png" alt="TerraClues for Schools" class="Screenshot" /></a>

                    <p>We realize the Schools area is dramatically different than before. The original version had powerful features like the ability to create private classrooms, curate specific hunts for them to play and track their progress. Don’t panic, we didn’t take these features away completely. You can still access the full <a target="_blank" href="https://www.terraclues.com/v1/Schools">Classic Mode</a> of the schools area.</p>

                    <p>We would love your feedback on the new design, good or bad. Email us at <a href="mailto:info@terraclues.com">info@terraclues.com</a> or reach out to us on <a target="_blank" href="https://www.facebook.com/TerraClues">Facebook</a> or follow us on <a target="_blank" href="https://www.twitter.com/TerraClues">Twitter</>.</p>]]></description>
    </item>
    <item>
      <title>Debugging IIS URL Rewrite Rules</title>
      <link>https://www.highwaynorth.com/blogs/bryan/debugging-iis-url-rewrite-rules</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/debugging-iis-url-rewrite-rules</guid>
      <pubDate>Thu, 26 Jan 2017 04:44:16 GMT</pubDate>
      <description><![CDATA[<p>As a follow up to my blog about <a href="https://www.highwaynorth.com/blogs/bryan/using-the-iis-url-rewrite-module-to-provide-canonical-urls-for-your-site">Using the IIS URL Rewrite Module to Provide Canonical URLs for your Site</a>, I found a couple of helpful articles on how to debug IIS URL Rewrite rules. The instructions seem a bit intimidating at first but if you give it a try I think you will find it pretty straightforward to setup and extremely helpful once you do.</p>

                    <ul>
                        <li><a target="_blank" href="https://www.iis.net/learn/extensions/url-rewrite-module/using-failed-request-tracing-to-trace-rewrite-rules">Using Failed Request Tracing to Trace Rewrite Rules</a></li>
                        <li><a target="_blank" href="https://www.iis.net/learn/troubleshoot/using-failed-request-tracing/troubleshooting-failed-requests-using-tracing-in-iis">Troubleshooting Failed Requests Using Tracing in IIS 7</a></li>
                    </ul>]]></description>
    </item>
    <item>
      <title>After the Rain on Piano</title>
      <link>https://www.highwaynorth.com/blogs/bryan/after-the-rain-on-piano</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/after-the-rain-on-piano</guid>
      <pubDate>Wed, 18 Jan 2017 04:49:56 GMT</pubDate>
      <description><![CDATA[<p>Me playing After the Rain by Blue Rodeo on piano. This one is real rough in spots. Pushing myself to just get these done and not think about it too much. Will improve over time.</p>

                <iframe width="560" height="315" src="https://www.youtube.com/embed/4W-glfe4EkU" frameborder="0" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>Dark Angel on Piano</title>
      <link>https://www.highwaynorth.com/blogs/bryan/dark-angel-on-piano</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/dark-angel-on-piano</guid>
      <pubDate>Wed, 18 Jan 2017 04:41:34 GMT</pubDate>
      <description><![CDATA[<p>Me playing Dark Angel by Blue Rodeo on piano.</p>

                <iframe width="560" height="315" src="https://www.youtube.com/embed/srHxX0KRze8" frameborder="0" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>Using the IIS URL Rewrite Module to Provide Canonical URLs for your Site</title>
      <link>https://www.highwaynorth.com/blogs/bryan/using-the-iis-url-rewrite-module-to-provide-canonical-urls-for-your-site</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/using-the-iis-url-rewrite-module-to-provide-canonical-urls-for-your-site</guid>
      <pubDate>Thu, 24 Nov 2016 21:39:04 GMT</pubDate>
      <description><![CDATA[<p>In my article about <a href="https://www.highwaynorth.com/blogs/Bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks">Getting Your Site to Play Nice with Search Engines and Social Networks</a> I discussed the importance of having canonical URLs for the pages on your site to avoid issues with multiple URLs for the same page causing your page reputation to be divided across the versions. While you can provide a <span class="CodeInline">&lt;link rel=”canonical” …&gt;</span> meta tag to achieve this, it’s also good practice to configure your site to redirect the various versions of URLs to the canonical version.</p>

                    <p>If you are using IIS as your web server, you can implement rules to redirect to canonical URLs with the IIS <a href="https://www.iis.net/downloads/microsoft/url-rewrite" target="_blank">URL Rewrite Module 2.0</a>. To use this module, <a href="https://www.microsoft.com/en-ca/download/details.aspx?id=7435" target="_blank">download</a> and install it on your web server. Once installed, you will see a URL Rewrite option in Internet Information Services (IIS) Manager when viewing the properties of your site.</p>

                    <a href="/static/0003/01-url-rewrite.png" target="_blank"><img src="/static/0003/01-url-rewrite.png" alt="Screen shot of URL rewrite" class="Screenshot" /></a>
                    

                    <p>The user interface for adding and modifying rules is very straightforward. When creating a new rule you will be presented with a variety of templates to start from for common rewrite cases. When a request is received, all matching rules are executed against your URL in the order in which they are defined. You can adjust the order of the rules. You can also set a property on some rule types to indicate that processing should stop and to not move on to the remaining rules.</p>

                    <p>Microsoft has documentation on <a href="https://www.iis.net/learn/extensions/url-rewrite-module/using-url-rewrite-module-20" target="_blank">Using URL Rewrite Module 2.0</a> and the invaluable <a href="http://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-20-configuration-reference" target="_blank">URL Rewrite Module v2.0 Configuration Reference</a>.</p>

                    <p>The user interface in IIS Manager saves the settings to the <span class="CodeInline">web.config</span> file. I will now go through each of the rewrite rules implemented on the <a href="https://www.highwaynorth.com/" target="_blank">Highway North</a> site with a screen shot of the settings in IIS Manager. At the end I will include the full code for the settings from the <span class="CodeInline">web.config</a> file.</p>

                    <p>Matching patterns in rules can be specified as <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions" target="_blank">JavaScript Regular Expressions</a> or wildcards.</p>

                    <h2>Ignored Paths Rule</h2>

                    <p>There are a few paths on our site that we don’t want to redirect from. For example, we have some URLs that our existing Android applications are expecting to be available and don’t have the ability to redirect from HTTP to HTTPS. The URL Rewrite Module makes available a {PATH_INFO} server variable which includes the path after the protocol prefix and domain name including the forward slash. It’s easy to match the ignored paths to the {PATH_INFO} server variable and set an action type of None (i.e. leave the URL alone) and then stop processing more rules.</p>

                    <a href="/static/0003/02-ignored-paths.png" target="_blank"><img src="/static/0003/02-ignored-paths.png" alt="Screen shot of ignored paths" class="Screenshot" /></a>

                    <table>
                        <tr>
                            <td>Name</td>
                            <td>Ignored Paths Rule</td>
                        </tr>                        
                        <tr>
                            <td>Match URL</td>
                            <td>Matches the regular expression: <span class="CodeInline">(.*)</span></td>
                        </tr>                        
                        <tr>
                            <td>Conditions</td>
                            <td>
                                {PATH_INFO} matches any of these regular expressions:<br/>
                                /AppInfo/.*<br />
                                /Mountie/Token<br />
                            </td>
                        </tr>
                        <tr>
                            <td>Action Type</td>
                            <td>None</td>
                        </tr>                                                                        
                        <tr>
                            <td>Stop processing of subsequent rules</td>
                            <td>Yes</td>
                        </tr>                                                                        
                    </table>                    


                    <h2>HTTP to HTTPS Redirect Rule</h2>

                    <p>We want to force users of our site to connect with HTTP secure (HTTPS). The URL Rewrite Module makes available an HTTPS server variable set to either ON or OFF to tell us if the URL is using HTTPS.</p>

                    <a href="/static/0003/03-http-to-https.png" target="_blank"><img src="/static/0003/03-http-to-https.png" alt="Screen shot of HTTP to HTTPS" class="Screenshot" /></a>

                    <table>
                        <tr>
                            <td>Name</td>
                            <td>HTTP to HTTPS Redirect Rule</td>
                        </tr>                        
                        <tr>
                            <td>Match URL</td>
                            <td>Matches the regular expression: <span class="CodeInline">(.*)</span></td>
                        </tr>                        
                        <tr>
                            <td>Conditions</td>
                            <td>{HTTPS} matches the regular expression: <span class="CodeInline">^OFF$</span></td>
                        </tr>
                        <tr>
                            <td>Action Type</td>
                            <td>Redirect</td>
                        </tr>                                                                        
                        <tr>
                            <td>Redirect URL</td>
                            <td><span class="CodeInline">https://{HTTP_HOST}{PATH_INFO}</span></td>
                        </tr>                                                                        
                        <tr>
                            <td>Append query string</td>
                            <td>Yes</td>
                        </tr>                                                                        
                        <tr>
                            <td>Redirect Type</td>
                            <td>Permanent (301)</td>
                        </tr>                                                                        
                        <tr>
                            <td>Stop processing of subsequent rules</td>
                            <td>No</td>
                        </tr>                                                                        
                    </table>                    

                    <h2>Canonical Host Name Rule</h2>

                    <p>Our site is accessible via both its domain name and via a ‘www’ name. i.e. <span class="CodeInline">https://highwaynorth.com</span> and <span class="CodeInline">https://www.highwaynorth.com</span>. We choose the ‘www’ version as our preferred version and redirect to it. We can look at the {HTTP_HOST} server variable to determine if our canonical host name was used or not.</p>

                    <a href="/static/0003/04-canonical-host-name.png" target="_blank"><img src="/static/0003/04-canonical-host-name.png" alt="Screen shot of canonical host name" class="Screenshot" /></a>

                    <table>
                        <tr>
                            <td>Name</td>
                            <td>Canonical Host Name Rule</td>
                        </tr>                        
                        <tr>
                            <td>Match URL</td>
                            <td>Matches the regular expression: <span class="CodeInline">(.*)</span></td>
                        </tr>                        
                        <tr>
                            <td>Conditions</td>
                            <td>{HTTP_HOST} does not match the regular expression: <span class="CodeInline">^www\.highwaynorth\.com$</span></td>
                        </tr>
                        <tr>
                            <td>Action Type</td>
                            <td>Redirect</td>
                        </tr>                                                                        
                        <tr>
                            <td>Redirect URL</td>
                            <td><span class="CodeInline">https://www.highwaynorth.com{PATH_INFO}</span></td>
                        </tr>                                                                        
                        <tr>
                            <td>Append query string</td>
                            <td>Yes</td>
                        </tr>                                                                        
                        <tr>
                            <td>Redirect Type</td>
                            <td>Permanent (301)</td>
                        </tr>                                                                        
                        <tr>
                            <td>Stop processing of subsequent rules</td>
                            <td>No</td>
                        </tr>                                                                        
                    </table>                    

                    <h2>Remove Trailing Slash Rule</h2>

                    <p>Whether or not your URLs end with a trailing slash is largely a matter of preference. Because your URL is treated as a separate URL by search engines when it has a trailing slash from when it does not, you should choose the one you prefer and make it canonical. You can add a rule to either add or remove a trailing slash. For our site, our preference is to remove the trailing slash. This can be achieved by matching URLs that end with a trailing slash.</p>

                    <a href="/static/0003/05-remove-trailing-slash.png" target="_blank"><img src="/static/0003/05-remove-trailing-slash.png" alt="Screen shot of remove trailing slash" class="Screenshot" /></a>

                    <table>
                        <tr>
                            <td>Name</td>
                            <td>Remove Trailing Slash Rule</td>
                        </tr>                        
                        <tr>
                            <td>Match URL</td>
                            <td>Matches the regular expression: <span class="CodeInline">(.*)/$</span></td>
                        </tr>                        
                        <tr>
                            <td>Conditions</td>
                            <td>
                                {REQUEST_FILENAME} is not a directory<br />
                                {REQUEST_FILENAME} is not a file
                            </td>
                        </tr>
                        <tr>
                            <td>Action Type</td>
                            <td>Redirect</td>
                        </tr>                                                                        
                        <tr>
                            <td>Redirect URL</td>
                            <td><span class="CodeInline">{R:1}</span></td>
                        </tr>                                                                        
                        <tr>
                            <td>Append query string</td>
                            <td>Yes</td>
                        </tr>                                                                        
                        <tr>
                            <td>Redirect Type</td>
                            <td>Permanent (301)</td>
                        </tr>                                                                        
                        <tr>
                            <td>Stop processing of subsequent rules</td>
                            <td>No</td>
                        </tr>                                                                        
                    </table>                    

                    <h2>Lower Case Rule</h2>

                    <p>Many sites redirect to an all lower case URL which is important because search engines will treat casing differences as being different URLs. However, for our site, we had too many existing links with mixed case that would now cause lots of redirects to happen. Also, we prefer the readability and look of mixed case URLs when users navigate our site or share links. We decided to accept the risk of our links being shared with mixed case and feel it will be a rare enough scenario not to worry about so we didn’t implement a rule to redirect to all lower case.</p>

                    <h2>Source Code of Rules</h2>

                    <p>Here is the full source code of the above rules as they appear in the <span class="CodeInline">web.config</span> file:</p>

<pre>
&lt;rewrite xdt:Transform="Insert"&gt;
&lt;rules&gt;
    &lt;clear /&gt;
    &lt;rule name="Ignored Paths Rule" stopProcessing="true"&gt;
    &lt;match url="(.*)" /&gt;
    &lt;conditions logicalGrouping="MatchAny" trackAllCaptures="false"&gt;
        &lt;add input="{PATH_INFO}" pattern="/AppInfo/.*" /&gt;
        &lt;add input="{PATH_INFO}" pattern="/Mountie/Token" /&gt;
        &lt;add input="{PATH_INFO}" pattern="/Mountie/api/.*" /&gt;
        &lt;add input="{PATH_INFO}" pattern="/Sasquatch/api/.*" /&gt;
        &lt;add input="{PATH_INFO}" pattern="/Tundra/api/.*" /&gt;
    &lt;/conditions&gt;
    &lt;action type="None" /&gt;
    &lt;/rule&gt;
    &lt;rule name="HTTP to HTTPS Redirect Rule"&gt;
    &lt;match url="(.*)" negate="false" /&gt;
    &lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false"&gt;
        &lt;add input="{HTTPS}" pattern="^OFF$" /&gt;
    &lt;/conditions&gt;
    &lt;action type="Redirect" url="https://{HTTP_HOST}{PATH_INFO}" /&gt;
    &lt;/rule&gt;
    &lt;rule name="Canonical Host Name Rule"&gt;
    &lt;match url="(.*)" /&gt;
    &lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false"&gt;
        &lt;add input="{HTTP_HOST}" pattern="^www\.highwaynorth\.com$" negate="true" /&gt;
    &lt;/conditions&gt;
    &lt;action type="Redirect" url="https://www.highwaynorth.com{PATH_INFO}" /&gt;
    &lt;/rule&gt;
    &lt;rule name="Remove Trailing Slash Rule"&gt;
    &lt;match url="(.*)/$" /&gt;
    &lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false"&gt;
        &lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
        &lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
    &lt;/conditions&gt;
    &lt;action type="Redirect" url="{R:1}" /&gt;
    &lt;/rule&gt;
&lt;/rules&gt;
&lt;/rewrite&gt;
</pre>

                    <p>Again, you don’t have to use the IIS Manager interface to configure your rules. Personally, I take the approach of using the UI to configure the rules against a local instance of IIS then copy and paste the code from the generated <span class="CodeInline">web.config</span> into our site’s <span class="CodeInline">web.config</span>.</p>]]></description>
    </item>
    <item>
      <title>Getting Your Site to Play Nice with Search Engines and Social Networks</title>
      <link>https://www.highwaynorth.com/blogs/bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks</guid>
      <pubDate>Thu, 24 Nov 2016 21:30:18 GMT</pubDate>
      <description><![CDATA[<p>I spent some time the last few weeks updating both the <a href="https://www.highwaynorth.com/" target="_blank">Highway North</a> site and my blog to play nice with search engines and social networks. Here are some of the things I implemented.</p>

                    <h2>Meta Tags</h2>

                    <p>There are a couple of helpful tags you can include in the header of your pages to tell search engines how you want your page described in search results and what link should be used to direct people to your site.</p>

                    <h3>Canonical URL</h3>

                    <p>It is common to have multiple URLs leading to the same page within your site. To search engines, these URLs are considered separate and any reputation earned for the page is split across the various versions of the URL. Here are some examples of scenarios where you might have multiple URLs for the same page:</p>

                    <ul>
                        <li>Site accessible via both its domain name and via a ‘www’ name. e.g. <span class="CodeInline">https://highwaynorth.com</span> and <span class="CodeInline">https://www.highwaynorth.com</span></li>
                        <li>Site accessible both over HTTP and HTTPS (different URL prefix)</li>
                        <li>URL parameters e.g. https://www.highwaynorth.com/contact<strong>?sessionid=12345</strong></li>
                    </ul>

                    <p>To solve this, define a <a href="https://support.google.com/webmasters/answer/139066?hl=en" target="_blank">canonical URL</a> for your pages. There are a couple of ways you can achieve this:</p>

                    <ul>
                        <li>Have additional versions of the URL perform an HTTP 301 permanent redirect to the canonical URL. I wrote an article about <a href="https://www.highwaynorth.com/blogs/bryan/using-the-iis-url-rewrite-module-to-provide-canonical-urls-for-your-site">Using the IIS URL Rewrite Module to Provide Canonical URLs for your Site</a>.</li>
                        <li>Add a canonical link tag to the <span class="CodeInline">&lt;head&gt;</span> of your page:</li>
                        <p class="Code">&lt;link href="https://www.highwaynorth.com/blogs/bryan" rel="canonical" /&gt;</p>
                    </ul>


                    <h3>Description</h3>

                    <p>Adding a description meta tag to the <span class="CodeInline">&lt;head&gt;</span> of your page tells search engines a bit more about your page and it also tells search engines how you want the page summarized in search results. There is no guarantee that your description will be used but providing it gives some level of control.</p>

                    <p class="Code">&lt;meta name="description" content="Provide a short description of your site here, 1-3 sentences." /&gt;</p>

                    <h3>Open Graph & Twitter Card Tags</h3>

                    <p>There are also a couple sets of tags that give you control over how your pages are described on Facebook and Twitter when people share links to your site.</p>

                    <p>When you share a link, Facebook and Twitter immediately crawl your page to choose an image and a description to include in the post. Without metadata, these sites make their best guess as to an appropriate image to show from the page and an appropriate description of the content. Sometimes this works OK but in many cases the result is suboptimal. To tell these sites how you want the content described, use <a href="https://developers.facebook.com/docs/sharing/webmasters" target="_blank">Facebook Open Graph</a> and <a href="https://dev.twitter.com/cards/overview" target="_blank">Twitter Cards</a>.</p>
                    
                    <p><a href="https://blog.kissmetrics.com/" target="_blank">Kissmetrics Blog</a> does a nice job of describing how to use these tags effectively in their article <a href="https://blog.kissmetrics.com/open-graph-meta-tags/" target="_blank">What You Need to Know About Open Graph Meta Tags for Total Facebook and Twitter Mastery</a>.</p>

                    <p>Note that when setting the <span class="CodeInline">og:image</span> tag, you’ll want to specify the URL to an image that is 1200x630 or larger. The image should have a 1.91 ratio.</p>

                    <p>For Twitter, you can choose either to use a <a href="https://dev.twitter.com/cards/types/summary" target="_blank">Summary Card</a> with a square thumbnail or a <a href="https://dev.twitter.com/cards/types/summary-large-image" target="_blank">Summary Card with Large Image</a> for a larger wide image. After adding Twitter Card tags to your page, test your URL in the card <a href="https://cards-dev.twitter.com/validator" target="_blank">validator</a>. Validating your URL also seems to whitelist it.</p>

                    <p>As a reference, here are the canonical URL, description, Open Graph and Twitter Card tags for this article:</p>

<pre>
&lt;link href="https://www.highwaynorth.com/blogs/bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks" rel="canonical" /&gt;
&lt;meta name="description" content="Sharing some tips on how to get your site to play nice with search engines and social networks by using helpful meta tags and by submitting your sitemap to Google and Bing." /&gt;

&lt;meta name="og:title" content="Getting Your Site to Play Nice with Search Engines and Social Networks" /&gt;
&lt;meta name="og:site_name" content="Mistakes and All - Bryan Bedard&#39;s Blog" /&gt;
&lt;meta name="og:url" content="https://www.highwaynorth.com/blogs/bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks" /&gt;
&lt;meta name="og:description" content="Sharing some tips on how to get your site to play nice with search engines and social networks by using helpful meta tags and by submitting your sitemap to Google and Bing." /&gt;
&lt;meta name="og:image" content="https://www.highwaynorth.com/static/0000/BryanBedardBlog2.jpg" /&gt;
&lt;meta name="og:type" content="article" /&gt;
&lt;meta name="og:locale" content="en_US" /&gt;

&lt;meta name="twitter:card" content="summary_large_image" /&gt;
&lt;meta name="twitter:url" content="https://www.highwaynorth.com/blogs/bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks" /&gt;
&lt;meta name="twitter:title" content="Getting Your Site to Play Nice with Search Engines and Social Networks" /&gt;
&lt;meta name="twitter:description" content="Sharing some tips on how to get your site to play nice with search engines and social networks by using helpful meta tags and by submitting your sitemap to Google and Bing." /&gt;
&lt;meta name="twitter:image" content="https://www.highwaynorth.com/static/0000/BryanBedardBlog2.jpg" /&gt;    
</pre>

                    <h2>Sitemap Registration</h2>

                    <p>Once search engines know about your site they do a decent job of discovering the pages it contains and figuring out what your site is about and what links are important based on the content and structure of your site. However, they don’t always present your content and <a href="https://support.google.com/webmasters/answer/47334?hl=en" target="_blank">sitelinks</a> exactly how you want them to. You can improve how your site is cataloged by providing a sitemap file and registering it within the <a href="https://www.google.com/webmasters/tools/home" target="_blank">Google Search Console</a> and <a href="http://www.bing.com/toolbox/webmaster" target="_blank">Bing Webmaster Tools</a>.</p>

                    <p>By providing a sitemap it gives you some control over the sitelinks that Google shows in search results for your site. This is how the Highway North site comes up after we submitted a sitemap and it was crawled by Google.</p>

                    <a href="/static/0002/01-sitelinks.png" target="_blank"><img src="/static/0002/01-sitelinks.png" alt="Screen shot of site links" class="Screenshot" /></a>

                    <p>With both Google Search Console and Bing Webmaster Tools you will need to claim ownership of your site. There are a few ways to verify that you own your site. The simple approach I took is to use the option of downloading a verification file and placing it in the root of my site. This proves that you have control over the site. You will need to claim ownership over the various versions of your site (HTTP vs. HTTPS and ‘www’ vs. domain only). With Google Search Console you can indicate which version of your URL is the preferred version.</p>

                    <p>Google provides excellent <a href="https://support.google.com/webmasters/answer/183668?hl=en" target="_blank">guidance</a> on building sitemaps with tips like using consistent, fully-qualified URLs.</p>

                    <h2>Clean Descriptive URLs</h2>

                    <p>Search engines harvest your URLs for information about the page such as keywords and information about the site structure. It’s a best practice to have clean, descriptive URLs without a lot of parameters. For example, when linking to an article, it’s better to have the title of your article in the URL then to have a parameter with an article ID. So,</p>

                    <p class="Code">https://www.highwaynorth.com/blogs/bryan/getting-your-site-to-play-nice-with-search-engines-and-social-networks</p>

                    <p>is a better choice of URL than</p>

                    <p class="Code">https://www.highwaynorth.com/blogs/bryan?articleid=106</p>

                    <p>Just sharing a few tips here. Search engine optimization is a big topic and there are several great references available to teach you how such as this <a href="https://moz.com/beginners-guide-to-seo" target="_blank">Beginner’s Guide to SEO</a>.</p>]]></description>
    </item>
    <item>
      <title>November Rain on Piano</title>
      <link>https://www.highwaynorth.com/blogs/bryan/november-rain-on-piano</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/november-rain-on-piano</guid>
      <pubDate>Sun, 13 Nov 2016 05:10:47 GMT</pubDate>
      <description><![CDATA[<p>Recorded another piano video tonight, November Rain by Guns N' Roses. Recorded a few takes. Messed up in a few spots but this was still the best take so I went with it.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/Ejj7DyRo6ec" frameborder="0" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>How to Develop and Run ASP.NET Core Applications on Linux in Azure</title>
      <link>https://www.highwaynorth.com/blogs/bryan/how-to-develop-and-run-asp-net-core-applications-on-linux-in-azure</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/how-to-develop-and-run-asp-net-core-applications-on-linux-in-azure</guid>
      <pubDate>Sat, 22 Oct 2016 03:04:23 GMT</pubDate>
      <description><![CDATA[<p>Recently, I wanted to try running ASP.NET core in Linux to see how it compares to running it under Windows. Overall, it was a simple process but there were more steps than I expected to get up and running so I thought it helpful to blog about it and leave some bread crumbs for “future Bryan” or anyone else who is trying to do this. Since I don’t have a Linux machine I decided to create an Unbuntu virtual machine (VM) in <a href="https://azure.microsoft.com/" target="_blank">Microsoft Azure</a>. I certainly could have done it in <a href="https://aws.amazon.com/" target="_blank">Amazon Web Services</a> (AWS) or <a href="https://cloud.google.com/" target="_blank">Google Cloud Platform</a>. The instructions are for Ubuntu on Azure but the process should very similar on Linux servers in other environments.</p>

                <p>Here is how to do it:</p>

                <h3>Login to the Azure Portal</h3>

                <p><a href="https://portal.azure.com" target="_blank">https://portal.azure.com</a></p>

                <h3>Create an Ubuntu VM</h3>

                <p>From the dashboard, click New and enter Ubuntu in the search box. Choose Ubuntu 16.04 LTS or whatever the current version is.</p>

                <a href="/static/0001/01-new-ervice.png" target="_blank"><img src="/static/0001/01-new-ervice.png" alt="Screen shot of new service" class="Screenshot" /></a>
                
                <p>Choose Resource Manager as the deployment model. With this deployment model, you can put resources you create such as websites, SQL Databases etc. in a resource group and manage them as a single application. Read more about the Resource Manager model and its benefits <a href="https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-compare-deployment-models/" target="_blank">here</a>.</p>

                <a href="/static/0001/02-deployment-model.png" target="_blank"><img src="/static/0001/02-deployment-model.png" alt="Screen shot of deployment model" class="Screenshot" /></a>

                <p>Click Create to configure the settings for your server. Enter these values:</p>

                <table>
                    <tr>
                        <td>Name:</td>
                        <td>dotnet-ubuntu</td>
                    </tr>
                    <tr>
                        <td>VM disk type:</td>
                        <td>HDD</td>
                    </tr>
                    <tr>
                        <td>User name:</td>
                        <td>(Choose a user name)</td>
                    </tr>
                    <tr>
                        <td>Authentication type:</td>
                        <td>Password</td>
                    </tr>
                    <tr>
                        <td>Password:</td>
                        <td>(Choose a password)</td>
                    </tr>
                    <tr>
                        <td>Subscription:</td>
                        <td>(Choose a subscription)</td>
                    </tr>
                    <tr>
                        <td>Resource group:</td>
                        <td>Create new</td>
                    </tr>
                    <tr>
                        <td>Resource group name:</td>
                        <td>dotnet-ubuntu</td>
                    </tr>
                    <tr>
                        <td>Location:</td>
                        <td>(Choose a location)</td>
                    </tr>                    
                </table>

                <p>Choose a size for your VM. An A1 standard is sufficient for this walkthrough which has 1 core, 1.75 GB of RAM and 2 data disks.</p>

                <p>Accept the default options related to storage, virtual network, subnet etc. At the end of the wizard, click OK to create the VM. A tile will appear on your dashboard while the VM is being created.</p>

                <h3>Connect via SSH</h3>

                <p>You can connect to your server via SSH using a tool such as <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" target="_blank">PuTTY</a>.</p>

                <p>Once your server has finished launching, click to view it from the dashboard. Make note of its public IP address. If your server is not pinned to the dashboard, you can find it either under the Virtual Machines sub-menu or by clicking on the dotnet-ubuntu resource group on the Resource Groups sub-menu.</p>

                <a href="/static/0001/03-server-ip.png" target="_blank"><img src="/static/0001/03-server-ip.png" alt="Screen shot of server IP" class="Screenshot" /></a>

                <p>Run Putty and enter the public IP address of your server in the host name field. Connect using SSH on port 22.</p>

                <a href="/static/0001/04-putty.png" target="_blank"><img src="/static/0001/04-putty.png" alt="Screen shot of PuTTY" class="Screenshot" /></a>

                <p>You will get a security warning that server’s host key is not cached in the registry. Click Yes to indicate that you trust this server and that you want to add the key to PuTTY’s cache.</p>

                <a href="/static/0001/05-certificate-warning.png" target="_blank"><img src="/static/0001/05-certificate-warning.png" alt="Screen shot of certificate warning" class="Screenshot" /></a>
                                
                <p>When prompted, enter the user name and password you chose while creating the server.</p>

                <h3>Install a Linux Desktop</h3>

                <p>To make it easier to work with your server, install a Linux desktop and connect to it with Remote Desktop Connection. There is a great blog post by Mark J Brown called <a href="https://markjbrown.com/linux-desktops-in-azure/" target="_blank">Running Linux Desktops in Azure</a> that walks you through the details of how to install a Linux desktop and open the RDP port. Mark’s blog post covers all of the steps we have covered here so far. The key steps I would like to preserve here as well are:</p>

                <ol>
                    <li>Update apt-get to make sure it has the latest references to available software packages.</li>
                    <p class="Code">sudo apt-get update</p>

                    <li>Install a Linux desktop. Mark recommends using <a href="http://http/www.xfce.org/" target="_blank">XFCE</a> which I also feel works well.</li>
                    <p class="Code">sudo apt-get install xfce4</p>                    

                    <li>Install XRDP.</li>
                    <p class="Code">sudo apt-get install xrdp</p>

                    <li>Open the RDP port, 3389 in the firewall settings for your VM in the Azure portal. Mark covers how to do this in his blog post. Basically, you need to locate the network security group your server is using and add an Inbound Security Role allowing RDP over TCP on port 3389.</li>
                    <p></p>

                    <li>Try connecting to your server. Run Remote Desktop Connection on a Windows PC and connect using the public IP address of the server. Login with the user name and password you chose while creating the server. You should see a desktop that looks like this.</li>
                    <p></p>
                </ol>

                <a href="/static/0001/06-xfce.png" target="_blank"><img src="/static/0001/06-xfce.png" alt="Screen shot of XFCE" class="Screenshot" /></a>

                <h3>Install a Web Browser</h3>

                <p>Install a web browser so that you can easily test your ASP.NET Core application from the server. Click the Applications button in the top left corner of the desktop and choose Terminal Emulator to open a command prompt. Run this command:</p>

                <p class="Code">sudo apt-get install firefox</p>

                <p>You can also run any of the command line commands in your PuTTY session instead of opening a command prompt in XFCE.</p>

                <p>After Firefox is installed, click the Applications button and choose Firefox Web Browser from the Internet sub-menu.</p>

                <p>Other browsers are available too of course such as <a href="https://www.google.ca/chrome/browser/desktop/index.html" target="_blank">Google Chrome</a>.</p>

                <h3>Install .NET Core</h3>

                <p>Download .NET Core for Linux from the <a href="https://www.microsoft.com/net/core" target="_blank">.NET Core</a> site. Choose the Ubuntu, Linux Mint version. Follow the instructions on the .NET Core site to add the apt-get feed and install the SDK. There is quite a bit to type at the command prompt to add the apt-get feed. Here are the steps for Ubuntu 16.04:</p>

                <ol>
                    <li>Add the dotnet apt-get feed</li>
                    <p class="Code">sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'</p>
                    <p class="Code">sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893</p>
                    <p class="Code">sudo apt-get update</p>

                    <li>Install .NET Core SDK</li>
                    <p class="Code">sudo apt-get install dotnet-dev-1.0.0-preview2-003131</p>                                        
                </ol>

                <h3>Hello World .NET Core on Linux</h3>

                <p>Follow the instructions on the .NET Core site to create a Hello World .NET Core application. Create a directory for your application and change to that directory then run this command to create a .NET Core project that outputs Hello World to the console:</p>

                <p class="Code">dotnet new</p>

                <p>This creates two files, Program.cs and project.json. The project.json file defines settings such as the version of .NET Core to use and lists the dependent packages. Run this command to download the required packages from NuGet:</p>

                <p class="Code">dotnet restore</p>

                <p>Then run this command to run the application:</p>

                <p class="Code">dotnet run</p>

                <p>This complies the code files in the current directory and looks for a class with a public static Main method to execute.</p>

                <p>You should see Hello World! printed to the console.</p>

                <h3>Hello World ASP.NET Core</h3>

                <p>Follow the instructions in the <a href="https://www.asp.net/get-started" target="_blank">tutorial</a> on the <a href="https://www.asp.net/" target="_blank">ASP.NET</a> site to download the code for a sample ASP.NET application to work from.</p>

                <p>Run this command to unzip the sample code you downloaded while completing the tutorial:</p>

                <p class="Code">unzip GetStarted-master.zip –d destination_folder</p>

                <p>If unzip is not yet installed, add it using this command:</p>

                <p class="Code">sudo apt-get install unzip</p>

                <p>Change to the directory you extracted the source code to and run this command to download the packages listed in <span class="CodeInline">project.json</span>:</p>

                <p class="Code">dotnet restore</p>

                <p>After restoring the packages, run the application with this command:</p>

                <p class="Code">dotnet run</p>

                <p>This will run the <a href="https://docs.asp.net/en/latest/fundamentals/servers.html#kestrel" target="_blank">Kestrel</a> web server and listen for HTTP requests on port 5000.</p>

                <a href="http://localhost:5000" target="_blank">http://localhost:5000</a>

                <p>You should see a message that reads Hello World! in your browser. Congratulations! You just ran your first ASP.NET Core application on Linux!</p>

                <h3>Install a Text Editor</h3>

                <p>You can write code under Linux too. To do this you will want to download a decent text editor. <a href="https://code.visualstudio.com/" target="_blank">Visual Studio Code</a> is a great choice. However, unfortunately, it <a href="https://github.com/Microsoft/vscode/issues/3451" target="_blank">does not work over XRDP</a>.</p>

                <p>Another great choice is <a href="https://www.sublimetext.com/" target="_blank">Sublime Text</a> editor. Follow these steps to install Sublime Text 2:</p>

                <p>Add the Sublime Text apt-get feed:</p>

                <p class="Code">sudo add-apt-repository ppa:webupd8team/sublime-text-2</p>

                <p>Update your apt-get repository now that you added Sublime Text:</p>

                <p class="Code">sudo apt-get update</p>

                <p>Install Sublime Text</p>

                <p class="Code">sudo apt-get install sublime-text</p>

                <p>To run Sublime Text, click Applications then choose Sublime Text from the Accessories sub-menu.</p>

                <h3>Wrap Up</h3>

                <p>This concludes my walkthrough of how to develop and run ASP.NET Core on Linux in Azure. Leave a comment or send me a message if you have any questions or suggestions.</p>]]></description>
    </item>
    <item>
      <title>My first Piano Video – The Music of the Night</title>
      <link>https://www.highwaynorth.com/blogs/bryan/my-first-piano-video---the-music-of-the-night</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/my-first-piano-video---the-music-of-the-night</guid>
      <pubDate>Mon, 10 Oct 2016 04:35:56 GMT</pubDate>
      <description><![CDATA[<p>Here is the first piano video I recorded and uploaded to YouTube. This is me playing The Music of The Night from The Phantom of The Opera. I have been playing this song for almost 30 years now. I still get a lot of joy from playing it and will always love the melody and the crescendo at the end.</p>

	<iframe width="560" height="315" src="https://www.youtube.com/embed/Efg_8DEakso" frameborder="0" allowfullscreen></iframe>]]></description>
    </item>
    <item>
      <title>Welcome to Mistakes and All</title>
      <link>https://www.highwaynorth.com/blogs/bryan/welcome-to-mistakes-and-all</link>
      <guid>https://www.highwaynorth.com/blogs/bryan/welcome-to-mistakes-and-all</guid>
      <pubDate>Mon, 10 Oct 2016 04:35:31 GMT</pubDate>
      <description><![CDATA[<p>Welcome to my new blog, <span style="font-weight:bold;">Mistakes and All</span>! Here I will share my adventures in software development. Throughout my life I have been on an unending journey of learning. When it comes to software, there is always something new to learn and no matter how much experience I have, I still make plenty of mistakes along the way. Hence, the title of the blog. I intend to share my experiences, “mistakes and all.” I don’t always get it right the first time and hopefully by sharing my mistakes it will save you from making the same ones.</p>

	<p>Outside of my work as a software developer I am also an amateur pianist. I plan to use this blog to share videos of songs I perform on the piano. When it comes to playing piano, I’m definitely a bit of a hacker and I make mistakes all the time. However, I still want to push myself to share these videos. I’m not going to wait for the perfect take. If there are mistakes, so be it. I’m recording them for me, my family and my friends and hopefully you’ll enjoy them too even if they contain a few flubbed notes here and there.</p>

	<p>I welcome your feedback. Please use the comment feature to share your thoughts.</p>

	<p>Follow me on Twitter: <a href="http://www.twitter.com/BryanBedard" target="_blank">@BryanBedard</a></p>

	<p>Email: <a href="mailto:info@highwaynorth.com">info@highwaynorth.com</a></p>]]></description>
    </item>
  </channel>
</rss>
