Indeed, actually I mixed up two workflows:

* use `syncdb` (without `--all`) and then `migrate`, which is the "clean" way of doing it, since this will use migrations and thus validate they are working correctly. In this case we can't create the superuser because of the migrations: the `create_user_rank` function in `signals.py` creates a user default rank when a `User` object is created, but since this happens before the migrations take place (thus the `game_rank` table doesn't exist yet, it crashes;
* use `syncdb --all` and `migrate --fake` which would then bypass the migrations.

The second workflow is the one we're using today but we'll need to change it when Django 1.7 comes out since the `syncdb` command will be deprecated in favour of the `migrate` command that will always use migrations (https://docs.djangoproject.com/en/dev/ref/django-admin/#django-admin-migrate).

I guess the correct way of documenting it is:

```
manage.py syncdb --noinput
manage.py migrate
manage.py createsuperuser
```

Another way of solving this issue would be to delete all the current migrations and create a new initial one based on the current state of the models. That wouldn't be an issue since the application is'n deployed anywhere at the moment so we don't need those migrations.