Game version in the menu: VERSION holds vYYYYMM-NNNNN, shown on the title screen and in the pause menu, tools/bump_version.py raises it with every change
This commit is contained in:
1 parent
1ec7492189
commit
dd4bb75b24
9 files changed
+86
-1
No files matched your search
@@ -1,2 +1,5 @@
|
|||||||
target/
|
target/
|
||||||
Cargo.lock.bak
|
Cargo.lock.bak
|
||||||
|
# WASM build outputs copied into www/ for the standalone file (the Docker image builds its own)
|
||||||
|
www/dungeoncraft.wasm
|
||||||
|
www/mq_js_bundle.js
|
||||||
@@ -4,6 +4,7 @@ RUN rustup target add wasm32-unknown-unknown
|
|||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY Cargo.toml Cargo.lock ./
|
COPY Cargo.toml Cargo.lock ./
|
||||||
COPY .cargo .cargo
|
COPY .cargo .cargo
|
||||||
|
COPY VERSION ./
|
||||||
# build dependencies first (Docker layer cache)
|
# build dependencies first (Docker layer cache)
|
||||||
RUN mkdir src && echo "fn main() {}" > src/main.rs \
|
RUN mkdir src && echo "fn main() {}" > src/main.rs \
|
||||||
&& cargo build --release --target wasm32-unknown-unknown \
|
&& cargo build --release --target wasm32-unknown-unknown \
|
||||||
|
|||||||
+11
@@ -116,6 +116,16 @@ A forgotten password is set again on the server with `docker compose stop saves
|
|||||||
|
|
||||||
All requests except health and login need `Authorization: Bearer <token>`. Limits: 1 MB per savegame, 500 MB in total, 30 write requests and 20 login attempts per minute. Settings: `SAVE_DIR` (default `/data`), `LISTEN` (default `0.0.0.0:8080`).
|
All requests except health and login need `Authorization: Bearer <token>`. Limits: 1 MB per savegame, 500 MB in total, 30 write requests and 20 login attempts per minute. Settings: `SAVE_DIR` (default `/data`), `LISTEN` (default `0.0.0.0:8080`).
|
||||||
|
|
||||||
|
## Version
|
||||||
|
|
||||||
|
`VERSION` holds the game version as `vYYYYMM-NNNNN`: year and month of the change, then the number of
|
||||||
|
changes in that month (`v202611-00001`). The title screen and the pause menu show it, `src/menu.rs`
|
||||||
|
reads the file with `include_str!`, and a test checks the scheme.
|
||||||
|
|
||||||
|
**With every change to the game** run `python3 tools/bump_version.py` before committing: it raises the
|
||||||
|
number by one (a new month starts again at `00001`) and prints the old and the new version. Do not edit
|
||||||
|
`VERSION` by hand.
|
||||||
|
|
||||||
## Adding a language
|
## Adding a language
|
||||||
|
|
||||||
1. Copy `lang/en.lang` to `lang/<code>.lang` and translate the texts (placeholders `{0}`, `{1}` stay as they are).
|
1. Copy `lang/en.lang` to `lang/<code>.lang` and translate the texts (placeholders `{0}`, `{1}` stay as they are).
|
||||||
@@ -129,3 +139,4 @@ All requests except health and login need `Authorization: Bearer <token>`. Limit
|
|||||||
| `play/DungeonCraft.html` | build the WASM file, then `python3 tools/make_standalone.py <www dir with dungeoncraft.wasm and mq_js_bundle.js> play/DungeonCraft.html` (the Docker image builds the same file under `/standalone/`) |
|
| `play/DungeonCraft.html` | build the WASM file, then `python3 tools/make_standalone.py <www dir with dungeoncraft.wasm and mq_js_bundle.js> play/DungeonCraft.html` (the Docker image builds the same file under `/standalone/`) |
|
||||||
| `docs/img/units`, `docs/img/icons` | `cargo test --release export_doc_images -- --ignored` |
|
| `docs/img/units`, `docs/img/icons` | `cargo test --release export_doc_images -- --ignored` |
|
||||||
| `BESTIARY.md` | `python3 tools/make_bestiary.py` |
|
| `BESTIARY.md` | `python3 tools/make_bestiary.py` |
|
||||||
|
| `VERSION` | `python3 tools/bump_version.py` - with every change to the game |
|
||||||
@@ -201,6 +201,7 @@ langsel.hint = Klicke eine Sprache an. Du kannst sie später in den Einstellunge
|
|||||||
|
|
||||||
# ---- Menüs
|
# ---- Menüs
|
||||||
menu.subtitle = Graben. Bauen. Verteidigen. Erobern.
|
menu.subtitle = Graben. Bauen. Verteidigen. Erobern.
|
||||||
|
menu.version = Version
|
||||||
menu.continue = Fortsetzen
|
menu.continue = Fortsetzen
|
||||||
menu.new = Neues Spiel
|
menu.new = Neues Spiel
|
||||||
menu.load = Spiel laden
|
menu.load = Spiel laden
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ langsel.hint = Click a language. You can change it later in the settings.
|
|||||||
|
|
||||||
# ---- menus
|
# ---- menus
|
||||||
menu.subtitle = Dig. Build. Defend. Conquer.
|
menu.subtitle = Dig. Build. Defend. Conquer.
|
||||||
|
menu.version = Version
|
||||||
menu.continue = Continue
|
menu.continue = Continue
|
||||||
menu.new = New Game
|
menu.new = New Game
|
||||||
menu.load = Load Game
|
menu.load = Load Game
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<script>var register_plugin; /* expected by the quad_net plugin in the bundle */</script>
|
<script>var register_plugin; /* expected by the quad_net plugin in the bundle */</script>
|
||||||
<script>
|
<script>
|
||||||
// the game module is embedded: fetching it is answered from these bytes
|
// the game module is embedded: fetching it is answered from these bytes
|
||||||
var DC_WASM = "AGFzbQEAAAAB2wZnYAF/AGAAAGADf39/AX9gA39/fwBgBn9/f39/fwBgBX9/f39/AGAEf39/fwBgAn9/AGAHf39/f39/fwF/YAJ/fwF/YAF/AX9gBH9/f38Bf2AFf39/f38Bf2ADf319AGAFf319fX0AYAd/fX19fX19AGAGf39/fX9/AGAGf39/f39/AX9gAAF8YAABf2AAAX1gCH9/f39/f39/AGAJf39/f39/f39/AGAHf39/f39/fwBgBH19fX0AYAF9AGAKf39/f39/f39/fwBgBH5+f38BfmADfn5/AX5gAX4Bf2AEf39/fQF/YAJ+fwF/YAJ/fQBgAn1/AX9gBn99fXx/fwBgB39/f39/f3wAYAV/f39/fABgC39/f39/f399fX98AGAGf39/f319AGAEf399fQBgBX9/fX1/AGAHf39/fX1/fABgB39/f39/fX0AYAN/f30AYAV/f398fwBgDX9/fX19f39/f39/f38AYAV9fX19fwBgBn19fX19fwBgBX99fX9/AGAHf39/fX19fwBgBn9/f398fwBgCH9/f39/f398AGAJf319f399f39/AGAMf319f399f39/f39/AGABfwF9YAl/f39/fX19f30AYAZ/f399fX8Bf2AFf39/fX0AYAJ9fQF/YAJ/fgBgB399fX99f30AYAN/f30BfWAHf399fX1/fwBgAn19AX1gCH9/f399fX19AGAJf399fX1/f39/AGACf3wAYAV/fX9/fwBgCH9/fX19fX1/AGAEfX1/fQBgBH9/fX8AYAN/fX8AYAR/fX9/AGAKf39/f39/f399fQBgBn9/fX19fQF/YAN/f30Bf2ACf38BfWAIf399f39/f38AYAV/f319fwF/YAR/f399AGAEf39/fgBgBX9/f35/AGAHf319fX1/fwBgBH9/fX0BfWATf39/f39/f39/f39/f39/f39/fwF/YAF/AX5gBn9+f39/fwBgCX9/f39/f35+fgBgBH99f38Bf2ADf31/AX9gA39+fgBgC39/f39/f39/f39/AX9gAAF+YAJ/fgF/YAN+fn4BfmAIf39/f39/f38Bf2AFf39+fX0AYAN/fn8AYAt/f39/f39/f39/fwBgAnx/AX9gAX0BfWAFf35+fn4AYAJ9fwF9AtcUegNlbnYLY29uc29sZV9sb2cAAANlbnYHZGNfaHR0cAARA2VudgxkY19zZXRfdG9rZW4ABwNlbnYDbm93ABIDZW52EWRjX2NvYXJzZV9wb2ludGVyABMDZW52DGRjX2ZpbGVfcG9sbAATA2VudgxkY19maWxlX3Rha2UAAANlbnYMZGNfaHR0cF9wb2xsAAoDZW52C2RjX2h0dHBfbGVuAAoDZW52DGRjX2h0dHBfdGFrZQAHA2Vudg5kY19zdG9yYWdlX3NldAAGA2VudhdkY19mZXRjaF9kb3dubG9hZF9zdGF0ZQATA2VudgtkY19kb3dubG9hZAAGA2VudgxkY19vcGVuX2ZpbGUAAQNlbnYLZGNfb3Blbl91cmwABwNlbnYMZGNfY2FjaGVfc2V0AAYDZW52EWRjX2ZldGNoX2Rvd25sb2FkAAYDZW52CmluaXRfd2ViZ2wAAANlbnYRc2V0dXBfY2FudmFzX3NpemUAAANlbnYMY2FudmFzX3dpZHRoABMDZW52DWNhbnZhc19oZWlnaHQAEwNlbnYJZHBpX3NjYWxlABQDZW52EnJ1bl9hbmltYXRpb25fbG9vcAAAA2Vudg5kY19zdG9yYWdlX2dldAAJA2Vudg9kY19zdG9yYWdlX3Rha2UAAANlbnYJZGNfcHJvbXB0AAsDZW52DWdsQmluZFRleHR1cmUABwNlbnYQZ2xDb3B5VGV4SW1hZ2UyRAAVA2Vudg1nbEdldEludGVnZXJ2AAcDZW52EWdsR2VuVmVydGV4QXJyYXlzAAcDZW52EWdsQmluZFZlcnRleEFycmF5AAADZW52C2dsR2V0U3RyaW5nAAoDZW52FHNhcHBfc2NoZWR1bGVfdXBkYXRlAAEDZW52DGdsR2VuUXVlcmllcwAHA2VudgxnbEJlZ2luUXVlcnkABwNlbnYKZ2xFbmRRdWVyeQAAA2VudgdnbEZsdXNoAAEDZW52CGdsRmluaXNoAAEDZW52DGNvbnNvbGVfd2FybgAAA2Vudg9nbENyZWF0ZVByb2dyYW0AEwNlbnYOZ2xBdHRhY2hTaGFkZXIABwNlbnYNZ2xMaW5rUHJvZ3JhbQAAA2Vudg5nbERldGFjaFNoYWRlcgAHA2Vudg5nbERlbGV0ZVNoYWRlcgAAA2Vudg5nbEdldFByb2dyYW1pdgADA2VudhNnbEdldFByb2dyYW1JbmZvTG9nAAYDZW52DGdsVXNlUHJvZ3JhbQAAA2VudhRnbEdldFVuaWZvcm1Mb2NhdGlvbgAJA2Vudg1nbEdlblRleHR1cmVzAAcDZW52D2dsQWN0aXZlVGV4dHVyZQAAA2Vudg1nbFBpeGVsU3RvcmVpAAcDZW52EmdsR2VuUmVuZGVyYnVmZmVycwAHA2VudhJnbEJpbmRSZW5kZXJidWZmZXIABwNlbnYgZ2xSZW5kZXJidWZmZXJTdG9yYWdlTXVsdGlzYW1wbGUABQNlbnYMZ2xUZXhJbWFnZTJEABYDZW52D2dsVGV4UGFyYW1ldGVyaQADA2VudhBnbEdlbmVyYXRlTWlwbWFwAAADZW52EWdsR2VuRnJhbWVidWZmZXJzAAcDZW52EWdsQmluZEZyYW1lYnVmZmVyAAcDZW52FmdsRnJhbWVidWZmZXJUZXh0dXJlMkQABQNlbnYMZ2xSZWFkUGl4ZWxzABcDZW52FGdsRGVsZXRlRnJhbWVidWZmZXJzAAcDZW52D2dsVGV4U3ViSW1hZ2UyRAAWA2VudhlnbEZyYW1lYnVmZmVyUmVuZGVyYnVmZmVyAAYDZW52DWdsRHJhd0J1ZmZlcnMABwNlbnYYZ2xDaGVja0ZyYW1lYnVmZmVyU3RhdHVzAAoDZW52FWdsRGVsZXRlUmVuZGVyYnVmZmVycwAHA2VudhBnbERlbGV0ZVRleHR1cmVzAAcDZW52E2dsR2V0QXR0cmliTG9jYXRpb24ACQNlbnYIZ2xFbmFibGUAAANlbnYJZ2xEaXNhYmxlAAADZW52C2dsRGVwdGhGdW5jAAADZW52C2dsRnJvbnRGYWNlAAADZW52CmdsQ3VsbEZhY2UAAANlbnYTZ2xCbGVuZEZ1bmNTZXBhcmF0ZQAGA2VudhdnbEJsZW5kRXF1YXRpb25TZXBhcmF0ZQAHA2VudgtnbEJsZW5kRnVuYwAHA2VudhNnbFN0ZW5jaWxPcFNlcGFyYXRlAAYDZW52FWdsU3RlbmNpbEZ1bmNTZXBhcmF0ZQAGA2VudhVnbFN0ZW5jaWxNYXNrU2VwYXJhdGUABwNlbnYLZ2xDb2xvck1hc2sABgNlbnYMZ2xHZW5CdWZmZXJzAAcDZW52DGdsQmluZEJ1ZmZlcgAHA2VudgxnbEJ1ZmZlckRhdGEABgNlbnYPZ2xCdWZmZXJTdWJEYXRhAAYDZW52D2dsRGVsZXRlQnVmZmVycwAHA2VudhpnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheQAAA2Vudg9nbERlbGV0ZVByb2dyYW0AAANlbnYKZ2xWaWV3cG9ydAAGA2VudglnbFNjaXNzb3IABgNlbnYLZ2xVbmlmb3JtMWkABwNlbnYWZ2xWZXJ0ZXhBdHRyaWJJUG9pbnRlcgAFA2VudhVnbFZlcnRleEF0dHJpYlBvaW50ZXIABANlbnYVZ2xWZXJ0ZXhBdHRyaWJEaXZpc29yAAcDZW52GWdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkAAANlbnYMZ2xVbmlmb3JtMWZ2AAMDZW52DGdsVW5pZm9ybTJmdgADA2VudgxnbFVuaWZvcm0zZnYAAwNlbnYMZ2xVbmlmb3JtNGZ2AAMDZW52DGdsVW5pZm9ybTFpdgADA2VudgxnbFVuaWZvcm0yaXYAAwNlbnYMZ2xVbmlmb3JtM2l2AAMDZW52DGdsVW5pZm9ybTRpdgADA2VudhJnbFVuaWZvcm1NYXRyaXg0ZnYABgNlbnYMZ2xDbGVhckNvbG9yABgDZW52DWdsQ2xlYXJEZXB0aGYAGQNlbnYOZ2xDbGVhclN0ZW5jaWwAAANlbnYHZ2xDbGVhcgAAA2VudgxnbFJlYWRCdWZmZXIAAANlbnYRZ2xCbGl0RnJhbWVidWZmZXIAGgNlbnYXZ2xEcmF3RWxlbWVudHNJbnN0YW5jZWQABQNlbnYOZ2xDcmVhdGVTaGFkZXIACgNlbnYOZ2xTaGFkZXJTb3VyY2UABgNlbnYPZ2xDb21waWxlU2hhZGVyAAADZW52DWdsR2V0U2hhZGVyaXYAAwNlbnYSZ2xHZXRTaGFkZXJJbmZvTG9nAAYDZW52EnNhcHBfc2V0X2NsaXBib2FyZAAHA2VudhJmc19nZXRfYnVmZmVyX3NpemUACgNlbnYOZnNfdGFrZV9idWZmZXIAAwNlbnYUc2FwcF9zZXRfY3Vyc29yX2dyYWIAAANlbnYPc2FwcF9zZXRfY3Vyc29yAAcDZW52E3NhcHBfc2V0X2Z1bGxzY3JlZW4AAAOqCqgKAwMJBgIAAwkDAQkDBwkDAAIDFwoABwAHABYXFhUVAhYFFQYWBQkHAxsJHAkcCQEAAQABAQEGBQAAAAAAAAAAAAAAAAADAAAAAAAHAAAAAAAAAAAAAAAAAAUDBwcCAwIHBwIHBwcJCQAJAwIAAwkdBwcAAwQHBQcFBwUHBQMEAwQDBAwLCQsLCwwMAwMDAwEDAwYGBgMHBwcDAxcEBAQEFxcXBgQDBwcHBwkJCwIMDAIHCwseCwsfCwsMByAJDAICCQICAgIMAgIJAgcCAwMKCgkMLine truncated
|
var DC_WASM = "AGFzbQEAAAAB0wZmYAF/AGAAAGADf39/AX9gA39/fwBgBn9/f39/fwBgBX9/f39/AGAEf39/fwBgAn9/AGAHf39/f39/fwF/YAJ/fwF/YAF/AX9gBH9/f38Bf2AFf39/f38Bf2ADf319AGAFf319fX0AYAd/fX19fX19AGAGf39/fX9/AGAGf39/f39/AX9gAAF8YAABf2AAAX1gCH9/f39/f39/AGAJf39/f39/f39/AGAHf39/f39/fwBgBH19fX0AYAF9AGAKf39/f39/f39/fwBgBH5+f38BfmADfn5/AX5gAX4Bf2AEf39/fQF/YAJ+fwF/YAJ/fQBgAn1/AX9gBn99fXx/fwBgB39/f39/f3wAYAV/f39/fABgC39/f39/f399fX98AGAGf39/f319AGAEf399fQBgBX9/fX1/AGAHf39/fX1/fABgB39/f39/fX0AYAN/f30AYAV/f398fwBgDX9/fX19f39/f39/f38AYAV9fX19fwBgBn19fX19fwBgBX99fX9/AGAHf39/fX19fwBgBn9/f398fwBgCH9/f39/f398AGAJf319f399f39/AGAMf319f399f39/f39/AGABfwF9YAJ/fgBgB399fX99f30AYAJ9fQF/YAZ/f399fX8Bf2AJf39/f319fX99AGADf399AX1gB39/fX19f38AYAJ9fQF9YAh/f39/fX19fQBgCX9/fX19f39/fwBgAn98AGAFf31/f38AYAh/f319fX19fwBgBH19f30AYAR/f31/AGADf31/AGAEf31/fwBgCn9/f39/f39/fX0AYAZ/f319fX0Bf2ADf399AX9gAn9/AX1gCH9/fX9/f39/AGAFf399fX8Bf2AEf39/fQBgBH9/f34AYAV/f39+fwBgB399fX19f38AYAR/f319AX1gE39/f39/f39/f39/f39/f39/f38Bf2ABfwF+YAZ/fn9/f38AYAl/f39/f39+fn4AYAR/fX9/AX9gA399fwF/YAN/fn4AYAt/f39/f39/f39/fwF/YAABfmACf34Bf2ADfn5+AX5gCH9/f39/f39/AX9gBX9/fn19AGADf35/AGALf39/f39/f39/f38AYAJ8fwF/YAF9AX1gBX9+fn5+AGACfX8BfQLXFHoDZW52C2NvbnNvbGVfbG9nAAADZW52B2RjX2h0dHAAEQNlbnYMZGNfc2V0X3Rva2VuAAcDZW52A25vdwASA2VudhFkY19jb2Fyc2VfcG9pbnRlcgATA2VudgxkY19maWxlX3BvbGwAEwNlbnYMZGNfZmlsZV90YWtlAAADZW52DGRjX2h0dHBfcG9sbAAKA2VudgtkY19odHRwX2xlbgAKA2VudgxkY19odHRwX3Rha2UABwNlbnYOZGNfc3RvcmFnZV9zZXQABgNlbnYXZGNfZmV0Y2hfZG93bmxvYWRfc3RhdGUAEwNlbnYLZGNfZG93bmxvYWQABgNlbnYMZGNfb3Blbl9maWxlAAEDZW52C2RjX29wZW5fdXJsAAcDZW52DGRjX2NhY2hlX3NldAAGA2VudhFkY19mZXRjaF9kb3dubG9hZAAGA2Vudgppbml0X3dlYmdsAAADZW52EXNldHVwX2NhbnZhc19zaXplAAADZW52DGNhbnZhc193aWR0aAATA2Vudg1jYW52YXNfaGVpZ2h0ABMDZW52CWRwaV9zY2FsZQAUA2VudhJydW5fYW5pbWF0aW9uX2xvb3AAAANlbnYOZGNfc3RvcmFnZV9nZXQACQNlbnYPZGNfc3RvcmFnZV90YWtlAAADZW52CWRjX3Byb21wdAALA2Vudg1nbEJpbmRUZXh0dXJlAAcDZW52EGdsQ29weVRleEltYWdlMkQAFQNlbnYNZ2xHZXRJbnRlZ2VydgAHA2VudhFnbEdlblZlcnRleEFycmF5cwAHA2VudhFnbEJpbmRWZXJ0ZXhBcnJheQAAA2VudgtnbEdldFN0cmluZwAKA2VudhRzYXBwX3NjaGVkdWxlX3VwZGF0ZQABA2VudgxnbEdlblF1ZXJpZXMABwNlbnYMZ2xCZWdpblF1ZXJ5AAcDZW52CmdsRW5kUXVlcnkAAANlbnYHZ2xGbHVzaAABA2VudghnbEZpbmlzaAABA2Vudgxjb25zb2xlX3dhcm4AAANlbnYPZ2xDcmVhdGVQcm9ncmFtABMDZW52DmdsQXR0YWNoU2hhZGVyAAcDZW52DWdsTGlua1Byb2dyYW0AAANlbnYOZ2xEZXRhY2hTaGFkZXIABwNlbnYOZ2xEZWxldGVTaGFkZXIAAANlbnYOZ2xHZXRQcm9ncmFtaXYAAwNlbnYTZ2xHZXRQcm9ncmFtSW5mb0xvZwAGA2VudgxnbFVzZVByb2dyYW0AAANlbnYUZ2xHZXRVbmlmb3JtTG9jYXRpb24ACQNlbnYNZ2xHZW5UZXh0dXJlcwAHA2Vudg9nbEFjdGl2ZVRleHR1cmUAAANlbnYNZ2xQaXhlbFN0b3JlaQAHA2VudhJnbEdlblJlbmRlcmJ1ZmZlcnMABwNlbnYSZ2xCaW5kUmVuZGVyYnVmZmVyAAcDZW52IGdsUmVuZGVyYnVmZmVyU3RvcmFnZU11bHRpc2FtcGxlAAUDZW52DGdsVGV4SW1hZ2UyRAAWA2Vudg9nbFRleFBhcmFtZXRlcmkAAwNlbnYQZ2xHZW5lcmF0ZU1pcG1hcAAAA2VudhFnbEdlbkZyYW1lYnVmZmVycwAHA2VudhFnbEJpbmRGcmFtZWJ1ZmZlcgAHA2VudhZnbEZyYW1lYnVmZmVyVGV4dHVyZTJEAAUDZW52DGdsUmVhZFBpeGVscwAXA2VudhRnbERlbGV0ZUZyYW1lYnVmZmVycwAHA2Vudg9nbFRleFN1YkltYWdlMkQAFgNlbnYZZ2xGcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlcgAGA2Vudg1nbERyYXdCdWZmZXJzAAcDZW52GGdsQ2hlY2tGcmFtZWJ1ZmZlclN0YXR1cwAKA2VudhVnbERlbGV0ZVJlbmRlcmJ1ZmZlcnMABwNlbnYQZ2xEZWxldGVUZXh0dXJlcwAHA2VudhNnbEdldEF0dHJpYkxvY2F0aW9uAAkDZW52CGdsRW5hYmxlAAADZW52CWdsRGlzYWJsZQAAA2VudgtnbERlcHRoRnVuYwAAA2VudgtnbEZyb250RmFjZQAAA2VudgpnbEN1bGxGYWNlAAADZW52E2dsQmxlbmRGdW5jU2VwYXJhdGUABgNlbnYXZ2xCbGVuZEVxdWF0aW9uU2VwYXJhdGUABwNlbnYLZ2xCbGVuZEZ1bmMABwNlbnYTZ2xTdGVuY2lsT3BTZXBhcmF0ZQAGA2VudhVnbFN0ZW5jaWxGdW5jU2VwYXJhdGUABgNlbnYVZ2xTdGVuY2lsTWFza1NlcGFyYXRlAAcDZW52C2dsQ29sb3JNYXNrAAYDZW52DGdsR2VuQnVmZmVycwAHA2VudgxnbEJpbmRCdWZmZXIABwNlbnYMZ2xCdWZmZXJEYXRhAAYDZW52D2dsQnVmZmVyU3ViRGF0YQAGA2Vudg9nbERlbGV0ZUJ1ZmZlcnMABwNlbnYaZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkAAANlbnYPZ2xEZWxldGVQcm9ncmFtAAADZW52CmdsVmlld3BvcnQABgNlbnYJZ2xTY2lzc29yAAYDZW52C2dsVW5pZm9ybTFpAAcDZW52FmdsVmVydGV4QXR0cmliSVBvaW50ZXIABQNlbnYVZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyAAQDZW52FWdsVmVydGV4QXR0cmliRGl2aXNvcgAHA2VudhlnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5AAADZW52DGdsVW5pZm9ybTFmdgADA2VudgxnbFVuaWZvcm0yZnYAAwNlbnYMZ2xVbmlmb3JtM2Z2AAMDZW52DGdsVW5pZm9ybTRmdgADA2VudgxnbFVuaWZvcm0xaXYAAwNlbnYMZ2xVbmlmb3JtMml2AAMDZW52DGdsVW5pZm9ybTNpdgADA2VudgxnbFVuaWZvcm00aXYAAwNlbnYSZ2xVbmlmb3JtTWF0cml4NGZ2AAYDZW52DGdsQ2xlYXJDb2xvcgAYA2Vudg1nbENsZWFyRGVwdGhmABkDZW52DmdsQ2xlYXJTdGVuY2lsAAADZW52B2dsQ2xlYXIAAANlbnYMZ2xSZWFkQnVmZmVyAAADZW52EWdsQmxpdEZyYW1lYnVmZmVyABoDZW52F2dsRHJhd0VsZW1lbnRzSW5zdGFuY2VkAAUDZW52DmdsQ3JlYXRlU2hhZGVyAAoDZW52DmdsU2hhZGVyU291cmNlAAYDZW52D2dsQ29tcGlsZVNoYWRlcgAAA2Vudg1nbEdldFNoYWRlcml2AAMDZW52EmdsR2V0U2hhZGVySW5mb0xvZwAGA2VudhJzYXBwX3NldF9jbGlwYm9hcmQABwNlbnYSZnNfZ2V0X2J1ZmZlcl9zaXplAAoDZW52DmZzX3Rha2VfYnVmZmVyAAMDZW52FHNhcHBfc2V0X2N1cnNvcl9ncmFiAAADZW52D3NhcHBfc2V0X2N1cnNvcgAHA2VudhNzYXBwX3NldF9mdWxsc2NyZWVuAAADrgqsCgMDCQYCAAMJAwEJAwcJAwACAxcKAAcABwAWFxUVFQIWBRUGFQYJBwMbCRwJHAkBAAEAAQEBBgUAAAAAAAAAAAAAAAAAAwAAAAAABwAAAAAAAAAAAAAAAAAFAwcHAgMCBwcCBwcHCQkACQMCAAMJHQcHAAMEBwUHBQcFBwUDBAMEAwQHBgwLCQsLCwsMDAMDAwMBAwMGBgYDBwcHAwMXBAQEBBcXFwYHBAMHBwcHCQkLAgwMAgcLCx4LCx8LCwwHIAkMAgIJAgICAgwCAgkCBwIDAwoKCQwJAwMLLine truncated
|
||||||
(function () {
|
(function () {
|
||||||
var realFetch = window.fetch ? window.fetch.bind(window) : null;
|
var realFetch = window.fetch ? window.fetch.bind(window) : null;
|
||||||
window.fetch = function (url, opts) {
|
window.fetch = function (url, opts) {
|
||||||
|
|||||||
+27
@@ -231,6 +231,14 @@ enum Btn {
|
|||||||
pub const REPO_URL: &str = "https://git.familie-zink.org/zink/dungeoncraft";
|
pub const REPO_URL: &str = "https://git.familie-zink.org/zink/dungeoncraft";
|
||||||
pub const CLAUDE_CODE_URL: &str = "https://claude.com/claude-code";
|
pub const CLAUDE_CODE_URL: &str = "https://claude.com/claude-code";
|
||||||
|
|
||||||
|
// the game version (file VERSION, "vYYYYMM-NNNNN"): tools/bump_version.py raises it with every
|
||||||
|
// change, and the title screen and the pause menu show it
|
||||||
|
const VERSION_FILE: &str = include_str!("../VERSION");
|
||||||
|
|
||||||
|
pub fn version() -> &'static str {
|
||||||
|
VERSION_FILE.trim()
|
||||||
|
}
|
||||||
|
|
||||||
// the Claude Code mark as pixel art (drawn next to the "made with" note)
|
// the Claude Code mark as pixel art (drawn next to the "made with" note)
|
||||||
const CLAUDE_MARK: [&str; 5] = [
|
const CLAUDE_MARK: [&str; 5] = [
|
||||||
"...############...",
|
"...############...",
|
||||||
@@ -683,6 +691,9 @@ impl Menu {
|
|||||||
self.buttons.push((r, Btn::ClaudeCode));
|
self.buttons.push((r, Btn::ClaudeCode));
|
||||||
let lic = tr("menu.license");
|
let lic = tr("menu.license");
|
||||||
gfx.text(&lic, grid_center(sw, gfx.measure(&lic, SMALL())), sh - CH() * 2.5, SMALL(), DIM);
|
gfx.text(&lic, grid_center(sw, gfx.measure(&lic, SMALL())), sh - CH() * 2.5, SMALL(), DIM);
|
||||||
|
let ver = tr("menu.version");
|
||||||
|
let line = format!("{} {}", ver, version());
|
||||||
|
gfx.text(&line, grid_center(sw, gfx.measure(&line, SMALL())), sh - CH() * 5.5, SMALL(), DIM);
|
||||||
let url = REPO_URL.trim_start_matches("https://");
|
let url = REPO_URL.trim_start_matches("https://");
|
||||||
let w = gfx.measure(url, SMALL());
|
let w = gfx.measure(url, SMALL());
|
||||||
let r = Rect::new(grid_center(sw, w), sh - CH() * 1.5, w, GH * SMALL() + 2.0);
|
let r = Rect::new(grid_center(sw, w), sh - CH() * 1.5, w, GH * SMALL() + 2.0);
|
||||||
@@ -760,6 +771,9 @@ impl Menu {
|
|||||||
gfx.window_titled(x, y, cols, rows, S(), true, FRAME_HI, Color::new(0.05, 0.03, 0.04, 0.97), &tr("menu.paused"), FRAME_HI);
|
gfx.window_titled(x, y, cols, rows, S(), true, FRAME_HI, Color::new(0.05, 0.03, 0.04, 0.97), &tr("menu.paused"), FRAME_HI);
|
||||||
let w = (cols - 6) as f32 * CW();
|
let w = (cols - 6) as f32 * CW();
|
||||||
self.column(gfx, x + CW() * 3.0, y + CH() * 2.0, w, &items);
|
self.column(gfx, x + CW() * 3.0, y + CH() * 2.0, w, &items);
|
||||||
|
let ver = tr("menu.version");
|
||||||
|
let line = format!("{} {}", ver, version());
|
||||||
|
gfx.text(&line, x + (cols as f32 * CW() - gfx.measure(&line, SMALL())) * 0.5, y + (rows as f32 - 1.7) * CH(), SMALL(), DIM);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_settings(&mut self, gfx: &Gfx, s: &Settings, tab: usize) {
|
fn draw_settings(&mut self, gfx: &Gfx, s: &Settings, tab: usize) {
|
||||||
@@ -1241,3 +1255,16 @@ pub fn goal_text(g: Goal) -> String {
|
|||||||
Goal::Freed(n) => trf("goal.freed", &[n.to_string()]),
|
Goal::Freed(n) => trf("goal.freed", &[n.to_string()]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn the_version_follows_the_scheme() {
|
||||||
|
let rest = super::version().strip_prefix('v').expect("the version starts with v");
|
||||||
|
let (month, number) = rest.split_once('-').expect("the version is vYYYYMM-NNNNN");
|
||||||
|
assert_eq!(month.len(), 6);
|
||||||
|
assert!(month.chars().all(|c| c.is_ascii_digit()));
|
||||||
|
assert_eq!(number.len(), 5);
|
||||||
|
assert!(number.parse::<u32>().expect("a number") >= 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Raise the game version in VERSION: vYYYYMM-NNNNN.
|
||||||
|
|
||||||
|
Run with every change to the game (the number counts the changes of the current month and
|
||||||
|
starts again at 00001 when the month turns). The version is shown on the title screen and in
|
||||||
|
the pause menu, and it is the version a savegame support question refers to.
|
||||||
|
"""
|
||||||
|
import datetime
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
FILE = pathlib.Path(__file__).resolve().parent.parent / "VERSION"
|
||||||
|
PATTERN = re.compile(r"^v(\d{6})-(\d{1,5})$")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
month = datetime.date.today().strftime("%Y%m")
|
||||||
|
current = FILE.read_text(encoding="utf-8").strip() if FILE.exists() else ""
|
||||||
|
match = PATTERN.match(current)
|
||||||
|
if match and match.group(1) == month:
|
||||||
|
number = int(match.group(2)) + 1
|
||||||
|
elif match: # a new month: count again from the first change
|
||||||
|
number = 1
|
||||||
|
elif current:
|
||||||
|
print(f"VERSION does not look like vYYYYMM-NNNNN: {current!r}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
number = 1
|
||||||
|
version = f"v{month}-{number:05d}"
|
||||||
|
FILE.write_text(version + "\n", encoding="utf-8")
|
||||||
|
if match:
|
||||||
|
print(f"{current} -> {version}")
|
||||||
|
else:
|
||||||
|
print(version)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in new issue
Block a user