Menu

Tree [e564b5] master /
 History

HTTPS access


File Date Author Commit
 .gitignore 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 AUTHORS 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 INSTALL 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 Makefile 2004-10-16 efalk efalk [9711c3] removed test programs
 README 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 TODO 2004-10-17 efalk efalk [d9d6ec] Notes about the monolith and hidden surfaces
 annunciators.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 autopilot.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 blast.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 blast_line0.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 blast_line1.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 bsp_object.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 bsp_utils.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 build_bsp.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 control.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 control_robot.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 control_ship.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 create_eship.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 create_monolith.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 create_planet.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 cursor1.pr 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 cursor2.pr 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 draw_bsp_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 draw_hsi_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 draw_image_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 draw_objects_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 draw_starfield_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 dstar.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 dstar.h 2004-10-17 efalk efalk [2e02ad] Fixed bug in robot that prevented it from updat...
 dstar.lsm 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 dstar.spec 2004-10-17 efalk efalk [8d5dd5] Bumped release.
 fighter.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 fighter1_bsp.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 fighter1_line.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 fighter2_bsp.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 fighter2_line.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 graphics.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 graphics_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 hsi.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 laser.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 line_object.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 master.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 matrix.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 missile.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 missile_control.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 missile_line.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 monolith_bsp.h 2004-10-17 efalk efalk [403952] made ends darker
 netio.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 netio.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 object_types.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 panel.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 parameters.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 planet1.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 planet2.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 radar.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 ringworld.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 ringworld_gfx.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 robot_special.c 2004-10-17 efalk efalk [2e02ad] Fixed bug in robot that prevented it from updat...
 small_moon.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 small_moon_gfx.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 special_gl.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 starfield.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 static.c 2004-10-16 efalk efalk [55ab7e] *** empty log message ***
 types.h 2004-10-16 efalk efalk [55ab7e] *** empty log message ***

Read Me

	$Id$
	(from: @(#)README 1.1 92/05/28 SMI)

"dstar" is a multi-player network 3-d video game.  In dstar, you are
the pilot of a spaceship armed with lasers and missiles.  You have the
pilot's-eye view out of the spaceship's front window.  Other people
playing the game on their workstations are playing in the same "space"
as you are.  Everybody sees everybody else in the game.  You fly up to
other spaceships and shoot them with your laser or launch rockets at
them.  Obviously, they want to do the same to you.

(WARNING: This is a horrible, militaristic, fascist, violent game.  It
desensitizes you from the brutal reality of warfare and acts as a
blatant propaganda tool for high-tech weaponry and the militarization
of space.  So sue me.)

This is the source code to the game "dstar".  Dstar is not complete by
any stretch of the imagination.  If you make any bug fixes/extensions
to the game, or even think of new features you'd like to see, please
send them back to me at

	efalk@sourceforge.net

so I can incorporate them into the game.  There's a "to do" list at the
end of this README file.












HOW TO RUN:

To simply run dstar, type

% dstar

If you are the first player, dstar will spend about 5 seconds looking
for other players.  If it doesn't find any, it assumes that you are
the first player in the game.  It's a good idea to use a robot as the
first player in the game (see below.)

Dstar uses broadcast packets to locate players playing on your local
net.  If you want to join a game running on a different network, type

% dstar <hostname>

where <hostname> is the name of any machine playing dstar.


To control the spaceship, move the cursor near the center of the screen
and click the left mouse button.  The cursor will change from an arrow
to an aiming box.  At this point, the cursor steers the ship; moving it
away from the center of the screen starts turning the ship in that
direction.  The further you move the cursor, the faster the ship
turns.

If you click the left mouse button again, the cursor returns to being
an arrow and the ship stops turning.

The <TODO> buttons roll the ship left and right along its axis.  This has
almost no utility, but can help you navigate sometimes.

To fire the lasers, press and hold the right button.  The lasers can
fire indefinately, but firing them makes you easier to see from a
distance.  The lasers fire in the direction indicated by the cursor.
The lasers have a limited range, and the target has to be quite close
in order to shoot it.

To turn the radar on, press 'r'.  The center of the screen changes from
blue to yellow or red.  Yellow indicates that the radar is on, red
indicates that the radar is on and is locked on a target.  The center
of the screen will switch back and forth between yellow and red as you
acquire and lose targets.  When you have a radar lock on someone, that
person will be alerted, so use radar sparingly.  The radar locks on the
nearest object within a certain range and near the center of the
screen.  Once the radar locks on a target, it stays locked on that
target until the target either leaves the radar's range, leaves the area
near the center of the screen or is destroyed.  Other objects coming
into range will not confuse the radar.  Pressing 'r' again will turn
the radar back off.

The tab key will cycle between targets within the radar's range.

To turn the auto pilot on, press 'a'.  When the auto pilot is on, it
will chase whatever the radar has locked onto.  If the radar is not
locked onto a target, the auto pilot will fly lazy circles.  If you
press 'A' instead of 'a', you get the "agressive" auto pilot which will
shoot the target if it comes within range.  Pressing 'a' again will
turn the auto pilot back off.  Note that the auto pilot is rarely as
good at flying or shooting as a human is, so don't think you'll win the
game on automatic.  When autopilot is on, the left mouse button switches
between manual control and autopilot, rather than flying straight.

To arm a missile, press 'q' or F2.  You cannot launch a missile until
you've armed it.  If you have more than a certain number (currently
eight) of missiles launched at the same time, you will not be able to
arm another.

To launch a missile, press 'w' or F3.  The missile will chase whatever
the radar is locked onto.  If the radar is not locked (or is not on),
the missile will fly in a straight line.  Missiles launched without
radar lock are harmless and just fly until they run out of fuel.
Missiles travel three times as fast as spaceships and last 15 seconds.
Missiles are not very maneuverable and can be dodged if you see them
coming.  Missiles launched from too far away will run out of steam before
hitting their target.  Missiles launched from too close will fly past
their targets before they can stabalize on course unless you have the
target right in the center of the screen when you launch.  Once a missile
loses its target, it flies harmlessly in circles until it times out.



THE ROBOT:

The robot is a simple fighter program that flies around in circles
and can be used for target practice, etc.  The robot is not a graphics
program and can thus be run from any system on the net.


to run:

% dstar-robot [-auto] [hostname]

Hostname is used for linking the robot to a game in progress on a
different sub-net.  This is the same as the hostname argument to dstar.

The -auto flag turns on the robot's auto-pilot.  The robot will chase
and attack anything that comes within the (narrow) view of its radar.




HINTS:

Run the robot first.  The first player (the master) has extra work
to do, so you may as well let the robot do it.  Also, there are
certain bugs that occur when players enter and leave the game frequently
these are mostly eliminated if the master is a robot.

All ships fly at the same speed; if someone is flying away from you,
you can't possibly catch them.  If they're not too far away, a missile
will get them, otherwise you'll have to wait for them to turn around
and come back.

If someone (or something) is flying in a constant circle, you can catch
up to them by getting behind them and then flying a tighter circle than
they are flying; since your speeds are the same, you'll catch up on the
inside.  If you fly to keep your quarry in the center of your screen,
you're flying almost the exact same circle they are and you'll never
catch up.  Instead, figure out which way they're turning (not hard to
do) and turn a little tighter than they're turning.  Keep the image of
the other ship about halfway between the center and the edge of the
screen.  For instance, if you're chasing a ship making a constant turn
to the right, keep it in the left half of your screen:

	+-------------------------------+
	|				|
	|				|
	|	    +-------+		|
	|	    |   |   |		|
	|    X-	    |-     -|		|
	|	    |   |   |		|
	|	    +-------+		|
	|				|
	|				|
	+-------------------------------+
	     ^
	     enemy ship, turning to the right.

When fighting someone head to head, you usually both lose.  Using
the agressive autopilot in this situation almost guarantees that you
won't miss unless your opponent is good at dogfighting, in which case
the autopilot will probably get you killed.  Various tricks may be
tried when in a head-to-head situation: wiggling back and forth or
spiraling may make it difficult for your opponent to aim at you.  You
might try waiting until just before you come within range and then
doing a tight (but not too tight) 360-degree turn.  This can be
very effective if done right since it causes your opponent to lose
sight of you and you usually come back behind them for an easy shot.

Robots make good bait.  Put a couple of robots into a game, and from
time to time someone will chase one thinking it's another player.  When
you see this happening, fall in behind and get them while they're
chasing the robot.  Sometimes whole convoys of players line up behind a
robot.  If you're lucky, you can come up behind this convoy and pick
off all the members one by one.  Caution: when you're chasing
people this way, count the number of players ahead of you.  If you
can't account for all the players in the game, there's a good chance
that someone's behind you.







INTERNAL NOTES FOR DEVELOPERS:

Networking:

Unlike mazewar or spacewar, dstar does not require a daemon to keep things
synchronized.  Instead, when the game starts up it sends out a broadcast
packet onto the local net.  If there is no answer for five seconds, the
program assumes that it is the first player in the game.  In this case,
the program becomes "master" and takes on the duties that would have
been assigned to a daemon otherwise.

There are three networking roles the program can take: Master, Submaster
or Slave.  The Master is the program that coordinates all communications
in the game.  Id numbers and missile ids are assigned by the master; in
short, the master's job is to act as a clearing house to keep all the
other players in touch with each other.  Initially, the master is the
first program to come up on the net, but this task can be re-assigned
to another program if the master leaves the game.

Submasters are programs that were the first to come up on the local
net.  Their job is to acts as relays between subnets.  When a new program
comes up and sends out the initial broadcast packet, the submaster
catches this broadcast and forwards it to the master.  The job of
being submaster can also be re-assigned as players leave the game.

A Slave is any program that is not master or submaster.  If a program
comes up and there is already a submaster on the local network, then
the program is a slave.  Slaves are not really "slaved" to any other
program, they are really clients with the master providing the service
of assigning id's etc..

Communications in the game are in the form of UDP "datagram" packets
sent directly from player to player.  These packets contain things like
requests to join the game, status updates, scoring information etc.
Internet addressing is used.

All networking code is contained in "netio.c".  This file contains two
kinds of subroutines, routines called from within the program to send
data over the net and routines called asynchronously by the notifier
when a message arrives.

Outgoing messages are queued internally to save network bandwidth.  The
queue is flushed whenever the intended recipient changes or when
net_flush() is called.

Here is how the game is run, a complete description of the individual
message packets are built can be found in h/netio.h:

When the program starts up, it calls init_netio which broadcasts a
NET_JOINING message to the local net.  This message asks the master to
give the game an id number and a list of other players in the game.  If
the game was started with the command "dstar <hostname>", the
NET_JOINING message is wrapped in a NET_BROADCAST message (see below)
and sent directly to the named host instead of being broadcast.

If there is no answer for five seconds, the program assumes that there
are no other players and becomes the master (assigning itself id # 0).

When the master receives a NET_JOINING message, it assigns an id number
to the new player and sends a NET_WELCOME message informing the new
player of its id number, team (not implemented yet) and other
information.  This is followed by NET_CURRENT_STATUS packets for all of
the other players in the game.  The new player is now in the game.

If the master does not hear from a player for 30 seconds, it sends a
NET_ARE_YOU_THERE packet to make sure the player is still active.  If
the master still has not heard from the player for 60 seconds, it sends
a NET_DIED packet to all of the other players informing them that the
player has left the game.

If a player or one of its missiles leaves the game, it sends out a
NET_DIED message to all of the other players.

If a player shoots something, it sends a NET_JUST_SCORED message out to
let everybody know about it.  If the destroyed object is a missile, the
owner of that missile will then send out a NET_DIED message to remove
the missile from the game.

All players periodically send out NET_CURRENT_STATUS packets to let all
the other players know its current status.  NET_CURRENT_STATUS packets
are also sent out on behalf of all of the player's missiles.  The
master periodically sends out a NET_CURRENT_STATUS on all of the static
objects in the game to keep them synchronized (not yet implemented).

When a player arms a missile, it sends a NET_REQUEST_MISSILE packet to
the master.  This is similar to a NET_JOINING packet.  The master will
assign an id number to the missile and return a NET_MISSILE packet to
the requesting player.

If any player receives a NET_BROADCAST packet, it rebroadcasts the
contents of the packet onto the local net.  This is used when programs
are joining games on other subnets and for reducing net bandwidth (see
below).

Broadcasting messages to all the players in the game can be a tricky
business.  When there are a small number of players, each player sends
status packets directly to all of the other players in the game.  This
means that net bandwidth goes up with the square of the number of
players.  This is avoided with a "netlist" mechanism:

The game maintains a list of players sorted by the subnets on which
they reside.  When the game wants to send a message to all of the other
players, it calls the routine "broadcast".  Broadcast goes through the
list of subnets in the game.  For each subnet, broadcast checks the
number of players on that subnet.  If this number is less than
BROADCAST_THRESH (currently 4), individual transmissions are made. 
If the number of players is greater than BROADCAST_THRESH and it is
the local network being examined, then a broadcast packet is sent to
the local network.  If the number of players is greater than
BROADCAST_THRESH and they are on a different subnet, then the entire
message is wrapped in a NET_BROADCAST packet and sent to the submaster
of that net.  The submaster will then rebroadcast the packet.

The net lists are re-computed every time a player enters or leaves the
game.  Static objects and missiles are not included in the lists.



Status block description:

The game maintains a block of data for every object.  This block
contains the following information (for more info, see h/object_types.h)

id		object id, assigned by master
name		object's name, assigned by object or object's owner
team		object's team for players (not implemented), object's
		owner for missiles and static object.
score		score (not implemented)
status		object's type: OBJ_EMPTY=empty slot in status block array,
		OBJ_SLEEPING=player who has closed the window, OBJ_DEAD=
		player who has just been shot, OBJ_STATIC=planets and
		things, OBJ_MISSILE=missile.
flags		flag word, indicates lasers or radar on.
Posn		object's position in 3-space
Forward,	three normalized normal vectors describing object's
Up, Right	orientation.  These three vectors plus Posn describe
		a 4x4 transformation matrix to convert object modelling
		coords to world coords and back.
Delta		vector in object modelling coords describing control
		inputs.  Delta plus Speed can be used to calculate
		object's position over time.
Pointing	vector describing the direction the object is "looking".
		indicates where the laser beam is.
Speed		Objects speed.  Currently fixed at 25.0 units/sec.
target		object radar is locked onto.
time		used for missiles etc.
description	index into table describing objects visual appearance.
address		object's (or object's owner's) internet address
sequence	data packet sequence number, not currently checked.
last_rep	time of last status report from object; used by master
		to detect dead players.
net_addr	first three bytes of object's internet address -- used
		as subnet id.
net_status	MASTER, SUBMASTER or SLAVE.
net_next	link to next player in this netlist.
net_num		number of players in this netlist.



Header Files:

  dstar.h		General declarations used everywhere
  parameters.h		Compile-time parameters
  types.h		Common types.
  object_types.h	Describe objects in the game.
  graphics.h		Graphics definitions
  bsp_object.h		Describe a node in a BSP tree
  line_object.h		Describe a point in a line drawing */
  netio.h		networking-related definitions

  blast_line0.h		Data to describe a line-drawing of an explosion
  blast_line1.h		Data to describe a line-drawing of an explosion
  fighter1_bsp.h	Data to describe one fighter
  fighter1_line.h	Data to describe the line drawing of a fighter
  fighter2_bsp.h	Data to describe fighter type 2
  fighter2_line.h	Data to describe the line drawing of a fighter
  missile_line.h	Data to describe a missile
  monolith_bsp.h	Monolith
  planet1.h		planet
  planet2.h		planet
  starfield.h		stars

  hsi.h			Head-up display data



general files:

dstar.c		- main program, used by all programs
control.c	- routines useful for controlling object behavior
netio.c		- communications routines
laser.c		- tests to see if a laser hit a target
prioritizer.c	- special prioritizer for the notifier


files that vary from program to program:

special.c	- routines specific to this program
control_ship.c	- routine to control this ship


files used for the fighter only

create_eship.c	- build enemy fighter image
blast.c		- build explosion image
draw_image.c	- draw the image on the screen
draw_hsi.c	- draw the hsi
draw_starfield.c - draw the star field
draw_objects.c	- draw all objects in list
draw_bsp.c	- draw a bsp tree



routines provided in special.c:

init_me()		- initialize ships position, state etc.  Called once
				at startup

init_game_graphics(&argc,argv)
			- initializes graphics (if any).  Called once at startup

init_communications()	- open communications.

dstar_main_loop()	- start the game

terminate_game()	- called from sigint handler to finish the game

normal_action()		- called once per time slice when state = OBJ_ACTIVE

blast_action()		- called once per time slice when state = OBJ_DEAD

set_blast_state(state)	- called once per state change when state = OBJ_DEAD