A procedural model is a description of a system (graphics, audio, AI) using algorithms rather than explicit, precomputed data. Thus, a common characteristic of all procedural methods is the use of code (in many different languages). As the richness of the programming language grows, the expressive potential will grow as well, and the procedural representation will unleash all its flexibility.
Additionally, procedural methods are resolution independent by nature (see Figure 21.1). When you hard-code an AI routine or create a texture map in Photoshop, you are essentially locking down the level of detail. The complexity of the AI and the texture resolution are fixed. Procedural systems are resolution independent, so you can scale up and down without losing detail. All you have to do is provide finer granularity algorithms, which can scale when needed. The same way a fractal can have infinite detail, a procedural method can be arbitrarily detailed as well.
Figure 21.1. View of the popular Mandelbrot fractal, a classic procedural model. Left: Overall view. Right: Zooming x 1000, a region showing the intricate, resolution-independent detail.
Another benefit of procedural techniques is data amplification: the capability to create high-complexity results from relatively simple input data sets so the procedure acts as a data amplifier. Again, fractals are a great example. A fractal terrain generator using midpoint displacement gets a quad as input, but can generate infinitely detailed mountains from it. Thus, the shader can sometimes not only filter and modify, but also create new detail as well.
Thus, procedural techniques are a great way to provide flexibility in game development. The learning curve might be the downside, but the overall balance is clearly positive. Games are both more flexible and easier to maintain because different team members have access to different game components.
Sometimes, procedural techniques are dealt with individually. We refer to vertex shaders, DSP routines for audio, Java scripts for AI, and so on. But it is important to understand that each of these (and many others) is nothing but a leaf of the same tree. The coding techniques might somehow differ, but the overall philosophy is the same.