Asgard 0.2.4

From Asgard
Jump to: navigation, search

Currently, Asgard uses ASCII newline-delimited flatfiles to describe data. Additionally no distinction exists between data that changes (Fighter statistics) and data that stays the same (Job class statistics). This has to change.

Features

  • XML data format for constant data. (Jobs, EventTypes, Monsters ...)
  • Binary data format for save files. (Fighter/Party data)
  • Objects should be able to self-load.
  • Dummy Random Battles

Task Chains

Chain #1 - Static XML Formats

Chain #2 - Binary Saves

  • Create Format for Save Files. 10/24/2006
  • Add format to wiki. 10/25/2006
  • Add Fighter binary string loading to Fighter constructor. 10/26/2006
  • Write ConsoleController.load() [unpack]. 10/26/2006
  • Write Fighter.toBinaryString(). [pack] 10/30/2006
  • Write ConsoleController.save(). 10/31/2006

Chain #3 - Game Flow

Chain #4 - Fighter Modifications

  • Add elemental modifiers to existing Fighter XML. 11/05/2006
  • Add status modifiers to existing Fighter XML. 11/05/2006
  • Modify Fighter constructor to load elemental modifiers. 11/05/2006
  • Modify Fighter constructor to load status modifiers. 11/05/2006
  • Fighter.getElemModifier and Fighter.getStatusModifier should access repsective modifier lists. 11/05/2006

Chain #5 - Sleep

Chain #6 - Heal

  • Add remove attribute to status element of eventtype XML. 11/05/2006
  • EventType constructor handles remove boolean. 11/05/2006
  • Modify EventType.afflictions[] to include remove boolean. 11/05/2006
  • EventType.detTransactions handles the remove boolean of EventType.afflictions[]. 11/05/2006
  • TransactionStatus.execute handles "add" member (based on EventType.afflictions[]). 11/05/2006
  • Create Heal eventtype XML file. (removes: poison, paralysis, madness, sleep) 11/05/2006

Chain #7 - Rabies

  • Add "madness" status to Transaction.execute(). 11/11/2006
    • Fighter constructor creates "ai" Statistic 11/11/2006
    • Playable receives 0 11/11/2006
    • Nonplayable receive 1 11/11/2006
    • Modify Fighter.makeEvent() to handle different AIs 11/11/2006
      • AI 0: user selects target and eventtype 11/11/2006
      • AI 1: monster AI 11/11/2006
      • AI 2: madness AI 11/11/2006
    • On entrance, exec a Transaction that changes ai's current to 2. 11/11/2006
  • Make eventtype XML file. (adds poison, madness) 11/11/2006

Chain #8 - Harm

  • Make eventtype XML file for harm. 11/06/2006
  • Elemental is holy. 11/06/2006

Chain #9 - Life

  • Transaction.execute() adds status death if HP less than 0. 11/07/2006
  • Death's entrance sets HP to 0, canmove = False. 11/07/2006
  • Death's exit add 25% max hp to current hp (i.e. 0), canmove = True. 11/07/2006
  • Add affectsDeath element as boolean to eventtype. 11/07/2006
  • Check whether eventtypes affect death when being used on dead Fighters.
  • Add genExit to battle over code (on victory only). 11/07/2006

Chain #10 - ChokeOut!

  • Add paralysis status. 11/8/2006
    • On entrance, set canmove = False. 11/8/2006
    • On exit, set canmove = True. 11/8/2006
  • Make eventtype XML file. (adds poison, paralysis) 11/8/2006

Chain #11 - Polishing

  • Add Lit1. 10/28/2006
  • Create status list on wiki.
  • Create monster fighter XML files. 11/12/2006
  • Move random eventtype helper functions to separate file. 10/26/2006
  • Debug until it works. 11/13/2006
  • Tar/GZ. 11/14/2006
  • Upload to gna.org. 11/14/2006
  • Update front page. 11/14/2006
  • Make Freshmeat re-release announcment. 11/14/2006
  • Make Sourceforge re-release announcement. 11/14/2006

Files

XML Static Data

XML files will contain static information that will be loaded into the game and not-rewritten to the XML files. Monsters, Event Types, Job Classes, and Initial Characters are all examples of XML files. We will be using the libxml2 Python module to do XPath queries to retrieve data from the XML files.

The code below is a possible XML format to describe the initial configuration of Hand, our hero. Notice how easy to read it is compared to the ASCII files that we've been using. No additional documentation is needed to explain what values mean what.

<fighter class="swordsman">
 <name>Hand</name>
 <playable>True</playable>

 <stat name="level" max="1"/>
 <stat name="exp" max="0"/>
 <stat name="exptnl" max="350"/>
 <stat name="hp"  max="500"/>
 <stat name="mp"  max="25"/>
 <stat name="str" max="30"/>
 <stat name="spd" max="6"/>
 <stat name="dex" max="10"/>
 <stat name="agl" max="10"/>
 <stat name="wis" max="7"/>
 <stat name="wil" max="12"/>

 <equiption>
  <head>Helm</head>
  <body>Cloak</body>
  <left>Shield</left>
  <right>Sword</right>
 </equiption>

</fighter>

Next is a code snippet used to interpret this file. Save a copy and try running.

import libxml2

class Fighter:
 	def __init__(self,file):
		doc = libxml2.parseFile(file)
               print doc.xpathEval("//name")[0].content
               if doc.xpathEval("//playable")[0].content == "True":
                       print "Playable"
               else:
                       print "Non-Playable"
		doc.freeDoc()
 f = Fighter("hand.xml")

Binary Save Data

Binary files, on the other hand, will be used for saving and loading games. This format is not static and will vary from game to game. It will contain information about characters, there location in the game (when that information is available), etc. One can think of these files like SMC files for SNES emulators. In order to read and write data from these files, we will need to do binary reads and writes. The format will have to be very specific and well documented as these files will not be human readable.

Formats will need to be decided upon and documented for both XML and binary file types.

The code below is an example of reading and writing binary data using Python. It uses Python's struct module for packing and unpacking data.

from struct import *

name = "Hand"
str = 25
wil = 10
wis = 10

binary_string = pack("5pBBB",name,str,wil,wis)
fptr = open("test.save","wb")
fptr.write(binary_string)
fptr.close()

# ... some time later

name = ""
str = 0
wil = 0
wis = 0

fighter_data = (name, str, wil, wis)

fptr = open("test.save","rb")
binary_string = fptr.read()
fptr.close()

fighter_data = unpack("5pBBB",binary_string)

print fighter_data

There are really 2 things to be learned here.

  • pack converts data into binary strings, and unpack binary strings back into useful data
  • these functions use a binary string description. in this case, it's "5pBBB"

The binary string description looks cryptic, but it's really quite simple. The one in the example means, "string of 5 bytes followed by 3 unsigned chars."

Behavior Changes

Dummy Startup Menu

There will be a dummy menu that appears at startup. From this menu, the user will have the option of starting a new game, loading an existing game, or quitting. Once again, this is a dummy menu so it will probably reside in either ConsoleController or ConsoleView.

  • Loading
This file will be in a binary format and will describe the current status of the "Hero" party. After selecting a file to load, the binary file will be processed and the Fighter objects will be populated. After that point, the player will engage in a "random battle."
  • New Game
If the "new game" option is selected, a new save binary will be created. It will be populated based on "initial" xml files for each Fighter. After the save binary is created, it will be loaded into the game just like any other save game, and a "random battle" will commence.
  • Quit
Very simple. It will exit the program.

Random Battles

For this release a number of varied monsters will be created to test the XML data and the additions from Asgard 0.2.3. Some number and combination of these monsters will be selected, at random when a save game is loaded. After the battle is over, experience will be divied out, levels will be gained, and the player will have the option of saving the game, quitting, or having another random battle.

Monsters

  • Imp
Standard weak goblin/orc-like creature.
Moves: Attack
  • Roc
Giant bird.
Moves: Attack, Lit1
  • Griffiend
Undead, tormented ancient warrior riding a Griffin.
Moves: Attack, Fright
Weak Against: holy
  • Briaru
Plant nymph that not only chokes out other plantlife, she'll also choke out foolish male warriors who fall to her enchantment.
Moves: Attack, ChokeOut, Sleep
Weak Against: fire, ice
  • Slithera
Giant tentacled creature that's very similar to a squid.
Moves: Attack
Weak Against: lit
  • Stonos
Earth golem that can crush the strongest of warriors with one fell swoop.
Moves: Attack
Susceptible: sleep
  • Wolf
Standard wolf.
Moves: Attack, Rabies
Susceptible: poison

Magic

  • fire1
MP: 5
  • ice1
MP: 5
  • lit1
MP: 5
  • poison
MP: 3
  • sleep
MP: 4
  • cure1
MP: 5
  • harm
MP: 8
MP: 8
  • heal
MP: 3
  • life
MP: 10

Special Moves

  • Rabies
Disease spread by wild animals.
Causes: madness, poison
MP: 10
  • ChokeOut
Technique employed by vicious plant-nymphs.
Causes: paralysis, poison
MP: 15
  • Fright
Scares warriors into helplessness.
Causes: paralysis
MP: 8

Statuses

  • sleep
  • poison
  • paralysis
  • madness
  • aglup
  • death

Maintenance Work

A number of small problems have cropped up that need to be fixed. This is just a list.

  • Move from raw_input() to pygame keys
  • Move miscellaneous computation functions from eventtypes.py class to free file.

See Also

libxslt2 python bindings