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

时间:2014-03-22 17:29:14

标签: python django django-models

我正在使用Python / Django开发一个基于回合制的战略浏览器游戏。 这个想法是这样的:玩家在转折期间与网站互动。他们观察他们的游戏状态(游戏“世界”)并发布将在下一次评估中执行的订单。 在某个时间点,网站被冻结并且转弯引擎从时间步长n的状态加上所有玩家的订单列表计算时间步长n + 1的新游戏状态。 在此时间步骤评估期间,我需要从时间步骤n读取对象的状态,并在时间步长n + 1处创建/写入对象。 如何实现这个最有效的方法? (这是关于数据库设计的问题)

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

第二种方法是: 每个时间步都有不同的物理上不相交的数据库。 也就是说,在时间步长演变期间,为时间步长n + 1创建一个新数据库。在评估期间,同时处理数据库(n,n + 1)。完成时间步长评估后,删除(或更好:归档)时间步长n的数据库,并将其替换为数据库n + 1。 (这会产生很好的副作用,即将每个时间步长的数据库快照作为备份) 后者似乎是对我更好的方法。但我需要一些关于如何同时处理两个数据库的建议。

是否有任何其他建议可以让我做出选择。 你还有其他可能的方法吗? 是否有任何第三方库或Django -plugins处理类似问题? 如果我会使用第二种方法,我怎么能告诉Django一次使用2个数据库,每个数据库都有相同类型的对象?

1 个答案:

答案 0 :(得分:1)

我认为你已经弄清楚了。两个数据库defaultfuture

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

参考文献: