The bad news - you’re not Valve or Bungie • Most of your team are weak links • Design is unclear and changes often • Have to make demos with little notice • Features get cut and added at all times • Content team and other coders don’t follow the rules
The Oddworld Method • Lead Programmers – make the whole company more productive • Use the code and engine to help other coders, content developers • Improve your weak points, don’t perfect your strong points – each company is unique • Rapid development and messy design – iteration, ease of changes, forgiving design tools • …
The Oddworld Method, cont. • robustness, flexibility, and rapid-response • the engine is at all times crash-free and can be turned into a shippable demo on short notice • little tips to improve productivity are worth millions • many of your coders are junior – make it hard for juniors to write broken code; eg. Code that seniors write should be self-correcting & self-enforcing
Never bring down other people • People make mistakes, you can’t stop that • Make mistakes only affect that one system • Everything is in perforce; roll back bad content, bad builds • All code is reviewed • Compiler asserts; table size checks • Exceptions…
Background : engine summary • All tools in Maya, all geometry triangle soup • Visibility through portals, clip frustum, scissor • Zones also define paging units and ticking objects; only current & adjacent zones tick • Collision on triangle soup w/ KDtree and spatial index • Lightmapper for static lighting; cube maps for characters; material-based renderer with high triangle throughput • Objects tick one by one and move themselves; simple zone-based manager • Paging in big blocks; huge continuous levels with persistent state
Exceptions • Not in final game • Not for normal errors, only for fatal errors • Default action is to propagate error; better than return values (malloc example) • Catch in individual object creation, tick & render • SEH is better than C++ EH, lets you write code in the catch and provides call stack • Handler can detect attached debugger and int 3 • Bad for cross-platform
Stack traces and error logs • Small binary stack traces on Xbox (64 bytes) • Parser on PC • Mailer to coders • VC double-click • Used for many things • Error messages – for anything the artists can get wrong. Log stack traces with every error.
Builder • Use free POP3 client; just check mail to build account • Run the subject line as a command • Batch file does sync+incredibuild+submit • Can easily do any task – so also process lipsync, make DVD, just use windows task scheduler
NetSlave • Simple distributed farm; master machine controls a set of slaves • Just a queue of commands, farmed out FIFO with dependency analysis • Lets you use simple single-proc tools; no need for multi-proc bugs! • Slaves use p4 for data transfer
Memory Management • Systems use more or less memory at different times. • Stack traced alloc tracker, parser for hierarchies in tabview. • 3 heaps – contiguous (20 M, relocatable), small block (5 M, fast), heap (used rarely at runtime). • STL and XMemAlloc directed into our allocators • Future – separate heap for 64 meg debug data
STL • Saves dev time; dev time is not just writing code • STL-port; configurable • Vector is used heavily; all other containers very rarely used • Array<>; few C-style arrays, lots of vectors! • …
STL - vector • Release(), tighten(), tighten if excessive • Modified vector growth scheme; doubles on PC, limit at 4k on Xbox • Vecsorted – like a map, but tight in memory; sometimes faster • Vector_s, vector_t, vector_a ; note that the base vector class itself is 12 bytes
Inst/Def paradigm • Many insts created from one shared def • CoreObject = instance, made from tag, class factory, needs to be IO’d in save games. • Resource = def, const, made from binary data blocks, const, shared, kept in memory across level loads, etc. • Many other things use inst/def
IOZ (the Z is for cool) • Templated type-traits based IO system. • Client code is very easy – just call IOZ on all members; all logic is compile-time • Type traits and template specialization know if a type is binary or not, also if vectors are vectors of binary, etc. • Pointer IO – CoreObject or Resource? • Resources written as Token references • CoreObject data must be written once, but other pointers just write references (use the RefCounted table index)
Smart Pointers • Every type should clean itself up on destruction, so pointers should too. • Other types of GC would be okay; GC reduces errors, GC is required for exceptions. SP is the simplest form of GC. • Weak Pointers – a reference, not a hack; 4 bytes + 4 for table entry. Table also provides index for IO. (2 byte table index, 2 byte UID) • …
Smart Pointers, cont. • Can’t have loops; use Weak or Naked for back pointers; must have a tree-structure of ownership. • Pass naked pointers; avoids exposing interface and avoids temporaries; can’t do with boost style SP, need base class RefCounted; need to be a little careful with this. • Stack-trace ref tracking for ref leaks; catches loops and other bugs.
Tweaker and Prefs • Text is nice for p4 diffs and searches with simple perl tools – making spreadsheets of all healths, dependency finding, etc. • Cvar – no per instance overhead, handles MI. In the future, generic template Reflection visitor. • GameControl system for spatial overrides and inheritance • In the future – more pref inheritance with rule-based inheritance, eg. Super Wolvark = Wolvark w/ health*2
Resource Bundler • Just load the level and track resource queries. • Bundle resources for NPC’s, Zones, cines, etc. • Bundle optimization – minimize bundle count, constrain to 64 meg limit, minimize total bundle size
ArtWatcher • Watch dirs with ReadDirectoryChangesW, copies content to Xbox and notifies game; ArtWatched resources override bundled content • Does p4 adds (we add .cpp and .h files too), helps artists a lot • Right click menu for common tools • One error – on restart, ArtWatched info is lost
Other stuff • Skeleton LOD • Cube Map Lighting • Practical PSM • Decorator Renderer • AI System • Animation control • … but technology is easy!
Conclusion • Code responds well to bad use – enforces rules, never crashes, flexible, easily changed. • Finish a good game on time; clearly helped OW • Hopefully one tip here is useful at your company • No C++ bashing please