Пошаговая браузерная игра Django - дизайн базы данных для обработки отдельных временных шагов

Я разрабатываю пошаговую стратегическую браузерную игру с Python/Django. Идея такова: игроки взаимодействуют с сайтом в течение хода n. Они следят за состоянием своей игры (игровой мир) и выдают приказы, которые должны быть выполнены при оценке следующего шага времени. В какой-то момент времени веб-сайт зависает, и механизм хода рассчитывает новый игровой статус для временного шага n+1, исходя из статуса на временном шаге n плюс список заказов всех игроков. Во время этой оценки временного шага мне нужно прочитать состояние объектов с временного шага n и создать / записать объекты с временным шагом n+1. Как реализовать это наиболее эффективным способом? (Речь идет о дизайне базы данных)

Я рассмотрел следующие варианты: Первый подход будет таким: Пусть каждый объект мира будет иметь параметр временного шага. Вероятно, будет очень громоздко всегда фильтровать по временному шагу. Кроме того, база данных будет расти с каждым временным шагом, поскольку она будет содержать всю историю, начиная с временного шага 0.

Второй подход заключается в следующем: иметь разные физически непересекающиеся базы данных для каждого временного шага. То есть во время эволюции временного шага создайте новую базу данных для временного шага n+1. Во время оценки работайте с базами данных (n, n+1) одновременно. По завершении оценки временного шага удалите (или лучше: заархивируйте) базу данных временного шага n и замените ее базой данных n+1. (Это будет иметь приятный побочный эффект, когда в качестве резервной копии будет использоваться моментальный снимок базы данных каждого временного шага). Последний вариант мне кажется лучшим подходом. Но мне нужен совет о том, как работать с двумя базами данных одновременно.

Есть еще какие-то советы, которые вы можете дать мне, чтобы сделать выбор. Видите ли вы другие возможные подходы? Существуют ли сторонние библиотеки или Django -плагины, занимающиеся аналогичными проблемами? Если бы я использовал второй подход, как я могу сказать Django использовать 2 базы данных одновременно, с одинаковыми типами объектов в каждой?

1 ответ

Решение

Я думаю, что вы в основном разобрались. Две базы данных, default а также future,

DATABASES = {
    'default': {
        'NAME': 'default',
        'ENGINE': 'django.db.backends.mysql',
        'USER': '',
        'PASSWORD': '',
    },
    'future': {
        'NAME': 'future',
        'ENGINE': 'django.db.backends.mysql',
        'USER': '',
        'PASSWORD': '',
    },
}

Напишите ваши взгляды / что-либо, как обычно, используя модели как обычно. Они будут записаны в defaultбаза данных, как вы, вероятно, привыкли.


Создайте команду управления, которая обновляет игровое состояние... (Вы также можете добавить этот код в задачу Celery или что-то еще, но для этого ответа я планирую вызывать из командной строки с помощью планировщика cron.)

# project/app/management/commands/run_turn.py

from django.conf import settings
from django.core.management.base import BaseCommand
import subprocess
from optparse import make_option

def copy_default_to_future():
    # Copy database before acting on game state
    # use the subprocess library for bash execution of mysql/postgres commands

    # ...

def copy_future_to_default():
    # Copy database after acting on game state
    # use the subprocess library for bash execution of mysql/postgres commands

    # ...

def upload_backup_to_cloud():
    # i recommend using django-cumulus and a custom backups storage container

    # ...

class Command(BaseCommand):
    args = '<attachment_path attachment_path ...>'
    help = 'Processes game state at end of turn'

    option_list = BaseCommand.option_list + (
        make_option('-u', '--upload-backup',
            action='store_true',
            dest='upload',
            default=False,
            help='Upload database export to cloud object storage'),
        )

    def handle(self, *args, **options):
         if options.get('upload', None):
             upload_backup_to_cloud()

         copy_default_to_future()

         # ... change your gamestate
         for player in Player.objects.using('future').all():
             player.increment()
         # ...

         copy_future_to_default()

         print "Game state updated."

patrick@lucca:~$ crontab -e

@hourly /home/patrick/.virtualenvs/browsergame/bin/python /path/to/project/manage.py run_turn --upload-backup

Рекомендации:

Другие вопросы по тегам