I assume usage of gettext() in the answers below. Arrays might be not as simple.
- PHP - no problem at all, just put strings within _(""), tedious but nothing really scary
- templates - not sure, but these are sore to php files as well, I have seen some tutorial to internationalize some wordpress templates so it should be doable
- JS - do not use JS?

Lame solution but works for me.
- DB - what type of game you have? In all my strategy games there is not even one field in the whole database that would require it, in my RPG games there are item, monster, quest tables at most. In addition, I keep all item definitions in php file, so I would need to add gettext to it and then rerun the database update (which won't disrupt gameplay since all item IDs would stay the same, I'm doing it already when I fix spelling mistakes in item descriptions).
Judging from my existing games (probably there are some types of games that would not have it such easy, but I can not think of any right now) translation should be fairly easy for singlebyte languages. I'm not sure about performance.
What bugs me are arrays:
$race=array('human','elf',...);
Using simple gettext on long arrays does not sound too smart...
$race=array(_('human'),_('elf'),...);
Maybe using implode/explode first? Like this:
$t=implode($array);
$array=_($t);
$race=explode($array);