v1.06 patch notes

Features

  • Added game timer. 
  • You will now receive desktop notifications when a match is found and you are not in the game tab. This allows people to safely go to another tab while searching for a match using the "find game" button. 
  • You can now destroy your own units with the delete key. 
  • C key will cancel ground unit movement. Current selected air units return to last destination if you hit C. 
  • You must now be logged in to use the find game button (auto-matchmaking). 
  • Added "view global rankings" and tournament info to the lobby info box. 

Fixes

  • Added back in the ability to change idle worker hotkey. 
  • Fixed units not spawning in Survival mode. 
  • Fixed sometimes not seeing what your ally could see.
  • Removed FFA as a game type (just use standard game type and set teams appropriately for FFA). 
  • You should no longer see "host cannot start the game ..." messages in the lobby. 
  • Reduced volume of the droid laser sounds.

Gameplay

  • Gladiator now requires tech lab to be built; cost changed from 100 ore / 50 carbon to 150 carbon. 
  • Gladiator primary weapon can no longer hit air units.
  • Gladiator Pulsar Cannon tech damage reduced from 250 to 175 and can no longer hit air units. 
  • Harpy ore cost reduced from 150 to 100; health increased from 1,930 to 2,500. 
  • Bomber ore cost reduced from 100 to 75; health increased from 830 to 1,200.
  • Gnat costs 50 carbon instead of 25 ore; build time reduced from 15 to 8 seconds. 
  • Roller ore cost reduced from 150 to 100. 
  • Command center cost reduced from 250 to 100 carbon. 
  • Javelin fire rate decreased from 4 to 3 sec.
  • Tech Lab build time increased from 40 to 60 seconds.
Tags: 

Starcraft 1 Pathfinding: A technical analysis

Imagine a Starcraft map as one big grid which is divided into hundreds of little squares. Most units, the smaller units (like marines and zerglings) occupy a single square while the larger units (such as dragoons and ultralisks) occupy multiple squares.

Starcraft 1 pathfinding grid

When a unit is issued a move command, the parameters of that command (the current location and destination in the grid) are run through the pathfinding algorithm which spits out an array of path coordinates. The unit then moves along the path, but it only goes 1 square at a time, one set of coordinates at a time. Each time it travels to a new square, it asks “is the next square along the path occupied?” If the answer is “no,” the unit keeps moving along the path. If the answer is “yes,” the unit waits a fraction of a second, and checks again. If the path is still unoccupied after a certain time increment, a new path is generated from the algorithm and the unit walks around the square that was unwalkable.

Another circumstance in which the path is re-calculated is when a new move command is issued while the unit is en route. This behavior has given rise to spam-clicking. The path is literally re-calculated each time you click, so technically a unit is finding the most efficient path at the point of time closest to the click. Because the grid (remember the starcraft map is just 1 big grid) which marks the walkable and unwalkable areas is constantly changing, so also are the results of the pathfinding algorithm. And the older those results are, the less efficient they will be. Hence: spam-clicking!

If you clicked your marine to go across the map, and a building gets placed in the middle of the map while the marine was en route, the original path calculated can no longer be considered accurate (because it was generated before the building was placed). A helper function detects when a path is no longer “accurate”. It asks “is the square in front of me occupied?” If no, it will continue along the path. If yes, it will wait, check again, and generate a new path if it is still occupied. All of this happens very quickly between animation frames.

At one point in the development of Strike Tactics, I utilized this same technique for pathfinding.

Notice how the units stop when they detect an object in front and politely wait for the object to move before continuing along the path? This is Starcraft 1 pathfinding. Units always remain visually separated at the expense of pathfinding efficiency. In other words, units take longer to get from point A to point B but they do so without walking on top of each other.

Here's a look at what the "helper function" which asks "is this node in front of me occupied?" looks like in Javascript. Each time a new node is walked to, the next node in the path is checked. If it's occupied, an interval begins (unit.waitInt) which waits for the node to become un-occupied. If it takes too long, the path is thrown out and a new one is calculated (in my game, setting the unit.goToTarget will cause the unit to find a new path). 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
function checkGoToNextNode(unit) {

    if (unit.path[0] != undefined) {

        var grid = staticGrid;
        var findPathMatrixNodeSize = matrixNodeSize;

        if (unitDefinitions[unit.unitName].size == 'lg') {
            var findPathMatrixNodeSize = matrixNodeSizeLG;
            var grid = getGridCloneOfStaticLGFromStatic(unit);
        }

        // lg units should reserve all 9 rather than just center 1
        var gridX = fnRound((unit.path[0] - (findPathMatrixNodeSize / 2)) / findPathMatrixNodeSize);
        var gridY = fnRound((unit.path[1] - (findPathMatrixNodeSize / 2)) / findPathMatrixNodeSize);

        // check if next path is walkable, if not, wait till it is
        if (grid.nodes[gridY][gridX].walkable || smoothPaths) {

            if (unit.nextWalkToNode != undefined) {
                var goToNodeCopy = [unit.nextWalkToNode.x, unit.nextWalkToNode.y];


                game.time.events.add(500, (function(goToNodeCopy) {
                    return function() {
                        setNode(goToNodeCopy);
                    };
                })(goToNodeCopy), this);

            }

            if (unitDefinitions[unit.unitName].size == 'lg') {
                // large units must reserve a node in the staticGrid to prevent other large units from going there
                var gridXInStatic = fnRound((unit.path[0] - (matrixNodeSize / 2)) / matrixNodeSize);
                var gridYInStatic = fnRound((unit.path[1] - (matrixNodeSize / 2)) / matrixNodeSize);

                staticGrid.nodes[gridYInStatic][gridXInStatic].walkable = false;

                unit.nextWalkToNode = staticGrid.nodes[gridYInStatic][gridXInStatic];

            } else {
                grid.nodes[gridY][gridX].walkable = false;

                unit.nextWalkToNode = grid.nodes[gridY][gridX];

            }
            moveToNext(unit);
        } else {


            if (unit.unitName != 'drone') {
                stopAnimationsNetwork(unit, false, 0);
            }
            unit.waitInt = setInterval(function() {
                unit.timesWaited++;

                var distanceFromEnd = Phaser.Math.distance(unit.x, unit.y, unit.goingX, unit.goingY);

                if ((distanceFromEnd <= 100) && (unit.timesWaited > 3)) {
                    clearInterval(unit.waitInt);
                    actionsAfterCompletingPath(unit);
                    return;
                } else if ((distanceFromEnd >= 100) && (unit.timesWaited > 20)) {
                    // find a new path
                    actionsAfterCompletingPath(unit);
                    clearInterval(unit.waitInt);
                    unit.goToTarget = {
                        'x': unit.goingX,
                        'y': unit.goingY

                    }
                    return;
                }

                if (grid.nodes[gridY][gridX].walkable) {
                    if (unit.nextWalkToNode != undefined) {
                        unit.nextWalkToNode.walkable = true;
                    }
                    unit.timesWaited = 0;
                    grid.nodes[gridY][gridX].walkable = false;
                    unit.nextWalkToNode = grid.nodes[gridY][gridX];

                    clearInterval(unit.waitInt);
                    walkMech(unit);

                    moveToNext(unit);

                }

            }, 50);

        }

    }

}

If you think that's complicated and messy, consider that this is just one small component of the system. That to me, was a big red flag. The more complicated a system is, the more likely it will fail. Simpler systems work better because there are fewer things in them that can fail. 

I discovered this technique on my own through experimentation and had no idea Starcraft used it until I saw Day9’s video. Although Day9 doesn't appear to understand what is going on under the hood, he explains what the pathfinding system feels like to the player and what the gameplay implications are - it just made me think hard about what the units were doing when looking for a path. I came to realize the units were constantly stopping and going because they were asking "is this square occupied?" just like in my own implementation.

At some point in pre-alpha, I ditched this entire approach and revamped pathfinding to something much simpler. Instead of units constantly checking if the node they are about to walk to is occupied, the units simply maintain relative distance from each other when they walk. The only nodes which are marked as unwalkable are the start and end destinations. Even though the same grid structure is used, units don't move like they are playing hopskotch because a second algorithm (independent of the pathfinding algorithm) smooths the paths. This is the system currently used in Strike Tactics.

Early feedback from alpha testers was the impetus to overhaul pathfinding in this way, and as soon as I made the change, “pathinding” ceased to even be a topic of discussion among alpha testers. That to me proved the new pathfinding was good, because it did its job unnoticed. My reasoning is that If players notice your pathfinding, that’s when you know it’s bad. The contrapositive is that you don’t get praise for good pathfinding, because no one notices it. SC2 pathfinding is probably the best pathfinding system ever devised for a dynamic world. Units of all sizes miraculously find their way to destinations, without overlapping each other and without stopping. Despite this, the only discussions surrounding SC2 pathfinding are in relation to brood war pathfinding, and how it just doesn’t have the same charm to it. Brood War pathfinding is considered "fun" for some players, because it requires more micro-management to move your units effectively. 

Anyway, I don’t recall the last time someone complained about pathfinding in Strike Tactics, so I like to think it’s a solved problem at this point. The units simply go directly to their destination in the fastest way mathematically possible. It might not look as good as the original system where units always remain visually separated, but it certainly feels better. And if there’s anything I’ve learned, feel is much more important than looks. Players prefer more efficient unit movement and pathfinding over all else. They don't care how it looks. Truthfully, I don’t think anyone (other than me) has noticed that units occasionally walk on top of each other in Strike Tactics. Yet that was one of my greatest fears and where i spend 99% of my energy writing pathfinding. Funny, the things developers feel are important don’t always align with the things players feel are important.

In Starcraft 1, you will also notice that units move in grid-fashion. In simpler terms, units move like they are playing one giant game of hop scotch. A unit can move to the square in front, the square to the left, the square behind, etc. But what units can’t do is move forward 1 degrees, back 2 degrees, left 3 degrees, etc. Movement is strictly limited to cardinal direction: N, S, E, W and NE, NW, SE, SW, etc. This is why the movement feels so “blocky.” Units need to move like this because they need to be able to ask "is this node i am walking to occupied?" If they moved outside the grid (like in sc2), they would not be able to ask that question. 

If the path the algorithm spits out is most accurate when it is newly created, why didn’t Blizzard automatically recalculate the path instead of only recalculating it on click or when a unit bangs into another?

Because these calculations are expensive, even by modern computing standards. Depending on the size of the grid, and the algorithm used calculating hundreds of paths for hundreds of units 10 times a second adds up. Thus algorithms like A* are only run when needed, on click or when a unit gets stuck.

The difficulties in implementing pathfinding is never a simple as “determining the quickest route to get from point a to point b,” although gamers - and people who have never worked on pathfinding - probably assume it as such. A lot of devs seem to think good pathfinding is all about choosing good pathfinding algorithms, but that's an oversimplification. It's sort of like assuming Chevy can design the best car by simply realizing they need to use wheels to move the car. The wheel part is already a solved problem. The algorithm part is already a solved problem. The difficulty is in implementation. 

Since in an RTS game, the world is constantly changing, the problem is never as simple as determining the fastest route to get from point a to point b. In a changing world, the problem is determining the fastest route from point a to point b  while not bumping into objects c, d, e, f, g, etc, which are  by the way, constantly moving at various speeds an in various directions. The difference between solving dynamic world pathfinding and static world pathfinding is the difference between shooting a moving target and one which stands still.

Many modern RTS games avoid the problem altogether by simply doing overlap/collision checks on every frame and separating units which get too close (think of it like bumper cars). Starcraft 2 uses this technique to some extent, but the technique is CPU intensive. With SC1 pathfinding, the only real CPU-heavy stuff (computing the path with the algorithm) happens when you issue a click command or when a unit gets stuck and needs to generate a new path. But with collision detection, the CPU intensive stuff is happening every millisecond. It absolutely would not be possible with 1999 tech.

Ranking changes, monthly tournaments with cash prizes

  • Beginning September 1st, the ELO system will reset monthly, with each player going back to 1,200 ELO at the start of each new month. The match history in your profile will stay the same, but I may put a space to indicate when a monthly ELO reset has taken place. 
  • At the end of each month, an official tournament will be held for the top 6 ELO players or for players further down the list if one or more of the top 6 are unable to play.  
  • The champion of the monthly tournament will receive a cash prize, the amount of which will be announced each month. The amount for September will be $50 USD.
  • The winner will also have his or her's username immortalized on the ladder page with a special section for "Champions," along with the ELO they achieved that month and a link to the tournament VOD. 

All of this stuff is subject to change in the future, but that is the plan right now.

v1.05 patch notes

Strike Tactics is now 100% free-to-play, with all content (including ranking and the map editor) being accessible to registered users. To become a registered user, create a free account here

Anyone who purchased or pre-ordered Strike Tactics can receive a 100% full refund. Just ask using the email contact link at the bottom of the website. 

Features

  • You can now zoom out with the mouse wheel while in observer mode. To easily test this functionality, enter into a game with yourself set to an observer and 2 AI on opposing teams. 
  • Selected units now have circles underneath to indicate their selection status.
  • Lobby now shows 10 most recent messages upon joining.
  • Added text to join Discord from the lobby. 

Fixes

  • Made improvements to ground unit movement net code.
  • Fixed AI not shooting at some players in multiplayer games.
  • Fixed heal unit sometimes not healing when the health was near max in deathmatch.
  • Droid laser sounds are more audible. 
  • Increased default game and music volume.
  • Fixed units sometimes not dying on all clients. 

Gameplay

  • Most upgrades are significantly cheaper. 

Hotfixes/Updates 8/18/17

  • Fixed "registration successful" message not disappearing after creating an account.
  • Gladiator build time reduced from 35 to 20 seconds; ore cost reduced from 150 to 100 and cannon damage increased from 100 to 150. 
  • Fixed ELO not graphing correctly.
  • Made tech upgrades even cheaper. 

Updates 8/19/17

  • Victory condition changed from destroy all enemy units and buildings to destroy all enemy buildings.
  • Adjusted sizes of currently selected unit circles - battleship has no circle.
Tags: 

v.104 patch notes

Features

  • Revamped transport/networking layer by switching from socket.io to ws as a websocket library. Network performance should signifigantly improve with disconnects being extremely rare and reconnect logic working properly. 
  • In the change server dialog, the ping of the server you are currently connected to will up date in real time as opposed to only on page load. 
  • Now showing logged in (paid) users at the top of the lobby list with links to the account profile and orange underlined text. Guests names are displayed in white with no link (as they do not have account pages), below logged in users.

Fixes

  • Fixed victory/defeat conditions in 2v2 games.
  • Ping updates more frequently.
  • Fixed lines sometimes not connecting in the end game stat charts.
  • Fixed map name sometimes showing as N/A in lobby games list.
  • You can now highlight text in lobby and pre-game root chat. 
  • Total players count in lobby should be more accurate. 
  • Fixed "you did not beat your best wave of undefined" in survival. 

Updates 8/9/17

  • Survival mode is now enabled on most ground maps. Instead of stuff spawning at spawn locations on 4-player maps, the spawn locations are always in the center of the map.
  • If a guest chooses a map with survival mode enabled, the default game type will be survival and an AI will automatically be added to the room (as an AI is required to play survival single player).
  • [Experimental] Find game button is hidden for guests.
  • Made survival mode easier. You start out with more units and face less in the first waves.
  • Fixed buildings/units sometimes spawning on top of each other in survival, especially in multiplayer.
  • Removed some of the trees in the center of the "Enclave" map.
  • Removed some of the volcanoes in the center of the "Burning Divide" map.

Updates 8/10/17

  • Camera now focuses on first units in survival. 

Hotfixes 8/11/17

  • Fixed lobby layout breaking and buttons appearing twice in some circumstances.

Hotfixes 8/13/17

  • Game rooms should properly get deleted after the host has left.
  • Guests now see the find game button again and no longer have game type set to survival on default (that was experimental).
  • Fixed production menu sometimes not appearing when you click a production building. 
  • Total players should never be lower than players here (that happened because total players only updated on page load).
  • You should no longer get "you were kicked from the game room" message when changing servers.  
  • Multiplayer game should now properly reconnect if your router or wifi device resets. 
Tags: 

v1.03 patch notes

Features

  • Added option to disable unit info window. 
  • Max players per server increased from 70 to 100.
  • Added error handling for when a map does not load properly. 
  • Translated more text to Russian and Spanish. 
  • Added a "Basic Controls" video which appears in a dialog box for users that are not logged in. 

Fixes

  • Fixed games list automatically going back to the first page when some of the data in the games list table changed. 
  • "Restart" button changed to "Return to lobby" in menu options for users not logged in.
  • Fixed room not opening when clicked in the games list.
  • Fixed hovering units flying off the map during lag spikes.
  • Fixed crash caused by moving units to a position not on the map. 
Tags: 

v.1.02 patch notes

Features

  • Lobby and pre-game room UI is now fully responsive and takes up screen dimensions based on the device. This also makes the game much more iframe-friendly. 

Fixes

  • Improved the networking layer to make it more reliable. Disconnects should be less frequent. 
  • Fixed game rooms not getting deleted long after the host left. 
  • Fixed victory/defeat sometimes not being accurate at end game screen.
  • You no longer get a reconnect screen when your oppenent goes to another tab. 
  • Background now blurs when you return to the lobby from a game. In-game UI elements, such as the mini map and unit info box should disappear. 
  • Lobby music plays upon returning to the lobby form in-game. 
  • Find game button now appears at end game screen after playing a non-multiplayer game. 

Hotfixes 8/2/17

  • Changed the port websockets used to 80. This should result in more stable connections as firewalls are less of a problem.
  • Fixed the lobby ui appearing off-screen after game ends.
  • Reduced the maximum height on players list so the list won't overflow on small screens.

Hotfixes 8/3/17

  • Disabled screen-scrolling by default for the game embedded in iframes.
  • Disabled Google translate Chrome feature as it ruins game performance. 
  • Added Russian translations for important UI text.
  • Removed a bunch of the slow loading maps from auto-matchmaking.
  • You should no longer get a reconnecting screen before the game has loaded. 
  • Re-enabled alternative transport methods, including XHR polling, as a fallback to websockets.
  • Reduced blur on lobby background game and removed slow motion so the background game plays at normal game speed. 
  • Updated socket.io to the latest for both the server and client. 
  • Made some adjustements to the networking layer. Disconnects should be less frequent. 
Tags: 

v1.0 patch notes

Features

  • Added two new servers: Europe 2 (Paris, France) and US West 1 (LA). 
  • You can now manually aim and fire the guns of your units by holding down the right button while the units are selected. The units will shoot in the direction you move the cursor. If the cursor is outside the range of the unit, the unit will continue to fire to their maximum range. At soon as you release RMB, units go back to auto targeting and firing. 
  • Update music files with final edits and live drums. 

Fixes

  • May have fixed the bug where players would get a reconnect screen every 20 seconds or so. Because this bug is so difficult to reproduce, I cannot know for sure if the fix works. 
  • Players in room ping will update every 5 seconds instead of every 20. 
  • If the server restarts and you are in the lobby, you will not properly rejoin the lobby. 
  • Fixed units sometimes not dying on all clients. 
  • Disabled the ability to click current selected unit icons as that causes selection box issues. 
  • Mantas no longer turn to a location you send them to if an enemy is neaby. 
  • Underscores should no longer appear in place of spaces in "Now playing" music text. 
  • The UI no longer changes opacity when you mouse drag. 
  • Updated the system hotkey text table in menu settings.
  • You are now restriced to playing game modes specified by the map uploader. 

Hotfixes 7/31/17

  • Fixed a bug which caused battleships to not die properly.
  • Fixed Weaver not taking up population.
  • Control-A now properly deselects all units first and will not select scouts.
  • Battleship bullet speed increased from 2K pixels/sec to 3K. Changed the bullet size (cosmetic) and removed bullet shadows on its triple cannons.
  • Fixed end game screen bug which caused your next game to crash.
  • Enemy aircraft now turn smoother in multiplayer games.
  • The auto-matchmaking finding players text now properly updates when you change servers.
  • Fixed ground units not going to maximum range when you click to attack something outside of range. I also made some adjustments to ground unit targeting like canceling the current path when you click to attack. In short, click to attack should work a lot better now for ground units.
  • If you are not the host of the room, you still see the same interface and if the host leaves and you become the host, you will be able to use all the hosts' buttons (e.g. start game, add ai).
  • Fixed the battleship scaling strangely in multiplayer games.
  • Manta no longer looks paranoid, constantly turning around when idle.
  • Set the default server to Europe 1.
  • Changed ping color levels. Anything less than 125 is green, between 125 and 250 is yellow. Greater than 250 is red.
  • Disabled standard game tutorial showing in death match.
Tags: 

v.999 (beta) patch notes

Features

  • Observer can now see icons of all the unit types and counts for every player in the game. The type and count icons appear in the same place (top right) as the unit type icons you see when not in observer mode. 
  • Observer can now select units and view info about that unit. 
  • Added a small box below the player list in the main lobby. The box has some social media links and the account name you are currently logged in, along with a link to your account profile and match history. 
  • Unit info now shows the DPS with bonus damage taken into account. 
  • Implemented auto-matchmaking. Enter auto-matchmaking by hitting the "find game" button in the lobby. Free players will be able to auto-matchmake for the deathmatch 1v1v1v1 game mode and paid players will be able to auto-matchmake for both deathmatch and standard 1v1 game modes. In the future, I may add more game modes to auto-matchmaking for paid players, including 2v2 standard and 2v2 deathmatch. 
  • Implemented a new unit: the weaver. The weaver is an advanced anti-air unit which can be built from the tank factory. It is meant to be a relatively cheap (25 ore, 50 carbon) upgrade to the merk if air units are giving you too much trouble in the mid game. It is slightly faster than all mechs as well (220 pixels/second vs 200) and shoots homing missiles (170 DPS to ground and 300 to air) which never miss, regardless of how fast the targeted unit is moving. Weavers are also relatively tanky compared to mechs with 1200 hp (the merk has only 900). 

Strike Tactics Weaver unit

Strike Tactics weaver unit attacking

 

Fixes

  • Workers will no longer lose their inventory when they cancel harvesting to do something else. 
  • You should no longer get a "server full" message when the servers are not all full. 
  • Redid all player colors other than player 1. Previously, the unit textures were created by doing a hue shift of 72 degrees on the player 1 texture. I now use an increment of 150 degrees, giving the units a more distinctive look. Player 2 (once purple) is now red, player 3 (once dark red) is bright green and player 4 (once yellow) is light purple. 
  • Fixed a game-breaking bug which was caused by game start functions being run more than once. 
  • Fixed 2 server-side errors which sometimes broke the game you were in. 
  • Unlock building UI should properly disappear at the end of a deathmatch game. They should also appear below other in-game interfaces (like the resources tab).
  • When a host leaves a room and there is still 1 or more people left, those people are no longer kicked. Instead, someone else in the room becomes the host. 
  • Shrunk the unit info window and made it appear only when appropriate. The unit info box also no longer receives input events (to allow move clicking to the bottom right of the window). 
  • Fixed the observer not being able to see worker lasers and effects. 
  • You can no longer add AI in Deathmatch as the AI I wrote is meant for standard mode. 
  • Ore is no longer drawn to the map in deathmatch, regardless of whether it exists in the map file. 
  • Removed the idle button in observer mode or non-standard game modes. 
  • Fixed some padding issues in the pre-game room. 
  • Fixed and re-enabled the tutorial. 
  • Adjusted some of the unit sound volumes. 
  • De-saturated the tech lab and tank factory so they fit the color balance on the other buildings. 
  • Fixed lobby online players list showing the same person twice. 
  • Fixed ping colors not showing properly in the "players in room" dialog box. 
  • If a player surrenders and goes to another tab while more than 1 person is still left playing the game, those people will not get a reconnecting screen for the tabbed-out player. 

Hotfixes 7/28/17

  • Fixed full screen button not working.
  • Weaver default hotkey now working.
  • Weaver build time increased from 5 seconds to 12 (oops).
  • ELO change now appears in proper format in match history (e.g. [old rank] +/- rank gained/lost).
Tags: 

Strike Tactics tournament #1 results

I had a lot of fun playing in the first official Strike Tactics tournament, "just for fun," last week. There was a lot of funny and surprising moments. I plan to make it a weekly or bi-weekly thing and anyone who wants to host can get in contact with me on discord. Hopefully the next time around there will be a prize pool. Many thanks to Dissonant for volunteering to cast even though he doesn't know much about the game yet (bombers attacking workers, seriously!?). Watch the full tournament with the youtube playlist below.

Pages