I'm in the same boat, myself. I've always understood "emulation" to mean the creation of an environment within which something can operate that's incompatible with the environments it naturally has access to. Whether you emulate that environment with exacting accuracy - which I would actually term a "simulation" or loosely, what matters about an emulator is that it make the software run as it was intended.
I guess the difference in terms here comes from whether you're trying to emulate City of Heroes or THE SERVER which runs City of Heroes. In this regard, I appreciate Leandro's point: The game runs fine on modern machines and we don't care about the architecture which intercepts the various server calls. We want to emulate City of Heroes itself, which means creating an environment suitable for its needs, and that doesn't have to be a copy of the original server architecture.
In this regard, Leandro's terminology is much more accurate. If you are attempting to create a server that the client recognizes and that behaves in a manner similar to the way the original CoH servers did with regard to broad gameplay, you are attemping to create a
compatible server.
Colloquially, these terms do not have consistent definition: they are used by people in whatever way they want. But in software development specifically, and in communities that focus on these areas, the terms have very specific usages that are generally followed consistently in the vast majority of cases.
Emulation refers to the behavior of a system treated as a black box. System A emulates System B if System A behaves like System B given the same inputs.
Simulation refers to the behavior of the components of a system. System A simulates System B
at some level if, for a particular breakdown of System B into components, the equivalent components of A behave in the same or similar way. In a sense, Emulation refers to the behavior of the system from the outside, simulation refers to the behavior of the system inside.
System A is
Compatible with System B if System A can replace System B in a way that allows other systems that normally interact with System B to continue to function correctly, if not necessarily identically.
A colloquial argument about the meaning of those terms goes nowhere, because the dictionary definition is vague and the technical definitions are only important to people involved usually. But if I were hiring a programmer to create a system, I would expect them to understand the difference between those three terms.
As to MAME, MAME is an interesting example. MAME
emulates game consoles - it reproduces their behavior. It contains processor emulators that emulate the behavior of CPUs and sound chips etc. But in a sense, it also
simulates game consoles, by reproducing the behavior of those components as they interact with each other. The stated purpose of MAME is to reproduce not just the behavior of the games, but also in a way that preserves their original design. Although they do not put it this way, I would say MAME intends to
simulate game consoles with a library of component
emulators to reproduce the behavior of the original game. So you could argue MAME drivers are emulators at one level, and simulators at another level. Albeit, they are extremely loose simulators at best, its not a trivial point since arguments over this precise detail have occurred within the MAME development community periodically over the years.
Where MAME crosses the line from emulator to simulator is in the area of unintended behavior. In the MAME community, the majority opinion has tended to be if the original game had an behavior the designer did not intend, a MAME driver that did not reproduce that behavior implicitly (as opposed to in an ad hoc manner) would fail to properly recreate the game to MAME standards. If the base MAME code and the MAME driver did their jobs correctly, such behaviors should automatically emerge from the system. This notion that a MAME driver with the appropriate roms should *automatically* reproduce all quirks of the original game without those behaviors being explicitly programmed into the code is a hallmark of a simulator more than an emulator.