War of Wizards: Plan
This page has the draft details for how my entry in the 2007 7DRL Challenge will work. Changes and suggestions are very welcome. Feel free to just edit them in and I'll keep anything I like.
A better name would be most appreciated!
The following is an ideal version of the game. It is unlikely that there will be time to write everything here.
Duelling Wizards is a turn-based text-output two-player roguelike game. Each player controls a wizard in a small random dungeon. The wizards cast spells and use potions until one of them is killed.
The game will be open source. It'll be written in Visual Basic 6, so will be Windows only.
I'll try to use as much code from my existing roguelike, Paprika, as possible. That's also open source and written in VB6.
Each wizard starts with 5 hit points. A random player takes the first move.
Each turn a player can move their wizard 0 to 5 squares in any direction. Then they do one of the following:
- Cast one of three randomly given spells for that turn
- Drink a potion from the ground
- Drink a potion from their inventory
- Pick up a potion
- Nothing (Press the 'end turn' key)
There are no weapons or hand-to-hand fighting.
The computer connected to is designated as the controller. That computer is responsible for generating stuff and the player using that computer can change game options, if they want.
The controller can release control between games.
The controller can change the game options if they want to. Configurable options are:
FoV - Default to on. If off, the whole level can be seen.
Max Level Size - Default to 25x25. This can only be odd numbers. The number of rooms randomly generated needs to be related to this.
Potions - Default to on. If off, no potions spawn in the dungeon or player inventories.
Changes to options can only be done while no game is in progress and they are not saved between sessions.
At the start of the game, the following things are generated on the controller computer:
- Random dungeon layout
- Random potion appearances (if necessary)
- Random potion locations (if necessary)
- Random potions in player inventories (if necessary)
- Random starting positions
This data is then sent to the other player.
After each turn, the following things are sent:
- Message ID's
- Dungeon layout (if changed)
- Magic effects locations (if necessary)
- Player positions (if changed)
- HP of both players (if changed)
- Potion locations (if changed)
- Lost/Win flag (if necessary)
Chat messages are sent immediately.
Moves are sent immediately.
Before sending, data needs to be compressed. A lot.
No Compression Needed
Messages are sent as very short ID numbers.
Chat mesages are sent seperately.
Moves are sent seperately.
Lost/win flag is just one character.
Dungeon layout will be a max of 25x25. This means 625 characters of uncompressed data.
How could this be compressed?
Outside edge of dungeon is always a wall, so no need to send that. This takes the layout to be sent down to 23x23, which is 529 characters.
Convert 0's (walls)
- 000 to c
- 00 to b
- 0 to a
Convert 1's (empty)
- 111 to C
- 11 to B
- 1 to A
After this, see what patterns are regularly left and convert those to other characters.
This will significantly reduce the data size.
Some spells can be worked out on the opponents computer from just the starting location. This method should be used if available.
To send a location, convert the X coords to letters (0=a,1=b, etc), keep the Y coord as a number, then add the alpha ID of the potion, spell or effect. For example:
h = X coord (h=8) 7 = Y coord f = ID of potion/spell/effect
Multiple locations are combined using a non-number non-alpha character.
Letters are always lowercase, for locations.
- Data is sent to the other player
- Previous dungeon layout is drawn
- Previous item locations are drawn
- New magical effects are drawn
- Pause for 250ms
- Update display of hitpoints
- New dungeon layout is drawn
- New item locations are drawn
- New player positions are drawn
- New messages are written to the log
Only show messages for the previous and current round. Needs wrapping. Needs ID's for all messages. Needs to incorporate chat messages, without removing game messages from view.
- Generate 25x25 square random perfect maze to fill the dungeon
- Wall squares are 0
- Empty squares are 1
- Overlay rooms. Rooms are never connected to each other
- Room squares are 2
- Remove all dead ends
- Place potions in random locations. Each square can contain one
- Create starting square for controller and opponent. Each player
starts in a different room.
Room sides are 3, 5 or 7 squares. 2, 3, 4, 5 or 6 rooms are generated.
Number of potions = Free squares / Something to be determined
The whole window needs to be small enough that I can fit two of it on my screen, for testing. The interface needs to contain:
- A space big enough to show the entire dungeon
- Game messages
- Chat messages
- Actions that can be done
- Each players hit points
- Who's move it is
- Available actions
Dungeon is displayed as text on a black background:
. (white) Empty # (white) Wall @ (white) Player @ (red) Opponent ! (various) Potion * (various) Effect
No characters are used to display room walls.
- Potions are drawn over empty tiles.
- Players are drawn over empty tiles, potions.
- Effects are drawn over empty tiles, potions, walls, players.
Ideally, variables should be contained in the form. So that two instances of the form can be generated in the same project. This will make testing a lot easier. Functions should be in a module.
All done via number pad, except for chatting.
/ Cast spell 1 * Cast spell 2 - Cast spell 3 12346789 Move 5 Drink potion from the ground 0 Pick up potion + Inventory, then 123456789 to drink a potion Enter Bring up chat prompt / Send chat message ./del End turn / Close chat prompt
The dungeon layout is initially unknown to both players. FoV will be used. Potions are only shown if they appear in the FoV.
Players can see up to six squares in every direction. The FoV is a square. This is six squares so that a player could use all their five moves to get next to the other player.
Can see: @.....@ Can't see: @......@ Can't see: @.#.@
There are no other creatures in the game. This is simply a 2-player, player-versus-player game.
Only good and neutral spells are randomly given. Bad spells can be done via the random spell or potions.
Rays of Cold - Fires in all 8 directions from the caster. Goes through walls (but doesn't destroy them) until it reaches the edge of the dungeon. No chance of avoiding. The caster is told if they hit their opponent. No messages for the opponent, but they might see the ray or get hit by it. (1 damage)
Fire Storm - Fire floods forward from the caster, up to a random distance between 5 and 10 squares. No chance of avoiding. The caster is told if they hit their opponent. No message for opponent, but they might see the fire or get hit by it. (1 damage)
Lightning Bolts Light bolts fire off north, west, south and east of the caster. This affects the lines next to the direct lines as well. No chance of avoiding. Message for opponent: "Thunder echoes all around the dungeon!". (1 damage)
Magic Mapping - Reveals the layout of the dungeon. No message for opponent.
Alter Dungeon - A new dungeon layout is generated until it has free squares where the players are. Existing potions are randomly placed in the new layout. The new layout is known to the caster, but unknown to the opponent. Opponent gets a message: "You sense your surroundings are different."
Identify - Identifies potions in the inventory. No message for opponent.
Item Detection - Shows the locations of some items in the dungeon. No message for opponent.
Life Detection - Shows the location of the opponent. Message for opponent: "You feel like you're being watched."
Restoration - Heals one hit point. No message for opponent.
Take Life - Steals one hit point from the opponent, if they can be seen. Message for opponent: "You feel like your soul is being taken away."
Mirror Earth - Everything is mirrored either horizontally, vertically or both. The layout of the dungeon becomes known to the caster and unknown to the opponent. Message for opponent: "You feel unaware of your surroundings."
Random - A random spell is cast.
Demolition - Randomly destroys rock around the caster. Message for opponent: "You hear rock being destroyed."
Navigate - Generate free squares north, west, south and east of the caster, until they reach the edge of the dungeon. Message for opponent, if anything changes: "You hear rock being destroyed."
Create Potions - d3 potions appears in a random unoccupied empty squares of the dungeon. No message for opponent.
Blink - Moves the caster to a new unoccupied random position in the dungeon. No message for opponent.
Blink All - Moves everyone to new unoccupied positions. Message for opponent: "You are teleported!"
Scream - Creates a loud sonic boom that has a chance to destroy nearby potions on the ground, potions held by the caster and the opponent, if they are nearby. Message for opponent: "A loud magical scream can be heard" if neary or "A loud magical scream can be heard in the distance" if out of range. This spell is usually negative, unless used carefully.
Forgetfullness - Parts of the dungeon are forgotten for the caster. No message for opponent.
Acid Rain - Acid rains down on the caster and the 8 adjacent squares. (1 damage). Message for opponent: "You can hear rain."
The player can have up to 9 potions in their inventory. Pressing + then the potion number (1, 2, etc) will drink the potion.
Potions have random appearances. Five different potion types will be used in each game. These will be: yellow, blue, red, green and orange.
Once a potion has been used, all other potions of that type will be identified to the player.
The dungeon and initial player inventories will contain a random small selection of variations of potions from the entire selection, to increase the chance of the same potion appearing multiple times. This is to give players a bigger chance of knowing potions that they find.
Players start with 2 different identified potions, so those appearance types are automatically identified.
It would be incredibly useful to get someone to help me test this. Ideally, this should be arranged before the week starts and then happen on the sixth or seventh day, when the game is 95%+ complete.
When one player has their hit points reduced to 0 or below, they are dead. The other player wins.