The System Shock Hack Project

"Look at you, Hacker. A pathetic creature of meat and bone, panting and sweating as you run through my corridors. How can you challenge a perfect, immortal machine?"

TSSHP main page


Dev Team

Screen shots


Glen's Junk

Unofficial specs


or A Hacker Writes ...

The current virtual manifestation of TSSHP (it will probably never get a physical manifestation) consists of quite a lot of miscellaneous technical info on System Shock and the Ultima Underworlds, a software-rendered engine which is slowly coming up to speed, and quite a lot of blathering on mailing lists about AI, physics etc. Oh, and this web page.

The basic idea is to reverse-engineer and then re-engineer System Shock. Why? Well, partly to preserve the legacy of the great Looking Glass studios. Partly to bring a classic game up to date. But mainly because we think it's tremendous fun.

The 3D engine

jim writes

Development of a 3d first-person game can be broadly divided into the following categories:

  • Technical
    • Graphics engine
    • Physics engine
    • AI
    • User interface (HUD, controls etc.)
  • Design
    • Level design
    • Artwork (textures, objects, HUD)
  • Testing
  • Packaging, marketing etc.
Looking at this list it becomes clear that we hackers are ahead of, if I may use the expression, the game. The design, which is probably the area involving the most work, has all been done for us. All we need to do is a little reverse-engineering. (Or in the case of a huge and complex game such as System Shock, a lot of reverse-engineering). Likewise we need do no marketing. Everybody who is likely to be interested already has a copy of the game, or at least knows about it. So we can concentrate on the fun bits, hackers that we are.

Technical: Graphics Engine

Believe it or not, this is actually the easy bit. After all, a polygon is a polygon is a polygon. he says, with the naïveté of somebody who hasn't actually tried it. One year on I'm thinking a little differently

System Shock, like the Ultima Underworld games which preceded it, uses a tile-based map. Unlike DooM and its ilk, which have a very small-scale grid and allow lines connecting any arbitrary points, the System Shock maps are 64x64 grids of quite large tiles. In this it resembles Wolfenstein 3D; however the UW/SS graphics engine is far more sophisticated allowing diagonal walls, variable-height and/or sloped floors and ceilings, and bridges and other objects which may be stood upon. A table might be useful here.

Graphics engines I have known and sometimes loved
Engine Grid Walls Floors/ceilings Look up/down 3D map Objects
Wolfenstein 3D Large tiles Square blocks Single fixed height No 2D only 2D sprites
Doom/DoomII Small 2D Arbitrary Variable height, flat No 2D, variable height 2D sprites
Heretic/Hexen Small 2D Arbitrary Variable height, flat Yes 2D, variable height 2D sprites
Quake Small 3D Arbitrary Arbitrary Yes True 3D 3D models
System Shock Large tiles Square / diagonal Variable height, sloped Yes 2D, can stand on objects Mixed 2D / 3D

Here we see that System Shock is not true 3D, but comes closer than the other pseudo-3D engines in the table. (Quake and its derivatives use true 3D engines). It is also the only game to use both sprites and 3D models for its objects. Unlike Doom and its derivatives, which have floors and walls always at right angles to one another, Shock surfaces can be at any angle. However, the map itself is basically 2-dimensional.

What does all this mean? In fact, very little for the purposes of the TSSHP engine, once we get the map loaded that is. All calculation is performed in 3D, and the renderer tries not to rely on the specific shape of System Shock / Underworld tiles (though the level loaders and some bits of the mapping code, and the automap of course, still do). Doom and Doom-alikes partition their maps into a tree of guaranteed-convex (really concave) "subsectors" using a Binary Space Partitioning algorithm. Fortuitously for us, however, the System Shock maps are already divided into convex subsectors; these are the tiles themselves.

At its heart, the current incarnation of the TSSHP renderer is a portal engine. This is something of a buzzword at the moment, but basically it means that the 3D world is partitioned into convex subsectors which are linked by portals: these are polygons through which the player can see from one sector to the next.

When traversing the world looking for sectors to draw, the engine starts off in the sector containing the viewpoint, and sets its current inclusion volume to the view frustrum for the screen (i.e. the interior of the polyhedron consisting of the projections of the four edges of the screen, plus planes to define a minimum and maximum draw distance. Say that again a few times slowly). Each time it encounters a portal, it is clipped against the inclusion volume and the resulting polygon, if any, is used to make a new inclusion volume containing only that part of the 3D world which can be seen through the portal. This provides an an elegant way of searching the world and there is no overdraw of surfaces.

The TSSHP renderer processes the world in 4 passes. First it compiles a list of potentially visible tiles (PVTs). This is a quick search without clipping against the individual portals: any tile which can be reached from the starting point through any number of portals without going outside of the view frustrum is included in the PVT list.

The second pass produces a partial ordering of tiles. This sorts tiles so that any tile appears in the PVT list before all tiles that can be seen directly through it. The reason this is separate from the previous is that there may be more than one route to a tile (set of portals through which it is visible).

In the third pass, tiles are processed according to the above partial ordering, and fully clipped by the portals through which they are visible, so that now only those tiles that can really be seen by the player are considered. Objects are queued here as belonging to the first tile in which they are encountered, so that they are drawn as far forward as possible. This isn't perfect, but will do for the time being.

The fourth pass traverses the world from back to front, and renders each tile. All drawable surfaces are backface culled and clipped, and if they pass they are lit, transformed to view space and passed to the back-end texture mapper. Then all the objects belonging to the tile (marked as so in the third pass) are rendered.

There are a few problems with the renderer as it stands. TSSHP uses the original tiles from the games unmodified as its sectors. This means that in large open spaces (particularly in Underworld) there are many portals that don't contribute anything to the clipping, and possibly many routes from the viewpoint to a distant tile. This is inefficient. Worse, in System Shock cyberspace, where everything is transparent, every surface is effectively a portal, and none of them clip at all! So a portal engine won't cut it for c/space.

An approach that occurred to me was to combine adjacent portals' inclusion volumes if they would be convex. However, this is awkward to do, and likely to be slow if carried out on the fly. Plus it doesn't go far enough towards solving the problem of cyberspace.

For cyberspace, the engine needs to sort a large number of convex tiles from front to back very quickly, without bothering about clipping. Hmmm. Maybe id Software have something to teach us after all. A plain old BSP tree would do the job very nicely, and we can take advantage of the grid nature of the game maps to make compiling one, normally very hard, a much simpler job.

I had also considered, for open spaces in the "real world", grouping sets of tiles whose combined volume is convex into larger sectors, and applying the portal engine to those. A potentially visible tile becomes a potentially visible sector, which might contain many tiles. Tiles are not clipped against each other within a sector (since they cannot occlude one another if their combined volume is convex), but they still need to be sorted from front to back ... very quickly, without bothering about clipping ...

At about this point a lightbulb went on over my head, rather startling the other people in the bar, but I didn't much care. Make TSSHP into a hybrid portal / BSP engine! The sectors (convex collections of tiles, of fairly arbitrary shape) are sorted using the existing portal system, with minor modifications. Each sector then contains a BSP tree, whose leaf nodes are the tiles. These trees are used to sort the individual tiles. For cyberspace, the entire level is effectively one big sector: in this case we can prune the tree to remove solid (undrawable) tiles.

Technical: Physics Engine

This is the meat of the coding, so to speak. System Shock's physics engine was hugely advanced for its time. (In fact, it's pretty advanced by today's standards; how many FPS games have cottoned on to the idea that leaning round corners to shoot things is a cool thing to be able to do?) We also have to contend with jumps, crouching, lying down, running, skating, climbing ladders and weapon recoil. We have to get these to feel right. This is going to mean lots and lots of playing System Shock. What a chore.

jim (TSSHP 3D engine)

The MFDs in System Shock

firefreak writes

[This text is a generalized copy being originally posted on the forums on sourceforge]


This text is about the MFDs and the contents of them in original SS and how they behave.

I have to admit, the MFDs of original SS1 are the best I've yet encountered. Even the MFDs of SS2 didn't match the features it's predecessor had have - They had to be hidden in an 'Inventory' mode because they couldn't be integrated well in 'Shoot' Mode.
(Don't get me wrong, I know that they went through about three overhauls of the interface and the final one /is/ cool - but the interface from SS1 impressed me the most). But that's enough about my personal opinion; here it's about SS1 alone.

MFD stands for Multi Function Display because these 'screens' have to (and are able to) display various of data. SS has three MFDs: one Center and two on the sides (Left and Right).

The Center MFD:

The center MFD is capable to display several lists (Weapons, Software, Inventory, ...) and Text (Logs, Data fragments, ...)

There are four groups of lists the player can access directly: Weapon, Hardware, Inventory and Software. By accessing the Multimedia Data Reader (Your InBox ;) it displays lists of Texts that are stored.
The player can do several things with the items of the lists: Select, Drag 'n' Drop, Activate/Use, ...

The Side MFDs:

The side MFDs are capable to display quite anything the player can (inter-)act with. Be it a Keypad, the contents of a container or the settings of his brand new skates he got out of the shop (without IRQ conflict ;).

The information those MFDs can display is grouped into five main groups: Weapon, Item, Map, Target and Data. While Weapon, Map and Target are quite easy to imagine, Item and Data are the ones being capable to display a wide variety of things.
I haven't quite found out what they 'generally' display, but it seems that Item mostly displays things that come from the inventory (Log pictures, Hardware settings, ...) and Data represents interfaces of or to the outside world (Puzzles, Keypads, ...).

The Biomonitor and Games (running against this rule of thumb) are displayed in Data. I guess the thought behind it is that they have 'Information' (or 'Data') to be shown instead of properties of a single item.

Special Functions:

The Sensaround Unit displays the image data from your left, back and right in the corresponding MFD. These images aren't linked to any MFD group.
Cyberspace displays Software in center and a small Text display on the side (could be Data) - nothing more.

Control of the Content:

Mainly the player is in control of what should be displayed where. He even can control both the side MFDs separately (eg: Weapon to the left, Map to the right).
Some things are 'hardcoded' in SS (eg the Biomonitor always pops up on the left side). I'm also guessing that SS displays information about an Item on the side which is 'nearer' to the Item - but I haven't verified this.

Multi View Architecture:

Of course, one can display the Map on both sides (It looks cool and you always know where you are ;). But let me go deeper into this example: It's even possible to display the Map with a high Zoom factor to the left and a lower one to the right. 'Simple' you say 'since they are two different maps'. Well - quite.
Another example: open up a keypad. It shows up in Data View - say on the left side. Now show Data View to the right - you'll see another keypad! Pressing a digit on either side will show it on both sides. a-ha!
You have two images showing the ident data - a Multi View Architecture! (Ever tried to play Ping in stereo mode? ;)

You're also experiencing this when you read a Log for example: while you see an Image plus Sender and Subject to the left you read the Body of the Log in the center - Both MFDs take their information from one Log.


What I have done in TSSHP according to the MFDs already matches the above definitions.
The implementation of the MFDs already the group separation and the event system (even an extended one). All in all the framework for the content is set and ready to be used.

What's currently in development is the Multi View Architecture and the integration of actual content (Logs and the like for example already can be read). Following this step is the access to player data (like the inventory).

firefreak (TSSHP 2D and HUD/MFD)