Skip to content

Java Settlers GPLv3 source code. Migrated 2012-09-28 from CVS; project home (downloads, bug tracking, etc) still at sourceforge.

License

Notifications You must be signed in to change notification settings

lartkma/JSettlers2

 
 

Repository files navigation

README.developer - Notes and current status of 2013 JSettlers development
	(version 2.0.xx, beta server running at nand.net)
	http://nand.net/jsettlers/devel/
	http://sourceforge.net/projects/jsettlers2/
	https://github.com/jdmonin/JSettlers2

Scroll down a bit for the current TODO list.
See VERSIONS.txt for recent changes.

CONTENTS
--------
- Overall structure of the code and project
- Tips for debugging
- Setup instructions for JSettlers as an Eclipse project
	(although you may use any IDE you want)
- Build setup and output
- Current partially-done work
- Current TODO list
- Coding Style
- github usage


Overall Structure
-----------------
The main server class is soc.server.SOCServer.
The client communication is soc.client.SOCPlayerClient, and in-game interface is in soc.client.SOCPlayerInterface.
Game state is held at the server in soc.game.SOCGame and its fields.  Partial game state is known at clients.
Communication is described in soc.message.SOCMessage.
Robots talk with the server like normal human clients.
Most robot messages are per-game; instead of being handled in SOCRobotClient,
these are handled in a loop in SOCRobotBrain.run().
Game options and scenario rules are controlled through SOCGameOption; see initAllOptions javadoc for a list.
Options have flags for their properties ("hidden internal option", "drop if not set", etc).
All scenario-related game option keynames start with "_SC_", and provide special rules for the scenario.

Coding is done in Java 1.5, but should compile cleanly in newer JDKs.
(Before v2.0, we restricted ourselves to 1.4 for backwards compatibility.)
The build system is Ant, which is natively understood by Eclipse.  Use any IDE you want, including vi.
Use spaces, not tabs.  Please try to keep the other conventions of the code already there.
(See "Coding Style" below for more details.)

When adding new methods or fields, describe them in javadoc, including the @since marker
and the one-sentence summary (even though some old methods don't have that summary).

When submitting patches, please use unified diff (-ur) format.

For more information about the AI, please see Robert S Thomas' dissertation.
For more information about the board coordinates, see the dissertation appendix A,
or javadocs in soc.game.SOCBoard, and src/docs/hexcoord.gif and hexcoord-6player.gif.

The client's structure was refactored in 2.0 by Paul Bilnoski.  Paul's description of this work:
Added two major new pieces of API: PlayerClientListener and GameDisplay. These are spliced between the
SOCPlayerClient and AWT UI code, primarily found in SOCPlayerInterface. The APIs are used by the player client
abstract network communication away from the UI - to communicate with the UI about network events received and
receive events to send to the server. Some of it is done using inner classes and interfaces which should be
split out into an improved package structure.


Tips for Debugging
------------------
You can use debug commands in any practice game, by typing into the game chat
textfield.  Type *help* for a list of commands.
(If you need to use debug commands over a network connection, start that server
 with -Djsettlers.allow.debug=Y and connect with username debug.  For security,
 please use sqlite or another database, and make a "debug" account with a password.
 See README.txt section "Database Setup".)

If you want to inspect the game object state at the server or robot:
	Set a breakpoint at SOCServer.processDebugCommand, or at "case SOCMessage.GAMETEXTMSG"
	  send a text msg from a client (the chat textfield), and inspect the game obj at that point
	To inspect game state at robot, breakpoint robotcli.treat and send a text msg like *BOTLIST* or robot2:current-plans
	On Linux/Unix JVMs, you can print a stack trace / thread dump to the shell by sending SIGQUIT.

Some game options are meant to be set by the server during game creation,
not requested by the client.  Their option keynames all start with '_'.
(These are used for game scenario rules.)  The New Game Options frame normally
hides them during game setup.  If you want to show them:
	Launch the client
	Start a Server, or Join a Server
	In the Nickname field, type: debug
	Click Practice or New Game
The values you set may still be overridden by the server in SOCGameOption.adjustOptionsToKnown.

To use the "Free Placement" debug mode, type this debug command on your turn:
	*FREEPLACE* 1
You can now build and place pieces without consuming resources, by clicking
or right-clicking on the board.  (Don't use the "Buy" buttons for Free Placement.)
The placements must follow game rules, except that they cost no resources.
To place for another player, click their face icon.  You cannot remove a piece
once it is placed.

The placed pieces accumulate victory points for their players as normal, and
Longest Road is tracked.  If a player gets 10 VP total, the game will be over
when their turn arrives; your own player would win the game immediately.

To exit Free Placement mode, either click "Done" (which will end your turn) or
type this debug command:
	*FREEPLACE* 0
When exiting Free Placement mode during initial placement, all players must have
either 1 settlement and road, or at least 2 settlements and roads.  This allows
the game setup routines to work properly during this debug mode.  The current
player will be set to the first player (if 2+ settlements/roads placed) or the
last player (1 settlement placed).


Setup instructions for JSettlers as an Eclipse project
------------------------------------------------------
  (written for Eclipse 3.6, should be applicable to other versions with minor changes)

- choose File -> New -> Project... -> Java Project from Existing Ant Buildfile.
- Browse to jsettlers-1.1.xx-src/build.xml, select the "javac" task in target "compile".
  Check "Link to the buildfile in the file system", hit Finish.
- Project -> Properties: Resource: Text file encoding: UTF-8
- You'll need to build once before you run it, to create version.info from resources/version.info.in.

Continue reading to see how to set up the builds and the coding style in Eclipse.


Build Setup and Output
----------------------
Before building, make sure you have the Java Development Kit version 5 or later.
If you simply want to run the client and server, you only need the Java Runtime (JRE).
If you wish to maintain a user database for your server, you need MySQL or PostgreSQL
installed and configured, or the sqlite jdbc driver for a file-based local database.

This package was designed to build with eclipse, or with the ANT tool available
from http://ant.apache.org tools.  We assume you have installed it correctly.

Check the "build.properties" file. There may be build variables you
may want to change locally. These can also be changed from the command
line if calling ant that way, by passing a "-Dname=value" parameter.

There are several build targets, here are the most useful ones:

 build      Create project jar files. (default)
 clean      Cleans the project of all generated files
 compile    Compile class files into "target/classes"
 dist       Build distribution tarballs and zips.
 javadoc    Creates JavaDoc files in "target/docs/api"
 src        Create a tarball of the source tree

All files created by building are in the "target" directory, including
JARs, Java .class files, and JavaDoc files. Distribution tarballs, zip
files, and installation files are placed in "dist".


Recommended debug/run configurations for testing
------------------------------------------------
  In my Eclipse project, I've created these debug/run configurations:

Java applet: soc.client.SOCPlayerClient$SOCApplet
   width 600, height 340
   parameters: PORT = 8880

Java applications:
  cli-noargs  soc.client.SOCPlayerClient
  socserver   soc.server.SOCServer
     arguments: -o NT=t -o PL=5 -Djsettlers.startrobots=7 -Djsettlers.client.maxcreategames=2
                -Djsettlers.allow.debug=Y 8880 20 dbuser dbpass
  socserver-sqlite  soc.server.SOCServer
     arguments: -o NT=t -o NT=y -Djsettlers.db.url=jdbc:sqlite:jsettlers.sqlite  -Djsettlers.startrobots=7
                -Djsettlers.allow.debug=Y 8880 20 dbuser dbpass

  The server will start 7 bots with the above configuration.  If you need to stop and start your
  own bots, then add
		-Djsettlers.bots.cookie=cook
  to the server configuration arguments, and create these Java application configs:
  robot1      soc.robot.SOCRobotClient
     arguments: localhost 8880 robot1 r1 cook
  robot2      soc.robot.SOCRobotClient
     arguments: localhost 8880 robot2 r2 cook


If you want to configure a sqlite database for testing
------------------------------------------------------
  These instructions are written for Eclipse 3.6.
  JSettlers+sqlite works with standard Eclipse; the j2ee eclipse also has a convenient data browser.
  Note that README.txt mentions a command-line option -Djsettlers.db.jar=driverfile.jar ; that's
  needed only while running the jsettlers JAR from the command line, not running inside eclipse.

  - See the "socserver-sqlite" line just above for the server command line;
	this is an eclipse Run Configuration for a jsettlers server which
	includes the sqlite database you're about to configure.

  - Download the driver from https://bitbucket.org/xerial/sqlite-jdbc

  - Eclipse menu -> prefs -> data mgmt -> connectivity -> driver definitions -> add
	  [this menu path will be available only under eclipse j2ee, not the basic eclipse]
	  select SQLite JDBC Driver
	  jar list -> edit (or add,if empty) -> navigate to sqlite-jdbc-3.7.2.jar -> OK

  - Project build path: libraries: include sqlite-jdbc-3.7.2.jar here too

  - Build the project (from build.xml; creates target/classes/resources/version.info)

  - Run socserver once to create the db file and exit cleanly:
	run configurations
	  main class: soc.server.SOCServer
	  program arguments: -Djsettlers.db.url=jdbc:sqlite:jsettlers.sqlite  -Djsettlers.db.script.setup=../src/bin/sql/jsettlers-tables.sql
	  working directory: filesystem: JSettlers2/target
	If sqlite crashes on launch, retry with -Dsqlite.purejava=true
	This line should appear in the console:
	Setup script was successful. Exiting now.

  - Add the database to eclipse j2ee, so you can add tables and query it:
	[skip this if your eclipse is not j2ee]
	Window -> show view -> other... -> data mgmt -> data source explorer
	Right-click Database Connections, choose New
	  Type: SQLite ; give a description and click Next
	  Browse to jsettlers.sqlite
		(it's most likely in your workspace, or the server's working directory)
	  Click "Test Connection"
	  Click Finish

  - Run the "socserver-sqlite" configuration
	  main class: soc.server.SOCServer
	  program arguments: -Djsettlers.db.url=jdbc:sqlite:jsettlers.sqlite  8880 20 dbs dbp
	  working directory: filesystem: JSettlers2/target
	This line should appear in the console:
	User database initialized.

  - The database is now ready for use, development, and debugging.
	To create player users, see README.txt and use SOCAccountClient.


Current partially-done work
---------------------------
	- Refactor SOCMessage classes to use templates
	- Some SOCMessage classes (SOCGames, SOCJoinGameRequest) accept objects like SOCGame and parse/create them;
	    over-the-network communication will always be strings only.


Current TODO list
-----------------
	Work on these items has not yet begun.
	This list is ranked from easier, to more difficult.
	You can also search the source for TODO for ideas.

	- User documentation is out of date; unsure if any user ever reads it anyway
	- Visual reminder to player when they've made a trade offer
	- Show # VP when choosing where to sit, if game is in progress
	- Keyboard shortcuts for "roll", "done" buttons
	- Occasionally an image does not re-scale when board is stretched.
		Instead of giving up (SOCBoardPanel.scaledHexFail, etc),
		try re-scaling again, but increase width or height by 1 pixel.
	- Kick robots if inactive but current player in game, assume they're buggy (use forceEndTurn)
	- Control the speed of robots in practice
		Adjust SOCRobotBrain.pause, ROBOT_FORCE_ENDTURN_TRADEOFFER_SECONDS, etc
	- Sound effects
	- Property to require an account (user/password) in database in order to connect
	- Properties for game option defaults for server startup
		-Djsettlers.game.N7=y  instead of -O N7=y
		allow lowercase too
		probably best done at bottom of SOCServer.parseCmdline_DashedArgs
	- Possible: Auto-add robots when needed as server runs, with server active-game count
		only do it if jsettlers.startrobots property is set
	- Refactor SOCRobotClient: Move simple handle-methods which don't
		put the message into brainQ, but only update game fields/
		methods, into SOCDisplayless if possible.
	- Refactor: SOCGameOption static methods to check and change values within a set
	- refactor: name of dev-cards consolidate
	- refactor: resource-type constants consolidate somewhere (Clay, Wheat, etc)
		current SOCResourceConstants.CLAY vs SOCPlayerElement.CLAY
	- At board reset, game observers not currently handled properly
	- Property for read-only database use without errors
	- Game "owner" with extra powers (kick out player, etc)
		What happens if owner loses connection?
	- Customize bot names (txt file or startup property) in srv.setupLocalRobots
	- Server-side storage of options between runs (config file, sqlite db, etc)
	- "Hot seat" mode (multiple human players sharing a screen on 1 client)
	- Per-game thread/message queue at server (use SOCMessageForGame.getGame)
	- Cities & Knights support
		- UI mock-ups
		- state change / network message plans
		- robot support
	- Refactor: combine the cli/displayless/robot endturn-like methods
		ex. search for ga.setCurrentDice(0), or newToOld, or ga.resetVoteClear



Coding Style
------------
Scroll down a bit if you just want to see how to set up the style in Eclipse.

This is the project's coding style, based on the original authors' style.
Although we may not agree with every detail of it, for consistency's sake,
please keep the conventions of the code that's already there.

Use spaces, not tabs.  The basic indent is 4.  Place braces on their own line.
Lines should be less than about 120 characters long; if you have to indent too
much, consider refactoring into a new method.

Use 1 blank line between methods.  If you have nested classes, use 3 blank 
lines between them, and comment each one's closing brace with the class name.
If you have a long method whose work can be divided into "sections",
preface each section with a /** javadoc-style */ multi-line comment.

If a declaration line is getting too long (about 120 characters), break it
and indent it slightly from the first line, not aligned with the method name.
Throws declarations are also always indented on the next line:
    public SOCGameOption(String key, int minVers, int lastModVers,
        boolean defaultValue, boolean dropIfUnused, String desc)
        throws IllegalArgumentException
If related methods have the same name but different sets of arguments, indent
all their declarations the same way for easier comparison.

Some methods return in the middle of their body, depending on conditions.
That kind of early return should be marked with a prominent comment such as:
	return;   // <--- Early return: Temporary piece ---

Some methods end with this style of code:
	if (x)
	    return y;
	else
	    return z;
In those cases, the return is part of the logical flow of the if-statement:
Both y and z are normal and valid, and deserve equal "visual weight" and indenting.
That section of code should not be reformatted to something like:
	if (x)
	    return y;
	return z;
because conventionally in jsettlers, that would mean z is the usual case
and y is less common or is an edge condition.

In emacs, you can place this in your .emacs file to use spaces instead of tabs:
(setq-default c-basic-offset 4)
(setq indent-tabs-mode nil)
	[ courtesy http://www.jwz.org/doc/tabs-vs-spaces.html, which also mentions vi ]
You will also want this to have this, which disables auto-reindenting:
(setq-default c-electric-flag nil)


Here's how to set up the coding style in Eclipse:

	preferences -> general -> editors -> text editors:
	[x] insert spaces for tabs
	displayed tab width: 8
	[x] show print margin
	print margin column: 120

	project properties -> java compiler -> configure workspace settings
	  compiler compliance level: 1.5

	prefs -> java -> code style -> formatter
		Click "Enable Project Specific Settings", then New
		{
		Profile name: 'jsettlers'
		"based on Eclipse built-in standard"
		[X] Open the edit dialog now

		(Indentation)
		Tab policy: Spaces only
		Indentation: 4
		Tab size: 8
		confirm is unchecked: [ ] Indent empty lines

		(Brace positions)
		All 'next line' except:
		Blocks in case stmt: Next line indented
		Array init: Next line indented
		[X] Keep empty array initializer on one line

		(Control Statements)
		[X] New line before else in if
		[X] New line before catch in try
		[X] New line before finally in try
		[ ] New line before while in do
		[X] Keep 'else if' on one line
		[ ] (all other options)

		(All other tabs)
		Take defaults

		}

		Hit OK
		Make sure the formatter "active profile" is jsettlers
		restart eclipse

		go to prefs -> java -> code style -> formatter
		  if it's not active: set active profile to jsettlers & restart eclipse

		prefs -> java -> editor -> typing
			Verify tab 8 spaces, indent 4 spaces:
	   [x] Tab key adjusts indentation of current line
	   "The tab display value (currently 8) and whether spaces are used to indent lines
	    are configured on the formatter preference page.  The current indentation size
	    is 4, using spaces."

When you hit enter and insert a new line in Eclipse, watch the whitespace, it
will add whitespace to the blank line to match the current indent.

If desired, in Eclipse preferences, you can bind a key combination to Remove Trailing Whitespace.
This will trim it from the entire file when the key is pressed.

To manually clean up trailing whitespace:
Eclipse preferences -> general -> editors -> text editors -> [x] Show whitespace characters
Find/Replace: Regular expressions: Find [\t ]+$

The rotated 3:1 port hexes' font is Optima Bold, 21 pt.


github
------
The project code lives at https://github.com/jdmonin/JSettlers2 .
Patches can be sent by email or by pull request.
Please make sure your patch follows the project coding style.

The master branch receives new features and enhancements for next 'minor'
release.  As soon as a bug is fixed or a feature's design is fairly stable, it
should be committed to master.

The master branch has new 2.0.xx development.  Until 2.0.00 is ready,
there's an old-1.1.xx branch in case of urgent bugfixes, so we can release
new stable versions.  Most work on 1.1.xx is backported from 2.0; changeset
comments often mention a hash from a master commit.  Version 2.0.00 was
split off right after releasing version 1.1.13.

Once 2.0.00 is out, we'll follow the usual jsettlers model:
There are no branches, because jsettlers2 is mature at this point.
Each minor release is a stable release, there is no experimental branch.

Each release's files are tagged for the release ("release-1.1.14").
The last commit for the release updates VERSIONS.txt with the final build number,
with a commit message like: Version 1.1.14 is build OV20120930
Then: git tag -a release-1.1.14 -m 'Version 1.1.14 is build OV20120930'

You can also see an overview of commit comments in the git log
histories of src/java/resources/version.info.in and VERSIONS.txt.

The github repo includes the full JSettlers2 CVS history formerly hosted at
http://sourceforge.net/projects/jsettlers2/develop through 2012-09-28.
The old old source history from Robert S Thomas (2004-2005) can be found at
http://sourceforge.net/projects/jsettlers/develop .

About

Java Settlers GPLv3 source code. Migrated 2012-09-28 from CVS; project home (downloads, bug tracking, etc) still at sourceforge.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 100.0%