Skip to content

Commit

Permalink
Merge pull request #253 from TruncateGame/main
Browse files Browse the repository at this point in the history
Production rules release
  • Loading branch information
bglw authored Apr 13, 2024
2 parents bc76c54 + 3317fb5 commit ce78950
Show file tree
Hide file tree
Showing 87 changed files with 3,148 additions and 2,098 deletions.
17 changes: 0 additions & 17 deletions .backstage/cmds

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy to outpost/coup
name: Deploy to production

on:
push:
Expand Down
101 changes: 101 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Truncate, Technically

Interested in Truncate under the hood? This file will (try to) get you up to speed.

Truncate is majority developed in Rust, so having a recent version of Rust installed is a prerequisite.
Some supporting scripts are written in NodeJS, which should also be installed.

Running Truncate's server requires a local Postgres database to exist on the default port.

## Main directory overview

- `dict_builder`
- The crate that generates Truncate's dictionary from a range of input sources.
- `truncate_client`
- The frontend rendering code for Truncate, implemented in egui.
- `truncate_core`
- The core engine of Truncate's game logic, and implements the rules and helpers for performing actions in a game.
- `truncate_dueller`
- A development crate not loaded in production. It simulates and pregenerates the future daily puzzles to ensure they're winnable and fair.
- `truncate_server`
- The backend that the client uses for things like multiplayer games and account persistence.
- `trunkshipper`
- A stub used to deploy a log aggregation tool for monitoring.
- `web_client`
- The static website providing the initial menu and wasm loading code.
- `word_definitions`
- A node script that generates the SQLite database full of word definitions for lookups. Eventually to be moved into the `dict_builder`

## Getting up and running locally

### Running the server

```bash
cd truncate_server && cargo run
```

Note: This will run by default without any word definitions for lookups. To run with word definitions:
- `gunzip` the `word_definitions/defs.db.gz` file into a `word_definitions/local_defs.db` file.
- Modify the `cargo run` above to `TR_DEFS_FILE=../word_definitions/local_defs.db cargo run`

### Running the web client

Building the WASM web client is done by running `./.backstage/build-web-client.sh` from the root of the repo.

Then, start the 11ty dev server with `cd web_client/src && npm start`.

### Running the native client

Truncate also runs as a native client, though with significantly more rough edges in the menu space.

Make sure your server is running, then execute:
```bash
cd truncate_client && cargo run --release ws://0.0.0.0:8080
```

## Specific details

See the `README.md` file within each directory for more information in that realm.

## Common tasks

### Running tests

From the root of the repo, `cargo insta test --review` will compile and test all crates.
Reminder to have your local Postgres running, as sqlx will require this to compile.

### Generate a new batch of daily puzzles

```bash
cd truncate_dueller && cargo run --release
```

### Generating the tileset

- Using Aseprite, open the `truncate_client/img/truncate.aseprite` file
- After making changes, select `File > Export > Export Tileset`
- Use the following settings:
- **Layout** tab:
- **Sheet Type**: By Rows
- **Constraints**: Fixed # of Columns: 30
- Uncheck **Merge Duplicates** and **Ignore Empty**
- **Sprite** tab:
- **Source**: Tilesets
- **Layers**: Selected layers (do not **Split Layers**)
- **Frames**: All Frames (do not **Split Tags**)
- **Borders** tab:
- **Border Padding**: 0
- **Spacing**: 0
- **Inner Padding**: 0
- **Trim Sprite**: unchecked
- **Trim Cels**: unchecked
- **Extrude**: CHECKED!
- **Output**:
- **Output File**: `truncate_packed.png`
- **JSON Data** unchecked

If you modified the tile order at all:
- Edit `truncate_client/img/tile_order` to match the new ordering of tiles
- If you added something 32x32, and thus taking up four tiles, suffix their tile names with `_NW`, `_NE`, `_SW`, and `_SE`
- From the root of the repo, run `.backstage/build-tile-data.js` to rerun the codegen for using tiles

20 changes: 12 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Truncate
# Truncate: A word-based strategy game

To build and serve a web client:
Spell words to cut off your enemy and conquer their town.

```bash
./.backstage/build-web-client.sh && python3 -m http.server -d web_client/ # or any webserver
```
![Truncate Town Homepage Screenshot](https://github.com/TruncateGame/Truncate/blob/3ae09319d9f255f7fd7e8fa1d491532c4c6f06b8/web_client/src/static/og.png)

Then load `localhost:8000?server=<server_addr>`
## Playing Truncate

Truncate can be played for free in your browser at https://truncate.town

## Working on Truncate

See the CONTRIBUTING.md file for technical information.
24 changes: 24 additions & 0 deletions dict_builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This crate builds the dictionaries, frequency lists and more that power Truncate.

Build dict with `cargo run --release`.

## Requirements

The following files must be created:
Expand All @@ -13,3 +15,25 @@ The following files must be created:
- Generated from the `word_definitions` folder of this repo
- `dict_builder/support_data/generated_scowl_wordlists/*`
- Containing the files from the `final` directory of the latest release of http://wordlist.aspell.net/

## Adding or removing words

Create a `tranche_<num>_<op>.txt` file inside `support_data` with the words to add or remove.

Reference your new file from `load_additions()` or `load_removals()` in `main.rs`

## Wordlist format

The current Truncate dictionary can be seen inside `final_wordlist.txt`. Excerpt:

```
a 10656 1.0000
aah 10656 0.9993
aalii 10656 0.0000
```

Leftmost is the valid word, lowercase.
In the middle is a heuristic score of how extensible this word is, used by the NPC for evaluating gameplay.
Rightmost is a word frequency from 0 → 1, used to filter what words the NPC "knows" when playing.

This file is compiled into the client, hence the lack of definitions, which must be sourced from the server database.
6 changes: 3 additions & 3 deletions dict_builder/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{
collections::{BTreeMap, BTreeSet, HashMap},
fs::{self, read, read_dir, File},
collections::{BTreeMap, BTreeSet},
fs::{self, read_dir, File},
io::{self, BufRead},
ops::{Add, AddAssign},
ops::AddAssign,
path::PathBuf,
};

Expand Down
4 changes: 2 additions & 2 deletions fly.citadel.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ internal_port = 8080
processes = ["app"]
protocol = "tcp"
[services.concurrency]
hard_limit = 25
soft_limit = 20
hard_limit = 1000
soft_limit = 800
type = "connections"

[[services.ports]]
Expand Down
1 change: 1 addition & 0 deletions truncate_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ futures = "0.3"
image = { version = "0.24", features = ["png"] }
ab_glyph = "0.2"
interpolation = "0.3.0"
tracing = "0.1.40"

# native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down
35 changes: 35 additions & 0 deletions truncate_client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Truncate Client

This crate represents all frontend code for rendering and playing Truncate.

It supports building as a native application, or as a WebAssembly module to load into a browser.
In both cases, `egui` (via `eframe`) is the GUI library used for all rendering and inputs.

## General client info

`egui` is an immediate mode UI framework, which means the entire screen will be repainted every frame.

Truncate targets a 4fps tick when idle, so all idle animations (e.g. wind effects) should be made for this tick rate.

On input (e.g. mouse movement) or during animations (e.g. tutorial text, battle animation), Truncate will run at a significantly higher framerate.

## Editing Tutorials

Tutorials can be found in the `tutorials/*.yml` files, whose format should be self-explanatory. Changes here are automatically compiled into the client.

## Editing images

See the repo root CONTRIBUTING.md for steps.

## Code structure

Generally, `app_inner.rs` is the main place to start (skipping the egui-specific logic in `app_outer`, `main`, and `lib`).

Communications go through the `*_comms.rs` files, but all handling is done inside `app_inner.rs`.

Large regions of gameplay, e.g. single player vs multiplayer, existing in the `regions/` directory.
Within this directory, `active_game.rs` is a special case, as it tends to be used by every other region to render the actual gameplay UI.

Smaller items exist inside `lil_bits/`, e.g. board rendering or dialogs.

Both of the above directories are in need of some love re: code structure and organization!
Loading

0 comments on commit ce78950

Please sign in to comment.