Achievement | Engine/Game | Why it's bad | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | storing world space positions in gbuffer | STALKER, F.E.A.R. | Depth buffer can be used to derive position saving a lot of memory bandwidth | uploaded texture upside down | Various engines, mostly Quake derived. | Difficult to debug with tools like apitrace, nsight, pix, renderdoc, etc | fixed function pipeline on top of a single vertex buffer | Tesseract, GoG porting layer | Inefficent use of modern rendering since you need to stream data every frame | made your own texture compression format that works with the driver's decoder somehow | Darkplaces (S2TC) | To avoid S3TC patents which are now expired | cleared color, depth and stencil buffers individually | idTech4, Unity | Clearing them individually is slow path in driver, all at once is optimal | line rendering with quads | Various | Less efficent and don't get hardware assisted AA like line rendering gets | per-vertex lighting | Cube, Minecraft, Gears of War, Skyrim | Looks very bad compared to lightmaps and or realtime lighting | used facet normals | Goldsrc, UE2, UE3 | Looks very bad compared to smooth normals, lighting will be incorrect | manual gamma correction on sRGB textures | Various | Incorrect and defeats the purpose of sRGB assist | used degenerate vertices to build triangle strip | UE1, Goldsrc, Source, Witness (lightmap mesh parameterization) | Degenerate vertices can lead to rendering artifacts depending on hardware | used separate vertex buffers for vertex attributes | Frostbite, idTech3, idTech4, UE3, UE4 | Interleaved data is more efficent | blamed it on the driver | Every engine | Wastes time | "fixed" shadow acne with subnormal bias | Irrlicht, Godot, Serious Sam | Floating point precision can lead to rendering artifacts | surface area heuristic uses hyperbolic functions | Irrlicht, Frostbite | Geometry is Euclidean not hyperbolic, this is just completely wrong | scene graph is a linked list | GL Quake, Serious Sam | Not very cache efficent | mixing audio in render loop | Win Quake, GL Quake, qfusion (Warsow) | Ties audio mixing to framerate and hitches in rendering can cause audio aliasing | blocking on hardware occlusion queries | Various | Defeats the purpose of culling (to speed things up; blocking is the opposite) | skeletal animation done in scripting language | Total Annihilation, Natrual Selection 2, Unity | Skeletal animation is expensive, why would you do it in non-native code? | wrote a geometry shader | Various "AAA" engines | Often slower than just feeding data from CPU due to how HW implements them | environment mapping using different sky texture | Various | Reflections are incorrect | block-compresssed tangent space normal maps | Various | Normal maps break when block-compressed | font rendering with texture per-glyph | libass, Gutair Hero III | That's a lot of textures and texture binds | wrote SIMD for unaligned data | idTech3, idTech4, Darkplaces, others | Processing unaligned data is slower than aligned and often slower than scalar | integrated Scaleform | Wayforward, CryEngine, XCOM2, Several others. | Scaleform is huge and crashes linkers, it's also full of bugs, don't use it | shipped a debug build | Skyrim | Debug builds run slower and often contain source code | shipped with debugger because it didn't crash in debugger | Wing Commander (sort of) | No time to fix a bug | modified debugger exception to hide a crash | Wing Commander | But time to hide it | compiled with -ffast-math and physics became more interesting | Anything which uses Bullet. | Bullet depends on subnormals and other strange float quirkyness to work | issued hardware occlusion queries for the HUD | Stardock (Galactic Civilizations) | The HUD is always visible why issue queries for it? | render functions are virtual | UE3, UE4, CryEngine | Virtual dispatch on different renderables is not cache friendly | glReadPixels without a PBO | Various | Blocks the render thread and forces a syncronization, i.e causes a hitch | destroyed render resources after deleting graphics context | Various | Undefined behavior | wrote software rasterizer because driver kept crashing | Epic (UT99) (Pixomatic) | Impressive but also a huge waste of time and technical debt | level stored in XML | Various tile/side-scroller games | XML is the worst serialization format for levels | shipped dedicated server bins for s390x only | Battlefield 1942 (x86 came later) | No one has s390x hardware | game scripting language requires a SAT solver | Mono scripting (C# requires SAT) | SAT solving is expensive and confusing | engine depends on Qt | Wayforward, Doomsday | Qt is a massive runtime dependency | hybrid shader language built ontop of macros targeting GLSL and HLSL | Source 2 (togl), Doom 3 BFG, RAGE | The readability of Perl | debug build is slower than running release build in valgrind | Neothyne | Valgrind emulates x86, imagine debug native slower than release interpreted | incremental GC is called when player takes damage | Several shipped RenPy and Love2D games. | Need to hide the GC pauses somewhere | in game updater uses bittorrent | WoW, Halo3 for PC. | Too cheap to host distribution so saturate everyone's internet instead | in-house developed SWF renderer | Doom 3 BFG, RAGE | SWF has embedded Actionscript | added whitespace because asset hashed to the same hash as another asset | Spyro: Enter the Dragon | Not enough time to replace the hash function | engine (or engine components) are shared libraries | Source 2, Godot, Irrlicht | Waste of development time to maintain builds and offers no real benefit | actually did something about "half pixel offset" in D3D that made things worse | Unity | Waste of development time to fix something that only made things worse | used both OpenGL and D3D at the same time | CryEngine (Compute was GL) | Impressive but also requires extensions to share resources between contexts | Ported to OSx and Linux by writing a D3D to OpenGL "porting layer" | CryEngine, Source | The time to develop that surely must've been more than just writing a GL backend | Physics simulation fixes T-junctions in meshes each physics step | CryEngine | It's possible to simulate without making T-junctions to begin with | Syncronization primitives implemented with shared memory and files (File system sync) | CryEngine | Using file IO to syncronize code | User interface is a webbrower | Tabletop Simulator, Overgrowth, GTA V, Several others. | Massive dependency full of security holes | Allocates all of system memory | Various | Waste of virtual address space makes context switching overhead more expensive | Input event processing on audio thread | Bioshock Infinite | Audio heavy scenes drop input events randomly | IPC using flat files on disk | XCOM | File explosion | Oblique frustum is actually a cylinder | Starsiege: Tribes | Doesn't work and causes culling issues | SIMD math code using virtual functions | No Man's Sky, Doom 3 BFG | Virtual dispatch breaks pipelining of SIMD on some older microarchitectures | Serialized entity state as separate files (with more open FDs than a default install supports) | ARK: Survival Evolved | File explosion and requires ulimit adjustments to work on Linux due to FD limit | native Linux/MacOS OpenGL port runs slower than Windows version in Wine | Source, Source2, Minetest | Bad port | shipped with assertions enabled | Shovel Knight | Makes things slower and can cause confusion for users if one triggers | bootstraps itself just so it can render its own icon set | Houdini | Excessive masturbation | creates temporary files to format strings, which is then used as keys to reference objects | CryEngine | File io to format strings and also lookup hashtable values by key | reference counted pointers for simple value types like vectors and events | Godot | Unnecessary | everything inherits from a base object type | Godot, UE, UE2, UE3, UE4, CryEngine | OOP spelt backwards is POO | decided to use a lesser supported graphics API than the one they wanted to use | Godot | Tons of extension wrangling that is buggy and requires driver workarounds |