Liquid War 6, a unique multiplayer wargame.
1 Introduction
1.1 In a nutshell
1.2 Project status
1.2.1 What works, and what does not (yet)
1.2.2 What has changed since Liquid War 5.x?
1.2.3 Revision history
1.2.4 Road map
1.3 How you can help
1.3.1 Help GNU
1.3.2 Todo list
2 User's manual
2.1 Mailing lists
2.1.1 General discussion
2.1.2 Announcements
2.1.3 Bugs
2.1.4 IRC channel
2.2 Getting the game
2.2.1 Download source
2.2.2 Download binaries
2.2.3 GIT repository
2.2.4 Daily snapshots
2.2.5 Check integrity
2.3 Installation
2.3.1 Requirements
2.3.2 Optional libraries
2.3.3 Optional tools
2.3.4 Installing requirements using RPM/DEB packages
2.3.5 Compiling
2.4 Extra maps
2.4.1 The extra maps package
2.4.2 Install extra maps on GNU/Linux and POSIX systems
2.4.3 Raw install of extra maps (all-platforms)
2.5 Troubleshooting
2.5.1 Compilation problems
2.5.2 Check installation
2.5.3 Problems running the game
2.6 Quick start
2.6.1 Quick start
2.7 Strategy tips
2.8 User interface
2.8.1 A reduced set of keys
2.8.2 Combining mouse, keyboard and joysticks
2.8.3 Quit with F10
2.9 Solo game
2.9.1 Current state
2.9.2 Team profiles
2.9.3 Weapons
2.10 Network games
2.10.1 Choose your "public url"
2.10.2 Starting a node
2.10.3 Connecting to a node
2.10.4 Communities
2.10.5 Firewall settings
2.10.6 Is the game secure?
2.11 Graphics
2.11.1 Standard, high and low resolution
2.11.2 Display rate
2.12 Sound & music
2.12.1 Current status
2.12.2 The future
2.13 Config file
2.14 Logs
2.15 Report bugs
3 Hacker's guide
3.1 Designing levels
3.1.1 Why is level design so important?
3.1.2 Format overview
3.1.3 Resolution (map size)
3.1.4 Metadata
3.1.5 map.png
3.1.6 layer2.png ... layer7.png
3.1.7 texture.png, texture.jpeg and texture-alpha.jpeg
3.1.8 glue.png and boost.png
3.1.9 danger.png and medicine.png
3.1.10 one-way-.png
3.1.11 cursor.png and cursor-color.png
3.1.12 rules.xml
3.1.13 hints.xml
3.1.14 style.xml
3.1.15 teams.xml
3.1.16 Resampling
3.1.17 Music
3.1.18 Experience ("exp")
3.2 Translating
3.2.1 Using gettext
3.2.2 Formatted strings
3.2.3 Partial translation
3.3 Architecture
3.3.1 C + Guile
3.3.2 Threading and SMP
3.3.3 Internal libraries
3.4 Memory structures
3.5 100% predictable algorithm
3.6 Graphics backends
3.6.1 Modularity
3.6.2 List of backends
3.6.3 How to write a new backend
3.7 Core algorithm
3.7.1 Introduction
3.7.2 Level, game struct, game state and pilot
3.7.3 Getting informations about where fighters are
3.8 Compilation tips
3.8.1 Advanced ./configure options
3.8.2 Debian packages
3.8.3 Red Hat packages
3.8.4 Microsoft Windows msys/mingw32 port
3.8.5 Mac OS X port
3.8.6 GP2X port
3.9 Coding guidelines
3.9.1 Project goals reminder
3.9.2 Common sense
3.9.3 Unitary tests
3.9.4 Memory allocation
3.9.5 Private and public interfaces
3.9.6 Commit policy
3.9.7 Audit the code
3.10 Using the console
3.11 Advanced tweaking
3.11.1 Hacking ressources
3.11.2 Optimize for speed
3.12 Writing modules
3.13 Use as a library
3.14 Network protocol
3.14.1 No server, no client, only nodes
3.14.2 Out of band messages
3.14.3 Regular messages overview
3.14.4 Regular control messages
3.14.5 Regular MISS messages
3.14.6 Regular META messages
3.14.7 Regular DATA messages
3.14.8 Other raw technical stuff (WIP)
3.15 Technical HOWTOs
3.15.1 Release check-list
3.15.2 Add a new option
3.15.3 Add a new internal library
3.15.4 Add a new module
3.16 Using GNU Arch
3.16.1 About GNU Arch
3.16.2 Getting the latest version from the repository
3.16.3 Setting up your own arch repository
3.16.4 Synchronizing your repository with upstream releases
3.16.5 Submitting patches
3.16.6 Recover from broken lock
3.17 Using GIT
3.17.1 About GIT
3.17.2 Getting the latest source
3.17.3 Developper access
3.17.4 Submitting patches
3.18 Jenkins builds
4 Reference
4.1 Basic options
4.1.1 about
4.1.2 audit
4.1.3 copyright
4.1.4 credits
4.1.5 debug
4.1.6 defaults
4.1.7 help
4.1.8 host
4.1.9 list
4.1.10 modules
4.1.11 pedigree
4.1.12 test
4.1.13 version
4.2 Doc options
4.2.1 example-hints-xml
4.2.2 example-rules-xml
4.2.3 example-style-xml
4.2.4 example-teams-xml
4.2.5 list-advanced
4.2.6 list-aliases
4.2.7 list-doc
4.2.8 list-funcs
4.2.9 list-graphics
4.2.10 list-hooks
4.2.11 list-input
4.2.12 list-map
4.2.13 list-map-hints
4.2.14 list-map-rules
4.2.15 list-map-style
4.2.16 list-map-teams
4.2.17 list-network
4.2.18 list-path
4.2.19 list-players
4.2.20 list-quick
4.2.21 list-show
4.2.22 list-sound
4.2.23 list-team-colors
4.2.24 list-weapons
4.3 Show options
4.3.1 show-build-abs-srcdir
4.3.2 show-build-bin-id
4.3.3 show-build-bugs-url
4.3.4 show-build-cflags
4.3.5 show-build-codename
4.3.6 show-build-configure-args
4.3.7 show-build-copyright
4.3.8 show-build-datadir
4.3.9 show-build-date
4.3.10 show-build-docdir
4.3.11 show-build-enable-allinone
4.3.12 show-build-enable-console
4.3.13 show-build-enable-fullstatic
4.3.14 show-build-enable-gcov
4.3.15 show-build-enable-gprof
4.3.16 show-build-enable-gtk
4.3.17 show-build-enable-instrument
4.3.18 show-build-enable-mod-caca
4.3.19 show-build-enable-mod-csound
4.3.20 show-build-enable-mod-gl1
4.3.21 show-build-enable-mod-gles2
4.3.22 show-build-enable-mod-http
4.3.23 show-build-enable-mod-ogg
4.3.24 show-build-enable-mod-soft
4.3.25 show-build-enable-openmp
4.3.26 show-build-enable-optimize
4.3.27 show-build-enable-paranoid
4.3.28 show-build-enable-profiler
4.3.29 show-build-enable-valgrind
4.3.30 show-build-endianness
4.3.31 show-build-gcc-version
4.3.32 show-build-gnu
4.3.33 show-build-gp2x
4.3.34 show-build-home-url
4.3.35 show-build-host-cpu
4.3.36 show-build-host-os
4.3.37 show-build-hostname
4.3.38 show-build-includedir
4.3.39 show-build-ldflags
4.3.40 show-build-libdir
4.3.41 show-build-license
4.3.42 show-build-localedir
4.3.43 show-build-mac-os-x
4.3.44 show-build-md5sum
4.3.45 show-build-ms-windows
4.3.46 show-build-package-id
4.3.47 show-build-package-name
4.3.48 show-build-package-string
4.3.49 show-build-package-tarname
4.3.50 show-build-pointer-size
4.3.51 show-build-prefix
4.3.52 show-build-stamp
4.3.53 show-build-time
4.3.54 show-build-top-srcdir
4.3.55 show-build-unix
4.3.56 show-build-version
4.3.57 show-build-version-base
4.3.58 show-build-version-major
4.3.59 show-build-version-minor
4.3.60 show-build-x86
4.3.61 show-config-file
4.3.62 show-cwd
4.3.63 show-data-dir
4.3.64 show-default-config-file
4.3.65 show-default-data-dir
4.3.66 show-default-log-file
4.3.67 show-default-map-dir
4.3.68 show-default-map-path
4.3.69 show-default-mod-dir
4.3.70 show-default-music-dir
4.3.71 show-default-music-path
4.3.72 show-default-prefix
4.3.73 show-default-script-file
4.3.74 show-default-user-dir
4.3.75 show-log-file
4.3.76 show-map-dir
4.3.77 show-map-path
4.3.78 show-mod-dir
4.3.79 show-music-dir
4.3.80 show-music-path
4.3.81 show-prefix
4.3.82 show-run-dir
4.3.83 show-script-file
4.3.84 show-user-dir
4.4 Path options
4.4.1 config-file
4.4.2 data-dir
4.4.3 log-file
4.4.4 map-dir
4.4.5 map-path
4.4.6 mod-dir
4.4.7 music-dir
4.4.8 music-path
4.4.9 prefix
4.4.10 script-file
4.4.11 user-dir
4.5 Players options
4.5.1 player1-control
4.5.2 player1-name
4.5.3 player1-status
4.5.4 player2-control
4.5.5 player2-name
4.5.6 player2-status
4.5.7 player3-control
4.5.8 player3-name
4.5.9 player3-status
4.5.10 player4-control
4.5.11 player4-name
4.5.12 player4-status
4.6 Input options
4.6.1 auto-release-delay
4.6.2 click-to-focus
4.6.3 cursor-sensitivity
4.6.4 custom-alt
4.6.5 custom-ctrl
4.6.6 custom-down
4.6.7 custom-enter
4.6.8 custom-esc
4.6.9 custom-left
4.6.10 custom-pgdown
4.6.11 custom-pgup
4.6.12 custom-right
4.6.13 custom-up
4.6.14 double-click-delay
4.6.15 max-cursor-speed
4.6.16 mouse-sensitivity
4.6.17 repeat-delay
4.6.18 repeat-interval
4.6.19 use-double-click
4.6.20 use-esc-button
4.6.21 zoom-step
4.6.22 zoom-stick-delay
4.7 Graphics options
4.7.1 capture
4.7.2 fullscreen
4.7.3 gfx-backend
4.7.4 gfx-quality
4.7.5 height
4.7.6 width
4.7.7 windowed-mode-limit
4.8 Sound options
4.8.1 ambiance-exclude
4.8.2 ambiance-file
4.8.3 ambiance-filter
4.8.4 fx-volume
4.8.5 music-volume
4.8.6 snd-backend
4.8.7 water-volume
4.9 Network options
4.9.1 bind-ip
4.9.2 bind-port
4.9.3 broadcast
4.9.4 cli-backends
4.9.5 known-nodes
4.9.6 node-description
4.9.7 node-title
4.9.8 password
4.9.9 public-url
4.9.10 skip-network
4.9.11 srv-backends
4.10 Map parameters
4.10.1 chosen-map
4.10.2 force
4.10.3 use-cursor-texture
4.10.4 use-hints-xml
4.10.5 use-music-file
4.10.6 use-rules-xml
4.10.7 use-style-xml
4.10.8 use-teams-xml
4.10.9 use-texture
4.11 Map rules.xml
4.11.1 boost-power
4.11.2 color-conflict-mode
4.11.3 cursor-pot-init
4.11.4 danger-power
4.11.5 exp
4.11.6 fighter-attack
4.11.7 fighter-defense
4.11.8 fighter-new-health
4.11.9 fighter-regenerate
4.11.10 frags-fade-out
4.11.11 frags-mode
4.11.12 frags-to-distribute
4.11.13 glue-power
4.11.14 highest-team-color-allowed
4.11.15 highest-weapon-allowed
4.11.16 max-cursor-pot
4.11.17 max-cursor-pot-offset
4.11.18 max-nb-cursors
4.11.19 max-nb-nodes
4.11.20 max-nb-teams
4.11.21 max-round-delta
4.11.22 max-zone-size
4.11.23 medicine-power
4.11.24 moves-per-round
4.11.25 nb-attack-tries
4.11.26 nb-defense-tries
4.11.27 nb-move-tries
4.11.28 respawn-delay
4.11.29 respawn-position-mode
4.11.30 respawn-team
4.11.31 round-delta
4.11.32 rounds-per-sec
4.11.33 side-attack-factor
4.11.34 side-defense-factor
4.11.35 single-army-size
4.11.36 spread-mode
4.11.37 spread-thread
4.11.38 spreads-per-round
4.11.39 start-blue-x
4.11.40 start-blue-y
4.11.41 start-cyan-x
4.11.42 start-cyan-y
4.11.43 start-green-x
4.11.44 start-green-y
4.11.45 start-lightblue-x
4.11.46 start-lightblue-y
4.11.47 start-magenta-x
4.11.48 start-magenta-y
4.11.49 start-orange-x
4.11.50 start-orange-y
4.11.51 start-pink-x
4.11.52 start-pink-y
4.11.53 start-position-mode
4.11.54 start-purple-x
4.11.55 start-purple-y
4.11.56 start-red-x
4.11.57 start-red-y
4.11.58 start-yellow-x
4.11.59 start-yellow-y
4.11.60 team-profile-blue-aggressive
4.11.61 team-profile-blue-fast
4.11.62 team-profile-blue-handicap
4.11.63 team-profile-blue-mobile
4.11.64 team-profile-blue-vulnerable
4.11.65 team-profile-blue-weapon-alternate-id
4.11.66 team-profile-blue-weapon-id
4.11.67 team-profile-blue-weapon-mode
4.11.68 team-profile-cyan-aggressive
4.11.69 team-profile-cyan-fast
4.11.70 team-profile-cyan-handicap
4.11.71 team-profile-cyan-mobile
4.11.72 team-profile-cyan-vulnerable
4.11.73 team-profile-cyan-weapon-alternate-id
4.11.74 team-profile-cyan-weapon-id
4.11.75 team-profile-cyan-weapon-mode
4.11.76 team-profile-green-aggressive
4.11.77 team-profile-green-fast
4.11.78 team-profile-green-handicap
4.11.79 team-profile-green-mobile
4.11.80 team-profile-green-vulnerable
4.11.81 team-profile-green-weapon-alternate-id
4.11.82 team-profile-green-weapon-id
4.11.83 team-profile-green-weapon-mode
4.11.84 team-profile-lightblue-aggressive
4.11.85 team-profile-lightblue-fast
4.11.86 team-profile-lightblue-handicap
4.11.87 team-profile-lightblue-mobile
4.11.88 team-profile-lightblue-vulnerable
4.11.89 team-profile-lightblue-weapon-alternate-id
4.11.90 team-profile-lightblue-weapon-id
4.11.91 team-profile-lightblue-weapon-mode
4.11.92 team-profile-magenta-aggressive
4.11.93 team-profile-magenta-fast
4.11.94 team-profile-magenta-handicap
4.11.95 team-profile-magenta-mobile
4.11.96 team-profile-magenta-vulnerable
4.11.97 team-profile-magenta-weapon-alternate-id
4.11.98 team-profile-magenta-weapon-id
4.11.99 team-profile-magenta-weapon-mode
4.11.100 team-profile-orange-aggressive
4.11.101 team-profile-orange-fast
4.11.102 team-profile-orange-handicap
4.11.103 team-profile-orange-mobile
4.11.104 team-profile-orange-vulnerable
4.11.105 team-profile-orange-weapon-alternate-id
4.11.106 team-profile-orange-weapon-id
4.11.107 team-profile-orange-weapon-mode
4.11.108 team-profile-pink-aggressive
4.11.109 team-profile-pink-fast
4.11.110 team-profile-pink-handicap
4.11.111 team-profile-pink-mobile
4.11.112 team-profile-pink-vulnerable
4.11.113 team-profile-pink-weapon-alternate-id
4.11.114 team-profile-pink-weapon-id
4.11.115 team-profile-pink-weapon-mode
4.11.116 team-profile-purple-aggressive
4.11.117 team-profile-purple-fast
4.11.118 team-profile-purple-handicap
4.11.119 team-profile-purple-mobile
4.11.120 team-profile-purple-vulnerable
4.11.121 team-profile-purple-weapon-alternate-id
4.11.122 team-profile-purple-weapon-id
4.11.123 team-profile-purple-weapon-mode
4.11.124 team-profile-red-aggressive
4.11.125 team-profile-red-fast
4.11.126 team-profile-red-handicap
4.11.127 team-profile-red-mobile
4.11.128 team-profile-red-vulnerable
4.11.129 team-profile-red-weapon-alternate-id
4.11.130 team-profile-red-weapon-id
4.11.131 team-profile-red-weapon-mode
4.11.132 team-profile-yellow-aggressive
4.11.133 team-profile-yellow-fast
4.11.134 team-profile-yellow-handicap
4.11.135 team-profile-yellow-mobile
4.11.136 team-profile-yellow-vulnerable
4.11.137 team-profile-yellow-weapon-alternate-id
4.11.138 team-profile-yellow-weapon-id
4.11.139 team-profile-yellow-weapon-mode
4.11.140 total-armies-size
4.11.141 total-time
4.11.142 use-team-profiles
4.11.143 vertical-move
4.11.144 weapon-charge-delay
4.11.145 weapon-charge-max
4.11.146 weapon-duration
4.11.147 weapon-tune-berzerk-power
4.11.148 weapon-tune-turbo-power
4.11.149 x-polarity
4.11.150 y-polarity
4.11.151 z-polarity
4.12 Map hints.xml
4.12.1 background-color-auto
4.12.2 downsize-using-bench-value
4.12.3 downsize-using-fighter-scale
4.12.4 fighter-scale
4.12.5 guess-colors
4.12.6 guess-moves-per-sec
4.12.7 hud-color-auto
4.12.8 max-map-height
4.12.9 max-map-surface
4.12.10 max-map-width
4.12.11 menu-color-auto
4.12.12 min-map-height
4.12.13 min-map-surface
4.12.14 min-map-width
4.12.15 resample
4.12.16 speed
4.12.17 system-color-auto
4.12.18 upsize-using-bench-value
4.12.19 upsize-using-fighter-scale
4.12.20 view-color-auto
4.12.21 wall-grease
4.13 Map style.xml
4.13.1 animation-density
4.13.2 animation-speed
4.13.3 background-color-root-bg
4.13.4 background-color-root-fg
4.13.5 background-color-stuff-bg
4.13.6 background-color-stuff-fg
4.13.7 background-style
4.13.8 blink-cursor
4.13.9 color-alternate-bg
4.13.10 color-alternate-fg
4.13.11 color-base-bg
4.13.12 color-base-fg
4.13.13 colorize
4.13.14 colorize-cursor
4.13.15 cursor-size
4.13.16 hidden-layer-alpha
4.13.17 hud-color-frame-bg
4.13.18 hud-color-frame-fg
4.13.19 hud-color-text-bg
4.13.20 hud-color-text-fg
4.13.21 hud-style
4.13.22 keep-ratio
4.13.23 menu-color-default-bg
4.13.24 menu-color-default-fg
4.13.25 menu-color-disabled-bg
4.13.26 menu-color-disabled-fg
4.13.27 menu-color-selected-bg
4.13.28 menu-color-selected-fg
4.13.29 menu-style
4.13.30 music-exclude
4.13.31 music-file
4.13.32 music-filter
4.13.33 pixelize
4.13.34 system-color-bg
4.13.35 system-color-fg
4.13.36 team-color-blue
4.13.37 team-color-cyan
4.13.38 team-color-dead
4.13.39 team-color-green
4.13.40 team-color-lightblue
4.13.41 team-color-magenta
4.13.42 team-color-orange
4.13.43 team-color-pink
4.13.44 team-color-purple
4.13.45 team-color-red
4.13.46 team-color-yellow
4.13.47 view-color-cursor-bg
4.13.48 view-color-cursor-fg
4.13.49 view-color-map-bg
4.13.50 view-color-map-fg
4.13.51 view-style
4.13.52 waves
4.13.53 x-wrap
4.13.54 y-wrap
4.13.55 zoom
4.13.56 zoom-max
4.13.57 zoom-min
4.14 Map teams.xml
4.14.1 bot-iq
4.14.2 bot-speed
4.14.3 bot1-ai
4.14.4 bot1-color
4.14.5 bot2-ai
4.14.6 bot2-color
4.14.7 bot3-ai
4.14.8 bot3-color
4.14.9 bot4-ai
4.14.10 bot4-color
4.14.11 bot5-ai
4.14.12 bot5-color
4.14.13 bot6-ai
4.14.14 bot6-color
4.14.15 bot7-ai
4.14.16 bot7-color
4.14.17 bot8-ai
4.14.18 bot8-color
4.14.19 bot9-ai
4.14.20 bot9-color
4.14.21 nb-bots
4.14.22 player1-color
4.14.23 player2-color
4.14.24 player3-color
4.14.25 player4-color
4.15 Advanced settings
4.15.1 base64-decode
4.15.2 base64-encode
4.15.3 bench
4.15.4 bench-value
4.15.5 bin-id
4.15.6 check
4.15.7 commands-per-sec
4.15.8 cunit
4.15.9 daemon
4.15.10 debug-layer-id
4.15.11 debug-team-id
4.15.12 demo
4.15.13 dialog-timeout
4.15.14 dirty-read
4.15.15 display-background
4.15.16 display-console
4.15.17 display-cursors
4.15.18 display-debug-gradient
4.15.19 display-debug-zones
4.15.20 display-fighters
4.15.21 display-fps
4.15.22 display-hud
4.15.23 display-log
4.15.24 display-map
4.15.25 display-menu
4.15.26 display-meta
4.15.27 display-mouse
4.15.28 display-mps
4.15.29 display-preview
4.15.30 display-progress
4.15.31 display-score
4.15.32 display-splash
4.15.33 display-url
4.15.34 executed-again
4.15.35 gfx-cpu-usage
4.15.36 gfx-debug
4.15.37 io-per-sec
4.15.38 jpeg-quality
4.15.39 loader-sleep
4.15.40 local-bench-delta
4.15.41 log-level
4.15.42 log-timeout
4.15.43 magic-number
4.15.44 max-local-bench-value
4.15.45 max-network-bench-value
4.15.46 memory-bazooka-eraser
4.15.47 memory-bazooka-size
4.15.48 net-log
4.15.49 net-per-sec
4.15.50 network-bench-delta
4.15.51 network-reliability
4.15.52 open-relay
4.15.53 pilot-lag
4.15.54 quick-start
4.15.55 reset
4.15.56 reset-config-on-upgrade
4.15.57 screenshots-per-min
4.15.58 server
4.15.59 simulate-basic
4.15.60 simulate-full
4.15.61 target-fps
4.15.62 trap-errors
4.15.63 trojan
4.15.64 z-decode
4.15.65 z-encode
4.16 C to Guile
4.16.1 c-gettext
4.16.2 c-lw6-exit
4.16.3 c-lw6-get-ret
4.16.4 c-lw6-release
4.16.5 c-lw6-set-ret
4.16.6 c-lw6bot-get-backends
4.16.7 c-lw6bot-new
4.16.8 c-lw6bot-next-move
4.16.9 c-lw6cfg-defaults
4.16.10 c-lw6cfg-get-option
4.16.11 c-lw6cfg-init
4.16.12 c-lw6cfg-load
4.16.13 c-lw6cfg-option-exists
4.16.14 c-lw6cfg-quit
4.16.15 c-lw6cfg-save
4.16.16 c-lw6cfg-set-option
4.16.17 c-lw6cfg-unified-get-log-file
4.16.18 c-lw6cfg-unified-get-map-path
4.16.19 c-lw6cfg-unified-get-music-path
4.16.20 c-lw6cfg-unified-get-user-dir
4.16.21 c-lw6cli-get-backends
4.16.22 c-lw6cns-console-support
4.16.23 c-lw6cns-init
4.16.24 c-lw6cns-poll
4.16.25 c-lw6cns-quit
4.16.26 c-lw6cns-term-support
4.16.27 c-lw6dsp-get-average-fps
4.16.28 c-lw6dsp-get-fullscreen-modes
4.16.29 c-lw6dsp-get-instant-fps
4.16.30 c-lw6dsp-get-last-frame-rendering-time
4.16.31 c-lw6dsp-get-nb-frames
4.16.32 c-lw6dsp-get-video-mode
4.16.33 c-lw6dsp-new
4.16.34 c-lw6dsp-release
4.16.35 c-lw6dsp-update
4.16.36 c-lw6gen-create-from-seed
4.16.37 c-lw6gen-seed-new
4.16.38 c-lw6gen-seed-normalize
4.16.39 c-lw6gfx-get-backends
4.16.40 c-lw6gui-default-look
4.16.41 c-lw6gui-input-reset
4.16.42 c-lw6gui-joystick1-get-move-pad
4.16.43 c-lw6gui-joystick1-pop-button-a
4.16.44 c-lw6gui-joystick1-pop-button-b
4.16.45 c-lw6gui-joystick1-pop-button-c
4.16.46 c-lw6gui-joystick1-pop-button-d
4.16.47 c-lw6gui-joystick1-pop-button-e
4.16.48 c-lw6gui-joystick1-pop-button-f
4.16.49 c-lw6gui-joystick1-pop-pad-down
4.16.50 c-lw6gui-joystick1-pop-pad-left
4.16.51 c-lw6gui-joystick1-pop-pad-right
4.16.52 c-lw6gui-joystick1-pop-pad-up
4.16.53 c-lw6gui-joystick2-get-move-pad
4.16.54 c-lw6gui-joystick2-pop-button-a
4.16.55 c-lw6gui-joystick2-pop-button-b
4.16.56 c-lw6gui-joystick2-pop-button-c
4.16.57 c-lw6gui-joystick2-pop-button-d
4.16.58 c-lw6gui-joystick2-pop-button-e
4.16.59 c-lw6gui-joystick2-pop-button-f
4.16.60 c-lw6gui-joystick2-pop-pad-down
4.16.61 c-lw6gui-joystick2-pop-pad-left
4.16.62 c-lw6gui-joystick2-pop-pad-right
4.16.63 c-lw6gui-joystick2-pop-pad-up
4.16.64 c-lw6gui-keyboard-get-move-pad
4.16.65 c-lw6gui-keyboard-is-pressed
4.16.66 c-lw6gui-keyboard-pop-arrow-down
4.16.67 c-lw6gui-keyboard-pop-arrow-left
4.16.68 c-lw6gui-keyboard-pop-arrow-right
4.16.69 c-lw6gui-keyboard-pop-arrow-up
4.16.70 c-lw6gui-keyboard-pop-key-alt
4.16.71 c-lw6gui-keyboard-pop-key-ctrl
4.16.72 c-lw6gui-keyboard-pop-key-enter
4.16.73 c-lw6gui-keyboard-pop-key-esc
4.16.74 c-lw6gui-keyboard-pop-key-pgdown
4.16.75 c-lw6gui-keyboard-pop-key-pgup
4.16.76 c-lw6gui-look-get
4.16.77 c-lw6gui-look-set
4.16.78 c-lw6gui-look-zoom-in
4.16.79 c-lw6gui-look-zoom-out
4.16.80 c-lw6gui-menu-append
4.16.81 c-lw6gui-menu-close-popup
4.16.82 c-lw6gui-menu-enable-esc
4.16.83 c-lw6gui-menu-has-popup
4.16.84 c-lw6gui-menu-new
4.16.85 c-lw6gui-menu-remove
4.16.86 c-lw6gui-menu-remove-all
4.16.87 c-lw6gui-menu-scroll-down
4.16.88 c-lw6gui-menu-scroll-up
4.16.89 c-lw6gui-menu-select
4.16.90 c-lw6gui-menu-select-esc
4.16.91 c-lw6gui-menu-set-breadcrumbs
4.16.92 c-lw6gui-menu-sync
4.16.93 c-lw6gui-mouse-get-state
4.16.94 c-lw6gui-mouse-poll-move
4.16.95 c-lw6gui-mouse-pop-button-left
4.16.96 c-lw6gui-mouse-pop-button-middle
4.16.97 c-lw6gui-mouse-pop-button-right
4.16.98 c-lw6gui-mouse-pop-double-click
4.16.99 c-lw6gui-mouse-pop-simple-click
4.16.100 c-lw6gui-mouse-pop-triple-click
4.16.101 c-lw6gui-mouse-pop-wheel-down
4.16.102 c-lw6gui-mouse-pop-wheel-up
4.16.103 c-lw6hlp-about
4.16.104 c-lw6hlp-get-default-value
4.16.105 c-lw6hlp-list
4.16.106 c-lw6hlp-list-advanced
4.16.107 c-lw6hlp-list-aliases
4.16.108 c-lw6hlp-list-doc
4.16.109 c-lw6hlp-list-funcs
4.16.110 c-lw6hlp-list-graphics
4.16.111 c-lw6hlp-list-hooks
4.16.112 c-lw6hlp-list-input
4.16.113 c-lw6hlp-list-map
4.16.114 c-lw6hlp-list-map-hints
4.16.115 c-lw6hlp-list-map-rules
4.16.116 c-lw6hlp-list-map-style
4.16.117 c-lw6hlp-list-map-teams
4.16.118 c-lw6hlp-list-network
4.16.119 c-lw6hlp-list-path
4.16.120 c-lw6hlp-list-players
4.16.121 c-lw6hlp-list-quick
4.16.122 c-lw6hlp-list-show
4.16.123 c-lw6hlp-list-sound
4.16.124 c-lw6hlp-list-team-colors
4.16.125 c-lw6hlp-list-weapons
4.16.126 c-lw6img-screenshot
4.16.127 c-lw6ker-add-cursor
4.16.128 c-lw6ker-build-game-state
4.16.129 c-lw6ker-build-game-struct
4.16.130 c-lw6ker-cursor-exists
4.16.131 c-lw6ker-did-cursor-win
4.16.132 c-lw6ker-do-round
4.16.133 c-lw6ker-dup-game-state
4.16.134 c-lw6ker-game-state-checksum
4.16.135 c-lw6ker-game-struct-checksum
4.16.136 c-lw6ker-get-cursor
4.16.137 c-lw6ker-get-moves
4.16.138 c-lw6ker-get-nb-colors
4.16.139 c-lw6ker-get-nb-cursors
4.16.140 c-lw6ker-get-nb-nodes
4.16.141 c-lw6ker-get-rounds
4.16.142 c-lw6ker-get-spreads
4.16.143 c-lw6ker-is-over
4.16.144 c-lw6ker-node-exists
4.16.145 c-lw6ker-register-node
4.16.146 c-lw6ker-remove-cursor
4.16.147 c-lw6ker-set-cursor
4.16.148 c-lw6ker-sync-game-state
4.16.149 c-lw6ker-unregister-node
4.16.150 c-lw6ldr-chain-entry
4.16.151 c-lw6ldr-exp-validate
4.16.152 c-lw6ldr-get-entries
4.16.153 c-lw6ldr-hints-get-default
4.16.154 c-lw6ldr-print-examples
4.16.155 c-lw6ldr-read
4.16.156 c-lw6ldr-read-relative
4.16.157 c-lw6map-exp-get-unlocked-team-color
4.16.158 c-lw6map-exp-get-unlocked-weapon
4.16.159 c-lw6map-exp-is-team-color-allowed
4.16.160 c-lw6map-exp-is-weapon-allowed
4.16.161 c-lw6map-get-look
4.16.162 c-lw6map-get-max-nb-colors
4.16.163 c-lw6map-get-max-nb-cursors
4.16.164 c-lw6map-get-max-nb-nodes
4.16.165 c-lw6map-get-music-dir
4.16.166 c-lw6map-get-title
4.16.167 c-lw6map-param-get
4.16.168 c-lw6map-rules-get-default
4.16.169 c-lw6map-rules-get-int
4.16.170 c-lw6map-rules-get-max
4.16.171 c-lw6map-rules-get-min
4.16.172 c-lw6map-style-get-default
4.16.173 c-lw6map-team-color-index-to-key
4.16.174 c-lw6map-team-color-index-to-label
4.16.175 c-lw6map-team-color-key-to-index
4.16.176 c-lw6map-team-color-list
4.16.177 c-lw6map-teams-get-default
4.16.178 c-lw6map-weapon-index-to-key
4.16.179 c-lw6map-weapon-index-to-label
4.16.180 c-lw6map-weapon-key-to-index
4.16.181 c-lw6map-weapon-list
4.16.182 c-lw6net-init
4.16.183 c-lw6net-quit
4.16.184 c-lw6p2p-db-default-name
4.16.185 c-lw6p2p-db-new
4.16.186 c-lw6p2p-db-reset
4.16.187 c-lw6p2p-node-calibrate
4.16.188 c-lw6p2p-node-client-join
4.16.189 c-lw6p2p-node-close
4.16.190 c-lw6p2p-node-disconnect
4.16.191 c-lw6p2p-node-get-entries
4.16.192 c-lw6p2p-node-get-id
4.16.193 c-lw6p2p-node-get-local-seq-0
4.16.194 c-lw6p2p-node-get-local-seq-last
4.16.195 c-lw6p2p-node-get-next-draft-msg
4.16.196 c-lw6p2p-node-get-next-reference-msg
4.16.197 c-lw6p2p-node-get-seq-draft
4.16.198 c-lw6p2p-node-get-seq-max
4.16.199 c-lw6p2p-node-get-seq-min
4.16.200 c-lw6p2p-node-get-seq-reference
4.16.201 c-lw6p2p-node-is-dump-needed
4.16.202 c-lw6p2p-node-is-peer-connected
4.16.203 c-lw6p2p-node-is-peer-registered
4.16.204 c-lw6p2p-node-is-seed-needed
4.16.205 c-lw6p2p-node-new
4.16.206 c-lw6p2p-node-poll
4.16.207 c-lw6p2p-node-put-local-msg
4.16.208 c-lw6p2p-node-refresh-peer
4.16.209 c-lw6p2p-node-server-start
4.16.210 c-lw6p2p-node-update-info
4.16.211 c-lw6pil-bench
4.16.212 c-lw6pil-build-pilot
4.16.213 c-lw6pil-calibrate
4.16.214 c-lw6pil-commit
4.16.215 c-lw6pil-did-cursor-win
4.16.216 c-lw6pil-dump-command-generate
4.16.217 c-lw6pil-execute-command
4.16.218 c-lw6pil-fix-coords
4.16.219 c-lw6pil-fix-coords-x10
4.16.220 c-lw6pil-get-last-commit-seq
4.16.221 c-lw6pil-get-looser
4.16.222 c-lw6pil-get-max-seq
4.16.223 c-lw6pil-get-next-seq
4.16.224 c-lw6pil-get-reference-current-seq
4.16.225 c-lw6pil-get-reference-target-seq
4.16.226 c-lw6pil-get-round-0
4.16.227 c-lw6pil-get-seq-0
4.16.228 c-lw6pil-get-winner
4.16.229 c-lw6pil-is-over
4.16.230 c-lw6pil-local-command
4.16.231 c-lw6pil-local-cursors-set-main
4.16.232 c-lw6pil-local-cursors-set-mouse-controlled
4.16.233 c-lw6pil-make-backup
4.16.234 c-lw6pil-poll-dump
4.16.235 c-lw6pil-round2seq
4.16.236 c-lw6pil-seed-command-generate
4.16.237 c-lw6pil-send-command
4.16.238 c-lw6pil-seq-random-0
4.16.239 c-lw6pil-seq2round
4.16.240 c-lw6pil-slow-down
4.16.241 c-lw6pil-speed-up
4.16.242 c-lw6pil-suite-get-checkpoint
4.16.243 c-lw6pil-suite-get-commands-by-node-index
4.16.244 c-lw6pil-suite-get-commands-by-stage
4.16.245 c-lw6pil-suite-get-node-id
4.16.246 c-lw6pil-suite-get-seq-0
4.16.247 c-lw6pil-suite-init
4.16.248 c-lw6pil-sync-from-backup
4.16.249 c-lw6pil-sync-from-draft
4.16.250 c-lw6pil-sync-from-reference
4.16.251 c-lw6snd-get-backends
4.16.252 c-lw6snd-is-music-file
4.16.253 c-lw6snd-new
4.16.254 c-lw6snd-play-fx
4.16.255 c-lw6snd-play-music-file
4.16.256 c-lw6snd-play-music-random
4.16.257 c-lw6snd-poll
4.16.258 c-lw6snd-release
4.16.259 c-lw6snd-set-fx-volume
4.16.260 c-lw6snd-set-music-volume
4.16.261 c-lw6snd-set-water-volume
4.16.262 c-lw6snd-stop-music
4.16.263 c-lw6srv-get-backends
4.16.264 c-lw6sys-build-get-abs-srcdir
4.16.265 c-lw6sys-build-get-bin-id
4.16.266 c-lw6sys-build-get-bugs-url
4.16.267 c-lw6sys-build-get-cflags
4.16.268 c-lw6sys-build-get-codename
4.16.269 c-lw6sys-build-get-configure-args
4.16.270 c-lw6sys-build-get-copyright
4.16.271 c-lw6sys-build-get-datadir
4.16.272 c-lw6sys-build-get-date
4.16.273 c-lw6sys-build-get-docdir
4.16.274 c-lw6sys-build-get-enable-allinone
4.16.275 c-lw6sys-build-get-enable-console
4.16.276 c-lw6sys-build-get-enable-fullstatic
4.16.277 c-lw6sys-build-get-enable-gcov
4.16.278 c-lw6sys-build-get-enable-gprof
4.16.279 c-lw6sys-build-get-enable-gtk
4.16.280 c-lw6sys-build-get-enable-instrument
4.16.281 c-lw6sys-build-get-enable-mod-caca
4.16.282 c-lw6sys-build-get-enable-mod-csound
4.16.283 c-lw6sys-build-get-enable-mod-gl1
4.16.284 c-lw6sys-build-get-enable-mod-gles2
4.16.285 c-lw6sys-build-get-enable-mod-http
4.16.286 c-lw6sys-build-get-enable-mod-ogg
4.16.287 c-lw6sys-build-get-enable-mod-soft
4.16.288 c-lw6sys-build-get-enable-openmp
4.16.289 c-lw6sys-build-get-enable-optimize
4.16.290 c-lw6sys-build-get-enable-paranoid
4.16.291 c-lw6sys-build-get-enable-profiler
4.16.292 c-lw6sys-build-get-enable-valgrind
4.16.293 c-lw6sys-build-get-endianness
4.16.294 c-lw6sys-build-get-gcc-version
4.16.295 c-lw6sys-build-get-home-url
4.16.296 c-lw6sys-build-get-host-cpu
4.16.297 c-lw6sys-build-get-host-os
4.16.298 c-lw6sys-build-get-hostname
4.16.299 c-lw6sys-build-get-includedir
4.16.300 c-lw6sys-build-get-ldflags
4.16.301 c-lw6sys-build-get-libdir
4.16.302 c-lw6sys-build-get-license
4.16.303 c-lw6sys-build-get-localedir
4.16.304 c-lw6sys-build-get-md5sum
4.16.305 c-lw6sys-build-get-package-id
4.16.306 c-lw6sys-build-get-package-name
4.16.307 c-lw6sys-build-get-package-string
4.16.308 c-lw6sys-build-get-package-tarname
4.16.309 c-lw6sys-build-get-pointer-size
4.16.310 c-lw6sys-build-get-prefix
4.16.311 c-lw6sys-build-get-stamp
4.16.312 c-lw6sys-build-get-time
4.16.313 c-lw6sys-build-get-top-srcdir
4.16.314 c-lw6sys-build-get-version
4.16.315 c-lw6sys-build-get-version-base
4.16.316 c-lw6sys-build-get-version-major
4.16.317 c-lw6sys-build-get-version-minor
4.16.318 c-lw6sys-build-is-gnu
4.16.319 c-lw6sys-build-is-gp2x
4.16.320 c-lw6sys-build-is-mac-os-x
4.16.321 c-lw6sys-build-is-ms-windows
4.16.322 c-lw6sys-build-is-unix
4.16.323 c-lw6sys-build-is-x86
4.16.324 c-lw6sys-debug-get
4.16.325 c-lw6sys-debug-set
4.16.326 c-lw6sys-delay
4.16.327 c-lw6sys-dump
4.16.328 c-lw6sys-dump-clear
4.16.329 c-lw6sys-generate-id-16
4.16.330 c-lw6sys-generate-id-32
4.16.331 c-lw6sys-generate-id-64
4.16.332 c-lw6sys-get-config-file
4.16.333 c-lw6sys-get-cwd
4.16.334 c-lw6sys-get-cycle
4.16.335 c-lw6sys-get-data-dir
4.16.336 c-lw6sys-get-default-config-file
4.16.337 c-lw6sys-get-default-data-dir
4.16.338 c-lw6sys-get-default-log-file
4.16.339 c-lw6sys-get-default-map-dir
4.16.340 c-lw6sys-get-default-map-path
4.16.341 c-lw6sys-get-default-mod-dir
4.16.342 c-lw6sys-get-default-music-dir
4.16.343 c-lw6sys-get-default-music-path
4.16.344 c-lw6sys-get-default-prefix
4.16.345 c-lw6sys-get-default-script-file
4.16.346 c-lw6sys-get-default-user-dir
4.16.347 c-lw6sys-get-hostname
4.16.348 c-lw6sys-get-log-file
4.16.349 c-lw6sys-get-map-dir
4.16.350 c-lw6sys-get-map-path
4.16.351 c-lw6sys-get-memory-bazooka-eraser
4.16.352 c-lw6sys-get-memory-bazooka-size
4.16.353 c-lw6sys-get-mod-dir
4.16.354 c-lw6sys-get-music-dir
4.16.355 c-lw6sys-get-music-path
4.16.356 c-lw6sys-get-prefix
4.16.357 c-lw6sys-get-run-dir
4.16.358 c-lw6sys-get-script-file
4.16.359 c-lw6sys-get-timestamp
4.16.360 c-lw6sys-get-uptime
4.16.361 c-lw6sys-get-user-dir
4.16.362 c-lw6sys-get-username
4.16.363 c-lw6sys-getenv
4.16.364 c-lw6sys-getenv-prefixed
4.16.365 c-lw6sys-idle
4.16.366 c-lw6sys-log
4.16.367 c-lw6sys-log-get-backtrace-mode
4.16.368 c-lw6sys-log-get-level
4.16.369 c-lw6sys-log-set-backtrace-mode
4.16.370 c-lw6sys-log-set-dialog-timeout
4.16.371 c-lw6sys-log-set-level
4.16.372 c-lw6sys-megabytes-available
4.16.373 c-lw6sys-openmp-get-num-procs
4.16.374 c-lw6sys-path-concat
4.16.375 c-lw6sys-path-file-only
4.16.376 c-lw6sys-path-parent
4.16.377 c-lw6sys-path-split
4.16.378 c-lw6sys-set-memory-bazooka-eraser
4.16.379 c-lw6sys-set-memory-bazooka-size
4.16.380 c-lw6sys-signal-custom
4.16.381 c-lw6sys-signal-default
4.16.382 c-lw6sys-signal-poll-quit
4.16.383 c-lw6sys-signal-send-quit
4.16.384 c-lw6sys-sleep
4.16.385 c-lw6sys-snooze
4.16.386 c-lw6sys-url-canonize
4.16.387 c-lw6tsk-loader-get-stage
4.16.388 c-lw6tsk-loader-new
4.16.389 c-lw6tsk-loader-pop
4.16.390 c-lw6tsk-loader-push-gen
4.16.391 c-lw6tsk-loader-push-ldr
4.17 Script hooks
5 C API
5.1 libliquidwar6
5.1.1 Overview
5.1.2 API
5.2 libbot
5.2.1 Overview
5.2.2 API
5.3 mod-brute
5.3.1 Overview
5.3.2 API
5.4 mod-follow
5.4.1 Overview
5.4.2 API
5.5 mod-idiot
5.5.1 Overview
5.5.2 API
5.6 mod-random
5.6.1 Overview
5.6.2 API
5.7 libcfg
5.7.1 Overview
5.7.2 API
5.8 libcli
5.8.1 Overview
5.8.2 API
5.9 mod-http
5.9.1 Overview
5.9.2 API
5.10 mod-tcp
5.10.1 Overview
5.10.2 API
5.11 mod-udp
5.11.1 Overview
5.11.2 API
5.12 libcns
5.12.1 Overview
5.12.2 API
5.13 libcnx
5.13.1 Overview
5.13.2 API
5.14 libdat
5.14.1 Overview
5.14.2 API
5.15 libdef
5.15.1 Overview
5.15.2 API
5.16 libdsp
5.16.1 Overview
5.16.2 API
5.17 libdyn
5.17.1 Overview
5.17.2 API
5.18 libgen
5.18.1 Overview
5.18.2 API
5.19 libgfx
5.19.1 Overview
5.19.2 API
5.20 mod-gl1
5.20.1 Overview
5.20.2 API
5.21 mod-gles2
5.21.1 Overview
5.21.2 API
5.22 mod-soft
5.22.1 Overview
5.22.2 API
5.23 shared-sdl
5.23.1 Overview
5.23.2 API
5.24 mod-caca
5.24.1 Overview
5.24.2 API
5.25 libglb
5.25.1 Overview
5.25.2 API
5.26 libgui
5.26.1 Overview
5.26.2 API
5.27 libhlp
5.27.1 Overview
5.27.2 API
5.28 libimg
5.28.1 Overview
5.28.2 API
5.29 libker
5.29.1 Overview
5.29.2 API
5.30 libldr
5.30.1 Overview
5.30.2 API
5.31 libmap
5.31.1 Overview
5.31.2 API
5.32 libmat
5.32.1 Overview
5.32.2 API
5.33 libmsg
5.33.1 Overview
5.33.2 API
5.34 libnet
5.34.1 Overview
5.34.2 API
5.35 libnod
5.35.1 Overview
5.35.2 API
5.36 libp2p
5.36.1 Overview
5.36.2 API
5.37 libpil
5.37.1 Overview
5.37.2 API
5.38 libscm
5.38.1 Overview
5.38.2 API
5.39 libsim
5.39.1 Overview
5.39.2 API
5.40 libsnd
5.40.1 Overview
5.40.2 API
5.41 mod-csound
5.41.1 Overview
5.41.2 API
5.42 mod-ogg
5.42.1 Overview
5.42.2 API
5.43 libsrv
5.43.1 Overview
5.43.2 API
5.44 mod-httpd
5.44.1 Overview
5.44.2 API
5.45 mod-tcpd
5.45.1 Overview
5.45.2 API
5.46 mod-udpd
5.46.1 Overview
5.46.2 API
5.47 libsys
5.47.1 Overview
5.47.2 API
5.48 libtsk
5.48.1 Overview
5.48.2 API
5.49 libvox
5.49.1 Overview
5.49.2 API
Appendix A Authors
Appendix B 2005 .plan
B.1 Complete rewrite
B.2 Technologies
B.2.1 Script + standard C + assembly
B.2.2 OpenGL
B.2.3 CSound
B.3 Functionnalities
B.3.1 Visual enhancements
B.3.2 Rules enhancements
B.3.3 Hey, you forgot my idea!!!
B.4 Road map
Appendix C Fanfic
C.1 The Battle of Emberlificoted
Appendix D Links
D.1 Official links
D.2 Other sites
D.3 Old stuff
Appendix E GNU GENERAL PUBLIC LICENSE
Appendix F GNU Free Documentation License
Appendix G Indexes
G.1 Concept index
G.2 Function and keyword index
G.3 Data types index
1 Introduction
**************
Read this chapter to discover Liquid War 6.
1.1 In a nutshell
=================
Liquid War 6 is a unique multiplayer wargame. Your army is a blob of
liquid and you have to try and eat your opponents. Rules are very
simple yet original, they have been invented by Thomas Colcombet. It is
possible to play alone against the computer but the game is really
designed to be played with friends, on a single computer, on a LAN, or
on Internet.
An older version, Liquid War 5 (http://www.ufoot.org/liquidwar/v5),
is available, but is not part of the GNU Project. Only Liquid War 6 is
part of the GNU Project (http://www.gnu.org/), it is a complete rewrite.
The official page of Liquid War 6 is
. For more information, you
can read the Wikipedia article (http://en.wikipedia.org/wiki/Liquid_War)
about Liquid War.
1.2 Project status
==================
1.2.1 What works, and what does not (yet)
-----------------------------------------
As of today, the game is in beta state. It can be installed, and you
can toy arround with. You can even play with. It is still far from
being complete as some key features are still missing.
What works:
* The whole framework is here, some functions are not implemented
yet, but the bases are set up, and they are believed solid. The
game is very modular, and is fully threaded. It is designed so
that graphics, sound, network and bot backends can be hacked at
will. It has a complete self-test suite, many debugging built-in
tools, and is regularly checked with automated tools. For
instance, you can check reports concerning global references
(http://www.ufoot.org/liquidwar/v6/doc/global/), code coverage
(http://www.ufoot.org/liquidwar/v6/doc/coverage/) and cyclomatic
complexity (http://www.ufoot.org/liquidwar/v6/doc/cyclo/). This is
not a quick hack.
* Documentation. Yes, you're reading it.
* Version 0.0.7beta is playable. Local game between humans (up to 4
players) is possible. Two bots are implemented, named random and
stupid. No great players but well, they move the cursor. A new
"deatchmatch" mode, different from LW5, is in place.
* Liquid War 6 already has some features which are nowhere to be
found in Liquid War 5, such as multiple layers. It can be worth
the upgrade.
* Maps. A number of interesting maps have already been designed
(thanks to Kasper Hviid).
* The game runs natively on GNU/Linux and has been ported to
Microsoft Windows and Mac OS X. Binaries are available for all
those platforms. Use at your own risk. If in doubt, get the
source and compile.
In the near future:
* Network play. Top-level priority. Yes, network has been promised
for months (years? ...yes, years) and is still not there. I said
"when it's done".
* Fix bugs ;) The current engine is somewhat buggy, fighters might
loose the cursor, it clearly needs polishing.
In the long run:
* Write new graphical backends so that the game does not require Mesa
or any OpenGL-like subsystem. The idea is to get rid of the
3D-accelerator dependency.
* Implement all the fancy 3D features, make it possible to play
Liquid War 6 on a Moebius ring.
* Use the cool features of CSound to provide dynamic, contextualized
sounds & musics.
* Optimize the bot algorithm, which is probably a complex AI problem.
You might be interested in checking the following URLs, which give a
view on opened tasks and bugs:
* bug list:
* task list:
1.2.2 What has changed since Liquid War 5.x?
--------------------------------------------
Liquid War 6 is a complete rewrite of Liquid War 5
(http://www.ufoot.org/liquidwar/v5). The rewrite started in 2005. So a
good question is "was the rewrite worth it?"...
Here's a list of key improvements:
* appearance, global rendering quality. Call it the way you want,
Liquid War 6 simply looks nicer than any previous release. Period.
* level features, including multi-layer (allowing the map designer to
create bridges and tunnels), wrapping (fighters disappearing on the
left can reappear on the right). Those really change the gameplay.
* deathmatch mode. Give it a try, it's now the default mode, and
definitely changes the rules.
* team profiles, as well as special "weapons", which are tricks you
can play on opponents.
* modularity, overall code quality. While this is not a user-visible
change, the game is far less monolithic, therefore hacking to
revamp the graphics engine, the algorithm, whatever, is easier.
The situation has changed from "this is impossible to hack" to "OK,
how much time can this take?". So while one can't promise every
idea will be implemented some day, at least many more things become
possible with the new codebase.
The most interesting change is still to come, and concerns network
games.
Stay tuned.
1.2.3 Revision history
----------------------
Liquid War 6 releases are "codenamed" after famous, historical, real or
mythical characters. Here is a short revision history. For details,
see the 'ChangeLog' and 'NEWS' files distributed with the game.
Additionnally, there's an ever-increasing "stamp" number which is
incremented each time a build is done with a different source. Latest
versions use the stamp as the revision number (the version 3rd number).
* 2006-12-18 : 0.0.1beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.1beta/)
* 2007-09-07 : 0.0.2beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.2beta/)
* 2008-01-30 : 0.0.3beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.3beta/),
codename "Napoleon", stamp 549
* 2008-09-19 : 0.0.4beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.4beta/),
codename "Clovis", stamp 756
* 2008-12-20 : 0.0.5beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.5beta/),
codename "Henri IV", stamp 1082
* 2009-01-10 : 0.0.6beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.6beta/),
codename "Cesar", stamp 1124
* 2009-10-03 : 0.0.7beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.7beta/),
codename "Geronimo", stamp 1465
* 2010-07-05 : 0.0.8beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.8beta/),
codename "Attila", stamp 1658
* 2010-08-23 : 0.0.9beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.9beta/),
codename "Chuck", stamp 2096
* 2011-07-29 : 0.0.10beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.10beta/),
codename "Gengis Kahn", stamp 2562
* 2011-10-02 : 0.0.11beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.11beta/),
codename "Ho Chi Minh", stamp 2785
* 2011-12-18 : 0.0.12beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.12beta/),
codename "Aguirre", stamp 2938
* 2011-12-24 : 0.0.13beta
(http://download.savannah.gnu.org/releases/liquidwar6/0.0.13beta/),
codename "Blackbeard", stamp 2950
* 2014-01-04 : 0.2.3551
(http://download.savannah.gnu.org/releases/liquidwar6/0.2.3551/),
codename "Davy Crockett"
* 2014-03-26 : 0.4.3681
(http://download.savannah.gnu.org/releases/liquidwar6/0.4.3681/),
codename "Hannibal"
* 2015-05-06 : 0.6.3902
(http://download.savannah.gnu.org/releases/liquidwar6/0.6.3902/),
codename "Goliath"
1.2.4 Road map
--------------
The game will probably be labelled "6.0.0" when network mode is up and
running. Until then there will probably be other improvements
concerning gameplay and appearance ("eye candy"). There's a balance to
keep between the major goals such as "make that network thingy work" and
the very real fact that "hacking must be fun".
1.3 How you can help
====================
1.3.1 Help GNU
--------------
Please remember that development of Liquid War 6 is a volunteer effort,
and you can also contribute to its development. For information about
contributing to the GNU Project, please read How to help GNU
(http://www.gnu.org/help/help.html).
1.3.2 Todo list
---------------
Here's a short list of todo items. It is probably too early to start
hacking the core engine itself, for it is still under heavy development,
might undergo major rewrites, and it's hard for documentation to keep up
with the reality of the code. However, there are still many things to
do.
* Try the game. Play. Test. Send bug reports. Without bug
reports, bugs don't get fixed.
* Write maps. Obviously, this is something which can perfectly be
delegated. Experience shows user-contributed maps are, on average,
better than maps conceived by the author...
* Translate texts. Liquid War 6 uses GNU gettext, so all messages
can be translated.
* ...any help is welcome.
Feel free to join the mailing-lists, this is clearly the best place
to start with.
There's also a list of opened tasks on Savannah at
which you can browse
online. Maybe there's some task for you!
Alternatively, you can contact Christian Mauduit
(mailto:ufoot@ufoot.org).
2 User's manual
***************
The Liquid War 6 user's manual hopefully contains any usefull
information to install the program and play the game. If you just want
to enjoy Liquid War 6 without diving into map creation and programming,
this is just for you.
2.1 Mailing lists
=================
2.1.1 General discussion
------------------------
The main discussion list is
(mailto:help-liquidwar6@gnu.org), and is used to discuss all aspects of
Liquid War 6, including installation, development, game strategies, and
whatever subject players and hackers might want to talk about, provided
it is Liquid War 6 related. If you don't know on which list to
subscribe, this is the one.
To subscribe to it, please send an empty mail with a Subject: header
line of just "subscribe" to the '-request' list, that is
(mailto:help-liquidwar6-request@gnu.org).
You can also subscribe to the list using the Mailman web interface
for help-liquidwar6
(http://lists.gnu.org/mailman/listinfo/help-liquidwar6) and consult
help-liquidwar6 archives
(http://lists.gnu.org/archive/html/help-liquidwar6/).
2.1.2 Announcements
-------------------
Announcements about LiquidWar 6 are made on
(mailto:info-liquidwar6@gnu.org). Subscribe to it to be informed of
major releases, and other significant news.
To subscribe to it, please send an empty mail with a Subject: header
line of just "subscribe" to the '-request' list, that is
(mailto:info-liquidwar6-request@gnu.org).
You can also subscribe to the list using the Mailman web interface
for info-liquidwar6
(http://lists.gnu.org/mailman/listinfo/info-liquidwar6) and consult
info-liquidwar6 archives
(http://lists.gnu.org/archive/html/info-liquidwar6/).
Please also consider reading the latest news on Savannah
(http://savannah.gnu.org/news/?group=liquidwar6).
2.1.3 Bugs
----------
There is also a special list used for reporting bugs,
(mailto:bug-liquidwar6@gnu.org). Please try
and describe the bug as precisely as possible. The more accurate the
description, the more chances it will get to be fixed.
While this is the standard GNU way of reporting bugs, modern SPAM
standards make it very hard to filter real bug reports from junk on this
list. It is more convenient to use a web interface, the URL is:
and you're
really encouraged to use it instead of sending emails.
Please take a look at the bug list
(http://savannah.gnu.org/bugs/?group=liquidwar6) before submitting new
bugs.
2.1.4 IRC channel
-----------------
IRC can be an interesting alternative to mailing-lists. There's an open
channel dedicated to Liquid War on freenode.net, you can access it on
that is, channel '#liquidwar' on
irc.freenode.net.
2.2 Getting the game
====================
2.2.1 Download source
---------------------
Liquid War 6 can be found on:
*
*
*
Downloading the latest file from this place, and compile it yourself
on your computer with a classical './configure && make && make install'
is the recommended way to install Liquid War 6.
2.2.2 Download binaries
-----------------------
Some binary packages might be available. Your mileage may vary.
GNU/Linux based systems are supported, through Debian
(http://www.debian.org/) '.deb' and Red Hat (http://www.redhat.com/)
'RPM' packages. There is also a Microsoft Windows installer.
However these binaries are not necessarly available for every single
version of the game.
2.2.3 GIT repository
--------------------
Latest work in progress versions can be obtained with GIT
(http://git-scm.com/). Here's the typicall command which will fetch the
latest version:
git clone git://git.sv.gnu.org/liquidwar6.git
If you are behing a firewall and can't use the native GIT protocol,
you can rely on the (slower) http protocol:
git clone http://git.sv.gnu.org/r/liquidwar6.git
You can browse the code online, consult log summary, and in a general
manner "follow" the project on
and
.
Beware, git does not contain all the files included in the official
source tarball. For instance, the './configure' script is not present.
You need to run :
autoreconf
./configure
make
make install
The 'autoreconf' call is really mandatory the first time, 'autoconf'
is not enough. You will also need all the prerequisites needed to build
the docs, generally speaking, getting the source from git requires more
tools to build the package than picking a ready-to-use tarball.
2.2.4 Daily snapshots
---------------------
Alternatively, you can download daily snapshots on
These files used to be
built every day, now they are generated by Jenkins
(http://jenkins-ci.org/) whenever there's a source change (commit). A
simple 'make' is done before generating source tarballs however a 'make
distcheck' is performed before generating binaries, therefore sometimes
you can have the source but no associated tarballs.
Beware of revision numbers, snapshots can make you believe version
X.Y is out when it's only a release candidate at best, and most of the
time just a work-in-progress.
Still, if you want bleeding edge versions, this is the way to go.
Documentation is automatically updated as well, and available on
.
2.2.5 Check integrity
---------------------
Most binary packages (at least '.deb' and 'RPM' GNU/Linux binaries)
should be signed using GnuPG (http://www.gnupg.org/). The following
keys are used when generating upstream/vendor packages:
* 1024D/FD409E94 2002-01-31 Christian Mauduit (U-Foot)
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQGiBDxZRPIRBACxPI8ZYEtkIGUliwLanAlZbIqVCI38d/SONo8MS3VUZkO82XRo
EAoj4KwX39fbUM3knpLK6SijzxKef/7Mw0w3W7lnQ/NegqSelTxiHmJxEQmeLulk
drP89CpXQPdir8ediZseR9/BAroiWgckDJK8YgMKsmBCjE62xfPrtxM2nwCghH0X
JAT/iD2uP0FdLpQGbM1dCnMD/jM3OcWIqQ1uGO8gp/lKTb7Kv7vEFQX0waLaIWOk
KJ45kx4guYuT7u4dVg1Y01PCbtnWTYJ9t1SW6GHhpNsdGybrw8izRk6zXE5TYFtN
9LN0kYYx5V+/Szjl4z5JabdEAt2OXZ9/N8Pb4PYInmG1jRr5fl78IO4SC1Gy03vK
9rL7A/9iXSGnN77/aNJ2qN3btTagwdLv4AYbk0ySneIpzKT9nmnM6MYs+seOwYeS
8e7i/SPISqblS5G10WZ4o/j5te0jotT7QFZdT3diO2NuUQXqqXIvRNxBGVKfX7Sg
TqvjZWlXMNAvH5KiuZ8vqgfEMqLS0hwjpJNVaZIPF4cifFgPFbQsQ2hyaXN0aWFu
IE1hdWR1aXQgKFUtRm9vdCkgPHVmb290QHVmb290Lm9yZz6IVwQTEQIAFwUCPFlE
8gULBwoDBAMVAwIDFgIBAheAAAoJEN4/K839QJ6Uk+YAnRuBRpn/rdD/JZNGHz0w
bJaVon9eAJ0YEdl0agCwJaWjKeZGWJl/f8TZqYhXBBMRAgAXBQI8WUTzBQsHCgME
AxUDAgMWAgECF4AACgkQ3j8rzf1AnpS+kgCeNl528f7waryDPBnEGJ0FjevrdNMA
oIDB+UCj1U65teCEbA3sEPyfkndFuQENBDxZRPUQBAD/PoWU0T2R4p0Fft5WQvCE
RqFSk+QZl0YXZCtwW59/v3ai0xEYzv193kjhojHqcDifoeHbO7bkEU5ZrbtwDt33
++/LZ4JqCi8wBXH2I+2msau/92Vn+WGZZf1fFRYJiputKyQrDnd05q41FvPI3knP
FBIMV/eKu0twqgGkLfHntwADBQP+PE4YN1NU01bScHiwkz62E5Xf/MwgOkBPFJ+D
L1o18xaUaNwrHSaI+nJc04de6QzxNrVfDdREwdjIm+M7CkK+ru4agmECyE3Ek3YL
76dFkE9geeOZTQ9A6MY9u/D1h+QHODg1r2sNfqoMnsFaNWOLXtivjjH4XWMN6Qze
N9H8UUqIRgQYEQIABgUCPFlE9QAKCRDePyvN/UCelJT4AJ94wSFLzyLxZLT29cBW
xybTpyt/jQCZAXEQi6LWVEo5jt/99FWRwDVNHK4=
=fcJV
-----END PGP PUBLIC KEY BLOCK-----
* 2048R/406FFCAB 2013-07-12 Jenkins Daemon (Christian Mauduit)
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQGiBDxZRPIRBACxPI8ZYEtkIGUliwLanAlZbIqVCI38d/SONo8MS3VUZkO82XRo
EAoj4KwX39fbUM3knpLK6SijzxKef/7Mw0w3W7lnQ/NegqSelTxiHmJxEQmeLulk
drP89CpXQPdir8ediZseR9/BAroiWgckDJK8YgMKsmBCjE62xfPrtxM2nwCghH0X
JAT/iD2uP0FdLpQGbM1dCnMD/jM3OcWIqQ1uGO8gp/lKTb7Kv7vEFQX0waLaIWOk
KJ45kx4guYuT7u4dVg1Y01PCbtnWTYJ9t1SW6GHhpNsdGybrw8izRk6zXE5TYFtN
9LN0kYYx5V+/Szjl4z5JabdEAt2OXZ9/N8Pb4PYInmG1jRr5fl78IO4SC1Gy03vK
9rL7A/9iXSGnN77/aNJ2qN3btTagwdLv4AYbk0ySneIpzKT9nmnM6MYs+seOwYeS
8e7i/SPISqblS5G10WZ4o/j5te0jotT7QFZdT3diO2NuUQXqqXIvRNxBGVKfX7Sg
TqvjZWlXMNAvH5KiuZ8vqgfEMqLS0hwjpJNVaZIPF4cifFgPFbQsQ2hyaXN0aWFu
IE1hdWR1aXQgKFUtRm9vdCkgPHVmb290QHVmb290Lm9yZz6IVwQTEQIAFwUCPFlE
8gULBwoDBAMVAwIDFgIBAheAAAoJEN4/K839QJ6Uk+YAnRuBRpn/rdD/JZNGHz0w
bJaVon9eAJ0YEdl0agCwJaWjKeZGWJl/f8TZqYhXBBMRAgAXBQI8WUTzBQsHCgME
AxUDAgMWAgECF4AACgkQ3j8rzf1AnpS+kgCeNl528f7waryDPBnEGJ0FjevrdNMA
oIDB+UCj1U65teCEbA3sEPyfkndFuQENBDxZRPUQBAD/PoWU0T2R4p0Fft5WQvCE
RqFSk+QZl0YXZCtwW59/v3ai0xEYzv193kjhojHqcDifoeHbO7bkEU5ZrbtwDt33
++/LZ4JqCi8wBXH2I+2msau/92Vn+WGZZf1fFRYJiputKyQrDnd05q41FvPI3knP
FBIMV/eKu0twqgGkLfHntwADBQP+PE4YN1NU01bScHiwkz62E5Xf/MwgOkBPFJ+D
L1o18xaUaNwrHSaI+nJc04de6QzxNrVfDdREwdjIm+M7CkK+ru4agmECyE3Ek3YL
76dFkE9geeOZTQ9A6MY9u/D1h+QHODg1r2sNfqoMnsFaNWOLXtivjjH4XWMN6Qze
N9H8UUqIRgQYEQIABgUCPFlE9QAKCRDePyvN/UCelJT4AJ94wSFLzyLxZLT29cBW
xybTpyt/jQCZAXEQi6LWVEo5jt/99FWRwDVNHK4=
=fcJV
-----END PGP PUBLIC KEY BLOCK-----
2.3 Installation
================
This section covers installation from source. Other ways of installing
the program are not described here.
2.3.1 Requirements
------------------
All these libraries are mandatory to compile the game. Liquid War 6
won't compile, let alone run, without them. Some of them could probably
be replaced by equivalent tools, but this would certainly require a
programming effort and some changes in Liquid War 6 source code.
* GCC (http://www.gnu.org/software/make/). Liquid War 6 does require
the GNU C Compiler to build, while other compilers might be able to
build the game, this is untested.
* Gomp (http://gcc.gnu.org/projects/gomp/). Liquid War 6 uses OpenMP
'#pragma' directives, this should help the game run faster on SMP
systems.
* GNU Make (http://www.gnu.org/software/make/). Liquid War 6 might
and certainly does use GNU Make extensions.
* GNU C library (http://www.gnu.org/software/libc/). Sounds obvious,
but you need a standard C library. It happens that glibc has some
rather usefull extensions (yes, as of 2006, some vendors continue
to offer C libraries without 'snprintf'...) and Liquid War 6 might
use them. In a general manner, Liquid War 6 is part of and
designed for GNU. You might however manage to compile it with
limited libc support, this is the case with mingw32 for instance
but, do it at your own risk.
* Perl (http://www.perl.com/). Some Makefile commands require Perl.
You don't need any Perl devel packages, and you can probably use
any Perl 5.x version, since no fancy recent feature of Perl is
used. Just plain Perl.
* Guile (http://www.gnu.org/software/guile/). Possibly the most
required library, since Liquid War 6 is a scheme program which uses
a set of functions coded in standard C. You need at least Guile
1.8.
* GNU MP (http://gmplib.org/). GMP is a free library for arbitrary
precision arithmetic, required by Guile.
* libgc (https://launchpad.net/libgc). This is a a garbage collector
library, recent versions of Guile might require this so in case
your version of Guile requires it, then Liquid War 6 will need it
too.
* ltdl (http://www.gnu.org/software/libtool/). This library, which
comes with libtool, provides a portable alternative to 'dlopen' and
'dlclose'. Check that you have a '/usr/include/ltdl.h' file, or
install the corresponding package.
* zlib (http://www.zlib.net/). Required by other libraries, but can
also be used directly by Liquid War 6 to compress network messages
for instance.
* expat (http://www.libexpat.org/). Used to read and write XML
files, which contain constants and configuration data.
* libpng (http://www.libpng.org/pub/png/libpng.html). Liquid War 6
uses libpng to read levels (maps), not to speak of other optional
libraries (SDL and the rest) who need it themselves.
* libjpeg (http://www.ijg.org/). Maps can also be provided as jpeg
files, so libjpeg is required as well.
* SQLite 3 (http://www.sqlite.org). Used to handle the list of
available servers.
2.3.2 Optional libraries
------------------------
While all these libraries are theorically optional (the game will
successfully compile without them), you'll obviously need, for instance,
one graphics backend. Otherwise, you'll simply have no display. This
is not acceptable. As of today, one can reasonnably consider all
SDL-related libraries are required. The rest is truely optional.
* libcunit (http://cunit.sourceforge.net/). Provides (hopefully)
more readable test output. It's not strictly mandatory but still
highly recommended. Building without is just allowed in case some
rare and bizarre platform would not have a libcunit port.
* ncurses (http://www.gnu.org/software/ncurses/). Required by
readline, needs to be there otherwise readline might not be
detected properly on some systems.
* GNU readline
(http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html). Used to
handle input on the console. Console is not absolutely mandatory,
but it's a must-have if you want to hack the game. Console
unavailable does not mean you won't get anything on stdout but, the
interactive script shell just won't work.
* GTK+ (http://www.gtk.org/). Used to display error/critical
messages, so that users who launch the game by clicking on a icon
(that is, not from the console) are still visually informed of
important messages.
* Mesa (http://www.mesa3d.org/). This library provides an API
similar to OpenGL and enables 2-D and 3-D drawing.
* SDL (http://www.libsdl.org/). SDL is used to set up a working
OpenGL environnement, and handle input (mouse and keyboard).
* SDL_image (http://www.libsdl.org/projects/SDL_image/). This SDL
extension is used to read textures and other graphics from disk.
* FreeType 2 (http://freetype.sourceforge.net/). This library is
required by SDL_ttf, to draw fonts.
* SDL_ttf (http://www.libsdl.org/projects/SDL_ttf/). This SDL
extension is used to draw fonts. It is UTF-8 enabled.
* libcaca (http://caca.zoy.org/). This library transforms bitmaps
into ascii-art images, allowing an alternative style of display,
TTY compatible.
* libcsound (http://www.csounds.com/). While this tool is not used
yet, it is meant to be the final sound backend, as CSounds offers
great power to the composer, enabling truely dynamically generated
sound & music. For now Liquid War 6 tries to detect csound 4 but
as the mainstream stable release is now 5 an update is needed. It
will probably be updated/fixed (Liquid War 6 using csounds 5) some
day, for now you can safely *not* install csound on your system and
enjoy all the possibilities of the game.
* SDL_mixer (http://www.libsdl.org/projects/SDL_mixer/). This SDL
extension is used to allow dynamic mixing of sounds, and it also
provides a builtin 'OGG/Vorbis' file renderer.
* libcURL (http://curl.haxx.se/libcurl/). Used to handle HTTP
requests, the idea being not to re-invent the wheel but use a
robust standards-compliant generic library.
2.3.3 Optional tools
--------------------
Those tools are used upstream to maintain the game, you normally do not
need them to build the game "as is" but if you modify the source code
and hack the game, you might be interested in installing them.
* Perl 5 (http://www.perl.org/). Liquid War 6 uses Perl for many
tedious task, including, but not limited to, parsing documentation.
* GNU Indent (http://www.gnu.org/software/indent/). Code is
regularly indented using the script 'src/indent.sh' which calls
'indent' automatically and recursively on the whole source tree.
* md5sum (GNU core utilities)
(http://www.gnu.org/software/coreutils/) This is used to stamp the
source code and help tracking exact build versions.
* Doxygen (http://www.stack.nl/~dimitri/doxygen/). Used to generate
documentation concerning C structs, more precisely, include the
struct members documentation into the official texinfo manual.
* xsltproc (http://xmlsoft.org/XSLT/xsltproc2.htm). Used to
post-process Doxygen output and transform it to texinfo.
* dot (http://www.graphviz.org/). Used to generate Doxygen call
graphs.
* Google Performance Tools
(http://code.google.com/p/google-perftools/). This tool is
convenient to optimize the program and find out what parts of it
take most of the CPU power to execute.
* lcov (http://ltp.sourceforge.net/coverage/lcov.php). Gives nice
output about code coverage.
* GNU global (http://www.ufoot.org/liquidwar/v6/doc/global/). Shows
global references through the code.
* pmccabe (http://parisc-linux.org/~bame/pmccabe/). Cyclomatic
complexity, shows what part of the code are bloated.
* Valgrind (http://www.valgrind.org/). Usefull to track down memory
leaks and many other programming errors.
2.3.4 Installing requirements using RPM/DEB packages
----------------------------------------------------
You might find it convenient not to install all the requirements from
source, but use your favorite GNU/Linux distribution packages.
On an RPM based GNU/Linux system, a typical command (tested with
Fedora (http://www.fedoraproject.org/) 15 "Lovelock") could be:
yum install \
make gcc glibc glibc-devel binutils \
libgomp \
guile guile-devel gmp gmp-devel libgc1c2 libgc-dev \
libtool libtool-ltdl libtool-ltdl-devel \
zlib zlib-devel expat expat-devel \
libpng libpng-devel libjpeg libjpeg-devel \
sqlite sqlite-devel \
ncurses ncurses-devel readline readline-devel \
libGL libGL-devel libGLU libGLU-devel \
SDL SDL-devel SDL_image SDL_image-devel \
SDL_mixer SDL_mixer-devel \
freetype freetype-devel SDL_ttf SDL_ttf-devel \
libcaca libcaca-devel \
libcurl libcurl-devel \
gtk2-devel \
perl lcov global valgrind graphviz gv ImageMagick \
texinfo-tex \
indent emacs doxygen libxml \
CUnit CUnit-devel \
rpm-build
On a DEB package based GNU/Linux system this command (tested with
Debian (http://www.debian.org/) 6.0 "squeeze") would be:
apt-get install \
make autoconf automake \
gcc libc6 libc6-dev binutils \
libgomp1 \
guile-2.0 guile-2.0-dev guile-2.0-libs libgmp10 libgmp3-dev \
libtool libltdl7 libltdl-dev \
zlib1g zlib1g-dev libexpat1 libexpat1-dev \
libpng12-0 libpng12-dev libjpeg8 libjpeg-dev \
libsqlite3-0 libsqlite3-dev \
libncurses5 libncurses5-dev libreadline6 libreadline6-dev \
libgl1-mesa-glx libgl1-mesa-dri libgl1-mesa-dev libglu1-mesa libglu1-mesa-dev \
libgles2-mesa libgles2-mesa-dev \
libsdl1.2debian libsdl1.2-dev libsdl-image1.2 libsdl-image1.2-dev \
libsdl-mixer1.2 libsdl-mixer1.2-dev \
libfreetype6 libfreetype6-dev libsdl-ttf2.0-0 libsdl-ttf2.0-dev \
libcaca0 caca-utils libcaca-dev \
libcurl4-gnutls-dev \
libgtk2.0-dev \
perl lcov global valgrind graphviz gv imagemagick \
texinfo texlive-base texlive-generic-extra \
texlive-fonts-recommended texlive-latex-extra \
indent emacs doxygen xsltproc pmccabe \
libcunit1-ncurses libcunit1-ncurses-dev \
google-perftools libgoogle-perftools-dev \
git git2cl \
zip nsis \
debhelper devscripts
Note that those requirements really depend on the exact distribution
you have, package names may vary from one to another.
2.3.5 Compiling
---------------
Liquid War 6 uses GNU Automake (http://www.gnu.org/software/automake/),
Autoconf (http://www.gnu.org/software/autoconf/) and GNU Libtool
(http://www.gnu.org/software/libtool/).
Once all the requirements are installed, run:
./configure
make
make install
Liquid War 6 supports the standard './configure --prefix=/my/path'
option (in fact, it supports much more than that) so you can install the
game in any directory. You do not need to be 'root' to install Liquid
War 6.
2.4 Extra maps
==============
2.4.1 The extra maps package
----------------------------
The main package contains some maps so that you can try out the game.
Still, an additionnal package, called 'extra-maps' or
'liquidwar6-extra-maps' is available, containing more maps. It really
does contain many of them, including most Liquid War 3 and Liquid War 5
legacy maps, plus new Liquid War 6 maps.
2.4.2 Install extra maps on GNU/Linux and POSIX systems
-------------------------------------------------------
On GNU/Linux systems (and possibly any POSIX unixish system) running:
./configure
make
make install
will install the extra maps on your system automatically, they will
then be available in the 'extra/' sub-directory when browsing maps.
The './configure' script has a '--enable-liquidwar6' switch which
will try and find automatically if there's an existing 'liquidwar6'
binary in the path. If there's such a binary, it will run it and ask
for its 'map-path' and use this value automatically.
2.4.3 Raw install of extra maps (all-platforms)
-----------------------------------------------
Another solution, which works on all platforms including Microsoft
Windows and Mac OS X but also works on GNU/Linux, is to simply unpack
the 'extra-maps' package (unzip or untar) in your custom map directory,
or in the system map directory. There's nothing else to do to install
these maps but simply put them on your hard drive in the right
directory.
Typically on an Microsoft Windows system, you would unpack the extra
maps in 'C:\Program Files\Liquid War 6\map\' (system directory) and on a
Mac OS X system you would unpack the extra maps in 'Liquid War
6.app/Contents/Resources/map/' (system directory) or
'$HOME/Library/Application Support/Liquid War 6/map' (user directory).
On a GNU/Linux or POSIX system you would unpack them in
'$HOME/.liquidwar6/map/' (user directory).
Next time you run the game, the maps should be browsable.
If you can't see them, run 'liquidwar6 --audit' and check that the
place where you unpacked the files is actually searched by the binary.
2.5 Troubleshooting
===================
2.5.1 Compilation problems
--------------------------
A quick survival guide:
* Check that you have all dependencies installed. Also check their
version number. Double-check that you have devel packages
installed, not only run-time binaries.
* Read carefully the output of './configure'. Running './configure >
configure.log 2> configure.err' does help.
* Editing '/etc/ld.so.conf' and running 'ldconfig' as 'root' can help
if some dependencies are installed in exotic places.
* Check the values of the environment variables 'CFLAGS', 'LDFLAGS'
and 'LD_LIBRARY_PATH'.
* Try './configure --enable-allinone', this will disable some fancy
but somewhat complicated dynamic '.so' file support, it can help if
shared libraries are handled differently on your system than on a
plain GNU/Linux box.
If none of these help, consider reporting a bug, or search the
mailing-lists for help.
2.5.2 Check installation
------------------------
Here's a check-list to ensure that your installation is correct:
* What was the output of 'make install'? 'make check'?
* Is the 'liquidwar6' binary in your 'PATH' environment variable? It
might be in '/usr/games'.
* Run 'liquidwar6 --pedigree'. Look at the output. Check the
compilation date & time, the version number.
* Run 'liquidwar6 --audit'. What do these paths look like? Are they
absolute paths? Do they exist? What's there? Normally, once the
game is installed, all of them should exist, and be populated with
sub-directories and files.
* Run 'liquidwar6 --modules', to know which modules where compiled.
You need at least one graphical module, for instance 'mod-gl1',
else the game won't run.
* Run 'liquidwar6 --host', this displays informations about the host
system the binary has been built for.
2.5.3 Problems running the game
-------------------------------
Now, game looks correctly installed, but you have problems running it.
* Run the game from a terminal, not from a Gnome or KDE launcher, you
need to see the console output.
* In the '$HOME/.liquidwar6/' directory, you'll find some files, the
main log file 'log.csv' and maybe 'dump.txt' or 'backtrace.txt'.
They might contain valuable information, read them. Note that
while 'log.csv' is overwritten each time you start the game,
'dump.txt' or 'backtrace.txt' are conserved until a new problem
arises. So check the date of these files to be sure you're
analyzing the right ones. Note that byt default on Microsoft
Windows '$HOME/.liquidwar6/' is replaced by 'C:\Documents and
Settings\\Liquid War 6' and on Mac OS X it is in
'/Users//Library/Application Support/Liquid War 6/'.
* Run 'liquidwar6 --defaults'. This will reset all options to
defaults. You might need to run this when upgrading from a version
to another, since some options might appear, disappear, or defaults
values can change.
* Run 'liquidwar6 --test'. This should run a complete test suite,
many functions in the game will be tested automatically, and errors
reported.
* Run 'liquidwar6 --show-script-file'. Are you really running the
right code?
* Game segfaults: try 'make uninstall && make clean && make && make
install'. Many problems can come from using a wrong shared module.
You can also launch the game with the '--trap-errors=false' switch,
this will disable the custom popup window and allow you to get the
real error.
* Game (still) segfaults: try 'gdb liquidwar6'. Type 'run
--trap-errors=false' and watch output.
* The dynamic library loader can sometimes have problemes, and does
not always report explicit messages on 'stdout' or 'stderr'. You
can change this by modifying some environment variables: 'export
LD_DEBUG=all'. This is very verbose but does help finding bugs.
* Consider compiling the game using './configure --enable-valgrind'
and then run it using Valgrind (http://valgrind.org/).
* Try 'find / -type d -a -name "liquidwar6*" 2> /dev/null' to ensure
you don't have an old version of Liquid War 6 somewhere else...
2.6 Quick start
===============
2.6.1 Quick start
-----------------
Once the game is installed, run it, click on 'Quick start' with the
mouse, and control the red ''a'' cursor with the mouse, or keyboard,
both work. Try and surround the green team, it's a stupid bot, you
should win ;)
You army is formed by all the red pixels on the screen, they should
try and rejoin the cursor (the blinking ''a'' letter) using the shortest
path. When red and green meet, they fight. Try it, toy arround.
The 'Quick start' button will always make you play red against a
green stupid bot, whatever other options you have set up.
Todo...
2.7 Strategy tips
=================
2.8 User interface
==================
2.8.1 A reduced set of keys
---------------------------
Liquid War 6 can be controlled using a reduced set of keys. This is to
make the game more portable and allow possible ports to platforms where
a full keyboard is not available. Depending on the graphics backend,
exact mapping might change, they should hopefully be obvious and
intuitive.
Those keys are:
* 'up' : the arrow up key
* 'down' : the down arrow key
* 'left' : the left arrow key
* 'right' : the right arrow key
* 'enter' : the enter / return key
* 'esc' : the escape key
* 'ctrl' : the control key
* 'alt' : the alt / meta key
* 'pgup' : the page up key
* 'pgdown' : the page down key
Basically,
2.8.2 Combining mouse, keyboard and joysticks
---------------------------------------------
It's also possible to control the game with the mouse only, or with a
joystick. By default the interface will trap all events and respond on
any of these possible devices.
Keyboard Mouse Joystick Menu action In-game
---------------------------------------------------------------------------
'up' mouse stick previous move cursor
pointer menu item up
'down' mouse stick next menu move cursor
pointer item down
'left' mouse stick change menu move cursor
pointer item value left
'right' mouse stick change menu move cursor
pointer item value right
'enter' left-click button A validate validate
menu chat line
'esc' right-click button B back to quit game
previous
menu
'ctrl' right-click button C N/A fire
or
double-click
on any
button
'alt' middle-click button D N/A alternate
or fire
triple-click
on any
button
'pgup' wheel up button E previous zoom in
menu item
'pgdown' wheel down button F next menu zoom out
item
A final word about joystick buttons: there's no such thing as
standard joystick buttons, some will come with 'A,B,C,D', others will
have 'A,B,start,select,L,R', there's no way to know. By default, the
game will use the buttons with the lowest indexes (returned by your
driver) for the most usefull functions. Validate menu entries is the
most usefull action, zooming in and out the one you can live without.
2.8.3 Quit with F10
-------------------
There's also an (almost) hardcoded shortcut which will quit the game
immediately, or at least as quickly as possible, without any prompt or
warning.
It is the 'F10' key.
Think of this feature as the procastinator's "whoops, here comes my
boss!!!" emergency function.
2.9 Solo game
=============
2.9.1 Current state
-------------------
As of today, Liquid War 6 is essentially a solo game since network is
not working. It allows you to toy arround in arcade mode on any map you
wish.
A real solo mode with campaign and goals to reach is planned, how it
will be implemented is yet to be defined.
2.9.2 Team profiles
-------------------
By default, teams behave differently, some of them move more rapidly,
some are more aggressive but vulnerable, some are more defensive but do
not attack as strong as others. This aspect of the game is under active
tuning, things might be unfair by now, you can toy arround with the
various 'team-profile-...' options, any report is appreciated.
Note that this is very different from Liquid War 5, and can give very
different gaming experiences, you can artificially set up arbitrary
strong bots, for instance.
Here's a description of the default color settings:
* 'blue': has a strong attack but is slow
* 'cyan': has an extremely good defense but is slow
* 'green': has a better defense than the average
* 'lightblue': has an extremely strong attack but is very slow
* 'magenta': is extremely fast but also very vulnerable
* 'orange': is fast, but has a very weak attack
* 'pink': has a very strong attack, but is also very vulnerable
* 'purple': has a very good defense but a weak attack
* 'red': moves faster than the average
* 'yellow': has a strong attack
2.9.3 Weapons
-------------
Additionnally, when profiles are used, each team has two weapons, a
primary weapon and an alternate one. Think of weapons as special
(usually nasty) tricks you can play on your opponents.
Here's a description of available weapons:
* 'atomic': nuclear explosion, all fighters arround your cursor are
about to die
* 'attract': all fighters from all teams are packed near your cursor
* 'berzerk': super-strong attack for a limited time, crush your
enemies
* 'control': you take the control of all other teams while your
cursor stays in place
* 'crazy': all your opponents go crazy for some time, acting with no
logic
* 'disappear': you disappear for some time from the battlefield, to
reappear later, somewhere else
* 'escape': fighters placed as far as possible from cursor, magically
escape from any grip
* 'fix': all other teams are freezed, you can move but not attack
them
* 'invincible': no damage for a limited time, move untouched
* 'kamikaze': you die along with the strongest team on the
battlefield, requires at least 3 teams
* 'mix': fighters exchange position, their properties being preserved
* 'permutation': will exchange colors, randomly, requires at least 3
teams (double edged weapon)
* 'plague': general disease, all fighters mysteriously loose health
* 'reverse': fighters continue to move normally, but attacks are done
in reverse mode, backwards
* 'rewind': make the battlefield be like it was a few seconds ago
* 'scatter': every fighters of every team scattered in random places
* 'shrink': reduces the number of fighters on the map
* 'steal': steals some fighters to other teams
* 'teleport': fighters placed as close as possible to cursor
* 'turbo': move faster for a limited time
Note that this is in progress, some of them are NOT IMPLEMENTED YET.
2.10 Network games
==================
2.10.1 Choose your "public url"
-------------------------------
Liquid War 6 needs to name your "node" (you can think as your server
instance of the game) and have a unique URL (address) to publish and
give to other nodes.
If only one network adapter is attached to your computer and your
address IP is 'A.B.C.D' then by default the game will pick automatically
the address 'http://A.B.C.D:8056/' and it should work flawlessly.
Problems can arise if you have a peculiar network configuration, if
you have multiple non-loopback network interfaces, if you use NAT to
protect yourself from intruders and/or if your context forces you to do
so. In that case, Liquid War won't be able to guess a correct URL
automatically. So you need to set it up manually either by editing the
'public-url' entry in the config file, changing environment variable
'LW6_PUBLIC_URL' or passing the '--public-url=http://:/'
argument when running the game. Typically, if you are behind a firewall
which does NAT, use the firewall address. The right address is the
address which, given to remote hosts, will allow them to connect on your
game instance.
2.10.2 Starting a node
----------------------
A node is started automatically when you run the game. Even if you
don't start to play, node starts in the background and exchanges data
with other nodes, mostly to discover them and maintain its internal map
of existing nodes and games.
So even without starting a network game, you should be able to point
a web browser on your node and see a web page describing it. Your node
address is displayed on 'stdout' (console) when starting the game. If
in doubt, try which should work unless you
modified defaults settings.
When you start a network game, the program simply changes your node
state from "idle" to "accepting connections".
2.10.3 Connecting to a node
---------------------------
The interface should show you the list of available nodes, just pick one
and try and connect to it.
Note that once you're connected on a remote node, you're still acting
as an independant node, and other nodes might connect to your node as
well as to the other nodes. In short, there's no real server or client,
everyone is a client for someone, and can act as a server.
Nodes connected together form a "community", which can disband,
accept new nodes, and in a general manner has its own immaterial life,
the first node which created the game might disappear, game can continue
without it.
This is why the main network module is called 'libp2p', this is a
reference to the term "peer to peer".
2.10.4 Communities
------------------
Once a node is connected to another one, they've started a "community".
Formally, a stand-alone node accepting for connection is already a
community, even if it has only one member, but the only really
interesting communities are those formed with several nodes.
A community can't be reached through a given server, to connect to
one you just need to connect on one of its member nodes. All nodes are
equivalent, there's no master, no root node, nodes collaborate to share
the same real-time information and maintaine an up-to-date game state.
Of course, conflicts can arise, and in that case nodes need to agree
on an acceptable solution. Normally, the program takes decisions
automatically (for instance, it could decide to "kick" a node out of the
community) so the player does not have to care about this, but this is
expected to be one of the most tricky (and passionating) part of Liquid
War 6 hacking.
2.10.5 Firewall settings
------------------------
By default, Liquid War 6 will communicate on port 8056, in both TCP and
UDP, and in both ways too (in/out). It's possible to play with partial
connectivity, in extreme case, you can even play without direct internet
access, using only a mere web proxy.
However, things will go faster and be much easier if the program can
use its default native protocol.
Here's an example of a typicall iptables (http://www.netfilter.org/)
configuration which allows you to play the game full-featured. It's
assumed that by default all packets are dropped, this configuration will
just open the necessary ports.
# outgoing TCP on port 8056 (liquidwar6)
iptables -A OUTPUT -p tcp --dport 8056 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --sport 8056 -m state --state ESTABLISHED -j ACCEPT
# incoming TCP on port 8056 (liquidwar6)
iptables -A INPUT -p tcp --dport 8056 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 8056 -m state --state ESTABLISHED -j ACCEPT
# outgoing UDP on port 8056 (liquidwar6)
iptables -A OUTPUT -p udp --dport 8056 --sport 1024:65535 -j ACCEPT
iptables -A INPUT -p udp --sport 8056 --dport 1024:65535 -j ACCEPT
# incoming UDP on port 8056 (liquidwar6)
iptables -A INPUT -p udp --dport 8056 --sport 1024:65535 -j ACCEPT
iptables -A OUTPUT -p udp --sport 8056 --dport 1024:65535 -j ACCEPT
If you can't change firewall settings and only have access to the web
through a web proxy, it can still be possible to play (with some
restrictions such as your node not being seen by others) if 'mod-http'
is available. This in turn depends on wether libcurl
(http://curl.haxx.se/) support was activated when compiling the game.
To use the proxy, you can set the 'http_proxy' environment variable.
For detailed informations, please refer to libcurl doccumentation
(http://curl.haxx.se/docs/).
2.10.6 Is the game secure?
--------------------------
As stated in the license, the program comes with NO WARRANTY. Period.
However, an important effort has been made so that it can reasonnably
be used online, exposed to various "common" attacks.
As far as security is concerned, there are two different issues:
* vulnerability to general security attacks, people typically trying
to gain prililedged access on your computer, relying on a security
flaw in the program. A good firewall is a must-have, as you can
never know for sure a program has no bugs. Running Liquid War 6 as
an unpriviledged user (certainly not "root") is also a good
practice.
* vulnerability to players "cheating" and sending malicious
informations to fake their moves, scores, and/or modify
informations concerning other players. This is a very important
point in Liquid War 6 since it has a multi-channel way of
exchanging data (think of the web interface, you have no garantee
of who the client is).
Here's a list of various steps which have been taken to make the
program more secure:
* a '--skip-network' option is here if you really do not want to be
bothered by networking risks;
* program has basic password support so that you can deny access to
unknown players;
* passwords are never sent in clear text over the network, only a
hash (checksum) is sent;
* no use of well-known buffer overflow friendly functions like
'strcpy', equivalents such as 'strncpy' are used;
* program never trusts what comes from network peers, when it wants
to know something, it checks it out by itself, for instance, the
node list is systematically verified by the local node before being
used and/or published;
* the built-in web server is not a general purpose web server which
will end up revealing some of your private files, it can only serve
game-related pages;
* the very fact that the game has no central server makes it hard to
attack it, because if someone wants to play "Oscar" annoying
"Alice" and "Bob" he well need to fool all the nodes participating
in a game, sending wrong informations to a single node won't have
much effect.
This being said, Liquid War 6 does not use any strong encryption
library to protect the data it sends. All the checksum machinery might
be vulnerable to a brute-force and/or strong cryptographic attack, so in
theory it's possible to fool the program.
In practise, if you want real privacy, play over a VPN (Virtual
Private Network).
2.11 Graphics
=============
2.11.1 Standard, high and low resolution
----------------------------------------
Liquid War 6 will try and pick up a default resolution when the game is
launched the first time. It won't use your maximum screen resolution
but will instead list all available fullscreen modes, and pick up one
which is usually something like two thirds of the highest mode. This is
to allow switching back and forth between fullscreen and windowed mode
using the same settings. This automatically picked-up resolution really
depends on your hardware and driver. It is called "standard" in the
graphics options menu.
Then it is possible to automatically select the minimum and maximum
resolution your hardware allows in fullscreen mode. These are called
"low" and "high" in the graphics options menu. Just click on the button
that display the resolution, it will change and use the next setting.
In windowed mode, the game won't accept the highest available mode but
will instead use a percentage of it, defined by the
'--windowed-mode-limit' parameter.
You might still be in a case where this is not enough. For instance
your maximum resolution is 1600x1200, Liquid War 6 picks a default mode
of 1280x960 for you but for some reason you want to play in 800x600,
fullscreen. In this case, simply switch to windowed mode, resize the
window with the mouse (the resolution button will show you the current
resolution) and just choose a resolution near 800x600. It does not even
need to be exactly 800x600, 798x603 would probably fit. Then when
switching back to fullscreen, you'll be in 800x600, the game will
automatically pick up the fullscreen mode which is closest to the
current windowed mode resolution.
2.11.2 Display rate
-------------------
By default the game will try and run at 60 frames per second. Given the
nature of Liquid War 6, this is probably enough. Higher values will
maybe give a slightly smoother display, but barely noticeable.
You can activate the display of frames per seconds (aka "fps")
through the menu ("options -> system") or with the command line
("-display-fps").
On a single processor system, reducing the number of frames per
second might allow the rest of the game run faster. So if you notice
the game is really slow, in terms of "fighters move slowly" then you
might be happy reducing the display rate and therefore giving power back
to the other parts of the program. On a dual-core (or more) or on a
multi-processor system, this is probably useless since the game is
threaded and has a dedicated thread for display purposes. The command
line option to reduce the number of frames per second is '--target-fps'.
Additionnally, the parameter '--gfx-cpu-usage' allows you to force
the display thread to "take a rest" and go idle for some time. This is
advanced settings, most users won't touch this.
2.12 Sound & music
==================
2.12.1 Current status
---------------------
As of today, the game is capable of playing Ogg Vorbis
(http://www.vorbis.com/) audio files. That's it.
2.12.2 The future
-----------------
In the long run, what is planned is to support Csound
(http://www.csounds.com/) which would allow very cool effects, such as
dynamically changing the music while the game is running, typically
following the action. If there's a lot of fight, the music could
reflect this.
For now this is only vaporware, just a nice idea among others,
nothing implmented yet.
2.13 Config file
================
The config file is a simple XML file. It uses XML only to benefit
standard parsing tools, but it's not a structured XML file, in the sense
that the tree is so simple that all items are at the same level. It is
just a simple key-value binding.
This file is in '$HOME/.liquidwar6/config.xml' on GNU/Linux and POSIX
systems, in 'C:\Documents and Settings\\Liquid War
6\config.xml' on Microsoft Windows and in
'/Users//Library/Application Support/Liquid War 6/config.xml'
on Mac OS X.
You're free to edit it manually, but all parameters are changeable
with command line options. The program will overwrite this file each
time it exits, so if you put comments in it, they will disappear. The
advantage of this is that if you mispell something, or if for some
reason the game does not understand a value, then when rewriting the
file, it will show you it just did not get it.
The file embeds the documentation for all its entries, it is
therefore rather verbose. The documentation is the same you will find
online or by quering the game with the '--about' option, also the same
you would get reading this manual.
2.14 Logs
=========
Liquid War 6 uses 'stdout' to output important messages, and 'stderr' to
log warnings and errors. It will also use syslog
(http://en.wikipedia.org/wiki/Syslog) if available.
Additionnally, a verbose log is available in
'$HOME/.liquidwar6/log.csv' on GNU/Linux and POSIX systems, in
'C:\Documents and Settings\\Liquid War 6\log.csv' on Microsoft
Windows and in '/Users//Library/Application Support/Liquid War
6/log.csv' on Mac OS X.
You can read this using any spreadsheet software capable of reading
csv file. It uses the tab ('\t') character as a separator. It contains
valuable informations including version and most default values for the
game, and for each line logged, it says where in the code the log
function was called. A must-have for debugging.
2.15 Report bugs
================
There are two ways to report bugs:
* send a mail to
(mailto:bug-liquidwar6@gnu.org);
* use the web-based Savannah bug tracker:
.
The latter (Savannah (http://savannah.gnu.org)) is much preferred,
because the mailing-list is bloated with spam... It also offers a list
of bugs (http://savannah.gnu.org/bugs/?group=liquidwar6) which you
should read before submitting a new one.
3 Hacker's guide
****************
This hacker's guide is for anyone who is curious about the game, and
wants to know how it works. It covers many aspects from simple map
creation to technical program internals. A great effort has been done
in Liquid War 6 so that it should be much more hackable than previous
versions. Any feedback is welcome.
3.1 Designing levels
====================
3.1.1 Why is level design so important?
---------------------------------------
As of Liquid War 5 (http://www.ufoot.org/liquidwar/v5), most levels have
been contributed by players. While the maintainer of Liquid War 6 has
technical knowledge to develop the game, artistic talent and taste might
not be his domain of excellence 8-)
Therefore contribution are truely welcomed when they take the form of
a new, original, fun and good looking level. It's believed the levels
often make the game much more than its engine. This is true for any
type of game, and Liquid War is no exception.
So this section is here to help players understand how to hack
existing levels, and create new ones, in the hope that 1) they can enjoy
their own creations and 2) possibly share their work with others.
Note that this manual might refer to levels and maps: they are just
two different names to describe the very same thing. It's an alias.
3.1.2 Format overview
---------------------
Liquid War 6 stores level information in a plain directory.
There is no such thing as an opaque '.dat' binary file. The name of
the level is the name of the directory itself, and its elements are the
files contained in it.
Files must follow a precise naming scheme. For instance Liquid War 6
expects a 'map.png' file to be present in each map directory.
All image files in a level use the Portable Network Graphics
(http://www.w3.org/Graphics/PNG/) or JPEG (http://www.jpeg.org/) format.
It is possible that in the long term, Liquid War 6 will be able to
handle levels as '.tar.gz' or '.zip' files. In that case these files
will only be a compressed image of the actual level directory.
See the './map/' directory of the source Liquid War 6 distribution to
see example of maps.
3.1.3 Resolution (map size)
---------------------------
Liquid War 6 does enforce a limit on map size. This is not to frustrate
map designers and/or players, simply, it would be a lie to pretend the
game can handle arbitrary big maps.
They might look great on your computer but will become unplayable
soon on an older machine. And most of the time they don't look that
great, carefully crafted 1280×720 just looks awesome and can represent
a great level complexity.
Here are the technical limits:
Type Max width Max height Max surface
----------------------------------------------------------------------------
Texture 3 000 2 000 6 000 000
Logical map 1 500 1 000 1 000 000
The texture can be somewhat bigger than the logical map, this allows
for pretty levels while limiting the horsepower needed to move the
fighters and animate everything. Note that you could technically feed
the game with a 'map.png' that is bigger than the logical map limit,
only it will be downscaled when being loaded.
The texture limits are generous enough to accept a full-HD 1920x1080
image, or a 4/3 1600x1200 image, while the "one million pixels" logical
map limit is enough to store a 16/9 1280x720 map or a 4/3 1024x768.
Keep in mind that the logical map ('map.png') will probably be scaled
whatsoever, even if it's within the absolute limits (the game adapts the
resolution to your computer speed) and your texture will rarely appear
in its native resolution, will probably be distorted, and so on.
3.1.4 Metadata
--------------
Older versions of Liquid War 6 used to load a plain 'README' file and
use this as metadata. Title was take from map directory name. This is
still supported, but it now also supports the addition of a
'metadata.xml' file in which you can describe your map.
The following files can be defined:
* 'title': map title, what will appear in the menus
* 'author': map author
* 'description': description of the map, to help players when
browsing folders
* 'license': map license (short version, just a simple one-liner,
don't use lenghtly copyright notices here, the 'README' file would
be the file to put long legal sections)
3.1.5 map.png
-------------
This is the only required file in a level.
In fact, the existence of 'map.png' makes a directory a level. When
checking wether a directory is a correct level, Liquid War 6 simply
tests the existence and validity of 'map.png'.
This image is a simple black & white area, where white zones are the
background, the sea, the places where fighters can move, and black zones
are the foreground, the walls, the places where fighters can't go.
This informations can be stored in a 2-color indexed file, or in a
grayscaled or even truecolor RGB file, but color information won't be
used. Internally, Liquid War 6 will read the color of every point. If
it is over 127 on a 0 to 255 scale, it will be considered as background,
if it is below 127, it will be considered as foreground.
3.1.6 layer2.png ... layer7.png
-------------------------------
Liquid War 6 can handle mutiple layer maps. Think of a pile of maps,
one being on top of the other. This allows you to create a volume, the
game considers every layer has two axis x and y, and the z axis is to
travel through layers. First layer corresponds to z=0, second layer to
z=1, and so on.
Here are the files you can use to define layers:
* 'map.png' this one is on top, it's always defined (z=0)
* 'layer2.png' (z=1)
* 'layer3.png' (z=2)
* 'layer4.png' (z=3)
* 'layer5.png' (z=4)
* 'layer6.png' (z=5)
* 'layer7.png' (z=6)
A 'layerX.png' file should be designed exactly like 'map.png'. In
fact, 'map.png' could simply have been called 'layer1.png'.
Up to 6 extra layers can be defined (from 'layer2.png' to
'layer7.png'). This is a hardcoded limit. It allows you to define 7
different layers, including the top 'map.png' layer. Keep in mind this
layer system is not real 3D, it's more a "2D and a half" model. Adding
layers can considerably slow down the game, so it's wise to try and use
as few layers as possible. Technically, 3 layers will allow you to
build bridges and tunnels, which is probably the most usefull
construction using layers. Fighters can also have difficulties
navigating through layers so piling up layers in narrow "vertical"
z-axis based tunnels is probably not a great idea.
The 'ufoot/concept/pass' map of the 'liquidwar6-extra-maps'
demonstrates basic layer usage.
3.1.7 texture.png, texture.jpeg and texture-alpha.jpeg
------------------------------------------------------
It is possible to define a texture for the map by putting a
'texture.png' or 'texture.jpeg' file. It does not need to have the same
dimensions as the map itself. Indeed, textures can be much more precise
than the actual logical map.
There's no theorical limit on how big a texture can be, more
precisely, it can be much bigger than any hardware/driver maximum
texture size. In practice, a too big texture will waste your video card
RAM, and slow everything down. Sizes ranging from 640x480 to 1600x1200
are reasonable texture sizes.
If you don't define this, the 'map.png' file will be used as the
texture, and also import colors from 'style.xml' if defined.
Note that the shape of the texture defines the shape of the map, that
is, the ratio with which it will appear on the screen.
The PNG alpha layer will be used for transparency. But to save disk
space, it can be convienient to prefer the JPEG format, use
'texture.jpeg' instead of 'texture.png' and store the alpha layer in a
separated file, called 'texture-alpha.jpeg'. This avoids handling heavy
PNG files, PNG compression not being performant on most textures.
In 'texture-alpha.jpeg', black is considered opaque, and white is
transparent. Different levels of gray correspond to different levels of
opacity. Previous versions of the game used the other way of doing
things (black is transparent) because this is technically, the most
obvious way to do things. Black is 0 and transparent is 0. But for a
human "reader" of the map this does not make sense. One generally
expects white to be the equivalent of "undrawn" or "blank", well, if
it's undecided, void, transparent, whatever, it's white. When the Gimp
(http://www.gimp.org/) flattens an image, it becomes white, not black.
So white is transparent. Period.
3.1.8 glue.png and boost.png
----------------------------
If there's a 'glue.png' or 'boost.png' file in the map directory (you
can use one of them or both) then they will be interpreted as follow:
* on areas where 'glue.png' and 'boost.png' are white, nothing
special happens, fighters follow their default behavior
* on areas where 'glue.png' is black, fighters will be slowed down.
How slowish they will be depends on the 'glue-power' parameter. If
'glue-power' is 3 then fighters will move three times slower.
* on areas where 'boost.png' is black, fighters will behave faster.
How fast they will be depends on the 'boost-power' parameter. If
'boost-power' is 2 then fighters will move two times faster.
* on areas where 'glue.png' or 'boost.png' are gray, they will be
slowed down less or speeded up less depending on how dark the grey
is.
There can be, at the same place, some gray or black in both
'boost.png' and 'glue.png'. How this will behave exactly is not really
clear at this stage, the recommendation is not to do this (it does not
really make sense anyway) but if you do it, game won't complain.
It's also wise not to abuse of 'boost.png' for obviously, a map
filled with "boosted" zones at a X10 pace will require much more CPU
than the same map with no such setting. This might fool the automatic
resampling algorithm and lead to maps that are unplayable. The spirit
of 'boost.png' is just to make a few spots go faster.
It's also important to note that behaving faster or slower means
moving faster or slower but also attacking faster or slower, and, in a
general manner doing any action with a different pace.
3.1.9 danger.png and medicine.png
---------------------------------
If there's a 'danger.png' or 'medicine.png' file in the map directory
(you can use one of them or both) then they will be interpreted as
follow:
* on areas where 'danger.png' and 'medicine.png' are white, nothing
special happens, fighters follow their default behavior
* on areas where 'danger.png' is black, fighters die automatically,
that is, they become black and loose health. How dangerous these
zones are depends on the 'danger-power' parameter.
* on areas where 'medicine.png' is black, fighters regenerate faster,
they become bright and shiny as if auto-healing. How efficient
this medicine is depends on the 'medicine-power' parameter.
* on areas where 'danger.png' or 'medicine.png' are gray, well, it's
in between, the "danger" and "medicine" effect will be proportional
to the level of gray.
There can be, at the same place, some gray or black in both
'medicine.png' and 'danger.png'. How this will behave exactly is not
really clear at this stage, the recommendation is not to do this (it
does not really make sense anyway) but if you do it, game won't
complain.
3.1.10 one-way-.png
------------------------------
The four files:
* 'one-way-north.png' (AKA "up")
* 'one-way-east.png' (AKA "right")
* 'one-way-south.png' (AKA "down")
* 'one-way-west.png' (AKA "left")
can be used to force the fighters to go in one given direction, on
some parts of the map. If an area is black on one of this meta-layers,
then fighters will go in the given direction. For instance, a black
zone in 'one-way-north' will make fighters go to the north (AKA "up"
direction) regardless of the cursor position. The fact that this is a
one-way path is understood by fighters and they will take this in
account when choosing the shortest path to go somewhere. You can
combine vertical and horizontal one-way informations, making diagonal
one-way paths.
3.1.11 cursor.png and cursor-color.png
--------------------------------------
By default, a simple cursor will be displayed, but you can use a custom
per-map cursor. Cursors are defined by two 64x64 bitmaps:
* 'cursor.png' is a PNG file, very likely to use transparency, which
will be default be colorized according to the map colors. You can
draw it any color, only greyscale informations will be used. You
can keep the original colors if you really want to by setting
'colorize-cursor' to false, but the default is to ignore the hue.
* 'cursor-color.png' is another PNG file, very likely to use
transparency too, which will always be colorized, replacing white
by the team color, and black by the "dead" color, which by default
is black and is usually a dark color. This colorization is a way
to recognize your cursor and know which team it belongs to.
You can define only one of those bitmaps, if doing so, then the other
layer will be empty, and won't be filled with the default cursor data.
Note that additionnally, a little letter (single character) will be
displayed using the team color, so that's yet another way to identify
which teams the cursor belongs too. The PNG files really need to be PNG
(JPEG won't work) and need to be 64x64, any other size will be ignored.
3.1.12 rules.xml
----------------
Whereas 'style.xml' is only about the appearance of the map, 'rules.xml'
allows the map designer to change pretty much any parameter.
Ultimately, the player can still ignore these settings and overide
them with its own values, but the idea is: most game options are only
pertinent in a given context. For instance, on some maps it's
interesting to move slowly, on some other it's interesting to move fast.
Some maps might be playable packed with fighters everywhere, some other
might be much more fun with almost nobody on them.
The approach in Liquid War 5 (http://www.ufoot.org/liquidwar/v5) was
to make the options available, but let the player himself find the right
settings for the right map. The consequence is that no one ever used
all those cryptic options in the advanced options menu, and probably 99%
of the players ended up playing with default settings. This is not that
bad, but given the fact that changing a few parameters one can totally
transform the gameplay, it has decided been that in Liquid War 6, the
map designer suggests the right options that matches his map.
This does not prevent the player from toying with options himself, he
can still do it.
There's also one important point to note: all these options are
technically implemented as integer parameters. We certainly do not want
any float here, since, and it is a Liquid War specific behavior, the
game must be 100,00% predictable and behave the same on every platform.
As there is nothing like exactness when speaking of floats, those are
forbidden here. As for strings, we are dealing here with low-level
internals, and this section is not about telling a story. They are
technical options only. Booleans are implemented with the usual 'false
= 0' and 'true = 1' convention. Note that other config files in Liquid
War 6 might rely on floats, strings, and booleans with conventionnal
'true' and 'false' values, but not this one. 'rules.xml' is special.
This 'rules.xml' file is a direct image of the internal "rules"
structure, so it contains technical, sometimes not very user-friendly
parameters. While hacking 'rules.xml' directly is a good way to test
things, most of the time, the other file 'hints.xml' contains more
high-level informations that do the job the right way. A typicall
example is speed.
*Note rules.xml reference: Map rules.xml.
3.1.13 hints.xml
----------------
This parameter is only used by the map loader. The map itself contains
none of these parameters, they are only clues (hints, in fact..) on
"how to load the map" which are passed to the loader.
Let's take an example : speed. This 'rules.xml' file has a (rather)
easy to use "speed" parameter, which will do all the job of finding the
right resolution for your map, the right "rounds-per-sec" and
"moves-per-round" parameters, in short, it will set many other
parameters to fit your needs.
As far as the map designer is concerned, 'rules.xml' and 'hints.xml'
could have been merged (but so would have 'style.xml') but internally
they are very different: 'rules.xml' contains the real parameters, the
one used by the algorithm whereas 'hints.xml' contains only instructions
which are used once when loading the map and then disappear. The core
algorithm has no idea of what was in 'hints.xml', once it's loaded.
*Note hints.xml reference: Map hints.xml.
3.1.14 style.xml
----------------
This is a simple XML file defining various appearance parameters. It
has absolutely no effect on gameplay. These settings can ultimately be
overriden by the player, but the idea is that if the map designer thinks
this level looks better with this or that option, let him say it in this
file.
*Note style.xml reference: Map style.xml.
3.1.15 teams.xml
----------------
In this file one can specify per-map team settings. In short, this is
where you can say how many bots you want, which color, and so on. This
can be on a per-map basis, so that each map has different customized
settings, some maps might be fun with only one bot, some other maps
might be fun packed with 8 opponents.
Technically, 'teams.xml' will allow you to define up to 4 players and
9 bots. This is an awfull lot considering there are only 10 colors.
Basically, it's OK to simply define:
* 2 players ('player1' and 'player2')
* 4 bots ('bot1' and 'bot2')
It might also be a clever idea to just set up 'player2' and 'bot1'
being the same color, in case of a conflict the game will pick up
another color, but in practice those two entries often correspond to
"the second player, bot or human, coming on the battlefield".
All in all, this represents 5 entries to set up (main player, other
player or first bot which can be the same, then 3 more bots), it's OK to
have the rest undefined or set to defaults.
Note that this can also simply be unset, and in that case the game
defaults will apply, and the user will be able to change them, whereas
if you set these up, the player will somewhat force to used the map
settings.
*Note teams.xml reference: Map teams.xml.
3.1.16 Resampling
-----------------
This is a very important point. Liquid War almost *always* resamples
maps, unless you ask it not to do it. This is not recommended, it is
believed in the general case, letting the internal algorithm make its
own decisions is better than trying to figure out oneself "which is the
best resolution".
The reason is, the right resolution (we're talking here of the
logical resolution, how many fighters wide is the battlefield) often
depends on the speed and general ressources the of the computer the
program is running on. The map designer does not have this information.
The program does. It runs a bench at startup. So this way it can
choose, at runtime, the resolution which fits best.
The recommended way of doing things is not to try to be too picky
about 'rules.xml' parameters related to speed and also let the default
map size limits in 'hints.xml' to their defaults. Do not use them
unless debugging stuff. Then the program will resample the map so that
the player can play on it at a reasonnable speed. If map is too big,
and it's often the case, then it will downsize it until there are
sufficiently few fighters so that the CPU can handle the job. This, of
course, is not rocket science. The bench calculation is a somewhat
brute-force approach of doing things. Formally, we would have to run
the map for good to figure out what is the right speed. Still, this
bench gives good approximations.
Previous versions of the game relied heavily on 'fighter-scale' to
resample maps, but this is not the case anymore. The 'fighter-scale' is
now a minor parameter which is used to upsize maps if they are too
small. In 99.9% of the cases, the map is first upsized by
'fighter-scale' for this parameter is by default set low (1.0) then
downsized by 'bench-value' for real-life personnal computers can't
handle 1600x1200 maps in real-time. Not yet.
There are a bazillion options to control map size, including
'min-map-surface'. They are here because it's important that,
ultimately, people can do whatever they want with the game. But for map
design, this is another story. Don't use them. Rely on 'bench-value'
and just care about game speed. This is achieved by changing the
"speed" parameter.
3.1.17 Music
------------
It is possible to store your own custom music file within the map
directory. You can call it whatever you want (you can keep its original
name, which is something music authors usually appreciate, even if
there's no strong "attribution" clause on the license, it can be
considered fair use not to fiddle to much with the name) you just have
to place it in the same directory than the other files like 'map.png' or
'texture.jpeg'.
The following formats are known to work with the default SDL_mixer
(http://www.libsdl.org/projects/SDL_mixer/) based 'mod_ogg' backend:
* 'ogg' (Ogg Vorbis (http://www.vorbis.com/) files)
* 'wav'
* 'midi' (extensions '.mid' and '.midi' should both work)
* 'mod', 's3m' and 'xm' files, AKA "modules".
To be more precise, here's how things work:
* step 1: the game tries to find the file 'music-file' (parameter
taken from 'style.xml' or defined/overriden by player) in the
current map directory; step 2: if not found, it will try every path
in 'music-path' to find this file. This includes the "system"
music directory with musics that ship with the game, but also the
'./music' subfolder in the user directory; step 3: if still not
found, it will try to play a random file, relying on 'music-filter'
to ignore some files.
3.1.18 Experience ("exp")
-------------------------
In 'rules.xml' you can set a special parameter which is 'exp' and allows
you to tell "a player can't load this map if he doesn't have at least
'N' at his/her 'exp' rating". Gaining 'exp' (stands for "experience")
isn't hard, you just need to win a level with 'exp=N' to gain 'exp=N+1'.
By default, the player's 'exp' is 0 and levels default to 1, so this
means only levels with 'exp' set explicitely to 0 in 'rules.xml' might
be used. Then player wins that level and is given access to all maps by
default, unless these are explicitely set with 'exp' greater than 1.
In solo game, when a player wins a level, he's automatically
redirected to the map which is in the same directory and has exactly the
'exp' he just gain. For instance, if you win a map with 'exp=5' then
you're chained to the first map (in alphabetical order) which has
'exp=6'. By setting up the 'exp' parameter the right way, with a map
for each 'exp' level one can transform a simple map directory in a
scenario that player will automatically follow.
Last, but not least, the game, at startup, only allows you to play
red, green, blue and yellow. Other colors are unlocked as you progress
among levels. Same things with weapons, there are "liberated"
continuously through the game.
This mechanics allows the following behavior:
* when game is launched first, only a small subset of maps are
accessible
* after you win one map (sort of quite easy) you gain access to the
next level, plus many of the maps of the 'extra' package.
* after each map you win, you're redirected to the next map, and
regularly, you gain access to new colors/weapons
As a final word, yes, it's possible to cheat, fool the exp system,
but it's believed this is moot and lame.
3.2 Translating
===============
3.2.1 Using gettext
-------------------
Liquid War 6 uses GNU gettext (http://www.gnu.org/software/gettext/) for
all its messages. There's an online manual
(http://www.gnu.org/software/gettext/manual/gettext.html) about this
tool. In practice, what you have to do as a translator is to edit the
'po/xx.po' file with 'xx' being your language / country code. For
instance, to translate the game in French, one needs to edit 'po/fr.po'.
3.2.2 Formatted strings
-----------------------
This is very important, you might already be aware of it if you are
familiar with gettext, but still it's worth mentionning : when a string
contains special characters such as '%d' or '%s' (in a general manner,
anything with a '%' it's important that all translations contain exactly
the same number of '%d's and '%s's than the original.
For instance:
"foo has %d bars (%s)"
can be translated to:
"ziblug zdonc %d zuc - %s - tac"
The number, order and type of '%' entries is preserved. To learn
more about these formats, use 'info printf' or 'man 3 printf'. In a
general manner, get informations about printf
(http://en.wikipedia.org/wiki/Printf).
Additionnally, some strings are used by Scheme (Guile) code and not
by C code. Thus, they don't use the standard C/printf convention. In
these strings, what you must preserve and be aware of is the tilde
character '~'. Very often you'll see '~a' in a string. As with the
printf '%', you must preserve the number, order and type of those.
There is a complete online reference
(http://www.gnu.org/software/guile/manual/html_node/Formatted-Output.html)
about this way of formatting strings.
3.2.3 Partial translation
-------------------------
Liquid War 6 has thousands and thousands of messages which could
theorically be translated. In practise it's counter-productive to spend
time to translate those, as the game is still evolving constantly, and
as most of these messages are technical messages which inform about rare
bugs and strange conditions. All sort of informations which, while
valuable, are not intented for end-users and are more destinated to be
reported in bug reports. To select only the interesting messages to
translate, the current gettext configuration only uses a reduced set of
files.
* 'src/scriptpo.c' : the most important file. It contains the
definitions used by all the Guile code, this is where you'll find
all the menu labels.
* 'src/lib/sys/sys-log.c' : log messages and keywords. These are not
the log messages themselves, it only concerns the log engine. One
can for instance replace 'WARNING' by 'ATTENTION'.
* 'src/lib/hlp/hlp-credits.c' : the credits, which are displayed at
game startup in the splash screen.
* 'src/lib/lw6-print.c' : contains some messages printed on the
console.
As a side note, the file 'src/lib/hlp/hlp-reference.c' contains all
the entries for the various configuration options, anything that can be
queried by 'liquidwar6 --about='. This is several hundred
messages. It might be interesting to translate them some day, but it's
obviously not a priority today.
3.3 Architecture
================
3.3.1 C + Guile
---------------
Technically, Liquid War 6 is a collection of C functions which are
exported to Guile. The main binary embeds a Guile interpreter, which
will run a Guile script. This script calls the exported C functions,
and glues them together.
It should be possible to implement the game without using Guile at
all, using C code to make the various modules communicate together.
This might seem an easier way to go, not involving several languages.
However, using this script level is a good way to achieve several
important goals:
* it's possible, at any time, to query the game about its internal
state, dump objects, take actions. That's what the console is
about. It's a bit like having an embedded debugger, it's really a
very convenient tool to develop, make experiments and track
problems.
* many hacks can be done without recompiling anything at all. Simply
edit a few files with an editor, and your patch is running. Once
the binary base is set up, hacking scripts on top of it is (almost)
a piece of cake.
* forcing the program to use scripts to transfer informations from a
module to another is a good way to avoid "spaghetti" code, when
modules cross-use each other in an uncontrollable way. Of course
in some cases, modules communicate directly, especially when
performance is important. But for many tasks, it's just very
comfortable and safe to have module A send orders to module B
through a high-level script API.
Having Guile to implement high-level stuff also decreases, to some
extent, the need for object-oriented features of C++. The big picture
is : low level code that require speed, optimized data processing, is
written in C. Code which is more high level and requires abstraction is
written in scheme.
3.3.2 Threading and SMP
-----------------------
Liquid War 6 makes a heavy usage of threads. Early versions of the game
did not have this feature but starting with 0.0.7beta, one can really
consider the game is heavily threaded.
There's basically:
* a thread to handle the main control flow. This thread runs scheme
code which Guile. It's not the most CPU-greedy thread, but when
it's stalled, there's no more interaction between the user and the
program.
* a thread to handle the display. Depending on rendering options,
this thread can consume lots of CPU cycle. On a single
processor/core system, it can be interesting to lower rendering
options in order to gain speed on other aspects of the game. On a
quad-core system, it's probably useless, just play with all bells
and whistles activated.
* two threads to run the core algorithm. One maintains the so-called
reference state, the other being dedicated to the draft sate. In a
local game there's no draft state so only one of those two threads
is used. There's even a technical optimization which can be turned
on and can theorically use even more threads and be efficient on
very big maps but well, it's rather untested and still has to prove
its real efficiency.
* a thread to handle map loading. This one is not active all the
time, it's just here to keep a preemptive interface while loading
complex maps.
* network code can also fire threads, especially when connecting on
remote systems.
So globally, if you have an SMP system, the game will be happy with
it. It will also run on a single processor, as the program uses POSIX
pthreads it's capable to run on any computer which has pthreads
implemented for it.
But, and this is a strong limitation, without pthreads, the game
won't run. At all. Or at least, not unless it's almost completely
rewritten.
3.3.3 Internal libraries
------------------------
The C code is splitted into several internal libraries. This allow
independant testing of various game modules.
The main module, the most important one, is 'libker', (stands for
"kernel"). This is were the core algorithm is. To some extent, the
rest of the code is just about how to provide this module with the right
data and environment. Logically, if you profle the game, you should
find out that a great part of the CPU time is spent here. Code here is
about spreading gradients, moving fighters and cursors.
The 'libmap' module is here to handle maps, it contains the code to
manipulate maps in memory. But it does not know how to load them from
disk. This is the responsability of another module, 'libldr', which is
linked against libraries such as libpng
(http://www.libpng.org/pub/png/libpng.html) or libjpeg
(http://www.ijg.org/) and does the job of transforming those standard
formats into a usable in-memory structure. The 'libgen' module also
works the same way, creating pseudo-random maps. There's still a
another moduled involved in map handling, it's 'libtsk', whose job is to
load a level in the background. It has a 2-steps asynchronous loading
system which allows the game to load maps while the user interface is
still responsive, and give a preview of the map as soon as possible,
when loading continues in the background, building optimizing structures
which are usefull when playing but not mandatory just to show the map.
At the other end of the algorithm-chain, the 'libpil' module will
"pilot" things. It's this module which will translate text readable
orders (typically adapted for network usage) into function calls. It
has event lists, keeps them in the right order, and will also
permanently maintain three different states of the game. A backup state
which can be used any time to go back in time and get the game in a
stable 100% sure state. A reference state which is correct but ever
changing. Basically backup plus all the orders received between backup
and reference gives reference. And finally a draft state which is as up
to date as possible but might be wrong. This is typically interesting
in network game, where we want to show something moving, something fast,
even if there's lag on the network and other computers fail to send
information in time. In this case we display draft while still keeping
reference and updating it when we finally receive valid informations.
Backup would be used to send bootstrap information when people are
joining a new game, or to check up if things are going right.
A special 'libbot' module is here to handle bot algorithms. A bot is
just a simple 'move' function which takes a game state as an input, and
returns an 'x,y' position, just the way a mouse handler would. How
complex a bot is "under the hood" depends on the type of bot. Current
bots are really basic. Additionnally, 'libsim' will run dummy fight
simulations to find out wether some team has a real advantage on another
one, speaking of team profiles depending on colors.
The 'libgfx' module handles all the graphics stuff. It is itself
splitted in several sub-modules, that is, it does not do anything but
load a module such as 'mod-gl1' which will actually contain the
implementation. In an object-oriented language, it would be an abstract
class, an inteface. The implementation does not need to be thread-safe.
It's better if it is, for theorically it could be possible to fire
Liquid War 6 with two display backends running at the same time on the
same game instance, but this code has yet to be written, and it's a rare
dual headed configuration which probably has no real-life usage. If
only one graphics backend is activated at a time, the rest of the
implementation garantees there will never be two concurrent calls to a
function is this module. It is the 'libdsp' ("display") which handles
this. It fires a thread for rendering purposes, and sends information
to this thread, detecting automatically if it's necessary to acquire a
mutex and update rendering informations. For the caller, this is
transparent, one just has to call an update function from time to time.
The module will even perform "dirty-reads" on a game state being
calculated, to render things in real time, as soon as possible.
An experimental 'libvox' module is under design/development and
might, in the future, provide a real-time voxel renderer. Still
pre-alpha stage.
To ease up the implementation of different graphics backends, a
'libgui' module contains code which is meant to be used by any graphics
backend. It's just a factorisation module, containing common code and
interfaces, related to displaying things. This is where, for instance,
one can find a high level menu object. In the same spirit, 'libmat'
contains generic math, vector and matrix code, which is commonly used in
3D interfaces.
The 'libsnd' module handles sound. It's also an abstract class, an
interface, which uses dynamic backends as implementations.
The 'libnet' module is a wrapper over different network APIs, it
handles Winsock and POSIX sockets in a uniform manner. The 'libcli' and
'libsrv' contain network client and server code, implementing the
various protocols in dynamically loadable sub-modules. It's the role of
'libp2p' to glue this together, handle the list of available servers,
the message queue, verifying nobody is cheating, and so on. All this
modules share information about current game state using code &
structures defined in 'libnod',use message utilities (format, parse)
defined in 'libmsg' and share code concerning connections in 'libcnx'.
Additionnally, 'libdat' provides facilities to store old network
messages and sort them.
The 'libsys' module contains most system and convenience functions,
it handles logs, type conversions, timer, memory allocation, it's the
fundamental module every other module depends on. It has a compation
'libglb' module with all the Gnulib
(http://www.gnu.org/software/gnulib/) shared code.
The 'libhlp' is used to handle keywords and internal
self-documentation (this is what is used by '--list' and '--about'),
'libcfg' knows how to read and save config files, 'libcns' handles the
console, and 'libdyn' can load '.so' shared files dynamically.
To glue all this, there are some Guile bindings with helper functions
available in 'libscm' which fills two needs, one being an easy way to
check if Guile linking is working correctly without requiring all other
modules to be available, and also performing automatic checks on some
actions such as registering or executing a function.
Finally there are small modules like 'libimg' (to make screenshots of
the game) which have been separated because they required special
libraries to link with and/or did not really fit in existing modules for
dependencies reasons.
So well, this is a lot of modules. The list might move a bit, but
the big picture is here. Each module is testable separately.
Below is a Graphviz (http://www.graphviz.org/) diagram, which shows
the modules dependencies.
3.4 Memory structures
=====================
The most important memory structures in Liquid War 6 are:
* map ('lw6map_level_t') : this contain the map immutable
informations. This is what resides in memory after a map has been
loaded from the disk. It contains all the various '.png' and
'.jpeg' files stored as pixel arrays, resampled if need, and also
contains the various map attributes. Once this structure is ready,
the game is capable of displaying the map on the screen, but it can
not do anything with it yet.
* game_struct ('lw6ker_game_struct_t') : this one contains the same
informations as the previous structure, only the information has
been post-treated so that it's ready for use by the core algorithm.
It will, for instance, contain the famous mesh structure, which
groups squares by packets of 1, 4, 16, 64 or more. The reason it's
been separated from the level is that operations such as creating
the mesh might require a lot of time. So to allow players to see
the level while black magic is still running in the background, it
was required to make a difference between what is required to view
the map ("level") and what is required to play on it
("game_struct").
* game_state ('lw6ker_game_state_t') : contains all the variable,
ever changing game data. This is where the position of fighters is
stored, their health, and such things. It is designed to be
synchronizable by using mostly simple calls to 'memcpy'. It
heavily relies on the previous structures, the idea is that one can
have several "game_state" plugged on a single "game_struct".
All these structures are defined in the 'ker/ker.h' header.
3.5 100% predictable algorithm
==============================
The core Liquid War 6 algorithm is 100% predictable, that is to say,
given the same input, it will produce the same results, on any computer.
Previous versions of the game also had this property. This is very
important for network games, since in a network only informations such
as "cursor A is at position x,y" are transmitted. Every node maintains
its own internal game state, so it's very important that every node
comes with the same output given the same input.
For this reason Liquid War 6 never uses floating point numbers for
its core algorithm, it uses fixed point numbers instead. It also never
relies on a real "random" function but fakes random behavior by using
predictable pseudo-random sources, implementation independant, such as
checksums, or modulos.
There are also some optimizations which are not possible because of
the predictability requirement, for instance one can not spread a
gradient and move the fighters in concurrent threads, or move fighters
from different teams in different threads.
If you read the code, you'll find lots of checksums here and there, a
global checksum not being enough for you never know where the problem
happened. The test suite uses those facilities to garantee that the
game will run the same on any platform.
Not being able to rely on a predictable algorithm would require to
send whole game states on the network, and this is certainly way too
much data to transmit. A moderate 200x200 map has a memory footprint of
possibly several megabytes, so serializing this and sending it to
multiple computers at a fast-paced rate is very hard, if possible at
all, even with a high bandwidth. We're talking about Internet play
here.
3.6 Graphics backends
=====================
3.6.1 Modularity
----------------
Liquid War 6 has a modular architecture which allows the programmer (and
the player) to plug pretty much any rendering/graphics backend, provided
this one is... developped.
As of 2009 the only available backend was 'mod-gl1', it would display
the game using 3D acceleration, if available, through the SDL
(http://www.libsdl.org/) library, using its GL bindings.
As of 2012, other backends are begin developped, the idea is that
each backend can provide the user with enough visual feedback to play,
and convey input informations to the core engine.
The rest of the game is exactly the same, this means playing with
'mod-gl1' you can do exactly the same things than with 'mod-caca'.
3.6.2 List of backends
----------------------
* mod-gl1
Liquid War 6 has a modular architecture which allows the programmer
(and the player) to plug pretty much any rendering/graphics
backend, provided this one is... developped.
As of 2009 the only available backend is still 'mod-gl1', it will
display the game using 3D acceleration, if available, through the
SDL (http://www.libsdl.org/) library, using its GL bindings.
Additionnally, versions available for Microsoft Windows and Mac OS
X will probably never any other backends available. For technical
reasons, those platforms do not have the flexibility of GNU/Linux
and do not allow graphical libraries to be loaded dynamically. In
practice, both of them require hacks that override the standard
'main' function. Microsoft Windows has its 'WinMain' instead, and
Mac OS X is even more pedantic, requiring graphical functions to be
executed in the main thread. So 'mod-gl1' is just linked
statically in those versions, and the modularity of the game is
purely theorical on these platforms.
This 'mod-gl1' module is really one of the key stones of Liquid War
6, and if you want to change graphical things, it's definitely the
place to hack on. The source is in 'src/lib/gfx/mod-gl1'.
The 'mod-gl1' backend requires "moderate" hardware, but it still
does require hardware acceleration. Pure software rendering
through mesa (http://www.mesa3d.org/) for instance, won't be
enough.
So if you're running Xorg on GNU/Linux and there's a DRI driver for
your card, the game should run fine.
On the programmer side, the counterpart is that one should not rely
on fancy OpenGL features. Textures have a maximum size of 512x512
for instance. Of course some maps are bigger than this but this
means that internally, 'mod-gl1' splits them into smaller tiles,
and displays those tiles one by one.
Inside the 'mod-gl1' backend, the 'src/lib/gfx/mod-gl1/gl-utils'
directory contains lots of common structures, factorized functions
which can (and should, if appliable) be used.
* mod-gles2
This is under development, the idea is to provide an alternative
renderer based on OpenGL ES 2, which could be used on standard
computers but also on mobile platforms.
Work in progress, don't hold your breath.
* mod-soft
This is under development, the idea is to provide a very basic
rendered which can be compiled pretty much anywhere as long as SDL
is available, since it does use software rendering only.
Work in progress, don't hold your breath.
* mod-caca
This is under heavy development, the idea is to provide a basic yet
surprising alternative text-based renderer, using libcaca.
3.6.3 How to write a new backend
--------------------------------
The starting point for any hack are the files 'src/lib/gfx/gfx.h'. This
is where the API is defined.
Basically, the type 'lw6gfx_backend_t' contains all the required
callbacks. You must provide an implementation for each function.
Let's take an example, taken from 'mod-gl1'. When calling
'lw6gfx_get_video_mode' and passing it a first argument which is a valid
'mod-gl1' backend, the function 'mod_gl1_utils_get_video_mode' will be
called. How this is done is a little C casting wizardry.
To understand how this works, read the files:
* 'src/lib/gfx/gfx-api.c': contains all the functions which are part
of the API and can be called elsewhere in the code.
* 'src/lib/gfx/gfx-register.c': contains the code that allows a
module to be loaded/unloaded at runtime. Will act differently if
the games is compile with the '--allinone' flag, but for the caller
this is transparent, just create and destroy backend, period.
* 'src/lib/gfx/mod-gl1/mod-gl1-backend.c': this is where the module
actually binds its internal functions with the callbacks defined in
the 'lw6gfx_backend_s' struct. None of these internal functions
should be called directly, code in 'libdsp' for instance should
only refer to the 'lw6gfx_...' bindings. Reading the code in
'src/lib/gfx/gfx-test.c' shows how these functions can be called,
and in which order.
All the functions should be defined, but some of them are obviously
more important. The two most critical functions are:
* 'pump_events' This is used to process inputs. The function should
update a 'lw6gui_input_s' struct and return it to the caller. How
this done is really up to the backend, it happens that all SDL
based backends ('mod-gl1', 'mod-gles2' and 'mod-soft') share the
same code for this, but another backend could do this differently,
there's no real need to use SDL.
Only, the returned input should behave correctly when queried with
function from 'libgui'. As a consequence, one needs to have a look
at 'libgui' to understand how input works. A look at
'src/lib/gfx/shared-sdl/shared-sdl-event.c' is a good example of
this, as this file contains the implementation for SDL-based input.
*Note libgfx reference: libgfx. *Note libgui reference: libgui.
* 'display' By far the most complicated function, this one is called
on each display loop to render the game. It's always used in the
same thread, so need not be reentrant, and on some platforms (eg
Mac OS X) it will even be called in the main thread (this can be of
some importance regarding some libraries such as SDL).
Still, beware, the 'game_state' object it uses can change on the
fly while rendering. In that case "changing" means that fighters
can move and gradients be updated but the global structure won't
change. So any pointer on a fighter will still be valid after it's
been obtained, but the renderer should not expect the game to be
static. In practice this is not really a problem. If you are
curious, you can look in 'libdsp' how and when this function is
called.
A very important parameter is 'mask', depending on its value, the
backend should, or not, display the menu, or the map, or both, etc.
The reference for this are the 'LW6GUI_DISPLAY_...' constants in
'src/lib/gui/gui.h'.
As a starting point, implementing menu display before anything else
is probably the best bet, since without menus it's hard to do
anything within the game.
To test out a backend, one can either launch the full game using
the "under development" backend, or launch the test suite by typing
'./liquidwar6gfx-test 1' in './src/lib/gfx'.
*Note libdsp reference: libdsp.
3.7 Core algorithm
==================
3.7.1 Introduction
------------------
Since Liquid War 3 (http://ufoot.org/liquidwar/v5/techinfo/algorithm)
the algorithm to power Liquid War is pretty much unchanged, at least,
there has been no revolution, the basic principles remain the same.
This has been explained in Liquid War 5 doc
(http://ufoot.org/liquidwar/v5/techinfo/algorithm), but is repeated
here, along with the specific Liquid War 6 stuff.
The very important things to remember are:
* The algorithm is 100.00% predictable. This means given the same
input, it will give exactly the same output. This is very
important for the network games to work correctly, therefore, the
algorithm does not ever use any call to 'rand' / 'random'
functions, it also does not use any float value either, since
different type of processors/contexts might give slightly different
results because of rounding problems.
* It's a two-pass algorithm, the first step is to calculate the
distance from any point of the map to the closest cursor. This
step is always imperfect, the shortest path is never really found,
the naive approach is to consider that if a place on the map is at
distance 'N' of the cursor, then in the worst case, all adjacent
places are at distance 'N+1'. As of Liquid War 6, the
corresponding code is in 'src/lib/ker/ker-spread.c'. The second
step is to move the fighters, make them act. In Liquid War 6, the
corresponding code is in 'src/lib/ker/ker-move.c'. One can have a
look at the code source for the function
'lw6ker_game_state_do_round' in 'src/lib/ker/ker-gamestate.c' to
see how these are called.
3.7.2 Level, game struct, game state and pilot
----------------------------------------------
Most of the algorithm code has something to do with the following types
(which are structs):
* 'lw6map_level_t' defined in which is used to store the level data.
* 'lw6ker_game_struct_t' defined in 'src/lib/map/map.h' which is used
to store the memory data required by the algorithm, but which are
immutable. There's a difference between those data and the ones
stored in the level struct. For instance, those data are "private"
since 'lw6ker_game_struct_t' is opaque, while everything is
'lw6map_level_t' is "public". Also, data in 'lw6ker_game_struct_t'
might be highly redundant for performance issues and is optimized
for speed while data in 'lw6map_level_t' is just plain data and
won't change if the algorithm is updated.
* 'lw6ker_game_state_t' defined in 'src/lib/ker/ker.h' which is used
to store the level data required by the algorithm, and which
changes during the game. This is typically where an information
such as "there's a red fighter in slot (3,23,1)" will be stored.
* 'lw6pil_pilot_t' defined in 'src/lib/pil/pil.h' which is used to
handle all the threading issues. It keeps a track of 3 game
states. A "reference" state which is the state of the game
considering all input has been received from the network, and is
validated. A "draft" state which might be anticipated and updated
"as if the players we did not get input from did not move there
cursors". This can give the illusion that the game is running
smoothly while in reality input from other players on the network
is choppy. In a local game, "draft" and "reference" are
equivalent, since there's no doubt about what's on the network.
And finally, a "backup" state which can be pulled in case of a
serious flaw and is a good way to solve the "hey, someone untrusted
is throwing garbage on the net". One can always pull a backup.
Most of the time, hacking on the algorithm, changing the gameplay,
does not require to touch anything but the code in 'src/lib/ker'.
See *Note libmap::. See *Note libker::. See *Note libpil::.
3.7.3 Getting informations about where fighters are
---------------------------------------------------
One of the key functions is 'lw6ker_game_state_get_fighter_id', which
will return the id of a fighter at a given position. Then its companion
function 'lw6ker_game_state_get_fighter_by_id' can be called, it will
return a 'lw6ker_fighter_t', which contains the real data.
The type 'lw6ker_fighter_t' is not opaque and can be freely accessed
by the caller, which, typically, is a graphics backend trying to display
informations. Try and grep for the string
"lw6ker_game_state_get_fighter_id" withing the 'src/lib/gfx' source tree
for examples.
One thing that is very important when hacking on 'libker': you should
always leave the 'lw6ker_game_state_t' struct in a state that is
compatible with a correct usage of public "getters" in
'src/lib/ker/ker.h'. The reason is that this code can be executed by
separate threads, more precisely, in "dirty read" mode, the rendering
thread will try and display a "game state" while this very "game state"
is being updated by another thread.
3.8 Compilation tips
====================
3.8.1 Advanced ./configure options
----------------------------------
In addition to all the common Autoconf
(http://www.gnu.org/software/autoconf/) switches such as '--prefix',
Liquid War 6 has some custom switches:
* '--disable-console': allows you to turn on/off console support.
Normally this is detected automatically but in case you really want
to disable it on platforms which support it, you can. This will
cause the program no to link against 'libreadline', among other
things.
* '--disable-gtk': allows you to turn on/off gtk support. Normally
this is detected automatically but in case you really want to
disable it on platforms which support it, you can. This will cause
the program not to link against GTK libs.
* '--disable-cunit': allows you to turn on/off CUnit
(http://cunit.sourceforge.net/) support. Normally this is detected
automatically but in case you really want to disable it on
platforms which support it, you can. This will cause the program
not to link against CUnit libs.
* '--enable-optimize': will turn on optimizations. This will turn on
compiler options such as '-fomit-frame-pointer' but also disable
some code in the program. Indeed, most of the advanced memory
checking in the game - which ensures it does not leak - will be
turned of. This will certainly speed up things, however, it's not
recommended to turn this on until program is not stable enough so
that memory leaks and other problems can be declared 'impossible'.
Turn this on if you really have some speed problem, otherwise it's
safer to use the full-featured 'slow' version of the game.
* '--enable-paranoid': will turn on very picky and pedantic checks in
the code, try this when you suspect a serious memory bug, a race
condition whatsoever, and want to track it down. Useless for
players.
* '--enable-headless': will allow compilation without any graphics
backend. The game is unplayable in that state but one can still
wish to compile what is compilable, for testing purposes.
* '--enable-silent': will allow compilation without any sound
backend. The game won't play any music in that state but one can
still wish to compile what is compilable, for testing purposes.
* '--enable-allinone': will stuff all the internal libraries into one
big executable. Very convenient for profiling. The major drawback
is that you need to have all the optional libraries installed to
compile all the optional modules. Another side effect is that with
this option there's no more dynamic loading of binary modules, so
if your platform has a strange or buggy support for '.so' files,
this option can help.
* '--enable-fullstatic': will build a totally static binary, that is
using the '--static' option for 'gcc' and the '-all-static' option
for 'libtool'. Currently broken, this option could in the future
allow for building binaries that run pretty much everywhere,
without requiring any dependency but a Kernel.
* '--enable-gprof': will enable profiling informations. This will
activate '--enable-allinone', else you would only track the time
spent in functions in the main 'liquidwar6' executable, and exclude
lots of interesting code contained in dynamic libraries.
* '--enable-instrument': will instrument functions for profiling.
This will turn on the '-finstrument-functions' switch when
compiling, so that the hooks '__cyg_profile_func_enter' and
'__cyg_profile_func_exit' are called automatically. Then you can
link against tools like cprof (http://cprof.sourceforge.net/) or
FunctionCheck (http://sourceforge.net/projects/fnccheck/).
* '--enable-profiler': will enable Google Performance Tools
(http://code.google.com/p/google-perftools/) support. Basically,
this means linking against 'libtcmalloc' and 'libprofiler'. You
could activate those by using 'LD_PRELOAD' or by using your own
'LDFLAGS' but using this option will also make the game tell you if
'CPUPROFILE' or 'HEAPPROFILE' are set when it starts. The 'pprof
-gv' output is very handy. Note that on some systems 'pprof' is
renamed 'google-pprof'.
* '--enable-gcov': will enable coverage informations, to use with
gcov (http://gcc.gnu.org/onlinedocs/gcc/Gcov.html) and lcov
(http://ltp.sourceforge.net/coverage/lcov.php). This is for
developpers only. It will activate '--enable-allinone', else there
would be some link errors when opening dynamic libraries. The
obtained information is available online: coverage
(http://www.ufoot.org/liquidwar/v6/doc/coverage/). and GNU global
(http://www.ufoot.org/liquidwar/v6/doc/global/).
* '--enable-valgrind': will enable some 'CFLAGS' options which are
suitable for the use of Valgrind (http://www.valgrind.org/), to
track down memory leaks and other common programming errors. Use
for debugging only, usually together with '--enable-allinone'.
3.8.2 Debian packages
---------------------
Liquid War 6 does have a './debian' in both main and extra maps
packages, so it's "debianized". To build the main '.deb' package, untar
the main source tarball, then:
make dist
cd pkg
cp ../liquidwar6-X.Y.Z.tar.gz . # X.Y.Z is the version
make deb
Note that you have to copy the source tarball to './pkg' and move to
this directory before typing 'make deb'. This is, among other things,
to simplify the main 'Makefile'.
To build the extra maps '.deb' package, untar the extra maps tarball,
then:
make deb
3.8.3 Red Hat packages
----------------------
Liquid War 6 does have a '.spec' files in both main and extra maps
packages. To build the main '.rpm' package, untar the main source
tarball, then:
make dist
cd pkg
cp ../liquidwar6-X.Y.Z.tar.gz . # X.Y.Z is the version
make rpm
Note that you have to copy the source tarball to './pkg' and move to
this directory before typing 'make rpm'. This is, among other things,
to simplify the main 'Makefile'.
To build the extra maps '.rpm' package, untar the extra maps tarball,
then:
make rpm
3.8.4 Microsoft Windows msys/mingw32 port
-----------------------------------------
This section describes how to compile the game from source under
Microsoft Windows. Note that players are encouraged to use a free
system such as GNU/Linux, which is the platform Liquid War 6 is being
hacked on by default. If you encounter problems with this port, you'll
probably save time by installing a double-boot with GNU/Linux coexisting
with your previous Microsoft Windows install.
Basically, Liquid War 6 requires MinGW (http://www.mingw.org/). More
precisely, it requires MSYS (http://www.mingw.org/msys.shtml). A
standard Cygwin (http://www.cygwin.com/) installation won't work,
because it is too UNIXish to allow third party libraries like SDL
(http://www.libsdl.org/) to compile natively. You might argue that SDL
is available for Cygwin, but in reality, the Cygwin port of SDL is a
MinGW port. Indeed, Cygwin brings all standard POSIX functions
including the use of 'main' instead of 'WinMain' and I suspect this is a
problem for graphical libraries like SDL which do require some sort of
direct access to the OS low-level functions. Therefore, MinGW is more
adapted for it does not define all these functions, and allows any
library to hook on Microsoft Windows internals directly. Point is then,
you also loose the cool effect of Cygwin which is to have a complete
glibc (http://www.gnu.org/software/libc) available, including network
functions like 'select' defined the POSIX way, and not the WinSock way.
If you ever ported code from POSIX sockets to WinSock 2, you know what I
mean. Using MinGW is also embarassing for some libraries won't compile
easily, and for instance programs which heavily rely on a real 'TTY'
interface to work are usually hard to port. This includes ncurses
(http://www.gnu.org/software/ncurses/) and GNU readline
(http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html). Liquid War 6
tries to have workarrounds for all this, and in some cases the
workarround is simply that embarassing code is not compiled on Microsoft
Windows. For this reason, some features are not available on this
platform. Period.
Now the reason you need MSYS and not only MinGW is that MSYS will
allow './configure' scripts to run, and this eases up the porting
process a lot. MinGW and MSYS packages are downloadable on the
SourceForge MinGW download page
(http://sourceforge.net/project/showfiles.php?group_id=2435).
Alternatively, there is a mirror on ufoot.org
(http://www.ufoot.org/download/liquidwar/v6/mingw32/pkg/), but files
might be outdated.
To compile Liquid War 6, first download and unzip all the following
files in the same directory, for instance 'C:\MSYS'. If you do not have
any tool to handle '.tar.gz' and '.tar.bz2' files under Microsoft
Windows, which is likely to be the case when MSYS is not installed yet,
you can untar these on any GNU/Linux box, then upload the whole
directory to the target Windows host.
* autoconf2.5-2.61-1-bin.tar.bz2
* autoconf-4-1-bin.tar.bz2
* autogen-5.9.2-MSYS-1.0.11-1-bin.tar.gz
* autogen-5.9.2-MSYS-1.0.11-1-dev.tar.gz
* autogen-5.9.2-MSYS-1.0.11-1-dll25.tar.gz
* automake1.10-1.10-1-bin.tar.bz2
* automake-3-1-bin.tar.bz2
* bash-3.1-MSYS-1.0.11-1.tar.bz2
* binutils-2.18.50-20080109-2.tar.gz
* bison-2.3-MSYS-1.0.11-1.tar.bz2
* coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
* crypt-1.1-1-MSYS-1.0.11-1.tar.bz2
* csmake-3.81-MSYS-1.0.11-2.tar.bz2
* cvs-1.11.22-MSYS-1.0.11-1-bin.tar.gz
* diffutils-2.8.7-MSYS-1.0.11-1.tar.bz2
* findutils-4.3-MSYS-1.0.11-1.tar.bz2
* flex-2.5.33-MSYS-1.0.11-1.tar.bz2
* gawk-3.1.5-MSYS-1.0.11-1.tar.bz2
* gcc-core-3.4.5-20060117-3.tar.gz
* gcc-g++-3.4.5-20060117-3.tar.gz
* gcc-g77-3.4.5-20060117-3.tar.gz
* gcc-objc-3.4.5-20060117-3.tar.gz
* gdb-6.8-mingw-3.tar.bz2
* gdbm-1.8.3-MSYS-1.0.11-1.tar.bz2
* gettext-0.16.1-1-bin.tar.bz2
* gettext-0.16.1-1-dll.tar.bz2
* gettext-0.16.1-MSYS-1.0.11-1.tar.bz2
* gettext-devel-0.16.1-MSYS-1.0.11-1.tar.bz2
* inetutils-1.3.2-40-MSYS-1.0.11-2-bin.tar.gz
* libiconv-1.11-1-bin.tar.bz2
* libiconv-1.11-1-dll.tar.bz2
* libiconv-1.11-MSYS-1.0.11-1.tar.bz2
* libtool1.5-1.5.25a-1-bin.tar.bz2
* libtool1.5-1.5.25a-1-dll.tar.bz2
* libtool1.5-1.5.25a-20070701-MSYS-1.0.11-1.tar.bz2
* lndir-6.8.1.0-MSYS-1.0.11-1.tar.bz2
* lpr-1.0.1-MSYS.tar.gz
* lzma-4.43-MSYS-1.0.11-1-bin.tar.gz
* make-3.81-MSYS-1.0.11-2.tar.bz2
* mingw-runtime-3.14.tar.gz
* mingw-utils-0.3.tar.gz
* minires-1.01-1-MSYS-1.0.11-1.tar.bz2
* MSYS-1.0.11-20071204.tar.bz2
* msysCORE-1.0.11-2007.01.19-1.tar.bz2
* openssh-4.7p1-MSYS-1.0.11-1-bin.tar.gz
* openssl-0.9.8g-1-MSYS-1.0.11-2-bin.tar.gz
* openssl-0.9.8g-1-MSYS-1.0.11-2-dev.tar.gz
* openssl-0.9.8g-1-MSYS-1.0.11-2-dll098.tar.gz
* perl-5.6.1-MSYS-1.0.11-1.tar.bz2
* perl-man-5.6.1-MSYS-1.0.11-1.tar.bz2
* regex-0.12-MSYS-1.0.11-1.tar.bz2
* tar-1.19.90-MSYS-1.0.11-1-bin.tar.gz
* texinfo-4.11-MSYS-1.0.11-1.tar.bz2
* vim-7.1-MSYS-1.0.11-1-bin.tar.gz
* w32api-3.11.tar.gz
* zlib-1.2.3-MSYS-1.0.11-1.tar.bz2
This file list might contain file which are not absolutely mandatory
for Liquid War 6, for instance the Fortran 77 compiler is absolutely
useless, but installing it won't harm either. Some packages might unzip
things the right way, but some do it in a subfolder. You might need to
run commands like:
cp -r coreutils*/* .
rm -rf coreutils*
Get rid of useless files:
rm ._.DS_Store .DS_Store
It's also mandatory to move everything that has been installed in
'/usr' or '/usr/local' to '/' since MSYS has some builtin wizardry which
maps '/usr' on '/'. You need to do this if you don't unzip files from a
MinGW shell, which is obviously the case when you first install it.
Usefull command can be:
mv usr/* .
rmdir usr
Next, 'libintl' is not correctly handled/detected by LW6, and can
raise an error like '"gcc.exe: C:/msys/local/lib/.libs/libintl.dll.a: No
such file or directory"' so one needs to copy some libraries in
'/usr/local/lib/.libs/':
mkdir local/lib/.libs
cp local/lib/libintl.* local/lib/.libs/
Another step is to edit '/etc/profile' and add lines like:
export CFLAGS="-g -I/usr/local/include"
export LDFLAGS="-L/usr/local/lib"
export GUILE_LOAD_PATH="C:\\MSYS\\local\\share\\guile\\1.8\\"
Close and re-launch your msys shell (rxvt) so that these changes take
effect. Check that those values are correctly set:
env | grep FLAGS
env | grep GUILE
Finally, your MSYS environment is (hopefully...) working.
Now you need to compile the following programs, from source. Files
are mirrored on ufoot.org
(http://www.ufoot.org/download/liquidwar/v6/mingw32/src/) for your
convenience, however these might be outdated. Still, there are known to
work. Proceed like if you were under a POSIX system. Some packages use
the '--disable-rpath' swith, there are various reasons for which rpath
is an issue (http://wiki.debian.org/RpathIssue). In the same manner,
'--disable-nls' when linking against 'libintl' or 'libiconv' was
painful.
* pthreads-win32 (http://sourceware.org/pthreads-win32/), untar
pthreads-w32-2-8-0-release.tar.gz then 'make clean GC; cp pthread.h
sched.h /usr/local/include/; cp pthreadGC2.dll /usr/local/bin/; cp
libpthreadGC2.a /usr/local/lib/'
* GNU MP (http://gmplib.org/), untar 'gmp-4.2.2.tar.gz' then
'./configure && make && make install'
* Guile (http://www.gnu.org/software/guile/), untar
'guile-1.8.5.tar.gz'. Edit 'libguile/guile.c' and insert '#undef
SCM_IMPORT' just before '#include '. Edit
'./libguile/threads.c' and place 'struct timespec { long tv_sec;
long tv_nsec; };' just before '#include "libguile/_scm.h"'. Then
'./configure --disable-nls --disable-rpath
--disable-error-on-warning --without-threads && make && make
install'. The 'GUILE_LOAD_PATH' value must be correctly set for
'guile-config' to work. For unknown reasons, running 'guile' can
throw a stack overflow error. Don't panic. See bug 2007506 on
SourceForge.net
(https://sourceforge.net/tracker/?func=detail&atid=102435&aid=2007506&group_id=2435)
for an explanation on why the Guile binary shipped with MSYS is not
suitable for Liquid War 6.
* expat (http://www.libexpat.org/), untar 'expat-2.0.1.tar.gz' then
'./configure && make && make install'
* SQLite (http://www.sqlite.org/), untar
'sqlite-amalgamation-3.5.9.tar.gz' then './configure && make &&
make install'
* libpng (http://www.libpng.org/pub/png/libpng.html), untar
'libpng-1.2.29.tar.gz' then './configure && make && make install'
* libjpeg (http://www.ijg.org/), untar 'jpegsrc.v6b.tar.gz' then
'./configure && make && make install && make install-lib'
* libcURL (http://curl.haxx.se/libcurl/), untar 'curl-7.18.1.tar.gz'
then './configure --without-ssl && make && make install'
* FreeType 2 (http://freetype.sourceforge.net/), untar
'freetype-2.3.5.tar.gz' then './configure && make && make install'
* libogg (http://www.xiph.org/), untar 'libogg-1.1.3.tar.gz' then
'./configure && make && make install'
* libvorbis (http://www.xiph.org/), untar 'libvorbis-1.2.0.tar.gz'
then 'LDFLAGS="$LDFLAGS -logg" && ./configure && make && make
install'
* SDL (http://www.libsdl.org/), untar 'SDL-1.2.13.tar.gz' then
'./configure && make && make install'
* SDL_image (http://www.libsdl.org/projects/SDL_image/), untar
'SDL_image-1.2.6.tar.gz' then './configure && make && make install'
* SDL_mixer (http://www.libsdl.org/projects/SDL_mixer/), untar
'SDL_mixer-1.2.8.tar.gz' then './configure && make && make install'
* SDL_ttf (http://www.libsdl.org/projects/SDL_ttf/), untar
'SDL_ttf-2.0.9.tar.gz' then './configure && make && make install'
For your convenience, a zip file containing a complete MSYS "Liquid
War 6 ready" environment is available. It is simply the result of all
the operations described above. Simply unzip
msys-for-liquidwar6-20080819.zip
(http://www.ufoot.org/download/liquidwar/v6/mingw32/msys-for-liquidwar6-20080819.zip)
(about 240 megs) in 'C:\MSYS\'. All dependencies compiled in '/local'
have been generated using the command:
cd /usr/local/src
./msys-for-liquidwar6-build.sh > ./msys-for-liquidwar6-build.log 2>&1
Note that this script does't do everything, you'll still need to edit
Guile source code and patch it manually.
It might even be possible to use this MSYS environment under Wine
(http://www.winehq.com/). Simply unzip it under '$HOME/.wine/drive_c',
and run 'wine "$HOME/.wine/drive_c/windows/system32/cmd.exe" /c
"c:\\msys\\msys.bat"' and with luck, you'll get a working shell. Note
that this might allow you to compile the game, but running it is another
story. Consider this MSYS over Wine trick as a hack enabling the use of
free software only when compiling for Microsoft proprietary platform.
It is not a reasonnable way to run the game. If running under a UNIXish
platform, or better, GNU, simply run native code. Use the Windows
32-bit port only if you are jailed on a Microsoft system.
Now, let's come to the real meat, untar the Liquid War 6 source
tarball, launch your MSYS shell, and:
./configure
make
make install
Now the binary is in 'src/.libs/liquidwar6.exe' (beware,
'src/liquidwar6.exe' is only a wrapper). This binary is an MSYS/MinGW
binary, so it read paths "à la" Microsoft, that is, it has no knowledge
of what '/usr' is, for instance. It requires paths starting by 'C:\'.
3.8.5 Mac OS X port
-------------------
This is still experimental. Basically, install MacPorts, and most
dependencies with, except for SDL which you compile from source. The
idea is to compile SDL using the native OS X bindings (and not some
other GL files you could have in '/opt/local' installed by MacPorts),
then compile the game and other SDL dependencies against this SDL.
The SDL_mixer library might need to be told to compile itself without
dynamic ogg support. By default it seems that it tries to load
'libvorbisfile.dylib' at runtime, and it can fail. To disable this
dynamic loading, use for instance :
/configure --prefix=/opt/extra --enable-music-ogg --disable-music-ogg-shared
Also, it might seem obvious for Mac OS X users, but there are some
important issues related to compiling options and handling dynamic
libraries at runtime.
* The command 'ldd' does not exist, run 'otool -L' instead.
* The equivalent of 'LD_LIBRARY_PATH' is 'DYLD_LIBRARY_PATH'.
* The extension for shared binaries is '.dylib' and not '.so'.
* You might need to set the 'OBJCFLAGS' environment variable along
with 'CFLAGS' because the Mac OS X port uses some Objective-C code.
It is very important to have the right SDL flags when linking the
Liquid War 6 binaries. For instance it could be:
-I/opt/extra/include -I/opt/local/include -Wl,-framework -Wl,CoreFoundation -I/opt/local/include -D_THREAD_SAFE -Wl,-framework -Wl,Cocoa -Wl,-framework -Wl,OpenGL -Wl,-framework -Wl,Cocoa
The point is to have Cocoa and OpenGL support. Depending on the way
you installed SDL, you might also need to include an SDL framework
support, this is mostly if you installed SDL from .dmg binary images,
and not from source with the command line. A typical output of
'sdl-config --libs' is:
-L/opt/extra/lib -lSDLmain -lSDL -Wl,-framework,Cocoa
Another important issue is to include 'SDL.h', which in turn includes
'SDLmain.h', in all the .c source files defining the standard 'main'
function. This is done in liquidwar6 but should you try to link
yourself on liquidwar6 libraries and/or hack code, you must do this or
you'll get errors when running the game. Such errors look like:
*** _NSAutoreleaseNoPool(): Object 0x420c90 of class NSCFNumber autoreleased with no pool in place - just leaking
The reason is that SDL replaces your 'main' with its own version of
it. One strong implication is that all the dynamic loading of SDL,
which works on sandard GNU/Linux boxes, won't work under Mac OS X, since
SDL hard codes itself by patching 'main' with '#define' C-preprocessor
commands.
A '.dmg' file (disk image) containing a 'Liquid War 6.app' folder (OS
X application) is available for your convenience. It might work or not.
In doubt, compile from source. The complicated part about this package
(a "bundle" is OS X language) is that it needs to embed various
libraries which are typically installed in '/opt' by MacPorts on a
developper's machine. So to build this package a heavy use of the
utilility 'install_name_tool' is required, normally all libraries needed
ship with the binary, remaining depedencies concern frameworks which
should be present on any working Mac OS X install. Still, this is only
theory. Needs to be widely tested.
The layout of the bundle follows:
* './Contents/Info.plist': metadata, bundle description file
* './Contents/MacOS': contains the main binary 'liquidwar6' as well
as all specific low-level libraries
* './Contents/Resources/data': general game data, does not contain
maps.
* './Contents/Resources/music': music for the game.
* './Contents/Resources/map': system maps, you can put your own maps
(or "extra" maps) here if you want all users to share them.
* './Contents/Resources/script': Liquid War 6 specific scripts, the
scheme scripted part of the program.
* './Contents/Resources/guile': common shared Guile scripts, part of
Guile distribution.
* './Contents/Resources/doc': documentation in HTML and PDF formats.
Additionnally, the Mac OS X port uses
'/Users//Library/Application Support/Liquid War 6/' to store
configuration file, logs, etc. It does not use '$HOME/.liquidwar6' like
the default UNIX port.
The Mac OS X port also has a special behavior, in order to load some
libraries with dlopen (SDL_image does this with libpng and libjpeg) it
needs to set 'DYLD_FALLBACK_LIBARY_PATH' to a value that contains these
libraries. This is typically in the bundle distributed on the disk
image. On a developper's computer this problem does not appear for
those libs are often in places like:
* '/usr/local/lib'
* '/usr/X11/lib'
* '/opt/local/lib'
So the program sets 'DYLD_FALLBACK_LIBARY_PATH' (but not
'DYLD_LIBRARY_PATH' else it breaks internal OS X stuff which relies, for
instance, on libjpeg library that has the same name but different
contents) but it needs to do it before it is even run, else the various
'dyld' functions do not acknowledge the change. That is, calling the C
function 'setenv()', even before 'dlopen()', has no effect. So the
program calls 'exec()' to re-run itself with the right environment
variable. This is why, on Mac OS X, there are two lines (exactly the
same ones) displaying the program description when it is started in a
terminal.
3.8.6 GP2X port
---------------
This is not working yet, but there are good hopes that some day, Liquid
War 6 can run on a GP2X console (http://www.gp2xwiz.co.kr/). This
handled gaming device uses a Linux kernel (http://kernel.org) on an ARM
processor, does support most GNU (http://www.gnu.org/) packages through
cross-compilation, and has basic SDL (http://www.libsdl.org/) support.
To compile Liquid War 6 for GP2X, you first need to set up a working
"toolchain". It's suggested you do this on a working GNU/Linux box.
There are several solutions, the recommended one being Open2x
(http://www.open2x.org/). Read the online documentation on how to
install Open2x
(http://wiki.gp2x.org/wiki/Installing_the_Open2x_toolchain).
Basically, the following should work:
mkdir /opt/open2x # check that you can write here
svn co https://open2x.svn.sourceforge.net/svnroot/open2x/trunk/toolchain-new open2x-toolchain
./open2x-gp2x-apps.sh
cd open2x-toolchain
Then, for your environment to be complete, you need to set up some
environment variables. For instance:
export OPEN2X_SYSTEM_PREFIX=/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux
export GP2X_USER_PREFIX=$HOME/gp2x
export CC=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-gcc
export CPP=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-cpp
export CXX=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-g++
export AS=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-as
export CFLAGS=''-I${OPEN2X_PREFIX}/include -I${GP2X_USER_PREFIX}/include''
export CPPFLAGS=''-I${OPEN2X_PREFIX}/include -I${GP2X_USER_PREFIX}/include''
export CXXFLAGS=''-I${OPEN2X_PREFIX}/include -I${GP2X_USER_PREFIX}/include''
export LDFLAGS=''-L${OPEN2X_PREFIX}/lib -L${GP2X_USER_PREFIX}/lib''
export PATH=''${GP2X_USER_PREFIX}/bin:${OPEN2X_SYSTEM_PREFIX}/bin:$PATH''
In this setting, there's a user '$HOME/gp2x' directory which will
contain all the Liquid War 6 related libraries while the '/opt/open2x'
remains untouched.
Then you need to install the requirements. All these packages need
to be cross-compiled. To make things clear and non-ambiguous, even if
you have 'CC' set up in your environment variables, pass '--build' and
'--host' arguments to the './configure' script of all these packages. A
typical command is:
./configure --build=i686-pc-linux-gnu --host=arm-open2x-linux --prefix=${GP2X_USER_PREFIX}
Here's the list of the requirements:
* SDL (http://www.libsdl.org/). 1.2.14 works zith the following
settings: './configure --prefix=$GP2X_USER_PREFIX
--build=x86_64-pc-linux-gnu --host=arm-open2x-linux
--disable-pulseaudio --disable-video-directfb'
* libtool (http://www.gnu.org/software/libtool/). Install a 1.5.x
version, and not 2.2.x. For some reasons, 2.2.x is unusable, it
keeps on complaining that lt_libltdl_LTX_preloaded_symbols is not
defined
(http://lists.cistron.nl/pipermail/freeradius-users/2009-September/msg00149.html).
Apparently the bug has already been reported
(http://www.archivum.info/bug-libtool@gnu.org/2009-01/00014/undefined_lt_ptr).
For Liquid War 6 needs, 1.5.x is very fine, use 1.5.26 for
instance, it works well.
* GNU MP (http://gmplib.org/) (version 4.3.1 reported to work)
* Guile (http://www.gnu.org/software/guile/) (version 1.8.7 reported
to work). You need to pass the '--witout-threads' switch to the
'./configure' script else it will try (and fail!) to run a test
program. Liquid War 6 does not use Guile threads, it does use
threads but uses them "directly" outside the Guile layer.
* zlib (http://www.zlib.net/) (version 1.2.3 reported to work). Do
not use '--build' and '--host' for this one, they are unsupported.
Package compiles fine anyway.
* expat (http://www.libexpat.org/) (version 2.0.1 reported to work).
* libpng (http://www.libpng.org/pub/png/libpng.html) (version 1.2.3
reported to work).
* libjpeg (http://www.ijg.org/) (version 7 reported to work).
* SQLite 3 (http://www.sqlite.org) (version 3.6.18 reported to work).
* libcURL (http://curl.haxx.se/libcurl/) (version 7.19.6 reported to
work).
Next, one needs to install a special version of SDL, which targets
the GP2X specifically. This is not a generic SDL, and it does have
limitations, which are related to the GP2X peculiar hardware. There are
installation instructions
(http://wiki.gp2x.org/wiki/How_to_install_the_SDL_libraries) about how
to do this. The following should work:
cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/open2x login # blank password
cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/open2x co libs-gp2x
3.9 Coding guidelines
=====================
3.9.1 Project goals reminder
----------------------------
One of the purposes of Liquid War 6 is to make a cleaner implementation
of Liquid War than the previous one, namely Liquid War 5
(http://www.ufoot.org/liquidwar/v5). While the latter has achieved the
practical goal of providing a playable implementation of the game, it
failed at providing an evolutive platform. Network capabilities where
finally added to Liquid War 5 (http://www.ufoot.org/liquidwar/v5), but
anyone who played on Internet with someone a few hundreds of
milliseconds away would agree that it's far from being perfect. The
main reason for this is that it is really had to hack on Liquid War 5
(http://www.ufoot.org/liquidwar/v5), especially when you are not the
core developper. The core developper himself, even knowing all the
various hacks in the game, is very quickly lost when trying to implement
major changes.
To put it short, Liquid War 5 (http://www.ufoot.org/liquidwar/v5) is
a global variable hell, a pile of hacks on top of a quick and dirty
implementation. Still, it works.
With Liquid War 6, the idea is to take the time to make something
stable, something nice which will enable developpers to implement the
cool features, and have fun along the way. Of course, this is only a
dream, and in the (hopefully "very") long run, Liquid War 6 will also
end up as a big unmaintainable mess, like any real-life program, until
then, it should remain hackable.
3.9.2 Common sense
------------------
Here are a few guidelines which I think are common sense advice, but
they are still worth mentionning:
* try and respect the GNU coding standards
(http://www.gnu.org/prep/standards/);
* absolutely no 'strcpy' or 'sprintf' anywhere in the code. Nowhere.
Use their equivalent 'strncpy' and 'snprintf' systematically, as
they are part of the glibc and are an order of magnitude safer.
Moreover, Liquid War 6 provides wrappers, such as
'lw6sys_new_sprintf' which handles all the nasty dirty memory
allocation stuff for you;
* keep global variables for when there is something truely global,
and even in that case try to fit them in clearly identified
structures.
3.9.3 Unitary tests
-------------------
Each of the internal libraries in Liquid War has a "test" program
associated with it. For instance 'liquidwar6sys-test' is associated to
'libliquidwar6sys', and its purpose is to test the features of this
library.
While it is fairly easy to test out unitary functions which require
no peculiar context, testing high-level functions which requires files,
graphical and possibly network contexts to exist is obviously harder to
achieve. There's no easy way to draw the line, but the idea is to put
in these test executables as many features as possible, to be sure that
what is tested in them is rock solid, bullet proof, and that one can
safely rely on it and trust that code when running it in a more complex
environnement.
These test executables are also very good places to see a library API
in action, find code fragments, and make experiments.
3.9.4 Memory allocation
-----------------------
Liquid War 6 provides macros to allocate and free memory. One should
use them systematically, except when trying to free something allocated
by another library, and in very special cases, mostly concerning low-low
level operations which are seldom hacked on.
Usage of macros 'LW6SYS_MALLOC', 'LW6SYS_CALLOC' and 'LW6SYS_FREE' is
straightforward, read any random chunk of code, for instance
'./src/lib/sys/sys-test.c' to see them in action. They are defined in
'sys/sys.h'.
Once used, these macros will track every single call to 'malloc' and
'free', and if there's a difference, it will report it. It will also
help you by showing what's in the non-freed memory area, at which line
of code it has been allocated, and when. This is very usefull to track
down memory leaks. Of course a debugger could tell you some of these
informations, but experience shows than when you encounter a memory bug,
it's very often impossible to reproduce it. So you one wastes time
trying to reproduce the bug, whereas with this tool you have the
information reported just when the problem happens.
3.9.5 Private and public interfaces
-----------------------------------
Each library exports a public interface and hides its internal. Since
Liquid War 6 uses standard C and no C++, there's no real standard way to
handle public/private features. The convention used in Liquid War 6 is
to show internal structures as opaque pointers ('void *') whenever some
function needs to operate on a structure which has possibly private
fields. This way the caller function has no way to access the
internals, and we are sure that no reference to any internal
implementation specific feature will appear.
Here's a code excerpt from 'src/gfx/setup.c':
void _lw6gfx_quit(_LW6GFX_CONTEXT *context) {
/*
* Implementation here.
*/
[...]
}
void lw6gfx_quit(void *context) {
_lw6gfx_quit((_LW6GFX_CONTEXT *) context);
}
The function '_lw6gfx_quit' (note the "_") is internal, declared in
'internal.h' whereas the function 'lw6gfx_quit' is public, and is
therefore exported in 'gfx.h'.
This way, functions in the program using 'lw6gfx_quit' do not know
what is in the '_LW6GFX_CONTEXT' structure, and they need not know it.
This does not mean it is not possible to have public structures, only
these structures must reflect some truely public, accessible and safe to
access structures.
3.9.6 Commit policy
-------------------
Basic rules :
* commits should be as small as possible, yet leave the code in a
consistent state. The general idea is that big commits tend to
make error tracking more complicated;
* a commit should not leave the code in a state in which it does not
compile and/or is consistent from a user point of view. The
general idea is to go step by step and break as little things as
possible.
* tests should be written along the way. The project is not
developped with a "test driven" method, still, it's a good practice
to write the tests functions as soon as possible.
To check that a commit does not break everything, a good practice is
to run a 'make check' before committing / submitting anything.
Then, once it's within the main GIT repository, check the Jenkins
builds (http://www.ufoot.org/jenkins/job/liquidwar6/) to see if the
program still builds correctly.
3.9.7 Audit the code
--------------------
Liquid War 6 is regularly audited with automated tools. You might need
to pass '--enable-gcov' to '--configure' if you want to use thes tools
yourself. More precisely:
* CUnit (http://cunit.sourceforge.net) is used for regression tests.
It's used to provide hopefully standardized output when testing,
and provide test statistics more easily. It's a rule of thumb to
try and write tests when new features and/or bug-fixes pour in.
* lcov (http://ltp.sourceforge.net/coverage/lcov.php) is run, ideally
with each release - but it's not garanteed, check the output date
and time - and the output is available online on
.
* GNU global (http://www.gnu.org/software/global/) is run too,
ideally with each release - again, check the output date and time -
and the output is available online on
.
* pmccabe (http://parisc-linux.org/~bame/pmccabe/) reports cyclomatic
complexity. It shows where the code is too complex and should
probably be rewritten. Output is post-processed using pmccabe2html
(http://www.gnu.org/software/gnulib/MODULES.html#module=pmccabe2html)
from gnulib (http://www.gnu.org/software/gnulib/). The output is
available online on .
* Valgrind (http://valgrind.org/) is run as well, it should report
absolutely no leak on all the core sub-libraries, eg running
'liquidwar6ker-test' or 'liquidwar6ker-pil'. Bits of code which
depend on other libraries are a different story, for some projects
on which Liquid War 6 depends might, for some reason, raise
warnings. But as far as Liquid War 6 is concerned, the goal is
simple: zero leak.
* Liquid War 6 is referenced on Open HUB (http://www.openhub.net/).
Visit to get time-based
statistics and facts about the source code.
Those tools certainly don't garantee the code is perfect, but they do
help improving the quality of the program. If you hack, it's
recommended you give them a try.
3.10 Using the console
======================
The console can be activated by passing '--display-console' when
starting the game or by using the system options menu.
When the console is activated, a 'lw6>' prompt should appear in the
terminal which launched the program. If you started Liquid War 6 by
clicking on an icon, console probably won't work at all since 'stdout'
and 'stdin' won't be attached to anything.
The console allows you to type arbitray Scheme/Guile code.
Try, for instance:
(+ 1 2)
(display "foo\n")
You can really break things with this console, it gives you a direct
access to all the program internals. At least, all the values which are
accessible through the script interface, that is, many of them.
You can call any internal C function which has been exported to
Guile, here are some examples:
(c-lw6sys-timestamp)
(c-lw6bot-get-backends)
(c-lw6sys-sleep 2.0)
(lw6-config-get-number "zoom")
(lw6-config-set-number! "zoom" 0.9)
(lw6-config-get-number "zoom")
While syntax (and possibly other) errors will be trapped by the
interpreter, note that if you break things inside the game by, say,
changing some global value, or in a general manner cause an error
elsewhere in the code, the game will really raise a fatal error and
stop. That's how you can "break things".
Still, this console is a very powerfull tool, very usefull for
debugging but also for tweaking the game without restarting it and/or
navigating through the menu interface.
3.11 Advanced tweaking
======================
3.11.1 Hacking ressources
-------------------------
Liquid War 6 tries to have as few hardcoded data as possible. So many
constants, and pretty much all the image files, are accessible in the
data directory. You can know where it is by launching 'liquidwar6
--show-data-dir'. If you look in this directory you'll find different
files, among them XML files.
Let's take an example. Try and find the file
'gfx/gl/hud/floating/gl-floating-const.xml'. Edit the line with the
'clock-y1' entry. Change the number after '"value"'. Re-run the
program. Play a game. What happens? Logically you should see that
"something" is not displayed at the same place than before.
You could also modify the textures (JPEG and PNG files). In a
general manner it's more cautious to keep them the same size but it
depends, sometimes other sizes will work as well.
Many of these parameters are really too technical and obscure to have
their place in the main config file (which is already rather big). Use
at your own risks, you can really break things touching this, but you
can also find out lots of things can be tuned.
3.11.2 Optimize for speed
-------------------------
Todo...
3.12 Writing modules
====================
Todo...
3.13 Use as a library
=====================
Todo...
3.14 Network protocol
=====================
This section describes how Liquid War 6 handles network messages. Note
that for now this is purely theorical, more of a draft, a plan, it might
change before being implemented.
3.14.1 No server, no client, only nodes
---------------------------------------
Liquid War 6 does not really have the notion of server or client, any
instance of the program can act as both server and client, therefore we
use the term node.
A node listens on a given port, in both TCP and UDP, and can connect
to other nodes on the same port. The main identifier of a node is its
public url, which is typically of the form
'http://:/'. This url is very important for it is (or
at least should be) a unique identifier of the node over the network.
Liquid War has 3 ways to communicate:
* raw TCP, this is the LW6 protocol, the easiest to implement and
debug, probably the most reliable one, but not always the fastest.
This involves the two modules 'mod-tcp' and 'mod-tcpd'.
* HTTP over TCP, this is a hack which allows the game to communicate
through HTTP proxies for instance. Additionnally, the fact any
node is a web server enables peering with a simple web browser.
Web server facility requires 'mod-httpd' and client part requires
'mod-http' which might or not be available, depending on how the
game was compiled.
* raw UDP, this is another version of the LW6 protocol, this is in
theory the fastest way to communicate, it requires 'mod-udp' and
'mod-udpd' to work. Using UDP only was not an option when
conceiving Liquid War since it's interesting to have other
solutions if, for instance, a firewall does not allow you to use
UDP the way you want.
On each of these channels, messages can be exchanged in two modes, an
"out of band" mode (AKA "oob"), and a regular message oriented, here we
speak of "connection".
3.14.2 Out of band messages
---------------------------
There are only 3 out of band messages:
* 'PING': requests for a simple 'PONG http://server:port/' answer,
this is just to check if a server is a valid server, and if the URL
we used to connect on it is the correct one.
* 'INFO': requests for a list of key/attributes pairs, which describe
the node, telling for instance its version, its uptime, and so on.
* 'LIST': requests for a list of other nodess this node is aware of.
You can test out of band messages by simply connecting on your server
with a command like:
telnet localhost 8056
At the telnet prompt, simply type:
INFO
and press return, and you should have a description of your node.
The complete syntax of OOB messages is:
[password] [url]
The 'password' and 'url' parameters are optionnal. 'password' can
contain either the plain text password or a checksum calculated from the
password which is, for security reasons, seeded with the public url of
the node we're connecting to, so that this password can't be re-used on
another node. 'url' is simply a clue we give to the other node to help
find us, the other node will automatically try to detect our IP address
and use standard LW6 port 8056, but if for some reason we use a
different setting, this is a good way to pass the hint.
Here are examples of valid messages:
LIST
PING http://myhost.mydomain:1234/
INFO secret http://myhost.mydomain:1234/
LIST 12ab34cd
If there's only one argument, the parser will first try and interpret
it as a URL. If it's not parseable that way, it will consider it's a
password. The password, in turn, may be specified as clear text or as a
32-bit checksum.
As far as OOB is concerned, TCP and UDP work almost the same, HTTP is
a bit different, the OOB commands are accessed through the following
URLs:
* '/ping.txt'
* '/info.txt'
* '/list.txt'
OOB messages are usually sent many times in redundant mode on the
network, as there's no tracking of them, sending them through multiple
channels ensures they make their way to the right place.
The parser for these messages is located in 'src/lib/msg/msg-oob.c'.
3.14.3 Regular messages overview
--------------------------------
All messages that are non-OOB share a common syntax. This is called the
"envelope" of messages.
The general syntax is:
LW6
Here's an example:
LW6 0.1.3485 - 2d1dbed7 - 3003300330033003 2002200220022002 - - DATA 8 0 1 1000000035005 3003300330033003 SET 3001 11 1 1 0
In this example, the messages carried is 'DATA 8 0 1 1000000035005
3003300330033003 SET 3001 11 1 1 0', the rest is part of the envelope
protocol.
Here's what those fields mean:
* 'LW6': should always be LW6, this is a marker to make sure we're
speaking the right protocol.
* '': the version of the program sending the message, the
receiver of the message should check this version is compatible.
* '': the password checksum, while a clear
password should still be correctly interpreted, as for OOB
messages, there's no reason to send the cleartext password, so the
checksum is just fine. Note that the checksum is short, and
vulnerable to brute-force attacks. If you want strong protection,
the general advice is to tunnel your connections through SSL or
TLS, use a VPN, LW6 won't implement "fortress mode", third party
tools should do this much better. If undefined, should be replaced
by the dash character '-'.
* '': a signature done by the sender, which is
unique for the combination message+from+to. This means two
different messages will generate two differents signatures, but
different senders and/or receivers will also change this, so it's
not possible, unless one has the "ticket" to fake a message. This
is clearly not bullet-proof, and more specifically, brute-force
attacks and/or network listening could break the protocol and/or
reveal the ticket, still, this is a good way to make sure that if
something is inconsistent, someone is trying to cheat. As every
node maintain its own game state, a cheater can "only" be a
nuisance by sending wrong key presses, but in the long run it will
be defeated by the fact that an attacker should intercept and
modify all messages on all channels (tcp, udp, http ...) and make
sure the official, real informations, never makes its way to the
right node. This is quite hard to achieve, very likely, an
inconsistency will be detected, nodes concerned should be
disconnected, period. When sending the first messages, ticket
might not be exchanged yet, so there's no way to calculate this,
during this period, 'ffffffff' is sent, and checksum errors are
ignored.
* '': another signature, but this one concerns
the physical sender/receiver. If the physical sender is the
logical sender, and the physical receiver is the logical receiver,
that is, if physical and logical nodes are the same pair of nodes,
then it need not be defined and can be replaced by the dash
character '-'. In fact, in that case, the physical and logical
signatures are obviously the same. However (not implemented yet)
the protocol is designed so that nodes can act as messages
forwarders, in that case they have no knowledge of the secret
ticket to use, so this ticket is here to ensure message consistency
for the final, real (logical) receiver of the message.
* '': the id of the physical sender, the node that
created the message.
* '': the id of the physical receiver, the node that
should receive the message.
* '': the id of the logical sender, if it's the same
than the physical sender, can be replaced by the dash character
'-'.
* '': the id of the logical receiver, if it's the same
than the physical receiver, can be replaced by the dash character
'-'.
* '': the message itself, it might in turn be separated by
spaces, or whatever the message delimiter is. It should not be too
long, as it must be sendable on the network by UDP, so it must fit
within the MTU (about 1.4 kb) with all the protocol (envelope)
stuff before it. In practice, it's cut into 1.2 kb parts by
'libdat', the constant '_LW6DAT_ATOM_MAX_SIZE' is used to split big
messages in smaller parts.
It's implemented in 'src/lib/msg/msg-envelope.c'.
3.14.4 Regular control messages
-------------------------------
To establish a connection, maintain it, and do the OOB job, a set of
control message is used. Those messages carry a bunch of informations
about who is sending them, in fact, they just contain the informations
that would otherwise be handled by out-of-band messages, but it's
convenient to have the information first-hand rather than relying on the
other protocol.
The syntax is:
LW6
Example:
LW6 0.1.3485 - ffffffff - 1001100110011001 2002200220022002 - - HELLO liquidwar6 0.1.3485 "Davy Crockett" 3485 1001100110011001 http://localhost:8057/ cGF0 RHVtbXkgdGVzdCBub2RlIEE= 0 10 0 5 372057f45b3d2ba5 10005 "Default map" 5 4 10 4 26 1 12 ""
The fields, starting from 'LW6' up to (and including)
'' are part of the envelope, described previously.
The message fields are:
* '': described below, the main command,
* '': should be 'liquidwar6'
* '': the version of the program. Yes, this is also in the
envelope, but one could think of instances relaying informations
for other peers, in that case this could prove useful.
* '': the code name of the program.
* '': the stamp, it's normally contained within the version,
but this avoids parsing issues.
* '': the node id (could be inferred from envelope, but repeated
here).
* '': the node url (could be inferred from envelope, but
repeated here).
* '': the readable title of the node, base64 encrypted.
* '': the readable description of the node, base64
encrypted.
* '': wether it's protected by a password or not, 0 if
not, 1 if protected.
* '': the bench of the node, giving its CPU strength in an
arbitrary unit.
* '': wether the node act as an open relay, 0 if not, 1
if in relaying.
* '': node uptime, in seconds.
* '': the community id, a unique id shared by all nodes
connected to a game session.
* '': the current round id.
* '': the minimum bench required to connect to this
node (used to avoid slow nodes connecting to way-too-fast games).
* '': number of colors playing.
* '': maximum number of colors allowed on this node.
* '': number of cursors playing.
* '': maximum number of cursors allowed on this node.
* '': number of nodes connected.
* '': maximum number of nodes allowed on this node.
* '': list of peers connected to this node.
* '': command-specific arguments
Here are the different possibilities for the '' field.
* 'HELLO': is used when connecting, this should be the first message
sent. In itself, the message means pretty much noting, it just
says "I'm here" which could be infered from any other message. No
command args.
* 'TICKET ': is used to inform the caller of the ticket we
use. The ticket sent from A to B is ised by B to sign messages for
A. A node typically sents a different ticket to all its peers so
when sending the same message to A and C, B will typically use two
different tickets, thus generating two different signatures, and if
sending the exact same string to C, A generate yet another
signature as it will have sent another ticket. There's one
optional argument, which is the ticket itself, a 64-bit hexa
integer.
* 'FOO ': is sent on a regular basis, it's really the
replacement of the OOB 'PING' message, it will update the peer
status and maintain consistent informations. It has two arguments,
the first one is 'key', a 32-bit hexa integer, which will, upon
'BAR' message reception, used to figure out "OK, this is the 'BAR'
message associated to this 'FOO' message I sent before". The
second one, 'serial', is used to inform the peer that, possibly,
there are new messages to fetch from us. The peer, in turn, might
fire 'MISS' messages, but without this feature, peers could "fall
asleep" and forget to pump messages, especially on non-reliable
connections.
* 'BAR ': is the response to 'FOO' which is received on
a regular basis, it's really the replacement of the OOB 'PONG'
message, it will update the peer status and maintain consistent
informations. It has two arguments, the first one is 'key', a
32-bit hexa integer, which will, upon reception, ne matched against
a corresponding 'FOO' messaged, used to figure out "OK, this is the
'BAR' message associated to this 'FOO' message I sent before". The
second one, 'serial', is used to inform the peer that, possibly,
there are new messages to fetch from us. The peer, in turn, might
fire 'MISS' messages, but without this feature, peers could "fall
asleep" and forget to pump messages, especially on non-reliable
connections.
* 'JOIN ': Used to join a game. In fact, having said
'HELLO' and exchanged 'FOO' and 'BAR' messages does not mean one
has joined the game for real. The reason for this is that those
messages help establishing a stable communication channel, then one
needs to come in with the right 'seq' and 'serial'. There are
basically two cases. First case, 'seq' can be zero, in that case
it means we're trying to connect on an existing server, which will
in turn send a 'JOIN' message with a non-zero value, giving the
current seq. Second case, 'seq' is non-zero, in that case it means
we're answering a connection request. In both cases, 'serial' is a
serial number other peers should use as a minimum limit, and never
ask for messages with a 'serial' lower than that.
* 'GOODBYE': symetric of 'HELLO', should be called on disconnection,
however, the peers should handle the case when no 'GOODBYE' message
is sent, this is just about being polite. No command args.
It's implemented in 'src/lib/msg/msg-cmd.c'.
3.14.5 Regular MISS messages
----------------------------
Todo...
3.14.6 Regular META messages
----------------------------
Todo...
3.14.7 Regular DATA messages
----------------------------
Todo...
3.14.8 Other raw technical stuff (WIP)
--------------------------------------
TCP messages:
LW6 [] MSG1
MSG2
TCP oobs:
# only works anonymous, same as INFO
INFO [] []
LIST [] []
PING [] []
UDP messages:
LW6 [] MSG1
LW6 [] MSG2
UDP oobs:
INFO [] []
LIST [] []
PING [] []
HTTP messages:
client id & password passed in HTTP headers
/lw6/version//////sig/MSG1
/lw6/version//////sig/MSG2
HTTP public URLs:
/ -> index.html
/index.html
/favicon.ico
/screenshot.jpeg
/robots.txt
/gpl.txt
/info.txt
/list.txt
/ping.txt
MSG syntax:
...
COMMAND examples:
2 1234abcd1234abcd REGISTER
3 1234abcd1234abcd ADD 5678 YELLOW
4 1234abcd1234abcd SET 5678 20 5
10 1234abcd1234abcd NOP
400 1234abcd1234abcd REMOVE 5678
1000 1234abcd1234abcd UNREGISTER
Sig is a checksum on string:
MSG
3.15 Technical HOWTOs
=====================
3.15.1 Release check-list
-------------------------
Summary off all operations required for a release:
* check the value of 'LW6MAP_RULES_DEFAULT_EXP' and default for
'--skip-network', which might have been changed will developping.
* in './src', run './indent.sh'.
* in './doc', run './gdoc-update.sh', './doxygen-update.sh' and
'./perf-update.sh'.
* edit 'NEWS' file, in both 'liquidwar6' and 'liquidwar6-extra-maps'.
Check 'ChangeLog' is OK.
* update the version history in 'doc/liquidwar6.texi'.
* update 'debian/changelog' files in both main and extra maps
packages.
* run 'make distcheck'... (at least!)
* build 'RPM' package ('make -C pkg rpm'), check 'yum install'
produces a working installation, also check the 'rpm -e' command to
verify uninstalling is OK too.
* build '.exe' main binary on Microsoft Windows then go back to
GNU/Linux and build '.exe' installer ('make -C pkg installer'), go
back to Microsoft Windows and test the installer (there are often
problems at this stage because of missing libraries or other
files...).
* build '.dmg' Mac OS X disk image, check it works even when '/opt'
and '/usr/local' or (re)moved, this is important, else execution
might rely on binaries which are only on the development machine
and do not ship with game.
* upload files (doc on
), with a command
like 'rsync --rsh=ssh --recursive --verbose --progress ./X.Y.Z/
login@dl.sv.nongnu.org:/releases/liquidwar6/X.Y.Z/'. Each file
must have its '.sig' corresponding file.
* update online docs with 'gendocs.sh', carefull, 'liquidwar6.html'
is suppressed by this, need to re-create it from previous version
and/or 'index.html' which is the same.
* update 'index.html', 'liquidwar6.html' and 'liquidwar6.fr.html' so
that they reflect the latest release. Check download links are OK.
* post news on ,
and
.
* after everything did work, upload files on ,
for instance use 'gnupload --to ftp.gnu.org:liquidwar6
liquidwar6-X.Y.Z.tar.gz'.
3.15.2 Add a new option
-----------------------
This describes how to add a new option to the game.
* edit 'src/lib/def/def-list.txt'
* in 'src/lib/def/def-update.py' run './def-update.py'. This will
automatically fill 'src/lib/def/def.h' and 'script/def.scm'. In
the code, you should always use 'LW6DEF_

' in C and
'lw6def-

' in scheme to refer to the option. This does help
avoiding typesetting errors.
* add the entry to 'src/lib/hlp/hlp-list.c', choose a category for it
* add the entry to 'src/lib/hlp/hlp-reference.c', give it a type,
documentation string and default values if needed
* to sort 'src/lib/def/def-list.txt' a common practice is to fill it
with the output of 'liquidwar6 --list' once the program has been
compiled and is aware of the new option.
Unless this is done, program won't accept the option.
Some options need more work, for instance:
* Any option which is a command-line argument needs to be added to
'src/lib/lw6-options.c'.
* Any option which is related to the build system (to enable or
disable some feature) must be referenced in 'src/lib/sys-build.c'
and also 'src/lw6-funcssys.c' to be callable from scripts.
* Any option which changes the map rules (any new rule...) impacts
the game checksums so these ones need to be updated in
'src/lib/map/map-test.c', 'src/lib/ker/ker-test.c',
'src/lib/pil/pil-test.c' and 'src/lib/pil/pil-suite.c'.
3.15.3 Add a new internal library
---------------------------------
This describes how to add a new 'libxyz' internal library:
* create a new 'src/lib/xyz' directory. The convention is to use 3
letters names and prefix every global identifier with 'lw6xyz'.
* copy 'Makefile.am', 'xyz.h', 'xyz-test.c' and 'xyz-testmain.c' from
an existing internal library ('libnod' is a good source, it does
not have complex dependencies).
* edit 'Makefile.am' to fill requirements, make necessary adjustments
to other files (many string replaces to make, both lowercase and
uppercase).
* add the entry in the 'SUBDIRS' and 'LW6_LIBS' sections of
'src/lib/Makefile.am'
* add the entry in the 'AC_CONFIG_FILES' of './configure.ac'.
* run 'automake' and 'autoconf'.
* edit 'src/lib/lw6-options.c' and add a call to 'lw6xyz_test()' for
both "check" and "test" cases.
* edit 'src/lib/lw6-test.c' and add a reference to the
'lw6xzy_test()' function.
* in every internal 'abc' library that depends on 'xyz', edit the
'lw6abc_test' function so that it contains a reference to
'lw6xzy_test'.
* in every internal 'abc' library that depends on 'xyz/xyz.h', edit
the 'abc/abc.h' header so that it includes 'xzy/xyz.h'. Also edit
'src/lib/liquidwar6.h.in'.
* in every internal 'abc' library that depends on 'libxyz', add a
reference to '../xyz/libxyz.la' inf the '_LDADD' section.
* create a new 'src/lib/lw6-funcsxyz.c' file which declares Guile
bindings for this lib, if needed
* edit 'doc/gdoc-update.sh' and add the entry for 'xyz'.
* edit 'doc/Makefile.am' and add 'xyz-gdoc.texi' in 'gdoc_TEXINFOS'.
* edit 'doc/doxygen-update.sh' and add the entry for 'xyz'.
* edit 'doc/Makefile.am' and add 'xyz-doxygen.texi' in
'doxygen_TEXINFOS'.
* edit 'doc/perf-update.sh' and add the entry for 'xyz'.
* in './doc', run './gdoc-update.sh', './doxygen-update.sh' and
'./perf-update.sh'.
* edit 'doc/doxygen/Makefile.am' and add the dependency on
'src/lib/xyz/xyz.h'.
* edit 'doc/liquidwar6.texi' to and a new node/section for this
internal library.
* edit 'doc/deps.dot' to update dependencies.
* run './configure && make', fix code if needed.
3.15.4 Add a new module
-----------------------
This describes how to add a new 'mod-ab' module, for instance a new bot,
but gfx, snd, cli or srv backends should work pretty much the same:
* add a new entry in 'src/lib/bot/Makefile.am'
* create the subdir 'src/lib/bot/mod-ab', with its 'Makefile.am'
(inspired from other existing modules)
* add the entry in 'configure.ac' so that
'src/lib/bot/mod-ab/Makefile' is generated.
* edit 'doc/gdoc-update.sh' and add an entry for 'mod-ab'
* edit 'doc/Makefile.am' and add 'mod-ab-gdoc.texi' in
'gdoc_TEXINFOS'.
* edit 'doc/doxygen-update.sh' and add an entry for 'mod-ab'
* edit 'doc/Makefile.am' and add 'mod-ab-doxygen.texi' in
'doxygen_TEXINFOS'.
* type 'touch doc/mod-ab-gdoc.texi doc/mod-ab-doxygen.texi' else
dependencies checking will fail.
* in './doc', run './gdoc-update.sh' and './doxygen-update.sh'.
* edit 'doc/liquidwar6.texi' to add a new node/section for this
module.
* edit 'doc/deps.dot' to update dependencies.
* edit 'src/lib/bot/bot-test.c', change the value of
'TEST_NB_BACKENDS' and modify the code so that the new 'ab' module
is tested too.
* edit 'src/lib/bot/bot-register.c', the code must updated pretty
much in every place with the conditionnal 'LW6_ALLINONE', you need
to add the new module.
* run 'automake', 'autoconf', './configure' and 'make'.
3.16 Using GNU Arch
===================
3.16.1 About GNU Arch
---------------------
Since March, 4th 2010, Liquid War 6 uses GIT (http://git-scm.com/) to
handle source code, track changes, branches, and the rest. It replaces
the GNU Arch (http://www.gnu.org/software/gnu-arch/) repository. This
old repository contains all sources up to version 0.0.7beta, following
versions, including 0.0.8beta, must be retrieved from GIT.
So the following informations only concern those who are interested
in previous versions of the game. Anybody else - probably you - should
use GIT instead.
*Note Using GIT::.
Still, this quick Arch survival guide is kept in the documentation.
Read the GNU Arch tutorial
(http://www.gnu.org/software/gnu-arch/tutorial/arch.html) to learn how
Arch works. Note that there are many other source control managers
available, some of which provide functionnalities similar to GNU Arch /
tla. GNU Arch has been chosen for Liquid War 6 because:
* it is Free Software,
* it is not limited to per-file commits like CVS, and supports atomic
commits involving several files,
* it is distributed,
* it enables developpers to sign each of their contributions,
* it was already available back in 2005.
3.16.2 Getting the latest version from the repository
-----------------------------------------------------
The repository for Liquid War 6 is accessible on
. This is a read-only
access, but with the distributed nature of GNU Arch, it still allows you
to keep track of your own changes, and submit patches. Accessing it in
read/write mode with sftp requires a Savannah account and special rights
on the Liquid War 6 project.
Here are typicall commands one can use to get Liquid War 6 source
from the GNU Arch repository:
tla register-archive http://arch.savannah.gnu.org/archives/liquidwar6
tla get -A liquidwar6@sv.gnu.org liquidwar6--beta
All the patches in the archive are signed with GnuPG
(http://www.gnupg.org/), so you can check their authenticity with my
public key (http://www.ufoot.org/ufoot.pub).
You might need to edit your
'$HOME/.arch-params/signing/=default.check' file and put the following
text in it:
tla-gpg-check gpg_command="gpg --verify-files -"
3.16.3 Setting up your own arch repository
------------------------------------------
This section is for those who want to hack the game and set up their own
repositories. This will enable you to keep track of your patches,
package them, and help the core maintainer merging them in the main
repository.
You can introduce yourself and create a repository by issuing
commands like:
You can introduce yourself and create a repository by issuing
commands like:
tla my-id me@home.net
tla register-archive me@home.net--2008 /home/me/tla-archives
Then, you can get create your own repository, with a command like:
tla tag -S liquidwar6@sv.gnu.org/liquidwar6--beta--0.1 me@home.net--2008/liquidwar6--beta--0.4
The idea is that you create, locally, a depot which has a name that
matches the name on savannah (http://arch.savannah.gnu.org) (this is for
convenience, you could technically give it any name...) and indicate
that they represent, today, the same thing.
You can get a working copy of your depot with the command:
tla get me@home.net--2008/liquidwar6--beta--0.4
This will create a complete source tree, which you are free to
modify, this is where you should hack.
3.16.4 Synchronizing your repository with upstream releases
-----------------------------------------------------------
To synchronize yourself with upstream developments, go into your copy
(the directory created by 'tla get') and type:
tla star-merge liquidwar6@sv.gnu.org/liquidwar6--beta--0.1
This will apply locally all the changes that happened since the last
synchronization. Of course this is one way to work, you can decide to
cherry pick patches and such stuff, but for most dayly uses, a good'ol
'star-merge' is fine.
Not that 'star-merge' will only apply patches on your working copy,
not on your repository. The only way to actually commit the
modifications on the repository is to use the 'commit' command.
3.16.5 Submitting patches
-------------------------
When using Arch, you can of course still send patches created with
'diff', or even send updated files directly, the way you would without
revision control.
But it can be more convenient to either
* Send the patches stored in the depot ('/home/me/tla-archives' in
our example).
* Make patches using 'tla mkpatch'.
Here's an example of an 'mkpatch' command, and which will compute the
differences between a previous 'liquidwar6--beta--0.4--patch-2' snapshot
and a not yet commited latest version:
tla mkpatch {arch}/++pristine-trees/unlocked/liquidwar6/liquidwar6--beta/liquidwar6--beta--0.4/me@home.net--2006/liquidwar6--beta--0.4--patch-2 . my-patch
This will create a 'my-patch' directory, which can be gzipped and
sent by mail.
3.16.6 Recover from broken lock
-------------------------------
Sometimes, when signing a patch, you might enter the wrong passphrase
several times, or you might press CTRL+D inadvertantly. In that case,
tla will be in a half-broken state, telling you it can't acquire
revision lock... A quick workarround for this is to go to the depot,
find the latest patch, and in this repository, create the following
folders:
++revision-lock/+contents
Both are directories, note the two ++ and the single +. the
'+contents' directory can be empty. Once you've done this, try to
re-commit.
3.17 Using GIT
==============
3.17.1 About GIT
----------------
There's no CVS or Subversion (AKA "SVN") source depot for Liquid War 6.
Instead, a GIT (http://git-scm.com/) depot is used. GIT has many
advantages over other source control managers (SCM), among them, it's
distributed, like GNU Arch (http://www.gnu.org/software/gnu-arch).
You can find interesting informations on GIT here:
*
*
*
3.17.2 Getting the latest source
--------------------------------
Simply install git and run the following command:
git clone git://git.sv.gnu.org/liquidwar6.git
If you are behing a firewall and can't have direct TCP/IP access:
git clone http://git.sv.gnu.org/r/liquidwar6.git
Additionnally, source can be browsed online here:
3.17.3 Developper access
------------------------
You need an ssh access on Savannah (http://savannah.gnu.org/) and
appropriate rights on the project, then you can type:
git clone login@git.sv.gnu.org:/srv/git/liquidwar6.git
3.17.4 Submitting patches
-------------------------
If you have developper access to the project, then a simply 'git push'
will commit your changes.
If not (that is, if you checked out anonymously using 'git clone
git://git.sv.gnu.org/liquidwar6.git' for instance, you can still submit
patches. Follow these steps:
* edit the code, make your patches, commit to your local GIT tree
* run 'git format-patch -p origin' this command will generate
'.patch' files, one for each of you commits, which you can send by
email. They can be easily integrated in the main source tree by
using 'git apply '.
Note that you can need to run 'git format-patch -p master' (with
'master' instead of 'origin') it not using a fresh checkout. Also
consider adding the '--stdout' switch, eg 'git format-patch -p master
--stdout > my-changes.patch' if you're not using a fresh checkout.
3.18 Jenkins builds
===================
Liquid War 6 uses Jenkins (http://jenkins-ci.org/) for continuous
integration.
Each time a commit is done on the main GIT source tree, a build is
triggered. The list of builds, their status, is available on:
* all Jenkins jobs on ufoot.org (http://www.ufoot.org/jenkins/).
* liquidwar6 Jenkins job on ufoot.org
(http://www.ufoot.org/jenkins/job/liquidwar6/).
It's interesting, among other things, to look at the log produced
when the game is built, as it contains the test suite output, and can
provide usefull informations of what is supposed to happen when the game
is built correctly, and what happens when things go wrong.
4 Reference
***********
This chapter is a technical reference. Most of its content is
self-generated by the program itself. That is to say, most if its
content is already available to you if you have the game installed.
Running 'liquidwar6 --list' and 'liquidwar6 --about=' is very
likely to give you the very same informations, the advantage being that
you'll be sure the information is up-to-date and corresponds to the
exact version of the program you have. However, publishing this in a
reader-friendly way is convenient, plus it enables web search engines to
harvest the content.
4.1 Basic options
=================
4.1.1 about
-----------
-- Command-line option: '--about='
Type: string
Will allow you to get informations about a given keyword. Let's
say that, for instance, you want informations about the keyword
'map-path'. Simply run 'liquidwar6 -about=map-path'. Note that
this internal self-documentation system can describe command line
switches as well as XML config file parameters or environment
variables, and even some Guile script functions. The '-list'
command line switch will give you the list of all available
keywords.
4.1.2 audit
-----------
-- Command-line option: '--audit'
Display all path values, defaults and current settings. This
output is very usefull to track down problems such as missing
directories, broken installations. If you get an error message
that suggests some file is missing, then give this option a try.
4.1.3 copyright
---------------
-- Command-line option: '--copyright'
Returns the copyright notice for the program.
4.1.4 credits
-------------
-- Command-line option: '--credits'
Gives hopefully extensive information on who contributed to the
game.
4.1.5 debug
-----------
-- Command-line option: '--debug'
Enables debug mode. This will turn on maximum log information, and
display everything on stderr, even messages which are normally only
stored in the log file.
4.1.6 defaults
--------------
-- Command-line option: '--defaults'
Clears the config file and run the game with default settings. Use
this if you suspect you have broken something by tweaking user
settings, or when upgrading the game to a new version.
4.1.7 help
----------
-- Command-line option: '--help'
Returns a short help for the program.
4.1.8 host
----------
-- Command-line option: '--host'
Display all known system host properties, including os and cpu
informations.
4.1.9 list
----------
-- Command-line option: '--list'
Returns the list of all keywords which can be queried for
information. This includes command-line options, environment
variables, and so on. This is the companion option of '-about'.
Results obtained with '-list' can be passed to '-about'.
4.1.10 modules
--------------
-- Command-line option: '--modules'
Tells which modules have been enabled when the game was compiled.
It's still possible to add or remove modules afterwards, but this
option allows you to know how things were at first.
4.1.11 pedigree
---------------
-- Command-line option: '--pedigree'
Display all build values, these are general constants which can
help debugging, tracing what binary you are running, and so on.
It's a good idea to take a look at the output of 'pedigree' if you
have problems running the game.
4.1.12 test
-----------
-- Command-line option: '--test'
Runs a (hopefully) complete test suite which will call most
internal Liquid War 6 functions and check out wether they work, in
a simple context, without any game interference. Usefull for
troubleshooting.
4.1.13 version
--------------
-- Command-line option: '--version'
Returns the version of the program, as defined by the GNU Coding
Standards.
4.2 Doc options
===============
4.2.1 example-hints-xml
-----------------------
-- Command-line option: '--example-hints-xml'
Dumps on stdout an example hints.xml file. Such a file is normally
shipped with the game. It is indeed generated using this command.
4.2.2 example-rules-xml
-----------------------
-- Command-line option: '--example-rules-xml'
Dumps on stdout an example options.xml file. Such a file is
normally shipped with the game. It is indeed generated using this
command.
4.2.3 example-style-xml
-----------------------
-- Command-line option: '--example-style-xml'
Dumps on stdout an example style.xml file. Such a file is normally
shipped with the game. It is indeed generated using this command.
4.2.4 example-teams-xml
-----------------------
-- Command-line option: '--example-teams-xml'
Dumps on stdout an example teams.xml file. Such a file is normally
shipped with the game. It is indeed generated using this command.
4.2.5 list-advanced
-------------------
-- Command-line option: '--list-advanced'
List advanced options which can be used for fine-tuning the game.
4.2.6 list-aliases
------------------
-- Command-line option: '--list-aliases'
List the keyword aliases. These are here for convenience.
4.2.7 list-doc
--------------
-- Command-line option: '--list-doc'
List documentation-related command line options. These commands
allow you to list all the keywords related to a given domain.
4.2.8 list-funcs
----------------
-- Command-line option: '--list-funcs'
List the C-functions which are exported to Guile, thus usable in
scripts.
4.2.9 list-graphics
-------------------
-- Command-line option: '--list-graphics'
List graphics options (resolution, fullscreen...).
4.2.10 list-hooks
-----------------
-- Command-line option: '--list-hooks'
List user-modifiable hooks.
4.2.11 list-input
-----------------
-- Command-line option: '--list-input'
List input (AKA controls) related options. Use these to change
keyboard, joystick and mouse settingds.
4.2.12 list-map
---------------
-- Command-line option: '--list-map'
List map-related entries, excluding rules.xml, hints.xml and
style.xml entries.
4.2.13 list-map-hints
---------------------
-- Command-line option: '--list-map-hints'
List 'hints.xml' entries. These parameters enable you to modify
the behavior of the map loader.
4.2.14 list-map-rules
---------------------
-- Command-line option: '--list-map-rules'
List 'options.xml' entries. These parameters enable you to modify
the gameplay.
4.2.15 list-map-style
---------------------
-- Command-line option: '--list-map-style'
List 'style.xml' entries. These parameters enable you to modify
the aspect of the game.
4.2.16 list-map-teams
---------------------
-- Command-line option: '--list-map-teams'
List 'teams.xml' entries. These parameters enable you to specify
which teams should play on the map.
4.2.17 list-network
-------------------
-- Command-line option: '--list-network'
List network options.
4.2.18 list-path
----------------
-- Command-line option: '--list-path'
List parameters which allow you to override the defaults of the
game, and force the game your own file paths and directories.
4.2.19 list-players
-------------------
-- Command-line option: '--list-players'
List player-related entries, that is to say 'who plays'.
4.2.20 list-quick
-----------------
-- Command-line option: '--list-quick'
List quick help entries, this includes the GNU standard options and
a few troubleshooting tools.
4.2.21 list-show
----------------
-- Command-line option: '--list-show'
List command-line options which begin with '-show-...'. These will
display on the console many internal parameters. Usefull when
debugging.
4.2.22 list-sound
-----------------
-- Command-line option: '--list-sound'
List sound options (volume...).
4.2.23 list-team-colors
-----------------------
-- Command-line option: '--list-team-colors'
List the team colors, there should be 10 of them
4.2.24 list-weapons
-------------------
-- Command-line option: '--list-weapons'
List the available weapons.
4.3 Show options
================
4.3.1 show-build-abs-srcdir
---------------------------
-- Command-line option: '--show-build-abs-srcdir'
Shows the top source directory on the machine where the binary was
compiled, as an absolute path.
4.3.2 show-build-bin-id
-----------------------
-- Command-line option: '--show-build-bin-id'
Shows the internal 'bin-id' value. This value does not mean
anything in itself but it's supposed to change each time you
compile the game.
4.3.3 show-build-bugs-url
-------------------------
-- Command-line option: '--show-build-bugs-url'
Shows the URL to make bug reports.
4.3.4 show-build-cflags
-----------------------
-- Command-line option: '--show-build-cflags'
Shows what value you should put in 'CFLAGS' (environment variable)
if you want to compile programs that use Liquid War 6 as a library,
and include 'liquidwar6.h'.
4.3.5 show-build-codename
-------------------------
-- Command-line option: '--show-build-codename'
Shows the codename associated with this version, generally the name
of someone famous who is war-related (a general, an emperor...).
4.3.6 show-build-configure-args
-------------------------------
-- Command-line option: '--show-build-configure-args'
Shows the arguments that have been passed to the GNU Autoconf
'./configure' script when building the program. This can be very
usefull if you want to know how the program has been built.
4.3.7 show-build-copyright
--------------------------
-- Command-line option: '--show-build-copyright'
Shows a very short copyright notice.
4.3.8 show-build-datadir
------------------------
-- Command-line option: '--show-build-datadir'
Shows the 'datadir' value as passed to the GNU Autoconf
'./configure' script when compiling the program. Default is
'/usr/local/share'. This is the generic, non Liquid War 6 specific
data directory. Liquid War 6 related data is stored elsewhere
(usually in a sub-directory) see the 'data-dir' switch for more
information. 'datadir' is not 'data-dir'. That's the point.
4.3.9 show-build-date
---------------------
-- Command-line option: '--show-build-date'
Shows the date when the binary was compiled.
4.3.10 show-build-docdir
------------------------
-- Command-line option: '--show-build-docdir'
Shows the 'docdir' value as passed to the GNU Autoconf
'./configure' script when compiling the program. Default is
'/usr/local/share/doc/liquidwar6'.
4.3.11 show-build-enable-allinone
---------------------------------
-- Command-line option: '--show-build-enable-allinone'
Shows wether the 'allinone' option has been chosen when building
the game. This depends on parameters passed to './configure'.
4.3.12 show-build-enable-console
--------------------------------
-- Command-line option: '--show-build-enable-console'
Shows wether the console has been enabled when building the game.
This depends on parameters passed to './configure' and also on the
presence of ncurses and readline.
4.3.13 show-build-enable-fullstatic
-----------------------------------
-- Command-line option: '--show-build-enable-fullstatic'
Shows wether the 'fullstatic' option has been chosen when building
the game. This depends on parameters passed to './configure'.
4.3.14 show-build-enable-gcov
-----------------------------
-- Command-line option: '--show-build-enable-gcov'
Shows wether the game was build with suitable informations for
gcov. This depends on parameters passed to './configure'.
4.3.15 show-build-enable-gprof
------------------------------
-- Command-line option: '--show-build-enable-gprof'
Shows wether the game was build with suitable informations for
gprof. This depends on parameters passed to './configure'.
4.3.16 show-build-enable-gtk
----------------------------
-- Command-line option: '--show-build-enable-gtk'
Shows wether GTK+ support has been enabled when building the game.
This depends on parameters passed to './configure' and also on the
presence of GTK+ headers and libs. It uses pkg-config to detect
it.
4.3.17 show-build-enable-instrument
-----------------------------------
-- Command-line option: '--show-build-enable-instrument'
Shows wether the game was build with the '-finstrument-functions'
GCC switch. This depends on parameters passed to './configure'.
4.3.18 show-build-enable-mod-caca
---------------------------------
-- Command-line option: '--show-build-enable-mod-caca'
Shows wether the mod-caca graphical backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of libcaca related
libraries.
4.3.19 show-build-enable-mod-csound
-----------------------------------
-- Command-line option: '--show-build-enable-mod-csound'
Shows wether the mod-csound audio backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of the csound library.
4.3.20 show-build-enable-mod-gl1
--------------------------------
-- Command-line option: '--show-build-enable-mod-gl1'
Shows wether the mod-gl1 graphical backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of SDL and OpenGL related
libraries.
4.3.21 show-build-enable-mod-gles2
----------------------------------
-- Command-line option: '--show-build-enable-mod-gles2'
Shows wether the mod-gles2 graphical backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of SDL and OpenGL ES related
libraries.
4.3.22 show-build-enable-mod-http
---------------------------------
-- Command-line option: '--show-build-enable-mod-http'
Shows wether the mod-http network backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of libCurl.
4.3.23 show-build-enable-mod-ogg
--------------------------------
-- Command-line option: '--show-build-enable-mod-ogg'
Shows wether the mod-ogg audio backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of SDL and related
libraries.
4.3.24 show-build-enable-mod-soft
---------------------------------
-- Command-line option: '--show-build-enable-mod-soft'
Shows wether the mod-soft graphical backend has been enabled when
building the game. This depends on parameters passed to
'./configure' and also on the presence of SDL related libraries.
4.3.25 show-build-enable-openmp
-------------------------------
-- Command-line option: '--show-build-enable-openmp'
Shows wether the program was built with OpenMP support. This
depends on parameters passed to './configure'.
4.3.26 show-build-enable-optimize
---------------------------------
-- Command-line option: '--show-build-enable-optimize'
Shows wether the 'optimize' option has been chosen when building
the game. This depends on parameters passed to './configure'.
4.3.27 show-build-enable-paranoid
---------------------------------
-- Command-line option: '--show-build-enable-paranoid'
Shows wether the game was build with paranoid memory management.
This is for debugging purposes, the default already includes some
controls, with turned it's really... paranoid.
4.3.28 show-build-enable-profiler
---------------------------------
-- Command-line option: '--show-build-enable-profiler'
Shows wether the game was build with Google Profiler support. This
depends on parameters passed to './configure'.
4.3.29 show-build-enable-valgrind
---------------------------------
-- Command-line option: '--show-build-enable-valgrind'
Shows wether the game was build with valgrind later use in mind.
This depends on parameters passed to './configure'.
4.3.30 show-build-endianness
----------------------------
-- Command-line option: '--show-build-endianness'
Returns the endianness. 'little' corresponds to x86-like systems,
'big' to ppc-like systems.
4.3.31 show-build-gcc-version
-----------------------------
-- Command-line option: '--show-build-gcc-version'
Returns the version of the GNU C compiler which was used to compile
the program.
4.3.32 show-build-gnu
---------------------
-- Command-line option: '--show-build-gnu'
Returns 1 (true) if host OS is a GNU system, or at least has been
considered as such when compiling, 0 (false) if not.
4.3.33 show-build-gp2x
----------------------
-- Command-line option: '--show-build-gp2x'
Returns 1 (true) if host is a GP2X, 0 (false) if not.
4.3.34 show-build-home-url
--------------------------
-- Command-line option: '--show-build-home-url'
Shows the URL of the program, its homepage.
4.3.35 show-build-host-cpu
--------------------------
-- Command-line option: '--show-build-host-cpu'
Shows the host CPU, as defined by 'host_cpu' in GNU Autoconf.
4.3.36 show-build-host-os
-------------------------
-- Command-line option: '--show-build-host-os'
Shows the host OS, as defined by 'host_os' in GNU Autoconf.
4.3.37 show-build-hostname
--------------------------
-- Command-line option: '--show-build-hostname'
Shows the name of the host where the binary was compiled.
4.3.38 show-build-includedir
----------------------------
-- Command-line option: '--show-build-includedir'
Shows the 'includedir' value as passed to the GNU Autoconf
'./configure' script when compiling the program. Default is
'/usr/local/include'.
4.3.39 show-build-ldflags
-------------------------
-- Command-line option: '--show-build-ldflags'
Shows what value you should put in 'LDFLAGS' (environment variable)
if you want to link programs against libliquidwar6.
4.3.40 show-build-libdir
------------------------
-- Command-line option: '--show-build-libdir'
Shows the 'libdir' value as passed to the GNU Autoconf
'./configure' script when compiling the program. Default is
'/usr/local/lib'. This is the generic, non Liquid War 6 specific
library directory. Dedicated Liquid War 6 modules are stored
elsewhere (usually in a sub-directory) see the 'mod-dir' switch for
more information.
4.3.41 show-build-license
-------------------------
-- Command-line option: '--show-build-license'
Shows the license of the program (GNU GPL v3 or later).
4.3.42 show-build-localedir
---------------------------
-- Command-line option: '--show-build-localedir'
Shows the 'localedir' value as passed to the GNU Autoconf
'./configure' script when compiling the program. Default is
'/usr/local/share/locale'.
4.3.43 show-build-mac-os-x
--------------------------
-- Command-line option: '--show-build-mac-os-x'
Returns 1 (true) if host OS is Mac OS X, 0 (false) if not.
4.3.44 show-build-md5sum
------------------------
-- Command-line option: '--show-build-md5sum'
Shows the MD5 checksum, which has been calculated from the C source
files. Complementary with 'show-build-stamp'.
4.3.45 show-build-ms-windows
----------------------------
-- Command-line option: '--show-build-ms-windows'
Returns 1 (true) if host OS is Microsoft Windows, 0 (false) if not.
4.3.46 show-build-package-id
----------------------------
-- Command-line option: '--show-build-package-id'
Shows the package tarname with its version, that is,
'liquidwar6-
4.3.47 show-build-package-name
------------------------------
-- Command-line option: '--show-build-package-name'
Shows the package name, that is, 'Liquid War 6'.
4.3.48 show-build-package-string
--------------------------------
-- Command-line option: '--show-build-package-string'
Shows the package string, that is, 'Liquid War 6
4.3.49 show-build-package-tarname
---------------------------------
-- Command-line option: '--show-build-package-tarname'
Shows the package tarname, that is, liquidwar6.
4.3.50 show-build-pointer-size
------------------------------
-- Command-line option: '--show-build-pointer-size'
Returns the pointer size, in bytes. Should be 4 on 32-bit systems
and 8 on 64-bit systems.
4.3.51 show-build-prefix
------------------------
-- Command-line option: '--show-build-prefix'
Shows the 'prefix' value as passed to the GNU Autoconf
'./configure' script when compiling the program. Default is
'/usr/local'.
4.3.52 show-build-stamp
-----------------------
-- Command-line option: '--show-build-stamp'
Shows the build stamp. A very usefull value, more precise than the
version to track down binaries. It is incremented each time the
core C code is updated. It won't reflect all the programs for it
does not take scripts in account, but if you are running a
work-in-progress version, it might be very convenient to use this
to know what your are running exactly. It's also used as the
revision number (the third number afer MAJOR.MINOR).
4.3.53 show-build-time
----------------------
-- Command-line option: '--show-build-time'
Shows the time when the binary was compiled.
4.3.54 show-build-top-srcdir
----------------------------
-- Command-line option: '--show-build-top-srcdir'
Shows the top source directory on the machine where the binary was
compiled, as a (possibly) relative path.
4.3.55 show-build-unix
----------------------
-- Command-line option: '--show-build-unix'
Returns 1 (true) if host OS is a UNIX system, or at least has been
considered as such when compiling, 0 (false) if not.
4.3.56 show-build-version
-------------------------
-- Command-line option: '--show-build-version'
Shows the version. Note that this is different from the standard
GNU 'version' command line option which shows a complete message
with a short copyright notice. This one will just return the
version, without the package tarname or anything else.
4.3.57 show-build-version-base
------------------------------
-- Command-line option: '--show-build-version-base'
Shows the version base. This is basically MAJOR.MINOR and
determines the level of compatibility of the program. Two programs
with the same base version should be able to communicate on the
network, share data files and even binary modules if on the same
platform.
4.3.58 show-build-version-major
-------------------------------
-- Command-line option: '--show-build-version-major'
Shows the major version number. This is just used to differenciate
alpha/beta releases (using 0) from stable releases (using 6).
4.3.59 show-build-version-minor
-------------------------------
-- Command-line option: '--show-build-version-minor'
Shows the minor version number. This is manually increased at each
significant, public release of the game.
4.3.60 show-build-x86
---------------------
-- Command-line option: '--show-build-x86'
Tells wether the CPU belongs to the x86 family.
4.3.61 show-config-file
-----------------------
-- Command-line option: '--show-config-file'
Shows the config file path. Default is
'$HOME/.liquidwar6/config.xml'.
4.3.62 show-cwd
---------------
-- Command-line option: '--show-cwd'
Shows the current working directory, the value that the pwd command
would return.
4.3.63 show-data-dir
--------------------
-- Command-line option: '--show-data-dir'
Shows the data directory path. This is where the games searches
for most of its data,the most important exception being maps, which
are stored elsewhere. Default is
'/usr/local/share/liquidwar6-/data'.
4.3.64 show-default-config-file
-------------------------------
-- Command-line option: '--show-default-config-file'
Shows the default config file path. Default is
'$HOME/.liquidwar6/config.xml'.
4.3.65 show-default-data-dir
----------------------------
-- Command-line option: '--show-default-data-dir'
Shows the default data directory path. This is where the games
searches for most of its data,the most important exception being
maps, which are stored elsewhere. Default is
'/usr/local/share/liquidwar6-/data'.
4.3.66 show-default-log-file
----------------------------
-- Command-line option: '--show-default-log-file'
Shows the default log file path. Default is
'$HOME/.liquidwar6/log.csv'.
4.3.67 show-default-map-dir
---------------------------
-- Command-line option: '--show-default-map-dir'
Shows the default map directory. This is where builtin maps are
stored. Default is '/usr/local/share/liquidwar6-/map'.
4.3.68 show-default-map-path
----------------------------
-- Command-line option: '--show-default-map-path'
Shows the default map search path. This is where the game searches
for maps. It's the combination of command-line arguments and
builtin paths. Might return more directories than the one
specified in a single 'map-path=dir1:dir2' argument.
4.3.69 show-default-mod-dir
---------------------------
-- Command-line option: '--show-default-mod-dir'
Shows the default module directory path. This is where all
dynamically loaded modules are stored. Default is
'/usr/local/lib/liquidwar6-'.
4.3.70 show-default-music-dir
-----------------------------
-- Command-line option: '--show-default-music-dir'
Shows the default music directory. This is where builtin musics
are stored. Default is
'/usr/local/share/liquidwar6-/music'.
4.3.71 show-default-music-path
------------------------------
-- Command-line option: '--show-default-music-path'
Shows the default music search path. This is where the game
searches for musics. It's the combination of command-line
arguments and builtin paths. Might return more directories than
the one specified in a single 'music-path=dir1:dir2' argument.
4.3.72 show-default-prefix
--------------------------
-- Command-line option: '--show-default-prefix'
Shows the default prefix used. This should logically be the value
passed to the GNU Autoconf ./configure script when building the
game. Most other path are deduced from this one. Default is
'/usr/local'.
4.3.73 show-default-script-file
-------------------------------
-- Command-line option: '--show-default-script-file'
Shows the default main script file path. This file is very
important, since the program is more or less a hudge scheme
interpreter, and this file is the file loaded by Guile. In short,
it is the main program. Default is
'/usr/local/share/liquidwar6-/script/liquidwar6.scm'.
4.3.74 show-default-user-dir
----------------------------
-- Command-line option: '--show-default-user-dir'
Shows the default user directory path. This is where run-time
data, config files, log files, are stored. Default is
'$HOME/.liquidwar6/'.
4.3.75 show-log-file
--------------------
-- Command-line option: '--show-log-file'
Shows the log file path. Default is '$HOME/.liquidwar6/log.csv'.
4.3.76 show-map-dir
-------------------
-- Command-line option: '--show-map-dir'
Shows the map directory. This is where builtin maps are stored.
Default is '/usr/local/share/liquidwar6-/map'.
4.3.77 show-map-path
--------------------
-- Command-line option: '--show-map-path'
Shows the map search path. This is where the game searches for
maps. It's the combination of command-line arguments and builtin
paths. Might return more directories than the one specified in a
single 'map-path=dir1:dir2' argument.
4.3.78 show-mod-dir
-------------------
-- Command-line option: '--show-mod-dir'
Shows the module directory path. This is where all dynamically
loaded modules are stored. Default is
'/usr/local/lib/liquidwar6-'.
4.3.79 show-music-dir
---------------------
-- Command-line option: '--show-music-dir'
Shows the music directory. This is where builtin maps are stored.
Default is '/usr/local/share/liquidwar6-/music'.
4.3.80 show-music-path
----------------------
-- Command-line option: '--show-music-path'
Shows the music search path. This is where the game searches for
musics. It's the combination of command-line arguments and builtin
paths. Might return more directories than the one specified in a
single 'music-path=dir1:dir2' argument.
4.3.81 show-prefix
------------------
-- Command-line option: '--show-prefix'
Shows the prefix used. This should logically be the value passed
to the GNU Autoconf ./configure script when building the game.
Most other path are deduced from this one. Default is
'/usr/local'.
4.3.82 show-run-dir
-------------------
-- Command-line option: '--show-run-dir'
Shows the run directory, usually the path where the binary is. It
depends on how and where the program is launched. It is guessed
from the argc/argv values at runtime.
4.3.83 show-script-file
-----------------------
-- Command-line option: '--show-script-file'
Shows the main script file path. This file is very important,
since the program is more or less a hudge scheme interpreter, and
this file is the file loaded by Guile. In short, it is the main
program. Default is
'/usr/local/share/liquidwar6-/script/liquidwar6.scm'.
4.3.84 show-user-dir
--------------------
-- Command-line option: '--show-user-dir'
Shows the user directory path. This is where run-time data, config
files, log files, are stored. Default is '$HOME/.liquidwar6/'.
4.4 Path options
================
4.4.1 config-file
-----------------
-- Command-line option: '--config-file'
Type: string
Default value: $HOME/.liquidwar6/config.xml
Set the config file path. This enables you to use whatever config
file you like, keeping all other informations in the same place.
4.4.2 data-dir
--------------
-- Command-line option: '--data-dir'
Type: string
Default value: /usr/local/share/liquidwar6-/data
Set the data directory. By changing ths value you'll be able to
use an alternative data directory.
4.4.3 log-file
--------------
-- Command-line option: '--log-file='
-- Environment variable: 'LW6_LOG_FILE'
-- XML key: 'log-file'
Type: string
Default value: $HOME/.liquidwar6/log.csv
Set the log file path. This enables you to use whatever log file
you like, keeping all other informations in the same place.
4.4.4 map-dir
-------------
-- Command-line option: '--map-dir'
Type: string
Default value: /usr/local/share/liquidwar6-/map
Set the map directory path. By changing this value you'll be able
to play with your own maps in your own directory. Note that there
are other ways to achieve that, but using this option will work.
However, a side effect is that you might not see builtin maps
anymore.
4.4.5 map-path
--------------
-- Command-line option: '--map-path='
-- Environment variable: 'LW6_MAP_PATH'
-- XML key: 'map-path'
Type: string
Default value:
$HOME/.liquidwar6/map:/usr/local/share/liquidwar6-/map
Set the map search path. By changing this value you'll be able to
play with your own maps in your own directory. This is different
from 'map-dir', since it includes 'map-dir', plus it adds a number
of other search paths. Unlike most other parameters, the values
given from the command-line, from the environment variables, or
from the config file, are not overwritten, but appended. That is
to say if you specify a 'map-path' with the command-line argument
'map-path=path', but also define the 'LW6_MAP_PATH' value and
finally edit 'config.xml' to change the 'map-path' entry in it,
you'll end up with the game searching for maps in all these
directories. Additionnally, 'map-dir' and '/map' will
always be in the list. Any given value can itself include several
pathes, separated by the path separator. This separator is ':' on
GNU/Linux, and ';' on Microsoft Windows. For instance, on a
GNU/Linux box, you could use the command-line argument
'map-path=/foo/bar/map:/home/user/map/:/map'.
4.4.6 mod-dir
-------------
-- Command-line option: '--mod-dir'
Type: string
Default value: /usr/local/lib/liquidwar6-
Set the module directory path. By changing this you will load
dynamic shared libraries (game specific modules such as the
graphical backend) from an alternative place. Use this at your own
risks, for there can always be a binary incompatibility. You've
been warned.
4.4.7 music-dir
---------------
-- Command-line option: '--music-dir='
-- Environment variable: 'LW6_MUSIC_DIR'
-- XML key: 'music-dir'
Type: string
Default value: /usr/local/share/liquidwar6-/music
Set the music directory path. By changing this value you'll be
able to use your own musics in your own directory. Note that there
are other ways to achieve that, but using this option will work.
The major side effect is that using this option, you really replace
the existing builtin musics by your own. If you simply want to add
musics you can store them in $HOME/.liquidwar6/music or in the map
directory itself.
4.4.8 music-path
----------------
-- Command-line option: '--music-path='
-- Environment variable: 'LW6_MUSIC_PATH'
-- XML key: 'music-path'
Type: string
Default value:
$HOME/.liquidwar6/music:/usr/local/share/liquidwar6-/music
Set the music search path. By changing this value you'll be able
to play with your own musics in your own directory. This is
different from 'music-dir', since it includes 'music-dir', plus it
adds a number of other search paths. Unlike most other parameters,
the values given from the command-line, from the environment
variables, or from the config file, are not overwritten, but
appended. That is to say if you specify a 'music-path' with the
command-line argument 'music-path=path', but also define the
'LW6_MUSIC_PATH' value and finally edit 'config.xml' to change the
'music-path' entry in it, you'll end up with the game searching for
musics in all these directories. Additionnally, 'music-dir' and
'/music' will always be in the list. Any given value can
itself include several pathes, separated by the path separator.
This separator is ':' on GNU/Linux, and ';' on Microsoft Windows.
For instance, on a GNU/Linux box, you could use the command-line
argument 'music-path=/foo/bar/music:/home/user/music/:/music'.
4.4.9 prefix
------------
-- Command-line option: '--prefix'
Type: string
Default value: /usr/local
Override the prefix value given to the GNU Autoconf ./configure
script when building the game. Not all path will be changed, some
of them might remain the same, for instance message translations
(localedir). But most game-specific data including maps, graphics,
sounds, will be searched according to the new given parameter.
4.4.10 script-file
------------------
-- Command-line option: '--script-file'
Type: string
Default value:
/usr/local/share/liquidwar6-/script/liquidwar6.scm
Set the main script file path. This file is very important, since
the program is more or less a hudge scheme interpreter, and this
file is the file loaded by Guile. In short, it is the main
program.
4.4.11 user-dir
---------------
-- Command-line option: '--user-dir='
-- Environment variable: 'LW6_USER_DIR'
-- XML key: 'user-dir'
Type: string
Default value: $HOME/.liquidwar6
Set the user directory path. This is where run-time data, config
files, log files, are stored. If you override this value, other
parameters such as where the config and log files reside, will
change.
4.5 Players options
===================
4.5.1 player1-control
---------------------
-- Command-line option: '--player1-control='
-- Environment variable: 'LW6_PLAYER1_CONTROL'
-- XML key: 'player1-control'
Type: string
Default value: mouse
Control for the first player, must be mouse, keyboard, joystick1,
joystick2 or custom.
4.5.2 player1-name
------------------
-- Command-line option: '--player1-name='
-- Environment variable: 'LW6_PLAYER1_NAME'
-- XML key: 'player1-name'
Type: string
Default value:
Name of the first player, the player used by default. A default
value is provided, you can of course, change it at will.
4.5.3 player1-status
--------------------
-- Command-line option: '--player1-status='
-- Environment variable: 'LW6_PLAYER1_STATUS'
-- XML key: 'player1-status'
Type: boolean
Default value: true
Status of the first player, true if player is activated, false if
idle.
4.5.4 player2-control
---------------------
-- Command-line option: '--player2-control='
-- Environment variable: 'LW6_PLAYER2_CONTROL'
-- XML key: 'player2-control'
Type: string
Default value: keyboard
Control for the second player, must be mouse, keyboard, joystick1,
joystick2 or custom.
4.5.5 player2-name
------------------
-- Command-line option: '--player2-name='
-- Environment variable: 'LW6_PLAYER2_NAME'
-- XML key: 'player2-name'
Type: string
Default value: player2-
Name of the second player. A default value is provided, you'll
certainly want to change it.
4.5.6 player2-status
--------------------
-- Command-line option: '--player2-status='
-- Environment variable: 'LW6_PLAYER2_STATUS'
-- XML key: 'player2-status'
Type: boolean
Default value: true
Status of the second player, true if player is activated, false if
idle.
4.5.7 player3-control
---------------------
-- Command-line option: '--player3-control='
-- Environment variable: 'LW6_PLAYER3_CONTROL'
-- XML key: 'player3-control'
Type: string
Default value: joystick1
Control for the third player, must be mouse, keyboard, joystick1,
joystick2 or custom.
4.5.8 player3-name
------------------
-- Command-line option: '--player3-name='
-- Environment variable: 'LW6_PLAYER3_NAME'
-- XML key: 'player3-name'
Type: string
Default value: player3-
Name of the third player. A default value is provided, you'll
certainly want to change it.
4.5.9 player3-status
--------------------
-- Command-line option: '--player3-status='
-- Environment variable: 'LW6_PLAYER3_STATUS'
-- XML key: 'player3-status'
Type: boolean
Default value: false
Status of the third player, true if player is activated, false if
idle.
4.5.10 player4-control
----------------------
-- Command-line option: '--player4-control='
-- Environment variable: 'LW6_PLAYER4_CONTROL'
-- XML key: 'player4-control'
Type: string
Default value: joystick2
Control for the fourth player, must be mouse, keyboard, joystick1,
joystick2 or custom.
4.5.11 player4-name
-------------------
-- Command-line option: '--player4-name='
-- Environment variable: 'LW6_PLAYER4_NAME'
-- XML key: 'player4-name'
Type: string
Default value: player4-
Name of the fourth player. A default value is provided, you'll
certainly want to change it.
4.5.12 player4-status
---------------------
-- Command-line option: '--player4-status='
-- Environment variable: 'LW6_PLAYER4_STATUS'
-- XML key: 'player4-status'
Type: boolean
Default value: false
Status of the fourth player, true if player is activated, false if
idle.
4.6 Input options
=================
4.6.1 auto-release-delay
------------------------
-- Command-line option: '--auto-release-delay='
-- Environment variable: 'LW6_AUTO_RELEASE_DELAY'
-- XML key: 'auto-release-delay'
Type: integer
Default value: 250
Time, in milliseconds, before which a key is automatically
released. This might or might not be used by the graphics backend,
it's typically used by backends which don't always handle key
releases events the right way, that is, don't fire them. Libcaca
is a good example of such a case.
4.6.2 click-to-focus
--------------------
-- Command-line option: '--click-to-focus='
-- Environment variable: 'LW6_CLICK_TO_FOCUS'
-- XML key: 'click-to-focus'
Type: boolean
Default value: false
If set to true, you'll need to click with the mouse to select a
menuitem or move the cursor in the game. If not, some actions will
be taken automatically without the need to click.
4.6.3 cursor-sensitivity
------------------------
-- Command-line option: '--cursor-sensitivity='
-- Environment variable: 'LW6_CURSOR_SENSITIVITY'
-- XML key: 'cursor-sensitivity'
Type: float
Default value: 1.0
Keyboard and joystick sensitivity while moving the cursor. 1.0 is
the default, 0.1 is slow, 10 is reponsive. This is used for moving
the cursor during the game only, the option has no impact on menu
navigation.
4.6.4 custom-alt
----------------
-- Command-line option: '--custom-alt='
-- Environment variable: 'LW6_CUSTOM_ALT'
-- XML key: 'custom-alt'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 110) ; SDLK_n
Guile custom code associated to the ALT key equivalent.
4.6.5 custom-ctrl
-----------------
-- Command-line option: '--custom-ctrl='
-- Environment variable: 'LW6_CUSTOM_CTRL'
-- XML key: 'custom-ctrl'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 98) ; SDLK_b
Guile custom code associated to the CTRL key equivalent.
4.6.6 custom-down
-----------------
-- Command-line option: '--custom-down='
-- Environment variable: 'LW6_CUSTOM_DOWN'
-- XML key: 'custom-down'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 100) ; SDLK_d
Guile custom code associated to the DOWN key equivalent.
4.6.7 custom-enter
------------------
-- Command-line option: '--custom-enter='
-- Environment variable: 'LW6_CUSTOM_ENTER'
-- XML key: 'custom-enter'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 103) ; SDLK_g
Guile custom code associated to the ENTER key equivalent.
4.6.8 custom-esc
----------------
-- Command-line option: '--custom-esc='
-- Environment variable: 'LW6_CUSTOM_ESC'
-- XML key: 'custom-esc'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 102) ; SDLK_f
Guile custom code associated to the ESC key equivalent.
4.6.9 custom-left
-----------------
-- Command-line option: '--custom-left='
-- Environment variable: 'LW6_CUSTOM_LEFT'
-- XML key: 'custom-left'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 99) ; SDLK_c
Guile custom code associated to the LEFT key equivalent.
4.6.10 custom-pgdown
--------------------
-- Command-line option: '--custom-pgdown='
-- Environment variable: 'LW6_CUSTOM_PGDOWN'
-- XML key: 'custom-pgdown'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 115) ; SDLK_s
Guile custom code associated to the PGDOWN key equivalent.
4.6.11 custom-pgup
------------------
-- Command-line option: '--custom-pgup='
-- Environment variable: 'LW6_CUSTOM_PGUP'
-- XML key: 'custom-pgup'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 119) ; SDLK_w
Guile custom code associated to the PGUP key equivalent.
4.6.12 custom-right
-------------------
-- Command-line option: '--custom-right='
-- Environment variable: 'LW6_CUSTOM_RIGHT'
-- XML key: 'custom-right'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 118) ; SDLK_v
Guile custom code associated to the RIGHT key equivalent.
4.6.13 custom-up
----------------
-- Command-line option: '--custom-up='
-- Environment variable: 'LW6_CUSTOM_UP'
-- XML key: 'custom-up'
Type: string
Default value: (c-lw6gui-keyboard-is-pressed 101) ; SDLK_e
Custom keycode to be used as the UP key equivalent.
4.6.14 double-click-delay
-------------------------
-- Command-line option: '--double-click-delay='
-- Environment variable: 'LW6_DOUBLE_CLICK_DELAY'
-- XML key: 'double-click-delay'
Type: integer
Default value: 333
Time, in milliseconds, determining wether two consecutive clicks
make a double-click or not.
4.6.15 max-cursor-speed
-----------------------
-- Command-line option: '--max-cursor-speed='
-- Environment variable: 'LW6_MAX_CURSOR_SPEED'
-- XML key: 'max-cursor-speed'
Type: float
Default value: 10.0
Maximum cursor speed when cursor is controlled with keyboard or
joystick joystick 1. Consider using cursor-sensitivity too.
4.6.16 mouse-sensitivity
------------------------
-- Command-line option: '--mouse-sensitivity='
-- Environment variable: 'LW6_MOUSE_SENSITIVITY'
-- XML key: 'mouse-sensitivity'
Type: float
Default value: 1.0
Mouse sensitivity, 1.0 is the default, 0.1 is slow, 10 is
reponsive. This is used for moving the cursor during the game
only, the option has no impact on menu navigation.
4.6.17 repeat-delay
-------------------
-- Command-line option: '--repeat-delay=