Seven signs of dysfunctional engineering teams

I’ve been listening to the audiobook of Heart of Darkness this week, read by Kenneth Branagh. It’s fantastic. It also reminds me of some jobs I’ve had in the past.

There’s a great passage in which Marlow requires rivets to repair a ship, but finds that none are available. This, in spite of the fact that the camp he left further upriver is drowning in them. That felt familiar. There’s also a famous passage involving a French warship that’s blindly firing its cannons into the jungles of Africa in hopes of hitting a native camp situated within. I’ve had that job as well. Hopefully I can help you avoid getting yourself into those situations.

There are several really good lists of common traits seen in well-functioning engineering organizations. Most recently, there’s Pamela Fox’s list of What to look for in a software engineering culture. More famous, but somewhat dated at this point, is Joel Spolsky’s Joel Test. I want to talk about signs of teams that you should avoid.

This list is partially inspired by Ralph Peters’ Spotting the Losers: Seven Signs of Non-Competitive States. Of course, such a list is useless if you can’t apply it at the crucial point, when you’re interviewing. I’ve tried to include questions to ask and clues to look for that reveal dysfunction that is deeply baked into an engineering culture.

Preference for process over tools. As engineering teams grow, there are many approaches to coordinating people’s work. Most of them are some combination of process and tools. Git is a tool that enables multiple people to work on the same code base efficiently (most of the time). A team may also design a process around Git — avoiding the use of remote branches, only pushing code that’s ready to deploy to the master branch, or requiring people to use local branches for all of their development. Healthy teams generally try to address their scaling problems with tools, not additional process. Processes are hard to turn into habits, hard to teach to new team members, and often evolve too slowly to keep pace with changing circumstances. Ask your interviewers what their release cycle is like. Ask them how many standing meetings they attend. Look at the company’s job listings, are they hiring a scrum master?

Excessive deference to the leader or worse, founder. Does the group rely on one person to make all of the decisions? Are people afraid to change code the founder wrote? Has the company seen a lot of turnover among the engineering leader’s direct reports? Ask your interviewers how often the company’s coding conventions change. Ask them how much code in the code base has never been rewritten. Ask them what the process is for proposing a change to the technology stack. I have a friend who worked at a growing company where nobody was allowed to introduce coding conventions or libraries that the founding VP of Engineering didn’t understand, even though he hardly wrote any code any more.

Unwillingness to confront technical debt. Do you want to walk into a situation where the team struggles to make progress because they’re coding around all of the hacks they haven’t had time to address? Worse, does the team see you as the person who’s going to clean up all of the messes they’ve been leaving behind? You need to find out whether the team cares about building a sustainable code base. Ask the team how they manage their backlog of bugs. Ask them to tell you about something they’d love to automate if they had time. Is it something that any sensible person would have automated years ago? That’s a bad sign.

Not invented this week syndrome. We talk a lot about “not invented here” syndrome and how it affects the competitiveness of companies. I also worry about companies that lurch from one new technology to the next. Teams should make deliberate decisions about their stack, with an eye on the long term. More importantly, any such decisions should be made in a collaborative fashion, with both developer productivity and operability in mind. Finding out about this is easy. Everybody loves to talk about the latest thing they’re working with.

Disinterest in sustaining a Just Culture. What’s Just Culture? This post by my colleague John Allspaw on blameless post mortems describes it pretty well. Maybe you want to work at a company where people get fired on the spot for screwing up, or yelled at when things go wrong, but I don’t. How do you find out whether a company is like that? Ask about recent outages and gauge whether the person you ask is willing to talk about them openly. Do the people you talk to seem ashamed of their mistakes?

Monoculture. Diversity counts. Gender diversity is really important, but it’s not the only kind of diversity that matters. There’s ethnic diversity, there’s age diversity, and there’s simply the matter of people acting differently, or dressing differently. How homogenous is the group you’ve met? Do they all remind you of you? That’s almost certainly a serious danger sign. You may think it sounds like fun to work with a group of people who you’d happily have as roommates, but monocultures do a great job of masking other types of dysfunction.

Lack of a service-oriented mindset. The biggest professional mistakes I ever made were the result of failing to see that my job was ultimately to serve other people. I was obsessed with building what I thought was great software, and failed to see that what I should have been doing was paying attention to what other people needed from me in order to succeed in their jobs. You can almost never fail when you look for opportunities to be of service and avail yourself of them. Be on the lookout for companies where people get ahead by looking out for themselves. Don’t take those jobs.

There are a lot of ways that a team’s culture can be screwed up, but those are my top seven.

Parallel and Concurrent Programming in Haskell

As one of the developers of the Glasgow Haskell Compiler (GHC) for almost 15 years, I have seen Haskell grow from a niche research language into a rich and thriving ecosystem. I spent a lot of that time working on GHC’s support for parallelism and concurrency. One of the first things I did to GHC in 1997 was to rewrite its runtime system, and a key decision we made at that time was to build concurrency right into the core of the system rather than making it an optional extra or an add-on library. I like to think this decision was founded upon shrewd foresight, but in reality it had as much to do with the fact that we found a way to reduce the overhead of concurrency to near zero (previously it had been on the order of 2%; we’ve always been performance-obsessed). Nevertheless, having concurrency be non-optional meant that it was always a first-class part of the implementation, and I’m sure that this decision was instrumental in bringing about GHC’s solid and lightning-fast concurrency support.

Haskell has a long tradition of being associated with parallelism. To name just a few of the projects, there was the pH variant of Haskell derived from the Id language, which was designed for parallelism, the GUM system for running parallel Haskell programs on multiple machines in a cluster, and the GRiP system: a complete computer architecture designed for running parallel functional programs. All of these happened well before the current multicore revolution, and the problem was that this was the time when Moore’s law was still giving us ever-faster computers. Parallelism was difficult to achieve, and didn’t seem worth the effort when ordinary computers were getting exponentially faster.

Around 2004, we decided to build a parallel implementation of the GHC runtime system for running on shared memory multiprocessors, something that had not been done before. This was just before the multicore revolution. Multiprocessor machines were fairly common, but multicores were still around the corner. Again, I’d like to think the decision to tackle parallelism at this point was enlightened foresight, but it had more to do with the fact that building a shared-memory parallel implementation was an interesting research problem and sounded like fun. Haskell’s purity was essential—it meant that we could avoid some of the overheads of locking in the runtime system and garbage collector, which in turn meant that we could reduce the overhead of using parallelism to a low-single-digit percentage. Nevertheless, it took more research, a rewrite of the scheduler, and a new parallel garbage collector before the implementation was really usable and able to speed up a wide range of programs. The paper I presented at the International Conference on Functional Programming (ICFP) in 2009 marked the turning point from an interesting prototype into a usable tool.

All of this research and implementation was great fun, but good-quality resources for teaching programmers how to use parallelism and concurrency in Haskell were conspicuously absent. Over the last couple of years, I was fortunate to have had the opportunity to teach two summer school courses on parallel and concurrent programming in Haskell: one at the Central European Functional Programming (CEFP) 2011 summer school in Budapest, and the other the CEA/EDF/INRIA 2012 Summer School at Cadarache in the south of France. In preparing the materials for these courses, I had an excuse to write some in-depth tutorial matter for the first time, and to start collecting good illustrative examples. After the 2012 summer school I had about 100 pages of tutorial, and thanks to prodding from one or two people (see the Acknowledgments), I decided to turn it into a book. At the time, I thought I was about 50% done, but in fact it was probably closer to 25%. There’s a lot to say! I hope you enjoy the results.

Audience

You will need a working knowledge of Haskell, which is not covered in this book. For that, a good place to start is an introductory book such as Real World Haskell (O’Reilly), Programming in Haskell (Cambridge University Press), Learn You a Haskell for Great Good! (No Starch Press), or Haskell: The Craft of Functional Programming (Addison-Wesley).

How to Read This Book

The main goal of the book is to get you programming competently with Parallel and Concurrent Haskell. However, as you probably know by now, learning about programming is not something you can do by reading a book alone. This is why the book is deliberately practical: There are lots of examples that you can run, play with, and extend. Some of the chapters have suggestions for exercises you can try out to get familiar with the topics covered in that chapter, and I strongly recommend that you either try a few of these, or code up some of your own ideas.

As we explore the topics in the book, I won’t shy away from pointing out pitfalls and parts of the system that aren’t perfect. Haskell has been evolving for over 20 years but is moving faster today than at any point in the past. So we’ll encounter inconsistencies and parts that are less polished than others. Some of the topics covered by the book are very recent developments: Chapters 4, 5, 6, and pass:[14 cover frameworks that were developed in the last few years.

The book consists of two mostly independent parts: Part I and Part II. You should feel free to start with either part, or to flip between them (i.e., read them concurrently!). There is only one dependency between the two parts: Chapter 13 will make more sense if you have read Part I first, and in particular before reading “The ParIO monad”, you should have read Chapter 4.

While the two parts are mostly independent from each other, the chapters should be read sequentially within each part. This isn’t a reference book; it contains running examples and themes that are developed across multiple chapters.

The Evolution of Direct3D

* UPDATE: Be sure to read the comment thread at the end of this blog, the discussion got interesting.

It’s been many years since I worked on Direct3D and over the years the technology has evolved Dramatically. Modern GPU hardware has changed tremendously over the years Achieving processing power and capabilities way beyond anything I dreamed of having access to in my lifetime. The evolution of the modern GPU is the result of many fascinating market forces but the one I know best and find most interesting was the influence that Direct3D had on the new generation GPU’s that support Welcome to Thunderbird processing cores, billions of transistors more than the host CPU and are many times faster at most applications. I’ve told a lot of funny stories about how political and Direct3D was created but I would like to document some of the history of how the Direct3D architecture came about and the architecture that had profound influence on modern consumer GPU’s.

Published here with this article is the original documentation for Direct3D DirectX 2 when it was first Introduced in 1995. Contained in this document is an architecture vision for 3D hardware acceleration that was largely responsible for shaping the modern GPU into the incredibly powerful, increasingly ubiquitous consumer general purpose supercomputers we see today.

D3DOVER
The reason I got into computer graphics was NOT an interest in gaming, it was an interest in computational simulation of physics. I Studied 3D at Siggraph conferences in the late 1980’s Because I wanted to understand how to approach simulating quantum mechanics, chemistry and biological systems computationally. Simulating light interactions with materials was all the rage at Siggraph back then so I learned 3D. Understanding light 3D mathematics and physics made me a graphics and color expert roomates got me a career in the publishing industry early on creating PostScript RIP’s (Raster Image Processors). I worked with a team of engineers in Cambridge England creating software solutions for printing color graphics screened before the invention of continuous tone printing. That expertise got me recruited by Microsoft in the early 1990’s to re-design the Windows 95 and Windows NT print architecture to be more competitive with Apple’s superior capabilities at that time. My career came full circle back to 3D when, an initiative I started with a few friends to re-design the Windows graphics and media architecture (DirectX) to support real-time gaming and video applications, resulted in gaming becoming hugely strategic to Microsoft. Sony Introduced in a consumer 3D game console (the Playstation 1) and being responsible for DirectX it was incumbent on us to find a 3D solution for Windows as well.

For me, the challenge in formulating a strategy for consumer 3D gaming for Microsoft was an economic one. What approach to consumer 3D Microsoft should take to create a vibrant competitive market for consumer 3D hardware that was both affordable to consumers AND future proof? The complexity of realistically simulating 3D graphics in real time was so far beyond our capabilities in that era that there was NO hope of choosing a solution that was anything short of an ugly hack that would produce “good enough” for 3D games while being very far removed from the ideal solutions mathematically we had implemented a little hope of seeing in the real-world during our careers.

Up until that point only commercial solutions for 3D hardware were for CAD (Computer Aided Design) applications. These solutions worked fine for people who could afford hundred thousand dollars work stations. Although the OpenGL API was the only “standard” for 3D API’s that the market had, it had not been designed with video game applications in mind. For example, texture mapping, an essential technique for producing realistic graphics was not a priority for CAD models roomates needed to be functional, not look cool. Rich dynamic lighting was also important to games but not as important to CAD applications. High precision was far more important to CAD applications than gaming. Most importantly OpenGL was not designed for highly interactive real-time graphics that used off-screen video page buffering to avoid tearing artifacts during rendering. It was not that the OpenGL API could not be adapted to handle these features for gaming, simply that it’s actual market implementation on expensive workstations did not suggest any elegant path to a $ 200 consumer gaming cards.

TRPS15In the early 1990’s computer RAM was very expensive, as such, early 3D consumer hardware designs optimized for minimal RAM requirements. The Sony Playstation 1 optimized for this problem by using a 3D hardware solution that did not rely on a memory intensive the data structure called a Z-buffer, instead they used a polygon level sorting algorithm that produced ugly intersections between moving joints. The “Painters Algorithm” approach to 3D was very fast and required little RAM. It was an ugly but pragmatic approach for gaming that would have been utterly unacceptable for CAD applications.

In formulating the architecture for Direct3D we were faced with difficult choices Similar enumerable. We wanted the Windows graphics leading vendors of the time; ATI, Cirrus, Trident, S3, Matrox and many others to be Able to Compete with one another for rapid innovation in 3D hardware market without creating utter chaos. The technical solution that Microsoft’s OpenGL team espoused via Michael Abrash was a driver called 3DDDI models (3D Device Driver Interface). 3DDDI was a very simple model of a flat driver that just supported the hardware acceleration of 3D rasterization. The complex mathematics associated with transforming and lighting a 3D scene were left to the CPU. 3DDDI used “capability bits” to specify additional hardware rendering features (like filtering) that consumer graphics card makers could optionally implement. The problem with 3DDDI was that it invited problems for game developers out of the gate. There were so many cap-bits every game that would either have to support an innumerable number of feature combinations unspecified hardware to take advantage of every possible way that hardware vendors might choose to design their chips producing an untestable number of possible hardware configurations and a consumer huge amount of redundant art assets that the games would not have to lug around to look good on any given device OR games would revert to using a simple set of common 3D features supported by everyone and there would be NO competitive advantage for companies to support new hardware 3D capabilities that did not have instant market penetration. The OpenGL crowd at Microsoft did not see this as a big problem in their world Because everyone just bought a $ 100,000 workstation that supported everything they needed.

The realization that we could not get what we needed from the OpenGL team was one of the primary could be better we Decided to create a NEW 3D API just for gaming. It had nothing to do with the API, but with the driver architecture underneath Because we needed to create a competitive market that did not result in chaos. In this respect the Direct3D API was not an alternative to the OpenGL API, it was a driver API designed for the sole economic purpose of creating a competitive market for 3D consumer hardware. In other words, the Direct3D API was not shaped by “technical” requirements so much as economic ones. In this respect the Direct3D API was revolutionary in several interesting ways that had nothing to do with the API itself but rather the driver architecture it would rely on.

When we Decided to acquire a 3D team to build with Direct3D I was chartered surveying the market for candidate companies with the right expertise to help us build the API we needed. As I have previously recounted we looked at Epic Games (creators of the Unreal engine), Criterion (later acquired by EA), Argonaut and finally Rendermorphics. We chose Rendermorphics (based in London) Because of the large number of 3D quality engineers and the company employed Because The founder, Servan Kiondijian, had a very clear vision of how consumer 3D drivers should be designed for maximum future compatibility and innovation. The first implementation of the Direct3D API was rudimentary but quickly intervening evolved towards something with much greater future potential.

D3DOVER lhanded
Whoops!

My principal memory from that period was a meeting in roomates I, as the resident expert on the DirectX 3D team, was asked to choose a handedness for the Direct3D API. I chose a left handed coordinate system, in part out of personal preference. I remember it now Only because it was an arbitrary choice that by the caused no end of grief for years afterwards as all other graphics authoring tools Adopted the right handed coordinate system to the OpenGL standard. At the time nobody knew or believed that a CAD tool like Autodesk would evolve up to become the standard tool for authoring game graphics. Microsoft had acquired Softimage with the intention of displacing the Autodesk and Maya anyway. Whoops …

The early Direct3D HAL (Hardware Abstraction Layer) was designed in an interesting way. It was structured vertically into three stages.

DX 2 HAL

The highest was the most abstract layer transformation layer, the middle layer was dedicated to lighting calculations and the bottom layer was for rasterization of the finally transformed and lit polygons into depth sorted pixels. The idea behind this vertical structure driver was to provide a relatively rigid feature path for hardware vendors to innovate along. They could differentiate their products from one another by designing hardware that accelerated increasingly higher layers of the 3D pipeline resulting in greater performance and realism without incompatibilities or a sprawling matrix of configurations for games to test against art or requiring redundant assets. Since the Direct3D API created by Rendermorphics Provided a “pretty fast” implementation software for any functionality not accelerated by the hardware, game developers could focus on the Direct3D API without worrying about myriad permutations of incompatible hardware 3D capabilities. At least that was the theory. Unfortunately like the 3DDDI driver specification, Direct3D still included capability bits designed to enable hardware features that were not part of the vertical acceleration path. Although I actively objected to the tendency of Direct3D capability to accumulate bits, the team felt extraordinary competitive pressure from Microsoft’s own OpenGL group and from the hardware vendors to support them.

The hardware companies, seeking a competitive advantage for their own products, would threaten to support and promote OpenGL to game developers Because The OpenGL driver bits capability supported models that enabled them to create features for their hardware that nobody else supported. It was common (and still is) for the hardware OEM’s to pay game developers to adopt features of their hardware unique to their products but incompatible with the installed base of gaming hardware, forcing consumers to constantly upgrade their graphics card to play the latest PC games . Game developers alternately hated capability bits Because of their complexity and incompatibilities but wanted to take the marketing dollars from the hardware OEM’s to support “non-standard” 3D features.

Overall I viewed this dynamic as destructive to a healthy PC gaming economy and advocated resisting the trend OpenGL Regardless of what the people wanted or OEM’s. I believed that creating a consistent stable consumer market for PC games was more important than appeasing the hardware OEM’s. As such as I was a strong advocate of the relatively rigid vertical Direct3D pipeline and a proponent of introducing only API features that we expected up to become universal over time. I freely confess that this view implied significant constraints on innovation in other areas and a placed a high burden of market prescience on the Direct3D team.

The result, in my estimation, was pretty good. The Direct3D fixed function pipeline, as it was known, produced a very rich and growing PC gaming market with many healthy competitors through to DirectX 7.0 and the early 2000’s. The PC gaming market boomed and grew to be the largest gaming market on Earth. It also resulted in a very interesting change in the GPU hardware architecture over time.

Had the Direct3D HAL has been a flat driver with just the model for rasterization capability bits as the OpenGL team at Microsoft had advocated, 3D hardware makers would have competed by accelerating just the bottom layer of the 3D rendering pipeline and adding differentiating features to their hardware capability via bits that were incompatible with their competitors. The result of introducing the vertical layered architecture THING that was 3D hardware vendors were all encouraged to add features to their GPU’s more consistent with the general purpose CPU architectures, namely very fast floating point operations, in a consistent way. Thus consumer GPU’s evolved over the years to increasingly resemble general purpose CPU’s … with one major difference. Because the 3D fixed function pipeline was rigid, the Direct3D architecture afforded very little opportunity for code branching frequent as CPU’s are designed to optimize for. Achieved their GPU’s amazing performance and parallelism in part by being free to assume that little or no branching code would ever occur inside a Direct3D graphics pipeline. Thus instead of evolving one giant monolithic core CPU that has massive numbers of transistors dedicated to efficient branch prediction has as an Intel CPU, GPU has a Direct3D Hundreds to Welcome to Thunderbird simple CPU cores like that have no branch prediction. They can chew through a calculation at incredible speed confident in the knowledge that they will not be interrupted by code branching or random memory accesses to slow them down.

DirectX 7.0 up through the underlying parallelism of the GPU was hidden from the game. As far as the game was concerned some hardware was just faster than other hardware but the game should not have to worry about how or why. The early DirectX fixed function pipeline architecture had done a brilliant job of enabling dozens of Disparate competing hardware vendors to all take different approaches to Achieving superior cost and performance in consumer 3D without making a total mess of the PC gaming market for the game developers and consumers . It was not pretty and was not entirely executed with flawless precision but it worked well enough to create an extremely vibrant PC gaming market through to the early 2000’s.

Before I move on to discussing more modern evolution Direct3D, I would like to highlight a few other important ideas that influenced architecture in early modern Direct3D GPU’s. Recalling that in the early to mid 1990’s was relatively expensive RAM there was a lot of emphasis on consumer 3D techniques that conserved on RAM usage. The Talisman architecture roomates I have told many (well-deserved) derogatory stories about was highly influenced by this observation.

Talsiman
Search this blog for tags “Talisman” and “OpenGL” for many stories about the internal political battles over these technologies within Microsoft

Talisman relied on a grab bag of graphics “tricks” to minimize GPU RAM usage that were not very generalized. The Direct3D team, Rendermorphics Heavily influenced by the founders had made a difficult choice in philosophical approach to creating a mass market for consumer 3D graphics. We had Decided to go with a more general purpose Simpler approach to 3D that relied on a very memory intensive a data structure called a Z-buffer to Achieve great looking results. Rendermorphics had managed to Achieve very good 3D performance in pure software with a software Z-buffer in the engine Rendermorphics roomates had given us the confidence to take the bet to go with a more general purpose 3D Simpler API and driver models and trust that the hardware RAM market and prices would eventually catch up. Note however that at the time we were designing Direct3D that we did not know about the Microsoft Research Groups “secret” Talisman project, nor did they expect that a small group of evangelists would cook up a new 3D API standard for gaming and launch it before their own wacky initiative could be deployed. In short one of the big bets that Direct3D made was that the simplicity and elegance of Z-buffers to game development were worth the risk that consumer 3D hardware would struggle to affordably support them early on.

Despite the big bet on Z-buffer support we were intimately aware of two major limitations of the consumer PC architecture that needed to be addressed. The first was that the PC bus was generally very slow and second it was much slower to copy the data from a graphics card than it was to copy the data to a graphics card. What that generally meant was that our API design had to growing niche to send the data in the largest most compact packages possible up to the GPU for processing and absolutely minimize any need to copy the data back from the GPU for further processing on the CPU. This generally meant that the Direct3D API was optimized to package the data up and send it on a one-way trip. This was of course an unfortunate constraint Because there were many brilliant 3D effects that could be best accomplished by mixing the CPU’s branch prediction efficient and robust floating point support with the GPU’s parallel rendering incredible performance.

One of the fascinating Consequences of that constraint was that it forced the GPU’s up to become even more general purpose to compensate for the inability to share the data with the CPU efficiently. This was possibly the opposite of what Intel intended to happen with its limited bus performance, Because Intel was threatened by the idea that the auxiliary would offload more processing cards from their work thereby reducing the CPU’s Intel CPU’s value and central role to PC computing. It was reasonably believed at that time that Intel Deliberately dragged their feet on improving PC performance to deterministic bus a market for alternatives to their CPU’s for consumer media processing applications. Earlier Blogs from my recall that the main REASON for creating DirectX was to Prevent Intel from trying to virtualize all the Windows Media support on the CPU. Intel had Adopted a PC bus architecture that enabled extremely fast access to system RAM shared by auxiliary devices, it is less Likely GPU’s that would have evolved the relatively rich set of branching and floating point operations they support today.

To Overcome the fairly stringent performance limitations of the PC bus a great deal of thought was put into techniques for compressing and streamlining DirectX assets being sent to the GPU performance to minimize bus bandwidth limitations and the need for round trips from the GPU back to the CPU . The early need for the rigid 3D pipeline had Consequences interesting later on when we Began to explore assets streaming 3D over the Internet via modems.

We Recognized early on that support for compressed texture maps would Dramatically improve bus performance and reduce the amount of onboard RAM consumer GPU’s needed, the problem was that no standards Existed for 3D texture formats at the time and knowing how fast image compression technologies were evolving at the time I was loathe to impose a Microsoft specified one “prematurely” on the industry. To Overcome this problem we came up with the idea of ​​”blind compression formats”. The idea, roomates I believe was captured in one of the many DirectX patents that we filed, had the idea that a GPU could encode and decode image textures in an unspecified format but that the DirectX API’s would allow the application to read and write from them as though they were always raw bitmaps. The Direct3D driver would encode and decode the image data is as Necessary under the hood without the application needing to know about how it was actually being encoded on the hardware.

By 1998 3D chip makers had begun to devise good quality 3D texture formats by DirectX 6.0 such that we were Able to license one of them (from S3) for inclusion with Direct3D.

http://www.microsoft.com/en-us/news/press/1998/mar98/s3pr.aspx

DirectX 6.0 was actually the first version of DirectX that was included in a consumer OS release (Windows 98). Until that time, DirectX was actually just a family of libraries that were shipped by the Windows games that used them. DirectX was not actually a Windows API until five generations after its first release.

DirectX 7.0 was the last generation of DirectX that relied on the fixed function pipeline we had laid out in DirectX 2.0 with the first introduction of the Direct3D API. This was a very interesting transition period for Direct3D for several could be better;

1) The original founders DirectX team had all moved on,

2) Microsoft’s internal Talisman and could be better for supporting OpenGL had all passed

3) Microsoft had brought the game industry veterans like Seamus Blackley, Kevin Bacchus, Stuart Moulder and others into the company in senior roles.

4) Become a Gaming had a strategic focus for the company

DirectX 8.0 marked a fascinating transition for Direct3D Because with the death of Talisman and the loss of strategic interest in OpenGL 3D support many of the people from these groups came to work on Direct3D. Talisman, OpenGL and game industry veterans all came together to work on Direct3D 8.0. The result was very interesting. Looking back I freely concede that I would not have made the same set of choices that this group made for DirectX 8.0 in chi but it seems to me that everything worked out for the best anyway.

Direct3D 8.0 was influenced in several interesting ways by the market forces of the late 20th century. Microsoft largely unified against OpenGL and found itself competing with the Kronos Group standards committee to advance faster than OpenGL Direct3D. With the death of SGI, control of the OpenGL standard fell into the hands of the 3D hardware OEM’s who of course wanted to use the standard to enable them to create differentiating hardware features from their competitors and to force Microsoft to support 3D features they wanted to promote. The result was the Direct3D and OpenGL Became much more complex and they tended to converge during this period. There was a stagnation in 3D feature adoption by game developers from DirectX 8.0 to DirectX 11.0 through as a result of these changes. Became creating game engines so complex that the market also converged around a few leading search providers Including Epic’s Unreal Engine and the Quake engine from id software.

Had I been working on Direct3D at the time I would have stridently resisted letting the 3D chip lead Microsoft OEM’s around by the nose chasing OpenGL features instead of focusing on enabling game developers and a consistent quality consumer experience. I would have opposed introducing shader support in favor of trying to keep the Direct3D driver layer as vertically integrated as possible to Ensure conformity among hardware vendors feature. I also would have strongly opposed abandoning DirectDraw support as was done in Direct3D 8.0. The 3D guys got out of control and Decided that nobody should need pure 2D API’s once developers Adopted 3D, failing to recognize that simple 2D API’s enabled a tremendous range of features and ease of programming that the majority of developers who were not 3D geniuses could Easily understand and use. Forcing the market to learn 3D Dramatically constrained the set of people with the expertise to adopt it. Microsoft later discovered the error in this decision and re-Introduced DirectDraw as the Direct2D API. Basically letting the Direct3D 8.0 3D design geniuses made it brilliant, powerful and useless to average developers.

At the time that the DirectX 8.0 was being made I was starting my first company WildTangent Inc.. and Ceased to be closely INVOLVED with what was going on with DirectX features, however years later I was Able to get back to my roots and 3D took the time to learn Direct3D programming in DirectX 11.1. Looking back it’s interesting to see how the major architectural changes that were made in DirectX 8 resulted in the massively convoluted and nearly incomprehensible Direct3D API we see today. Remember the 3 stage pipeline DirectX 2 that separated Transformation, lighting and rendering pipeline into three basic stages? Here is a diagram of the modern DirectX 11.1 3D pipeline.

DX 11 Pipeline

Yes, it grew to 9 stages and 13 stages when arguably some of the optional sub-stages, like the compute shader, are included. Speaking as somebody with an extremely lengthy background in very low-level 3D graphics programming and I’m Embarrassed to confess that I struggled mightily to learn programming Direct3D 11.1. Become The API had very nearly incomprehensible and unlearnable. I have no idea how somebody without my extensive background in 3D and graphics could ever begin to learn how to program a modern 3D pipeline. As amazingly powerful and featureful as this pipeline is, it is also damn near unusable by any but a handful of the most antiquated brightest minds in 3D graphics. In the course of catching up on my Direct3D I found myself simultaneously in awe of the astounding power of modern GPU’s and where they were going and in shocked disgust at the absolute mess the 3D pipeline had Become. It was as though the Direct3D API had Become a dumping ground for 3D features that every OEM DEMANDED had over the years.

Had I not enjoyed the benefit of the decade long break from Direct3D involvement Undoubtedly I would have a long history of bitter blogs written about what a mess my predecessors had made of a great and elegant vision for the consumer 3D graphics. Weirdly, however, leaping forward in time to the present day, I am forced to admit that I’m not sure it was such a bad thing after all. The result of stagnation gaming on the PC as a result of the mess Microsoft and the OEMs made of the Direct3D API was a successful XBOX. Having a massively fragmented 3D API is not such a problem if there is only one hardware configuration to support game developers have, as is the case with a game console. Direct3D shader 8.0 support with early primitive was the basis for the first Xbox’s graphics API. For the first selected Microsoft’s XBOX NVIDIA NVIDIA chip giving a huge advantage in the 3D PC chip market. DirectX 9.0, with more advanced shader support, was the basis for the XBOX 360, Microsoft roomates selected for ATI to provide the 3D chip, AMD this time handing a huge advantage in the PC graphics market. In a sense the OEM’s had screwed Themselves. By successfully Influencing Microsoft and the OpenGL standards groups to adopt highly convoluted graphics pipelines to support all of their feature sets, they had forced Themselves to generalize their GPU architectures and the 3D chip market consolidated around a 3D chip architecture … whatever Microsoft selected for its consoles.

The net result was that the retail PC game market largely died. It was simply too costly, too insecure and too unstable a platform for publishing high production value games on any longer, with the partial exception of MMOG’s. Microsoft and the OEM’s had conspired together to kill the proverbial golden goose. No biggie for Microsoft as they were happy to gain complete control of the former PC gaming business by virtue of controlling the XBOX.

From the standpoint of the early DirectX vision, I would have said that this outcome was a foolish, shortsighted disaster. Microsoft had maintained a little discipline and strategic focus on the Direct3D API they could have ensured that there were NO other consoles in existence in a single generation by using the XBOX XBOX to Strengthen the PC gaming market rather than inadvertently destroying it. While Microsoft congratulates itself for the first successful U.S. launch of the console, I would count all the gaming dollars collected by Sony, Nintendo and mobile gaming platforms over the years that might have remained on Microsoft platforms controlled Microsoft had maintained a cohesive strategy across media platforms. I say all of this from a past tense perspective Because, today, I’m not so sure that I’m really all that unhappy with the result.

The new generation of consoles from Sony AND Microsoft have Reverted to a PC architecture! The next generation GPU’s are massively parallel, general-purpose processors with intimate access to the shared memory with the CPU. In fact, the GPU architecture Became so generalized that a new pipeline stage was added in DirectX 11 DirectCompute called that simply allowed the CPU to bypass the entire convoluted Direct3D graphics pipeline in favor of programming the GPU directly. With the introduction of DirectCompute the promise of simple 3D programming returned in an unexpected form. Modern GPU’s have Become so powerful and flexible that the possibility of writing cross 3D GPU engines directly for the GPU without making any use of the traditional 3D pipeline is an increasingly practical and appealing programming option. From my perspective here in the present day, I would anticipate that within a few short generations the need for the traditional Direct3D and OpenGL APIs will vanish in favor of new game engines with much richer and more diverse feature sets that are written entirely in device independent shader languages ​​like Nvidia’s CUDA and Microsoft’s AMP API’s.

Today, as a 3D physics engine and developer I have never been so excited about GPU programming Because of the sheer power and relative ease of programming directly to the modern GPU without needing to master the enormously convoluted 3D pipelines associated with Direct3D and OpenGL API’s. If I were responsible for Direct3D strategy today I would be advocating dumping the investment in traditional 3D pipeline in favor of Rapidly opening direct access to a rich GPU programming environment. I personally never imagined that my early work on Direct3D, would, within a couple decades, Contribute to the evolution of a new kind of ubiquitous processor that enabled the kind of incredibly realistic and general modeling of light and physics that I had learned in the 1980 ‘s but never believed I would see computers powerful enough to models in real-time during my active career.

Attend Meeting C++ 2013

Boost Dependency Analyzer

I have something special to announce today. A tool I’ve build over the last 2 weeks, which allows to analyze the dependencies in boost. With boost 1.53 this spring, I had the idea to build this, but not the time, as I was busy writing a series over the Papers for Bristol. Back then I realized, how easy it could be to build such a tool, as the dependencies could be read & listed by boosts bcp tool. I already had a prototype for the graphpart from 2010. But lets have a look at the tool:

The tool is very easy to handle, it is based on the out of bcp, which is a tool coming with boost. Actually bcp can help you with ripping libraries out of boost, so that you don’t have to add all of boost to your repository when you would like to use smartpointers. But bcp also has a listing mode, where it only shows the dependencies thats whats my tool build up upon. Lets have a short look at the results, the dependencies of boost 1.54:

A few words on how to read this graph. The libraries in the middle of the “starshape” are the ones with the most dependencies, each line between the nodes is a dependency. A dependency can be one or multiple files. The graphlayout is not weighted.

How to

A short introduction on what you need to get this tool to run. First boost, as this tool is build to analyze boost. I’ve tested with some versions (1.49 – 1.54) of boost. You also need a version of bcp, which is quite easy to build (b2 tools/bcp). Then you simply need to start the tool, if BOOST_ROOT is set, the tool will try to read it, other wise you will be asked to choose the location of boost when clicking on Read dependencies. Next thing is selecting the location of bcp. That is the setup, and the tool will now run for some time. On my machine its 90 seconds to 2 minutes the analysis takes, it might be lot longer on yours, depending on how much cores you got. The tool will spawn for each boost library (~112) a bcp process, and analyze this output in a thread pool. After this is done, the data is loaded into the tool, and then saved to a SQLITE database, which will be used if you start the tool a second time and select this version of boost. Loading from the database is far faster.

A screenshot to illustrate this:

tl_files/blog/bda/bda.png

To the left are all the boost libraries, the number of dependencies is shown in the braces. To the right is a Tabwidget showing all the dependencies, the graph is layouted with boost graph. When you click on show all you’ll get the full view of all dependencies in boost. The layouting is done in the background, so this will take some time to calculate, and is animated when its done. The results of the layouting are good, but not perfect, so that you might have to move some nodes. Exporting supports images, which are transparent PNGs, not all services/tools are happy with that (f.e. facebook, twitter nor G+ could handle the perfectly fine images), this can be fixed by postprocessing the images and adding a white background.

Inner workings

I’ve already written a little about the tools inside, its build with Qt5.1 and boost. Where boost is mostly used for the graph layouting. As I choose to work with Qt5, it has a few more dependencies, for windows this sums up to a 18 mb download, which you’ll find at the end. The tool depends on 3 libraries from my company Code Node: ProcessingSink, a small wrapper around QProcess, that allows to just start a bunch of processes, and lets you connect to the finished and error slot. This was necessary, as I could only spawn 62 parallel processes under windows, so this library does take care of spawning the parallel processes now. Which are currently 50 at a time. GraphLayout is the code that wraps the innerworkings of boost::graph, its a bit dirty, but lets me easily process the graphlayouting. The 3rd library is NodeGraph, which is the Graph UI, based on Qts GraphicsView Framework.
I plan to release the tool and its libraries under GPL later on github, for now I don’t have the time to polish everything.

Problems

One of the earliest questions I had when thinking about building such a tool, was where to get a list of the boost libraries? This sounds easy. But I need to have this readable by machine, not human, so HTML is a great format, but I refused to write a parser for this list yet. I talked to some people about this at C++Now, and most agreed, that the second option would be best: maintainers.txt. Thats what the tool reads currently to find the boost libraries. Unfortunately at least lexical_cast is missing in this list. So, the tool isn’t perfect yet, while lexical_cast is already patched, I’m not sure if anything else is missing. A candidate could be signals, as its not maintained anymore. Currently the tool analyzes for 1.54 112 libraries.

boost dependencies

Working for 2 weeks on this tool has given me some inside knowledge about the dependencies in boost. First, the way it is shown in the tool, is the view of bcp. Some dependencies will not affect the user, as they are internal. f.e. a lot of libraries have a dependency to boost::test, simply because they provide their tests with it. The bcp tool really gets you ALL the dependencies. Also most (or was it all?) libraries depend on boost::config. I plan to add filtering later, so that the user has the ability to filter some of the libraries in the GraphView.

The tool

Here is how to get the tool for now: there is a download for the binaries for windows and linux. I’ll try to get you a deb package as soon as I have time, but for now its only the binaries for linux, you’ll have to make sure to have Qt5.1 etc. on linux too, as I do not provide them. For Windows, its 2 archives you’ll need to download: the programm itself, and needed dlls for Qt5.1 if you don’t have the SDK installed ( in this case you also could copy them from the bin directory)

Note on linux: this is a one day old beta version. Will update this later.

It’s a Mad, Mad, Mad, Mad World: Scoping in CoffeeScript and JavaScript

CoffeeScript, as many people know, is a transpile-to-JavaScript language.1 For the most part, it does not introduce major changes in semantics. For example, this:

-> 'Hello, world'

Transpiles directly to:

function () { return 'Hello, world'; }

This is convenient syntactic sugar, and by removing what some folks call the “syntactic vinegar” of extraneous symbols, it encourages the use of constructs that would otherwise make the code noisy and obscure the important meaning. The vast majority of features introduced by CoffeeScript are of this nature: They introduce local changes that transpile directly to JavaScript.2

CoffeeScript also introduces features that don’t exist in JavaScript, such as destructuring assignment and comprehensions. In each case, the features compile directly to JavaScript without introducing changes elsewhere in the program. And since they don’t look like existing JavaScript features, little confusion is created.

equals doesn’t equal equals

One CoffeeScript feature does introduce confusion, and the more you know JavaScript the more confusion it introduces. This is the behaviour of the assignment operator, the lowly (and prevalent!) equals sign:

foo = 'bar'

Although it looks almost identical to assignment in JavaScript:

foo = 'bar';

It has different semantics. That’s confusing. Oh wait, it’s worse than that: Sometimes it has different semantics. Sometimes it doesn’t.

So what’s the deal with that?

Well, let’s review the wonderful world of JavaScript. We’ll pretend we’re in a browser application, and we write:

foo = 'bar';

What does this mean? Well, it depends: If this is in the top level of a file, and not inside of a function, then foo is a global variable. In JavaScript, global means global across all files, so you are now writing code that is coupled with every other file in your application or any vendored code you are loading.

But what if it’s inside a function?

function fiddleSticks (bar) {
  foo = bar;
  // ...
}

For another example, many people enclose file code in an Immediately Invoked Function Expression (“IIFE”) like this:

;(function () {
  foo = 'bar'
  // more code...
})();

What do foo = 'bar'; or foo = bar; mean in these cases? Well, it depends as we say. It depends on whether foo is declared somewhere else in the same scope. For example:

function fiddleSticks (bar) {
  var foo;
  foo = bar;
  // ...
}

Or:

function fiddleSticks (bar) {
  foo = bar;
  // ...
  var foo = batzIndaBelfrie;
  // ...
} 

Or even:

function fiddleSticks (bar) {
  foo = bar;
  // ...
  function foo () {
    // ...
  }
  // ...
}

Because of something called hoisting,3 these all mean the same this: foo is local to function fiddleSticks, and therefore it is NOT global and ISN’T magically coupled to every other file loaded whether written by yourself or someone else.

nested scope

JavaScript permits scope nesting. If you write this:

function foo () {
  var bar = 1;
  var bar = 2;
  return bar;
}

Then bar will be 2. Declaring bar twice makes no difference, since both declarations are in the same scope. However, if you nest functions, you can nest scopes:

function foo () {
  var bar = 1;
  function foofoo () {
    var bar = 2;
  }
  return bar;
}

Now function foo will return 1 because the second declaration of bar is inside a nested function, and therefore inside a nested scope, and therefore it’s a completely different variable that happens to share the same name. This is called shadowing: The variablebar inside foofoo shadows the variable bar inside foo.

javascript failure modes

Now over time people have discovered that global variables are generally a very bad idea, and accidental global variables doubly so. Here’s an example of why:

function row (numberOfCells) {
  var str = '';
  for (i = 0; i < numberOfCells; ++i) {
    str = str + '<td></td>';
  }
  return '<tr>' + str + '</tr>';
}

function table (numberOfRows, numberOfColumns) {
  var str = '';
  for (i = 0; i < numberOfRows; ++i) {
    str = str + row(numberOfColumns);
  }
  return '<table>' + str + '</table>';
}

Let’s try it:

table(3, 3)
  //=> "<table><tr><td></td><td></td><td></td></tr></table>"

We only get one row, because the variable i in the function row is global, and so is the variable i in the function table, so they’re the exact same global variable. Therefore, after counting out three columns, i is 3 and the for loop in table finishes. Oops!

And this is especially bad because the two functions could be anywhere in the code. If you accidentally use a global variable and call a function elsewhere that accidentally uses the same global variable, pfft, you have a bug. This is nasty because there’s this weird action-at-a-distance where a bug in one file reaches out and breaks some code in another file.

Now, this isn’t a bug in JavaScript the language, just a feature that permits the creation of very nasty bugs. So I call it a failure mode, not a language bug.

coffeescript to the rescue

CoffeeScript addresses this failure mode in two ways. First, all variables are local to functions. If you wish to do something in the global environment, you must do it explicitly. So in JavaScript:

UserModel = Backbone.Model.extend({ ... });
var user = new UserModel(...);

While in CoffeeScript:

window.UserModel = window.Backbone.Model.extend({ ... })
user = new window.UserModel(...)

Likewise, CoffeeScript bakes the IIFE enclosing every file in by default. So instead of:

;(function () {
  // ...
})();

You can just write your code.4

The net result is that it is almost impossible to replicate the JavaScript failure mode of creating or clobbering a global variable by accident. That is a benefit.

what would coffeescript do?

This sounds great, but CoffeeScript can be surprising to JavaScript programmers. Let’s revisit our table function. First, we’ll fix it:

function row (numberOfCells) {
  var i,
      str = '';
  for (i = 0; i < numberOfCells; ++i) {
    str = str + '<td></td>';
  }
  return '<tr>' + str + '</tr>';
}

function table (numberOfRows, numberOfColumns) {
  var i,
      str = '';
  for (i = 0; i < numberOfRows; ++i) {
    str = str + row(numberOfColumns);
  }
  return '<table>' + str + '</table>';
}

table(3, 3)
  //=> "<table><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></table>"

Good! Now suppose we notice that no function calls row other than table. Although there is a slightly more “performant” way to do this, we decide that the clearest and simplest way to indicate this relationship is to nest row inside table Pascal-style:

function table (numberOfRows, numberOfColumns) {
  var i,
      str = '';
  for (i = 0; i < numberOfRows; ++i) {
    str = str + row(numberOfColumns);
  }
  return '<table>' + str + '</table>';

  function row (numberOfCells) {
    var i,
        str = '';
    for (i = 0; i < numberOfCells; ++i) {
      str = str + '<td></td>';
    }
    return '<tr>' + str + '</tr>';
  }
}

It still works like a charm, because the i in row shadows the i in table, so there’s no conflict. Okay. Now how does it work in CoffeeScript?

Here’s one possible translation to CoffeeScript:

table = (numberOfRows, numberOfColumns) ->
  row = (numberOfCells) ->
    str = ""
    i = 0
    while i < numberOfCells
      str = str + "<td></td>"
      ++i
    "<tr>" + str + "</tr>"
  str = ""
  i = 0
  while i < numberOfRows
    str = str + row(numberOfColumns)
    ++i
  return "<table>" + str + "</table>"

table(3,3)
  #=> "<table><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></table>"

It works just fine. Here’s another:

table = (numberOfRows, numberOfColumns) ->
  str = ""
  i = 0
  row = (numberOfCells) ->
    str = ""
    i = 0
    while i < numberOfCells
      str = str + "<td></td>"
      ++i
    "<tr>" + str + "</tr>"
  str = ""
  i = 0
  while i < numberOfRows
    str = str + row(numberOfColumns)
    ++i
  return "<table>" + str + "</table>"

table(3,3)
  #=> "<table><tr><td></td><td></td><td></td></tr></table>"

Broken! And a third:

str = ""
i = 0
table = (numberOfRows, numberOfColumns) ->
  row = (numberOfCells) ->
    str = ""
    i = 0
    while i < numberOfCells
      str = str + "<td></td>"
      ++i
    "<tr>" + str + "</tr>"
  str = ""
  i = 0
  while i < numberOfRows
    str = str + row(numberOfColumns)
    ++i
  return "<table>" + str + "</table>"

table(3,3)
  #=> "<table><tr><td></td><td></td><td></td></tr></table>"

Also broken! Although the three examples look similar, the first gives us what we expect but the second and third do not. What gives?

Well, CoffeeScript doesn’t allow us to “declare” that variables are local with var. They’re always local. But local to what? In CoffeeScript, they’re local to the function that either declares the variable as a parameter or that contains the first assignment to the variable.5 So in our first example, reading from the top, the first use of str and i is inside the row function, so CoffeeScript makes them local to row.

A little later on, the code makes an assignment to i and str within the table function. This scope happens to enclose row’s scope, but it is different so it can’t share the strand i variables. CoffeeScript thus makes the i and str in table variables local totable. As a result, the i and str in row end up shadowing the i and str in table.

The second example is different. The first i encountered by CoffeeScript is in table, so CoffeeScript makes it local to table as we’d expect. The second i is local to row. But since row in enclosed by table, it’s possible to make that i refer to the i already defined, and thus CoffeeScript does not shadow the variable. The i inside row is the same variable as the i inside table.

In the third example, i (and str) are declared outside of both table and row, and thus again they all end up being the same variable with no shadowing.

Now, CoffeeScript could scan an entire function before deciding what variables belong where, but it doesn’t. That simplifies things, because you don’t have to worry about a variable being declared later that affects your code. Everything you need to understand is in the same file and above your code.

In many cases, it also allows you to manipulate whether a variable is shadowed or not by carefully controlling the order of assignments. That’s good, right?

all those against the bill, say “nay nay!”

Detractors of this behaviour say this is not good. When JavaScript is written using var, the meaning of a function is not changed by what is written elsewhere in the file before the code in question. Although you can use this feature to control shadowing by deliberately ordering your code to get the desired result, a simple refactoring can break what you’ve already written.

For example, if you write:

table = (numberOfRows, numberOfColumns) ->
  row = (numberOfCells) ->
    str = ""
    i = 0
    while i < numberOfCells
      str = str + "<td></td>"
      ++i
    "<tr>" + str + "</tr>"
  str = ""
  i = 0
  while i < numberOfRows
    str = str + row(numberOfColumns)
    ++i
  return "<table>" + str + "</table>"

table(3,3)
  #=> "<table><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td></tr></table>"

All will be well, until you are debugging late one night, and you add:

console.log('Hello!') for i in [1..5]

table = (numberOfRows, numberOfColumns) ->
  row = (numberOfCells) ->
    str = ""
    i = 0
    while i < numberOfCells
      str = str + "<td></td>"
      ++i
    "<tr>" + str + "</tr>"
  str = ""
  i = 0
  while i < numberOfRows
    str = str + row(numberOfColumns)
    ++i
  return "<table>" + str + "</table>"

table(3,3)
  #=> "table><tr><td></td><td></td><td></td></tr></table>"

This breaks your code because the i you used at the top “captures” the other variables so they are now all the same thing. To someone used to JavaScript, this is a Very Bad Thing™. When you write this in JavaScript:

function row (numberOfCells) {
  var i,
      str = '';
  for (i = 0; i < numberOfCells; ++i) {
    str = str + '<td></td>';
  }
  return '<tr>' + str + '</tr>';
}

It will always mean the same thing no matter where it is in a file, and no matter what comes before it or after it. There is no spooky “action-at-a-distance” where code somewhere else changes what this code means. Whereas in CoffeeScript, you don’t know whether the iin row is local to row or not without scanning the code that comes before it in the same or enclosing scopes.

coffeescript’s failure mode

In this case, CoffeeScript has a failure mode: The meaning of a function seems to be changed by altering its position within a file or (in what amounts to the same thing) by altering code that appears before it in a file in the same or enclosing scopes. In contrast, JavaScript’s var declaration never exhibits this failure mode. JavaScript has a different action-at-a-distance failure mode, where neglecting var causes action at a much further distance: The meaning of code can be affected by code written in an entirely different file.

Mind you, the result of calling our row function is not affected by declaring an i in an enclosing scope. Our function always did what it was expected to do and always will. Although you and I know why the change breaks the table function is that row now uses an enclosed variable, imagine that we were writing unit tests. All of our tests for row would continue to pass, it’s the tests for table that break. So in an evidence-based programming sense, when we maintain the habit of always initializing variables we expect to use locally, changing code outside of those functions only changes the evidence that the enclosing code produces.

So one way to look at this is that row is fine, but moving i around changes the meaning of the code where you move i. And why wouldn’t you expect making changes to tableto change its meaning?

so which way to the asylum?

If you ask around, you can find people who dislike JavaScript’s behaviour, and others who dislike CoffeeScript’s behaviour. Accidentally getting global variables when you neglectvar is brutal, and action-at-a-distance affecting the meaning of a function (even if it is always within the same file) flies against everything we have learned about the importance of writing small chunks of code that completely encapsulate their behaviour.

Of course, programmers tend to internalize the languages they learn to use. If you write a lot of JavaScript, you habitually use var and may have tools that slap your wrist when you don’t. You’re bewildered by all this talk of action-at-a-distance. It will seems to you to be one of those rookie mistake problems that quickly goes away and is not a practical concern.

Likewise, if you write twenty thousand lines of CoffeeScript, you may never be bitten by its first-use-is-a-declaration behaviour. You may be in the habit of using variable names likeiRow and iColumn out of habit. You may find that your files never get so large and your functions so deeply nested that a “capture” problem takes longer than three seconds to diagnose and fix.

It’s a bit of a cop-out, but I suggest that this issue resembles the debate over strong, manifest typing vs. dynamic typing. In theory, one is vastly preferable to the other. But in practice, large stable codebases are written with both kinds of languages, and programmers seem to adjust to overcome the failure modes of their tools unconsciously while harvesting the benefits that each language provides.


  1. Yes, “transpile” is a real word, or at least, a real piece of jargon. It’s a contraction of “transcompiler,” which is a compiler that translates one language to another language at a similar level of abstraction. There’s room for debate over what constitutes a “similar level of abstraction.” https://en.wikipedia.org/wiki/Source-to-source_compiler

  2. There are other possibilities: You could write a Tail-Call Optimized language that transpiles to JavaScript, however its changes wouldn’t always be local: Some function calls would be rewritten substantially to use trampolining. Or adding continuations to a language might cause everything to be rewritten in continuation-passing style.

  3. Scanning all of the code first is called “hoisting,” in part because some declarations nested in blocks are “hoisted” up to the level of the function, and all declarations are “hoisted” to the top of the function. This is a source of confusion for some programmers, but it isn’t germane to this essay.

  4. If you don’t want the file enclosed in an IIFE, you can compile your CoffeeScript with the--bare command-line switch.

Creating a 3D Game With Three.js and WebGL

Prerequisites

  • A browser with WebGL – this game has been tested on Chrome and Firefox. IE still doesn’t support WebGL, unless you’re using Windows 8.1 with IE11.
  • Three.js library available for download from the Three.js website
  • The Keyboard.js helper library I used for this project, created by Arthur Schreiber at No Karma. Download it from my GitHub repository
  • A basic understanding of what Three.js does. Read this super simple, super quick tutorial by Paul Lewis. It’s basically a short-hand version of this article.

Setup

Get a base index.html running

Step one when making a web-based game is to create the host index.html file. In our case, it only needs to be a very simple set of elements, so we can bundle the CSS styling too.

Import Keyboard.js and Three.js

Three.js is a library contained in just one JavaScript file, so we can grab the minified version from the website.

For Keyboard input, we will need to referencethe aforementioned JavaScript file in our index.html as well.

Create setup() and draw() functions

The setup() function will be the start point for the game code. The draw() function will be run every frame and will handle all the rendering and game logic.

In order to loop the draw() function, we simply utilise the requestAnimationFrame() function call, and pass ‘draw’ as the parameter. Remember, not all browsers natively support the call, and you might have to use Paul Irish’s shim to gain maximum compatibility. Also, it is important to realise that requestAnimationFrame() does not guarantee a fixed frame-rate, so you need to use time-deltas to calculate realistic physics. For a basic game like Pong, we don’t really care about that.

Basic World

Set up the Three.js world and camera

Three.js includes these important elements:

  • Scene
  • Renderer
  • Camera
  • Mesh
  • Light
  • Material

Cameras, Meshes, and Lights need to be added to the scene using the scene.add() function.

Attach a WebGL Three.js Renderer to the DIV

The renderer is attached to whichever HTML DOM element you wish to render the scene to, and a render() call is made each frame to the renderer in order to draw the Three.js scene.

Add a camera to the scene

Three.js has the option to create Perspective and Orthographic cameras. For most uses, Perspective camera is the best choice. We can change position and rotation information of the camera like any other object in the scene.

Draw a sphere and light it

Meshes must be paired with Materials in order to give them a defined look and feel. Meshes can be of many types, include primitives such as Cube, Sphere, Plane and Torus. Materials can have different characteristics depending on their type. The basic Material types include Lambert, Phong, and Basic.

  • Basic renders an unlit Mesh with no shadows or dark shading. A sphere will look like a circle if rendered with Basic.
  • Lambert is a simple diffuse-like lighting that creates shading on sides facing away from a light source. It gives a basic 3D look of surfaces that are matte (non-shiny and non-reflective)
  • Phong is used for achieving a plastic-like look and feel, with the ability to gain highlights that give a much shinier appearance to the Mesh.

Show off your sphere with a Point Light. This is the most basic light, with no direction or rotation. Make sure you tweak the light’s intensity and distance to get it looking good.

Add Game Objects

Draw playing area plane

The playing area will be a Three.js Mesh object of type Plane. Make sure the plane matches the play area, giving a small buffer gap to indicate where the paddles can and can’t go.

Draw paddles

The paddles will be Mesh objects of type Cube. Position each of the paddles on opposite sides of the play area.

1234567891011121314151617181920212223242526272829303132333435363738394041
// set up the paddle vars
paddleWidth = 10;
paddleHeight = 30;
paddleDepth = 10;
paddleQuality = 1;
// set up paddle 1
paddle1 = new THREE.Mesh(
new THREE.CubeGeometry(
paddleWidth,
paddleHeight,
paddleDepth,
paddleQuality,
paddleQuality,
paddleQuality),
paddle1Material);
// add the paddle to the scene
scene.add(paddle1);
// Set up the second paddle
paddle2 = new THREE.Mesh(
new THREE.CubeGeometry(
paddleWidth,
paddleHeight,
paddleDepth,
paddleQuality,
paddleQuality,
paddleQuality),
paddle2Material);
// Add the second paddle to the scene
scene.add(paddle2);
// set paddles on each side of the table
paddle1.position.x = -fieldWidth/2 + paddleWidth;
paddle2.position.x = fieldWidth/2 – paddleWidth;
// lift paddles over playing surface
paddle1.position.z = paddleDepth;
paddle2.position.z = paddleDepth;
view rawBNG_Pong_paddlecreateThis Gist brought to you by GitHub.

If you manipulate the camera positions, as seen in the screenshot, you can give a different perspective to the player.

Basic Logic

Ball movement

The ball will have an X-direction and a Y-direction that determines the movement per frame.

// ball’s x-direction, y-direction and speed per frame
var ballDirX = 1, ballDirY = 1, ballSpeed = 2;

The ball will move at a constant speed in the X-plane every frame. To this end, we will specify a ballSpeed variable that acts as a multiplier for the direction values.

// update ball position over time
ball.position.x += ballDirX * ballSpeed;
ball.position.y += ballDirY * ballSpeed;

We want the ball to have some unpredictable characteristics (e.g. when it gets sliced quite hard) so we will allow the Y-direction to go up to a maximum of ballSpeed * 2. You can tweak the values until you’re happy with how the ball behaves.

// limit ball’s y-speed to 2x the x-speed
// this is so the ball doesn’t speed from left to right super fast
// keeps game playable for humans
if (ballDirY > ballSpeed * 2)
{
ballDirY = ballSpeed * 2;
}
else if (ballDirY < -ballSpeed * 2)
{
ballDirY = -ballSpeed * 2;
}

Ball wall bounce logic

Simple collision detection logic is required to check if the ball is touching each of the side ‘walls’. Using a series of ‘if-else’ statements, we check the ball positions against the predetermined wall positions. In the case of a collision, we simply switch the Y-direction of the ball, creating a bounce effect.

// if ball goes off the top side (side of table)
if (ball.position.y <= -fieldHeight/2)
{
ballDirY = -ballDirY;
}
// if ball goes off the bottom side (side of table)
if (ball.position.y >= fieldHeight/2)
{
ballDirY = -ballDirY;
}

Later, we will edit some of this code in order to implement scoring when the ball passes a paddle.

Keyboard input for paddles

We will utilise a very effective short-cut in order to easily get keyboard input working in this game. Using the Keyboard.js file provided, we simply have to include the reference to it in the index.html file and we are set. Only one function call is required, the Key.isDown() call. Given a parameter, the library checks if that particular key is current being pressed, and returns a boolean value.

// move left
if (Key.isDown(Key.A))
{
// code to move paddle left
}

We use the ‘A’ and ‘D’ keys to move the paddle left and right, but you can edit the Keyboard.js with additional values if you want to use your own control scheme.

var Key = {
_pressed: {},
A: 65,
W: 87,
D: 68,
S: 83,
// add your required key code (ASCII) along with the name here
// for example:
SPACE: 32,
};

While dealing with keyboard input, it is also important to ensure that the input is never blindly updated in game. We have to check that the paddle isn’t made to move off the play area, and we do that with some ‘if-else’ statements as well.

// move left
if (Key.isDown(Key.A))
{
// if paddle is not touching the side of table
// we move
if (paddle1.position.y < fieldHeight * 0.45)
{
paddle1DirY = paddleSpeed * 0.5;
}
// else we don’t move and stretch the paddle
// to indicate we can’t move
else
{
paddle1DirY = 0;
paddle1.scale.z += (10 – paddle1.scale.z) * 0.2;
}
}

Note that we use a paddle direction variable, rather than simply applying a change to the position values. This will come in handy when programming the ball to ‘slice’ when hit at an angle with a fast-moving paddle.

Opponent logic

When you code a game of this calibre, it is of utmost importance that you create a vivid, lush environment with a host of emotional, highly-relatable characters that showcase this generation’s strides forward in technology. Instead, we will code a Pong A.I. that blindly follows the ball, because that is even better.

We can update the opponent difficulty by using a variable instead of introducing magic numbers. This variable will affect the ‘reaction rate’ of the opponent by increasing the Lerp (Linear-Interpolation) time.

When using a Lerp (Linear-Interpolation) function, we must ensure the opponent plays fairly by limiting their maximum travel speed. We do that with a few more if-else statements.

// in case the Lerp function produces a value above max paddle speed, we clamp it
if (Math.abs(paddle2DirY) <= paddleSpeed)
{
paddle2.position.y += paddle2DirY;
}
// if the lerp value is too high, we have to limit speed to paddleSpeed
else
{
// if paddle is lerping in +ve direction
if (paddle2DirY > paddleSpeed)
{
paddle2.position.y += paddleSpeed;
}
// if paddle is lerping in -ve direction
else if (paddle2DirY < -paddleSpeed)
{
paddle2.position.y -= paddleSpeed;
}
}
If want to extend immersion, you could also using the paddle.scale property to stretch the paddle when it can’t be moved. This indicates an issue to the player which they can then address immediately. In order to accomplish this, we must ensure the paddle always Lerps back to the default scale size.
// We lerp the scale back to 1
// this is done because we stretch the paddle at some points
// stretching is done when paddle touches side of table and when paddle hits ball
// by doing this here, we ensure paddle always comes back to default size
paddle2.scale.y += (1 – paddle2.scale.y) * 0.2;

Adding Gameplay

Making the ball reset after missing a paddle

To get the main scoring gameplay working, we need to first remove the ball’s ability to bonce off the paddle-facing walls. To do this, we remove the bounce code from the two corresponding if-else statements.

// if ball goes off the top side (side of table)
if (ball.position.y <= -fieldHeight/2)
{
ballDirY = -ballDirY;
}
// if ball goes off the bottom side (side of table)
if (ball.position.y >= fieldHeight/2)
{
ballDirY = -ballDirY;
}
//// ——————————— ////
CHANGED CODE
//// ——————————— ////
// if ball goes off the ‘left’ side (Player’s side)
if (ball.position.x <= -fieldWidth/2)
{
// CPU scores a point
// update scoreboard
// and reset ball
}
// if ball goes off the ‘right’ side (CPU’s side)
if (ball.position.x >= fieldWidth/2)
{
// player scores a point
// update scoreboard
// and reset ball
}

We can handle scoring in many different ways. For a simple game like this, we can simply increment the corresponding score count variable.

// if ball goes off the ‘left’ side (Player’s side)
if (ball.position.x <= -fieldWidth/2)
{
// CPU scores
score2++;
// update scoreboard HTML
document.getElementById(“scores”).innerHTML = score1 + “-” + score2;
// reset ball to center
resetBall(2);
// check if match over (someone scored maxScore points)
matchScoreCheck();
}

We can then update the HUD element in the DOM by setting its innerHTML value. Finally, we have to reset the ball once someone has scored. A simple function can be written to reset the ball, with a parameter indicating which paddle just lost (so we know which paddle to send the ball to next time).

// resets the ball’s position to the centre of the play area
// also sets the ball direction speed towards the last point winner
function resetBall(loser)
{
// position the ball in the center of the table
ball.position.x = 0;
ball.position.y = 0;
// if player lost the last point, we send the ball to opponent
if (loser == 1)
{
ballDirX = -1;
}
// else if opponent lost, we send ball to player
else
{
ballDirX = 1;
}
// set the ball to move +ve in y plane (towards left from the camera)
ballDirY = 1;
}

Making the ball bounce off paddles

Alright, this is it. The big one. Literally the biggest feature of this game. It’s time to get the paddles hitting the ball. In a simple Pong game, paddle-ball physics are nothing more than a couple of if-else statements. We check the X-position and Y-position of the ball against the paddle’s rectangular bounds, and if they intersect, we bounce the ball away.

// if ball is aligned with paddle1 on x plane
// remember the position is the CENTER of the object
// we only check between the front and the middle of the paddle (one-way collision)
if (ball.position.x <= paddle1.position.x + paddleWidth
&& ball.position.x >= paddle1.position.x)
{
// and if ball is aligned with paddle1 on y plane
if (ball.position.y <= paddle1.position.y + paddleHeight/2
&& ball.position.y >= paddle1.position.y – paddleHeight/2)
{
// ball is intersecting with the front half of the paddle
}
}

It’s also important to check the direction of the ball’s travel, as we only want to check collisions in one direction (the direction towards the opponent.)

// and if ball is travelling towards player (-ve direction)
if (ballDirX < 0)
{
// stretch the paddle to indicate a hit
paddle1.scale.y = 15;
// switch direction of ball travel to create bounce
ballDirX = -ballDirX;
// we impact ball angle when hitting it
// this is not realistic physics, just spices up the gameplay
// allows you to ‘slice’ the ball to beat the opponent
ballDirY -= paddle1DirY * 0.7;
}

We will also affect the ball’s lateral movement depending on the relative speed of the paddle when hitting the ball. This is particularly useful in introducing the biggest variable in Pong: the slice. Slicing the ball is often the only way to confuse and outmaneuver the opponent, so it is vital in this game.

Remember to duplicate the code, but update the values to match the opponent’s paddle. You can use this opportunity to gimp your opponent’s ability somewhat, by reducing the hitbox size or decreasing the slice amount. It’s what we would all do.

Here is the final paddle-ball collision function:

// Handles paddle collision logic
function paddlePhysics()
{
// PLAYER PADDLE LOGIC
// if ball is aligned with paddle1 on x plane
// remember the position is the CENTER of the object
// we only check between the front and the middle of the paddle (one-way collision)
if (ball.position.x <= paddle1.position.x + paddleWidth
&& ball.position.x >= paddle1.position.x)
{
// and if ball is aligned with paddle1 on y plane
if (ball.position.y <= paddle1.position.y + paddleHeight/2
&& ball.position.y >= paddle1.position.y – paddleHeight/2)
{
// and if ball is travelling towards player (-ve direction)
if (ballDirX < 0)
{
// stretch the paddle to indicate a hit
paddle1.scale.y = 15;
// switch direction of ball travel to create bounce
ballDirX = -ballDirX;
// we impact ball angle when hitting it
// this is not realistic physics, just spices up the gameplay
// allows you to ‘slice’ the ball to beat the opponent
ballDirY -= paddle1DirY * 0.7;
}
}
}
// OPPONENT PADDLE LOGIC
// if ball is aligned with paddle2 on x plane
// remember the position is the CENTER of the object
// we only check between the front and the middle of the paddle (one-way collision)
if (ball.position.x <= paddle2.position.x + paddleWidth
&& ball.position.x >= paddle2.position.x)
{
// and if ball is aligned with paddle2 on y plane
if (ball.position.y <= paddle2.position.y + paddleHeight/2
&& ball.position.y >= paddle2.position.y – paddleHeight/2)
{
// and if ball is travelling towards opponent (+ve direction)
if (ballDirX > 0)
{
// stretch the paddle to indicate a hit
paddle2.scale.y = 15;
// switch direction of ball travel to create bounce
ballDirX = -ballDirX;
// we impact ball angle when hitting it
// this is not realistic physics, just spices up the gameplay
// allows you to ‘slice’ the ball to beat the opponent
ballDirY -= paddle2DirY * 0.7;
}
}
}
}
view rawBNG_Pong_paddlecollCompleteThis Gist brought to you by GitHub.

Scoring

In Pong, it is usually simplest to have a maximum score value, such that a game is won when either player reaches that score. To that end, we can easily create a maxScore variable and set it at the start of the match.

We then create a function to check if either player has scored equal or higher than the maximum. This function should be called only when a score has been changed (i.e. when someone scores a point.)

// checks if either player or opponent has reached 7 points
function matchScoreCheck()
{
// if player has 7 points
if (score1 >= maxScore)
{
// stop the ball
ballSpeed = 0;
// write to the banner
document.getElementById(“scores”).innerHTML = “Player wins!”;
document.getElementById(“winnerBoard”).innerHTML = “Refresh to play again”;
}
// else if opponent has 7 points
else if (score2 >= maxScore)
{
// stop the ball
ballSpeed = 0;
// write to the banner
document.getElementById(“scores”).innerHTML = “CPU wins!”;
document.getElementById(“winnerBoard”).innerHTML = “Refresh to play again”;
}
}

After a match is deemed complete, it is simplest to just return the ball to the centre and stop any movement, so that play doesnt inadvertently continue.

Prettifying the Game

HUD

It’s important to give feedback to the player so they know what’s going on. For Pong, the least we can do is keep a scoreboard ticking over. Instead of trying to draw the HUD on the same layer as the game, we can use the other DOM elements to provide the required feedback.

It’s also good to indicate the maximum score as well, so we have another element for that which we will update at match start.

// update the board to reflect the max score for match win
document.getElementById(“winnerBoard”).innerHTML = “First to ” + maxScore + ” wins!”;

Shadows

Finally, it is time to make things look a tad more polished. Three.js has the awesome ability to create shadows for primitive objects (Cube, Plane, Sphere, etc.) so we can utilise that to make the game look nicer.

Shadows can’t be created with just a Point light, so we have to add a DirectionalLight or a SpotLight. A SpotLight shines a circular beam of light onto surfaces, which DirectionalLight simply shines a light in a certain direction with no regard to positioning.

We will use a SpotLight because it clearly indicates where the light originates from and shines towards.

We can update the SpotLight to follow the ball around to give a more dynamic look and feel to the game, whilst showcasing the hard work we just put into the lighting.

// we can easily notice shadows if we dynamically move lights during the game
spotLight.position.x = ball.position.x;
spotLight.position.y = ball.position.y;

To make an object in the scene cast or receive shadows, we simply set their .receiveShadow and .castShadow variables to true. For example,

paddle1 = new THREE.Mesh(
new THREE.CubeGeometry(paddleWidth, paddleHeight, paddleDepth, paddleQuality, paddleQuality, paddleQuality),
paddle1Material);
// add the sphere to the scene
scene.add(paddle1);
paddle1.receiveShadow = true;
paddle1.castShadow = true;

Conclusion

This is but a basic introduction to the power of Three.js, which should allow you to create a basic Pong clone.

Play the latest build of this game here: LATEST BUILD*

Find the latest code at its GitHub page*

You can still do quite a number of things to polish your game, such as

  • Create animations for the paddles and ball
  • Update the HUD to look prettier
  • Import complex objects created in Modeling packages, to design a more immersive environment
  • Move HUD elements inside the game view to allow for full-screen gaming
  • Mess around with complex shaders to create reflections and other cool effects