Пошаговая браузерная игра 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
Рекомендации: