基于Django回合的浏览器游戏-数据库设计来处理单独的时间步骤



我正在用Python/Django开发一款回合制策略浏览器游戏。其理念是:玩家在第n回合与网站互动。他们观察自己的游戏状态(游戏邦注:即游戏"世界"),并发布将在下一个时间步骤评估中执行的命令。在某个时间点,网站被冻结,回合引擎从时间步n的状态加上所有玩家的订单列表中计算出时间步n+1的新游戏状态。在这个时间步求值期间,我需要从时间步n读取对象的状态,并在时间步n+1创建/写入对象。如何以最有效的方式实现这一点?(这是一个关于数据库设计的问题)

我考虑了以下选项:第一种方法是:让每个世界对象携带一个时间步长参数。总是按时间步长过滤可能会很麻烦。此外,数据库将随着时间步长而增长,因为它将包含自时间步长0以来的整个历史。

第二种方法是:对每个时间步骤使用不同的物理上不相交的数据库。也就是说,在时间步演变过程中,为时间步n+1创建一个新的数据库。在求值期间,同时处理数据库(n, n+1)。一旦时间步求值完成,删除(或者更好:存档)时间步n的数据库,并用数据库n+1替换它。(这样做的好处是,每个时间步骤都有一个数据库快照作为备份)对我来说,后者似乎是更好的方法。但是我需要一些关于如何同时处理两个数据库的建议。

你能给我其他的建议来做选择吗?你觉得还有其他可行的方法吗?有任何第三方库或Django插件处理类似的问题吗?如果我使用第二种方法,我怎么能告诉Django同时使用两个数据库,每个数据库中都有相同类型的对象?

我想你已经基本明白了。两个数据库,defaultfuture

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

写你的视图/任何正常使用模型像往常一样。这些将被写入default数据库,因为你可能已经习惯了。


创建一个更新游戏状态的管理命令…(您也可以将此代码扔到芹菜任务或其他东西中,但对于这个答案,我计划使用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

引用:

  • https://docs.djangoproject.com/en/dev/topics/db/multi-db/selecting-a-database-for-save

最新更新