A minor supplementary answer: many games help to separate mechanics from the engine with the use of a scripting language such as Lua. So for example, the core engine may be programmed in C++, but the logic for an ability might be coded in Lua. Often, the scripting language is interpreted rather than compiled, allowing game designers or modders to adjust existing mechanics or develop new mechanics without having to recompile the game.
The main disadvantage of an interpreted scripting language is that it's much slower than compiled code, so a well-designed game will try not to put any performance-critical code into the scripting language. How much the performance matters will completely depend on your game - for example, performance is typically much less of an issue in a turn-based game.
Example: Sins of a Solar Empire defines most of its ships and abilities in terms of JSON files. [...]
Obviously, going with this dynamic, data-driven approach is much slower than having native code directly describe the behavior of the system. Performance-wise, hard-coding wins, hands down (both for loading time and for actually executing the simulation of the game mechanics).
To be clear, pure data like what you would store in JSON is generally going to be loaded and parsed once, either when the game boots or the first time that data is accessed. There shouldn't be any performance impact during gameplay.