Liquid War 6, a unique multiplayer wargame. Table of Contents ***************** 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.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.3 Installation 2.3.1 Requirements 2.3.2 Optional libraries 2.3.3 Installing requirements using RPM/DEB packages 2.3.4 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 About mod-gl 3.6.1 The main renderer 3.6.2 Hardware requirements 3.6.3 The gl-utils toolbox 3.7 Compilation tips 3.7.1 Advanced ./configure options 3.7.2 Debian packages 3.7.3 Red Hat packages 3.7.4 Microsoft Windows msys/mingw32 port 3.7.5 Mac OS X port 3.7.6 GP2X port 3.8 Coding guidelines 3.8.1 Project goals reminder 3.8.2 Common sense 3.8.3 Unitary tests 3.8.4 Memory allocation 3.8.5 Private and public interfaces 3.8.6 Audit the code 3.9 Using the console 3.10 Advanced tweaking 3.10.1 Hacking ressources 3.10.2 Optimize for speed 3.11 Writing modules 3.12 Use as a library 3.13 Network protocol 3.13.1 No server, no client, only nodes 3.13.2 Out of band messages 3.13.3 Other raw technical stuff (WIP) 3.14 Technical HOWTOs 3.14.1 Release check-list 3.14.2 Add a new option 3.14.3 Add a new internal library 3.14.4 Add a new module 3.15 Using GNU Arch 3.15.1 About GNU Arch 3.15.2 Getting the latest version from the repository 3.15.3 Setting up your own arch repository 3.15.4 Synchronizing your repository with upstream releases 3.15.5 Submitting patches 3.15.6 Recover from broken lock 3.16 Using GIT 3.16.1 About GIT 3.16.2 Getting the latest source 3.16.3 Developper access 3.16.4 Submitting patches 4 Reference 4.1 Basic options 4.1.1 about 4.1.2 audit 4.1.3 copyright 4.1.4 debug 4.1.5 defaults 4.1.6 help 4.1.7 host 4.1.8 list 4.1.9 modules 4.1.10 pedigree 4.1.11 test 4.1.12 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-bin-id 4.3.2 show-build-bugs-url 4.3.3 show-build-cflags 4.3.4 show-build-codename 4.3.5 show-build-configure-args 4.3.6 show-build-copyright 4.3.7 show-build-datadir 4.3.8 show-build-date 4.3.9 show-build-docdir 4.3.10 show-build-enable-allinone 4.3.11 show-build-enable-console 4.3.12 show-build-enable-fullstatic 4.3.13 show-build-enable-gcov 4.3.14 show-build-enable-gprof 4.3.15 show-build-enable-gtk 4.3.16 show-build-enable-instrument 4.3.17 show-build-enable-mod-csound 4.3.18 show-build-enable-mod-gl 4.3.19 show-build-enable-mod-http 4.3.20 show-build-enable-mod-ogg 4.3.21 show-build-enable-openmp 4.3.22 show-build-enable-optimize 4.3.23 show-build-enable-paranoid 4.3.24 show-build-enable-profiler 4.3.25 show-build-enable-valgrind 4.3.26 show-build-endianness 4.3.27 show-build-gcc-version 4.3.28 show-build-gnu 4.3.29 show-build-gp2x 4.3.30 show-build-home-url 4.3.31 show-build-host-cpu 4.3.32 show-build-host-os 4.3.33 show-build-hostname 4.3.34 show-build-includedir 4.3.35 show-build-ldflags 4.3.36 show-build-libdir 4.3.37 show-build-license 4.3.38 show-build-localedir 4.3.39 show-build-mac-os-x 4.3.40 show-build-md5sum 4.3.41 show-build-ms-windows 4.3.42 show-build-package-name 4.3.43 show-build-package-string 4.3.44 show-build-package-tarname 4.3.45 show-build-pointer-size 4.3.46 show-build-prefix 4.3.47 show-build-stamp 4.3.48 show-build-time 4.3.49 show-build-top-srcdir 4.3.50 show-build-unix 4.3.51 show-build-version 4.3.52 show-build-x86 4.3.53 show-config-file 4.3.54 show-cwd 4.3.55 show-data-dir 4.3.56 show-default-config-file 4.3.57 show-default-data-dir 4.3.58 show-default-log-file 4.3.59 show-default-map-dir 4.3.60 show-default-map-path 4.3.61 show-default-mod-dir 4.3.62 show-default-music-dir 4.3.63 show-default-music-path 4.3.64 show-default-prefix 4.3.65 show-default-script-file 4.3.66 show-default-user-dir 4.3.67 show-log-file 4.3.68 show-map-dir 4.3.69 show-map-path 4.3.70 show-mod-dir 4.3.71 show-music-dir 4.3.72 show-music-path 4.3.73 show-prefix 4.3.74 show-run-dir 4.3.75 show-script-file 4.3.76 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 click-to-focus 4.6.2 cursor-sensitivity 4.6.3 custom-alt 4.6.4 custom-ctrl 4.6.5 custom-down 4.6.6 custom-enter 4.6.7 custom-esc 4.6.8 custom-left 4.6.9 custom-pgdown 4.6.10 custom-pgup 4.6.11 custom-right 4.6.12 custom-up 4.6.13 double-click-delay 4.6.14 max-cursor-speed 4.6.15 mouse-sensitivity 4.6.16 repeat-delay 4.6.17 repeat-interval 4.6.18 use-double-click 4.6.19 use-esc-button 4.6.20 zoom-step 4.6.21 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-mobile 4.11.63 team-profile-blue-vulnerable 4.11.64 team-profile-blue-weapon-alternate-id 4.11.65 team-profile-blue-weapon-id 4.11.66 team-profile-blue-weapon-mode 4.11.67 team-profile-cyan-aggressive 4.11.68 team-profile-cyan-fast 4.11.69 team-profile-cyan-mobile 4.11.70 team-profile-cyan-vulnerable 4.11.71 team-profile-cyan-weapon-alternate-id 4.11.72 team-profile-cyan-weapon-id 4.11.73 team-profile-cyan-weapon-mode 4.11.74 team-profile-green-aggressive 4.11.75 team-profile-green-fast 4.11.76 team-profile-green-mobile 4.11.77 team-profile-green-vulnerable 4.11.78 team-profile-green-weapon-alternate-id 4.11.79 team-profile-green-weapon-id 4.11.80 team-profile-green-weapon-mode 4.11.81 team-profile-lightblue-aggressive 4.11.82 team-profile-lightblue-fast 4.11.83 team-profile-lightblue-mobile 4.11.84 team-profile-lightblue-vulnerable 4.11.85 team-profile-lightblue-weapon-alternate-id 4.11.86 team-profile-lightblue-weapon-id 4.11.87 team-profile-lightblue-weapon-mode 4.11.88 team-profile-magenta-aggressive 4.11.89 team-profile-magenta-fast 4.11.90 team-profile-magenta-mobile 4.11.91 team-profile-magenta-vulnerable 4.11.92 team-profile-magenta-weapon-alternate-id 4.11.93 team-profile-magenta-weapon-id 4.11.94 team-profile-magenta-weapon-mode 4.11.95 team-profile-orange-aggressive 4.11.96 team-profile-orange-fast 4.11.97 team-profile-orange-mobile 4.11.98 team-profile-orange-vulnerable 4.11.99 team-profile-orange-weapon-alternate-id 4.11.100 team-profile-orange-weapon-id 4.11.101 team-profile-orange-weapon-mode 4.11.102 team-profile-pink-aggressive 4.11.103 team-profile-pink-fast 4.11.104 team-profile-pink-mobile 4.11.105 team-profile-pink-vulnerable 4.11.106 team-profile-pink-weapon-alternate-id 4.11.107 team-profile-pink-weapon-id 4.11.108 team-profile-pink-weapon-mode 4.11.109 team-profile-purple-aggressive 4.11.110 team-profile-purple-fast 4.11.111 team-profile-purple-mobile 4.11.112 team-profile-purple-vulnerable 4.11.113 team-profile-purple-weapon-alternate-id 4.11.114 team-profile-purple-weapon-id 4.11.115 team-profile-purple-weapon-mode 4.11.116 team-profile-red-aggressive 4.11.117 team-profile-red-fast 4.11.118 team-profile-red-mobile 4.11.119 team-profile-red-vulnerable 4.11.120 team-profile-red-weapon-alternate-id 4.11.121 team-profile-red-weapon-id 4.11.122 team-profile-red-weapon-mode 4.11.123 team-profile-yellow-aggressive 4.11.124 team-profile-yellow-fast 4.11.125 team-profile-yellow-mobile 4.11.126 team-profile-yellow-vulnerable 4.11.127 team-profile-yellow-weapon-alternate-id 4.11.128 team-profile-yellow-weapon-id 4.11.129 team-profile-yellow-weapon-mode 4.11.130 total-armies-size 4.11.131 total-time 4.11.132 use-team-profiles 4.11.133 vertical-move 4.11.134 weapon-charge-delay 4.11.135 weapon-charge-max 4.11.136 weapon-duration 4.11.137 weapon-tune-berzerk-power 4.11.138 weapon-tune-turbo-power 4.11.139 x-polarity 4.11.140 y-polarity 4.11.141 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 daemon 4.15.9 debug-layer-id 4.15.10 debug-team-id 4.15.11 demo 4.15.12 dirty-read 4.15.13 display-background 4.15.14 display-console 4.15.15 display-cursors 4.15.16 display-debug-gradient 4.15.17 display-debug-zones 4.15.18 display-fighters 4.15.19 display-fps 4.15.20 display-hud 4.15.21 display-log 4.15.22 display-map 4.15.23 display-menu 4.15.24 display-meta 4.15.25 display-mouse 4.15.26 display-mps 4.15.27 display-preview 4.15.28 display-progress 4.15.29 display-score 4.15.30 display-splash 4.15.31 display-url 4.15.32 executed-again 4.15.33 gfx-cpu-usage 4.15.34 gfx-debug 4.15.35 io-per-sec 4.15.36 loader-sleep 4.15.37 log-level 4.15.38 log-timeout 4.15.39 magic-number 4.15.40 max-local-bench-value 4.15.41 max-network-bench-value 4.15.42 memory-bazooka-eraser 4.15.43 memory-bazooka-size 4.15.44 net-log 4.15.45 network-reliability 4.15.46 open-relay 4.15.47 pilot-lag 4.15.48 quick-start 4.15.49 reset 4.15.50 reset-config-on-upgrade 4.15.51 server 4.15.52 simulate-basic 4.15.53 simulate-full 4.15.54 target-fps 4.15.55 trap-errors 4.15.56 trojan 4.15.57 z-decode 4.15.58 z-encode 4.16 C to Guile 4.16.1 c-gettext 4.16.2 c-lw6-exit 4.16.3 c-lw6-release 4.16.4 c-lw6bot-get-backends 4.16.5 c-lw6bot-new 4.16.6 c-lw6bot-next-move 4.16.7 c-lw6cfg-defaults 4.16.8 c-lw6cfg-get-option 4.16.9 c-lw6cfg-init 4.16.10 c-lw6cfg-load 4.16.11 c-lw6cfg-option-exists 4.16.12 c-lw6cfg-quit 4.16.13 c-lw6cfg-save 4.16.14 c-lw6cfg-set-option 4.16.15 c-lw6cfg-unified-get-log-file 4.16.16 c-lw6cfg-unified-get-map-path 4.16.17 c-lw6cfg-unified-get-music-path 4.16.18 c-lw6cfg-unified-get-user-dir 4.16.19 c-lw6cli-get-backends 4.16.20 c-lw6cns-init 4.16.21 c-lw6cns-poll 4.16.22 c-lw6cns-quit 4.16.23 c-lw6cns-support 4.16.24 c-lw6dsp-get-average-fps 4.16.25 c-lw6dsp-get-fullscreen-modes 4.16.26 c-lw6dsp-get-instant-fps 4.16.27 c-lw6dsp-get-last-frame-rendering-time 4.16.28 c-lw6dsp-get-nb-frames 4.16.29 c-lw6dsp-get-video-mode 4.16.30 c-lw6dsp-new 4.16.31 c-lw6dsp-release 4.16.32 c-lw6dsp-update 4.16.33 c-lw6gfx-get-backends 4.16.34 c-lw6gui-default-look 4.16.35 c-lw6gui-input-reset 4.16.36 c-lw6gui-joystick1-get-move-pad 4.16.37 c-lw6gui-joystick1-pop-button-a 4.16.38 c-lw6gui-joystick1-pop-button-b 4.16.39 c-lw6gui-joystick1-pop-button-c 4.16.40 c-lw6gui-joystick1-pop-button-d 4.16.41 c-lw6gui-joystick1-pop-button-e 4.16.42 c-lw6gui-joystick1-pop-button-f 4.16.43 c-lw6gui-joystick1-pop-pad-down 4.16.44 c-lw6gui-joystick1-pop-pad-left 4.16.45 c-lw6gui-joystick1-pop-pad-right 4.16.46 c-lw6gui-joystick1-pop-pad-up 4.16.47 c-lw6gui-joystick2-get-move-pad 4.16.48 c-lw6gui-joystick2-pop-button-a 4.16.49 c-lw6gui-joystick2-pop-button-b 4.16.50 c-lw6gui-joystick2-pop-button-c 4.16.51 c-lw6gui-joystick2-pop-button-d 4.16.52 c-lw6gui-joystick2-pop-button-e 4.16.53 c-lw6gui-joystick2-pop-button-f 4.16.54 c-lw6gui-joystick2-pop-pad-down 4.16.55 c-lw6gui-joystick2-pop-pad-left 4.16.56 c-lw6gui-joystick2-pop-pad-right 4.16.57 c-lw6gui-joystick2-pop-pad-up 4.16.58 c-lw6gui-keyboard-get-move-pad 4.16.59 c-lw6gui-keyboard-is-pressed 4.16.60 c-lw6gui-keyboard-pop-arrow-down 4.16.61 c-lw6gui-keyboard-pop-arrow-left 4.16.62 c-lw6gui-keyboard-pop-arrow-right 4.16.63 c-lw6gui-keyboard-pop-arrow-up 4.16.64 c-lw6gui-keyboard-pop-key-alt 4.16.65 c-lw6gui-keyboard-pop-key-ctrl 4.16.66 c-lw6gui-keyboard-pop-key-enter 4.16.67 c-lw6gui-keyboard-pop-key-esc 4.16.68 c-lw6gui-keyboard-pop-key-pgdown 4.16.69 c-lw6gui-keyboard-pop-key-pgup 4.16.70 c-lw6gui-look-get 4.16.71 c-lw6gui-look-set 4.16.72 c-lw6gui-look-zoom-in 4.16.73 c-lw6gui-look-zoom-out 4.16.74 c-lw6gui-menu-append 4.16.75 c-lw6gui-menu-close-popup 4.16.76 c-lw6gui-menu-enable-esc 4.16.77 c-lw6gui-menu-has-popup 4.16.78 c-lw6gui-menu-new 4.16.79 c-lw6gui-menu-scroll-down 4.16.80 c-lw6gui-menu-scroll-up 4.16.81 c-lw6gui-menu-select 4.16.82 c-lw6gui-menu-select-esc 4.16.83 c-lw6gui-menu-set-breadcrumbs 4.16.84 c-lw6gui-menu-sync 4.16.85 c-lw6gui-mouse-get-state 4.16.86 c-lw6gui-mouse-poll-move 4.16.87 c-lw6gui-mouse-pop-button-left 4.16.88 c-lw6gui-mouse-pop-button-middle 4.16.89 c-lw6gui-mouse-pop-button-right 4.16.90 c-lw6gui-mouse-pop-double-click 4.16.91 c-lw6gui-mouse-pop-simple-click 4.16.92 c-lw6gui-mouse-pop-triple-click 4.16.93 c-lw6gui-mouse-pop-wheel-down 4.16.94 c-lw6gui-mouse-pop-wheel-up 4.16.95 c-lw6hlp-about 4.16.96 c-lw6hlp-get-default-value 4.16.97 c-lw6hlp-list 4.16.98 c-lw6hlp-list-advanced 4.16.99 c-lw6hlp-list-aliases 4.16.100 c-lw6hlp-list-doc 4.16.101 c-lw6hlp-list-funcs 4.16.102 c-lw6hlp-list-graphics 4.16.103 c-lw6hlp-list-hooks 4.16.104 c-lw6hlp-list-input 4.16.105 c-lw6hlp-list-map 4.16.106 c-lw6hlp-list-map-hints 4.16.107 c-lw6hlp-list-map-rules 4.16.108 c-lw6hlp-list-map-style 4.16.109 c-lw6hlp-list-map-teams 4.16.110 c-lw6hlp-list-network 4.16.111 c-lw6hlp-list-path 4.16.112 c-lw6hlp-list-players 4.16.113 c-lw6hlp-list-quick 4.16.114 c-lw6hlp-list-show 4.16.115 c-lw6hlp-list-sound 4.16.116 c-lw6hlp-list-team-colors 4.16.117 c-lw6hlp-list-weapons 4.16.118 c-lw6ker-add-cursor 4.16.119 c-lw6ker-build-game-state 4.16.120 c-lw6ker-build-game-struct 4.16.121 c-lw6ker-cursor-exists 4.16.122 c-lw6ker-did-cursor-win 4.16.123 c-lw6ker-do-round 4.16.124 c-lw6ker-dup-game-state 4.16.125 c-lw6ker-game-state-checksum 4.16.126 c-lw6ker-game-struct-checksum 4.16.127 c-lw6ker-get-cursor 4.16.128 c-lw6ker-get-moves 4.16.129 c-lw6ker-get-rounds 4.16.130 c-lw6ker-get-spreads 4.16.131 c-lw6ker-is-over 4.16.132 c-lw6ker-node-exists 4.16.133 c-lw6ker-register-node 4.16.134 c-lw6ker-remove-cursor 4.16.135 c-lw6ker-set-cursor 4.16.136 c-lw6ker-sync-game-state 4.16.137 c-lw6ker-unregister-node 4.16.138 c-lw6ldr-chain-entry 4.16.139 c-lw6ldr-exp-validate 4.16.140 c-lw6ldr-get-entries 4.16.141 c-lw6ldr-hints-get-default 4.16.142 c-lw6ldr-print-examples 4.16.143 c-lw6ldr-read 4.16.144 c-lw6ldr-read-relative 4.16.145 c-lw6map-exp-get-unlocked-team-color 4.16.146 c-lw6map-exp-get-unlocked-weapon 4.16.147 c-lw6map-exp-is-team-color-allowed 4.16.148 c-lw6map-exp-is-weapon-allowed 4.16.149 c-lw6map-get-look 4.16.150 c-lw6map-get-music-dir 4.16.151 c-lw6map-param-get 4.16.152 c-lw6map-rules-get-default 4.16.153 c-lw6map-rules-get-int 4.16.154 c-lw6map-rules-get-max 4.16.155 c-lw6map-rules-get-min 4.16.156 c-lw6map-style-get-default 4.16.157 c-lw6map-team-color-index-to-key 4.16.158 c-lw6map-team-color-index-to-label 4.16.159 c-lw6map-team-color-key-to-index 4.16.160 c-lw6map-team-color-list 4.16.161 c-lw6map-teams-get-default 4.16.162 c-lw6map-weapon-index-to-key 4.16.163 c-lw6map-weapon-index-to-label 4.16.164 c-lw6map-weapon-key-to-index 4.16.165 c-lw6map-weapon-list 4.16.166 c-lw6net-init 4.16.167 c-lw6net-quit 4.16.168 c-lw6p2p-db-default-name 4.16.169 c-lw6p2p-db-new 4.16.170 c-lw6p2p-db-reset 4.16.171 c-lw6p2p-node-close 4.16.172 c-lw6p2p-node-get-entries 4.16.173 c-lw6p2p-node-get-id 4.16.174 c-lw6p2p-node-new 4.16.175 c-lw6p2p-node-poll 4.16.176 c-lw6pil-bench 4.16.177 c-lw6pil-build-pilot 4.16.178 c-lw6pil-calibrate 4.16.179 c-lw6pil-commit 4.16.180 c-lw6pil-did-cursor-win 4.16.181 c-lw6pil-execute-command 4.16.182 c-lw6pil-fix-coords 4.16.183 c-lw6pil-fix-coords-x10 4.16.184 c-lw6pil-get-last-commit-seq 4.16.185 c-lw6pil-get-looser 4.16.186 c-lw6pil-get-max-seq 4.16.187 c-lw6pil-get-next-seq 4.16.188 c-lw6pil-get-reference-current-seq 4.16.189 c-lw6pil-get-reference-target-seq 4.16.190 c-lw6pil-get-winner 4.16.191 c-lw6pil-is-over 4.16.192 c-lw6pil-local-command 4.16.193 c-lw6pil-local-cursors-set-main 4.16.194 c-lw6pil-local-cursors-set-mouse-controlled 4.16.195 c-lw6pil-make-backup 4.16.196 c-lw6pil-send-command 4.16.197 c-lw6pil-seq-random-0 4.16.198 c-lw6pil-slow-down 4.16.199 c-lw6pil-speed-up 4.16.200 c-lw6pil-sync-from-backup 4.16.201 c-lw6pil-sync-from-draft 4.16.202 c-lw6pil-sync-from-reference 4.16.203 c-lw6snd-get-backends 4.16.204 c-lw6snd-is-music-file 4.16.205 c-lw6snd-new 4.16.206 c-lw6snd-play-fx 4.16.207 c-lw6snd-play-music-file 4.16.208 c-lw6snd-play-music-random 4.16.209 c-lw6snd-poll 4.16.210 c-lw6snd-release 4.16.211 c-lw6snd-set-fx-volume 4.16.212 c-lw6snd-set-music-volume 4.16.213 c-lw6snd-set-water-volume 4.16.214 c-lw6snd-stop-music 4.16.215 c-lw6srv-get-backends 4.16.216 c-lw6sys-build-get-bin-id 4.16.217 c-lw6sys-build-get-bugs-url 4.16.218 c-lw6sys-build-get-cflags 4.16.219 c-lw6sys-build-get-codename 4.16.220 c-lw6sys-build-get-configure-args 4.16.221 c-lw6sys-build-get-copyright 4.16.222 c-lw6sys-build-get-datadir 4.16.223 c-lw6sys-build-get-date 4.16.224 c-lw6sys-build-get-enable-allinone 4.16.225 c-lw6sys-build-get-enable-console 4.16.226 c-lw6sys-build-get-enable-fullstatic 4.16.227 c-lw6sys-build-get-enable-gcov 4.16.228 c-lw6sys-build-get-enable-gprof 4.16.229 c-lw6sys-build-get-enable-gtk 4.16.230 c-lw6sys-build-get-enable-instrument 4.16.231 c-lw6sys-build-get-enable-mod-csound 4.16.232 c-lw6sys-build-get-enable-mod-gl 4.16.233 c-lw6sys-build-get-enable-mod-http 4.16.234 c-lw6sys-build-get-enable-mod-ogg 4.16.235 c-lw6sys-build-get-enable-openmp 4.16.236 c-lw6sys-build-get-enable-optimize 4.16.237 c-lw6sys-build-get-enable-paranoid 4.16.238 c-lw6sys-build-get-enable-profiler 4.16.239 c-lw6sys-build-get-enable-valgrind 4.16.240 c-lw6sys-build-get-endianness 4.16.241 c-lw6sys-build-get-gcc-version 4.16.242 c-lw6sys-build-get-home-url 4.16.243 c-lw6sys-build-get-host-cpu 4.16.244 c-lw6sys-build-get-host-os 4.16.245 c-lw6sys-build-get-hostname 4.16.246 c-lw6sys-build-get-includedir 4.16.247 c-lw6sys-build-get-ldflags 4.16.248 c-lw6sys-build-get-libdir 4.16.249 c-lw6sys-build-get-license 4.16.250 c-lw6sys-build-get-localedir 4.16.251 c-lw6sys-build-get-md5sum 4.16.252 c-lw6sys-build-get-package-name 4.16.253 c-lw6sys-build-get-package-string 4.16.254 c-lw6sys-build-get-package-tarname 4.16.255 c-lw6sys-build-get-pointer-size 4.16.256 c-lw6sys-build-get-prefix 4.16.257 c-lw6sys-build-get-stamp 4.16.258 c-lw6sys-build-get-time 4.16.259 c-lw6sys-build-get-top-srcdir 4.16.260 c-lw6sys-build-get-version 4.16.261 c-lw6sys-build-is-gnu 4.16.262 c-lw6sys-build-is-gp2x 4.16.263 c-lw6sys-build-is-mac-os-x 4.16.264 c-lw6sys-build-is-ms-windows 4.16.265 c-lw6sys-build-is-unix 4.16.266 c-lw6sys-build-is-x86 4.16.267 c-lw6sys-debug-get 4.16.268 c-lw6sys-debug-set 4.16.269 c-lw6sys-delay 4.16.270 c-lw6sys-dump 4.16.271 c-lw6sys-dump-clear 4.16.272 c-lw6sys-generate-id-16 4.16.273 c-lw6sys-generate-id-32 4.16.274 c-lw6sys-generate-id-64 4.16.275 c-lw6sys-get-config-file 4.16.276 c-lw6sys-get-cwd 4.16.277 c-lw6sys-get-cycle 4.16.278 c-lw6sys-get-data-dir 4.16.279 c-lw6sys-get-default-config-file 4.16.280 c-lw6sys-get-default-data-dir 4.16.281 c-lw6sys-get-default-log-file 4.16.282 c-lw6sys-get-default-map-dir 4.16.283 c-lw6sys-get-default-map-path 4.16.284 c-lw6sys-get-default-mod-dir 4.16.285 c-lw6sys-get-default-music-dir 4.16.286 c-lw6sys-get-default-music-path 4.16.287 c-lw6sys-get-default-prefix 4.16.288 c-lw6sys-get-default-script-file 4.16.289 c-lw6sys-get-default-user-dir 4.16.290 c-lw6sys-get-hostname 4.16.291 c-lw6sys-get-log-file 4.16.292 c-lw6sys-get-map-dir 4.16.293 c-lw6sys-get-map-path 4.16.294 c-lw6sys-get-mod-dir 4.16.295 c-lw6sys-get-music-dir 4.16.296 c-lw6sys-get-music-path 4.16.297 c-lw6sys-get-prefix 4.16.298 c-lw6sys-get-run-dir 4.16.299 c-lw6sys-get-script-file 4.16.300 c-lw6sys-get-timestamp 4.16.301 c-lw6sys-get-uptime 4.16.302 c-lw6sys-get-user-dir 4.16.303 c-lw6sys-get-username 4.16.304 c-lw6sys-getenv 4.16.305 c-lw6sys-getenv-prefixed 4.16.306 c-lw6sys-idle 4.16.307 c-lw6sys-log 4.16.308 c-lw6sys-log-get-level 4.16.309 c-lw6sys-log-set-level 4.16.310 c-lw6sys-megabytes-available 4.16.311 c-lw6sys-openmp-get-num-procs 4.16.312 c-lw6sys-path-concat 4.16.313 c-lw6sys-path-file-only 4.16.314 c-lw6sys-path-parent 4.16.315 c-lw6sys-path-split 4.16.316 c-lw6sys-set-memory-bazooka-eraser 4.16.317 c-lw6sys-set-memory-bazooka-size 4.16.318 c-lw6sys-signal-custom 4.16.319 c-lw6sys-signal-default 4.16.320 c-lw6sys-signal-poll-quit 4.16.321 c-lw6sys-signal-send-quit 4.16.322 c-lw6sys-sleep 4.16.323 c-lw6sys-snooze 4.16.324 c-lw6sys-url-canonize 4.16.325 c-lw6tsk-loader-get-stage 4.16.326 c-lw6tsk-loader-new 4.16.327 c-lw6tsk-loader-pop 4.16.328 c-lw6tsk-loader-push 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 libgfx 5.18.1 Overview 5.18.2 API 5.19 mod-gl 5.19.1 Overview 5.19.2 API 5.20 libglb 5.20.1 Overview 5.20.2 API 5.21 libgui 5.21.1 Overview 5.21.2 API 5.22 libhlp 5.22.1 Overview 5.22.2 API 5.23 libimg 5.23.1 Overview 5.23.2 API 5.24 libker 5.24.1 Overview 5.24.2 API 5.25 libldr 5.25.1 Overview 5.25.2 API 5.26 libmap 5.26.1 Overview 5.26.2 API 5.27 libmsg 5.27.1 Overview 5.27.2 API 5.28 libnet 5.28.1 Overview 5.28.2 API 5.29 libnod 5.29.1 Overview 5.29.2 API 5.30 libp2p 5.30.1 Overview 5.30.2 API 5.31 libpil 5.31.1 Overview 5.31.2 API 5.32 libscm 5.32.1 Overview 5.32.2 API 5.33 libsim 5.33.1 Overview 5.33.2 API 5.34 libsnd 5.34.1 Overview 5.34.2 API 5.35 mod-csound 5.35.1 Overview 5.35.2 API 5.36 mod-ogg 5.36.1 Overview 5.36.2 API 5.37 libsrv 5.37.1 Overview 5.37.2 API 5.38 mod-httpd 5.38.1 Overview 5.38.2 API 5.39 mod-tcpd 5.39.1 Overview 5.39.2 API 5.40 mod-udpd 5.40.1 Overview 5.40.2 API 5.41 libsys 5.41.1 Overview 5.41.2 API 5.42 libtsk 5.42.1 Overview 5.42.2 API 5.43 libvox 5.43.1 Overview 5.43.2 API Appendix A 2005 .plan A.1 Complete rewrite A.2 Technologies A.2.1 Script + standard C + assembly A.2.2 OpenGL A.2.3 CSound A.3 Functionnalities A.3.1 Visual enhancements A.3.2 Rules enhancements A.3.3 Hey, you forgot my idea!!! A.4 Road map Appendix B Fanfic B.1 The Battle of Emberlificoted Appendix C Links C.1 Official links C.2 Other sites C.3 Old stuff Appendix D GNU GENERAL PUBLIC LICENSE Appendix E GNU Free Documentation License Appendix F Indexes F.1 Concept index F.2 Function and keyword 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 `http://www.gnu.org/software/liquidwar6/'. 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.gnu.org/software/liquidwar6/global/), code coverage (http://www.gnu.org/software/liquidwar6/coverage/) and cyclomatic complexity (http://www.gnu.org/software/liquidwar6/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?) 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: `http://savannah.gnu.org/bugs/?group=liquidwar6' * task list: `http://savannah.gnu.org/task/?group=liquidwar6' 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. * 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 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 `http://savannah.gnu.org/task/?group=liquidwar6' 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: `http://savannah.gnu.org/bugs/?func=additem&group=liquidwar6' 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.2 Getting the game ==================== 2.2.1 Download source --------------------- Liquid War 6 can be found on `http://download.savannah.gnu.org/releases/liquidwar6/' and `http://www.ufoot.org/download/liquidwar/v6/'. 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 `http://git.savannah.gnu.org/gitweb/?p=liquidwar6.git' and `http://git.savannah.gnu.org/cgit/liquidwar6.git'. 2.2.4 Daily snapshots --------------------- Alternatively, you can download daily snapshots on `http://www.ufoot.org/liquidwar/v6/snapshots/' These files should be built every day, but a `make distcheck' is done before creating them. So if the source code is, for some reason, broken, then they won't be generated. It is a good source if you want the most up-to-date code which is not completely unstable. This is typically the place to go if you want to know a reported bug is correctly fixed. Please do not rely on snapshots generated on the fly by the source content manager, daily snapshots mentionned above are better since a `make dist' has been run on them. Using a checkout is really for developpers. 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. * 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. * 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 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 \ libcurl libcurl-devel \ perl lcov global valgrind graphviz gv texinfo-tex \ gtk2-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 gcc libc6 libc6-dev binutils \ libgomp1 \ guile-1.8 guile-1.8-dev guile-1.8-libs libgmp3c2 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 \ 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 \ libcurl4-gnutls-dev \ perl lcov global valgrind graphviz gv \ texinfo texlive-base texlive-generic-extra \ libgtk2.0-dev debhelper Note that those requirements really depend on the exact distribution you have, package names may vary from one to another. 2.3.4 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-gl', 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 pointer stick previous menu move cursor up item `down' mouse pointer stick next menu item move cursor down `left' mouse pointer stick change menu move cursor item value left `right' mouse pointer stick change menu move cursor item value right `enter' left-click button A validate menu validate 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 fire or triple-click on any button `pgup' wheel up button E previous menu zoom in item `pgdown' wheel down button F next menu item zoom out 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 `http://localhost:8056/' 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: `http://savannah.gnu.org/bugs/?func=additem&group=liquidwar6'. 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. There's still a third 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-gl' 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. 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. digraph g { node [label="\N"]; subgraph cluster_bot { graph [label="bot backends"]; "mod-brute" [shape=hexagon]; "mod-follow" [shape=hexagon]; "mod-idiot" [shape=hexagon]; "mod-random" [shape=hexagon]; bot -> "mod-brute" [dir=both]; bot -> "mod-follow" [dir=both]; bot -> "mod-idiot" [dir=both]; bot -> "mod-random" [dir=both]; } subgraph cluster_cli { graph [label="cli backends"]; "mod-tcp" [shape=hexagon]; "mod-udp" [shape=hexagon]; "mod-http" [shape=hexagon]; cli -> "mod-tcp" [dir=both]; cli -> "mod-udp" [dir=both]; cli -> "mod-http" [dir=both]; } subgraph cluster_gfx { graph [label="gfx backends"]; "mod-gl" [style=filled, fillcolor=lightgrey, shape=hexagon]; gfx -> "mod-gl" [dir=both]; } subgraph cluster_snd { graph [label="snd backends"]; "mod-ogg" [shape=hexagon]; "mod-csound" [shape=hexagon]; snd -> "mod-ogg" [dir=both]; snd -> "mod-csound" [dir=both]; } subgraph cluster_srv { graph [label="srv backends"]; "mod-tcpd" [shape=hexagon]; "mod-udpd" [shape=hexagon]; "mod-httpd" [shape=hexagon]; srv -> "mod-tcpd" [dir=both]; srv -> "mod-udpd" [dir=both]; srv -> "mod-httpd" [dir=both]; } subgraph cluster_script { graph [label="Guile scripts"]; script [style=filled, fillcolor=lightgrey, shape=triangle]; scm -> script; } subgraph cluster_ext { graph [label="external libraries", color=grey, fontcolor=grey]; expat [color=grey, fontcolor=grey]; curl [color=grey, fontcolor=grey]; readline [color=grey, fontcolor=grey]; ltdl [color=grey, fontcolor=grey]; SDL [color=grey, fontcolor=grey]; GL [color=grey, fontcolor=grey]; SDL_image [color=grey, fontcolor=grey]; SDL_ttf [color=grey, fontcolor=grey]; gnulib [color=grey, fontcolor=grey]; jpeg [color=grey, fontcolor=grey]; gomp [color=grey, fontcolor=grey]; png [color=grey, fontcolor=grey]; zlib [color=grey, fontcolor=grey]; sqlite [color=grey, fontcolor=grey]; guile [color=grey, fontcolor=grey]; SDL_mixer [color=grey, fontcolor=grey]; csound [color=grey, fontcolor=grey]; pthread [color=grey, fontcolor=grey]; math [color=grey, fontcolor=grey]; SDL_image -> jpeg; SDL_image -> png; } sys [style=filled, fillcolor=lightgrey]; ker [style=filled, fillcolor=lightgrey]; p2p [style=filled, fillcolor=lightgrey]; liquidwar6 [style=filled, fillcolor=lightgrey]; data [style=filled, fillcolor=lightgrey, shape=triangle]; bot -> dyn; bot -> pil; cfg -> hlp; cfg -> expat; cli -> dyn; cli -> msg; cli -> net; "mod-http" -> curl; cns -> sys; cnx -> glb; cns -> readline; dat -> msg; dsp -> gfx; dyn -> sys; dyn -> ltdl; gfx -> dyn; gfx -> vox; gfx -> pil; "mod-gl" -> SDL; "mod-gl" -> GL; "mod-gl" -> SDL_image; "mod-gl" -> SDL_ttf; glb -> sys; glb -> gnulib; gui -> map; gui -> cfg; hlp -> sys; img -> cfg; img -> jpeg; ker -> map; ker -> gomp; ldr -> cfg; ldr -> map; ldr -> png; ldr -> jpeg; map -> sys; msg -> cnx; msg -> nod; msg -> zlib; net -> cfg; net -> glb; nod -> sys; p2p -> dat; p2p -> cli; p2p -> srv; p2p -> sqlite; pil -> ker; scm -> hlp; scm -> guile; sim -> bot; snd -> dyn; snd -> cfg; "mod-ogg" -> SDL; "mod-ogg" -> SDL_mixer; "mod-csound" -> csound; srv -> dyn; srv -> msg; srv -> net; sys -> def; sys -> pthread; sys -> math; tsk -> ldr; vox -> gui; vox -> ker; liquidwar6 -> sim; liquidwar6 -> dsp; liquidwar6 -> img; liquidwar6 -> tsk; liquidwar6 -> cns; liquidwar6 -> p2p; liquidwar6 -> snd; liquidwar6 -> scm; script -> liquidwar6; expat -> data; jpeg -> data; png -> data; SDL_ttf -> data; SDL_mixer -> data; } 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 About mod-gl ================ 3.6.1 The main renderer ----------------------- 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-gl', 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-gl' is just linked statically in those versions, and the modularity of the game is purely theorical on these platforms. This `mod-gl' 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-gl'. 3.6.2 Hardware requirements --------------------------- The `mod-gl' 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-gl' splits them into smaller tiles, and displays those tiles one by one. 3.6.3 The gl-utils toolbox -------------------------- Inside the `mod-gl' backend, the `src/lib/gfx/mod-gl/gl-utils' directory contains lots of common structures, factorized functions which can (and should, if appliable) be used. 3.7 Compilation tips ==================== 3.7.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: * `--enable-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. * `--enable-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 no to link against GTK 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.gnu.org/software/liquidwar6/coverage/). and GNU global (http://www.gnu.org/software/liquidwar6/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.7.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.7.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.7.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.7.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.7.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.8 Coding guidelines ===================== 3.8.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.8.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.8.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.8.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.8.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.8.6 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: * 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 `http://www.gnu.org/software/liquidwar6/coverage/'. * 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 `http://www.gnu.org/software/liquidwar6/global/'. * 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 `http://www.gnu.org/software/liquidwar6/cyclo/'. * 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 ohloh (http://www.ohloh.net/). Visit `http://www.ohloh.net/p/liquidwar6' 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.9 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.10 Advanced tweaking ====================== 3.10.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.10.2 Optimize for speed ------------------------- Todo... 3.11 Writing modules ==================== Todo... 3.12 Use as a library ===================== Todo... 3.13 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.13.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.13.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. 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' 3.13.3 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.14 Technical HOWTOs ===================== 3.14.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'. * 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 `http://savannah.gnu.org/maintenance/DownloadArea'), with a command like `rsync --rsh=ssh --recursive ./version/ login@dl.sv.nongnu.org:/releases/liquidwar6/version/'. 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. * run `./configure --enable-gcov ; make clean ; make'. Then run `src/liquidwar6 --test', stay here and get ready to respond interactively to various questions. Then cd to `./doc/coverage' and run `make opt'. Copy files to web CVS, sync them. * cd to `./doc/global' and run `make opt'. Copy files to web CVS, sync them. * cd to `./doc/cyclo' and run `make opt'. Copy files to web CVS, sync them. * post news on `https://savannah.gnu.org/news/?group=liquidwar6', `http://lists.gnu.org/mailman/listinfo/help-liquidwar6' and `http://lists.gnu.org/mailman/listinfo/info-liquidwar6'. 3.14.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_