diff --git a/.ci/build b/.ci/build index 3d3c359..cc0ac9a 100755 --- a/.ci/build +++ b/.ci/build @@ -1,6 +1,11 @@ #!/bin/bash -e set -Eeuo pipefail +if [[ ! -f hugo/hugo ]]; then + curl -L https://github.com/gohugoio/hugo/releases/download/v0.110.0/hugo_0.110.0_linux-arm64.tar.gz | tar -xvz -C hugo/ +fi +export PATH="$(pwd)/hugo:$PATH" + cd siterepo ./build.sh -cp -r ./assets/* ./assets/.??* ../sitegen/ +cp -r ./assets/* ./assets/.??* ./hugo-static/public/* ../sitegen/ diff --git a/.concourse.yml b/.concourse.yml index 3bd10aa..436db36 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -17,6 +17,7 @@ jobs: inputs: - name: siterepo caches: + - path: hugo - path: node_modules - path: dist outputs: diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..158b648 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "hugo-static/themes/hugo-book"] + path = hugo-static/themes/hugo-book + url = https://github.com/alex-shpak/hugo-book diff --git a/LICENSE b/LICENSE index ce4b4af..bb5f03d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2022 The Authors +Copyright 2023 The Authors Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,3 +9,28 @@ Redistributions in binary form must reproduce the above copyright notice, this l Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +License for bootstrap icons: + +The MIT License (MIT) + +Copyright (c) 2011-2023 The Bootstrap Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/build.sh b/build.sh index 3a59a81..bf13665 100755 --- a/build.sh +++ b/build.sh @@ -4,3 +4,5 @@ npm install -Dy npm exec webpack cp ./node_modules/xterm/css/xterm.css ./assets/ cp dist/main.js ./assets/main.js +cd hugo-static +hugo --theme hugo-book diff --git a/hugo-static/.gitignore b/hugo-static/.gitignore new file mode 100644 index 0000000..1516e93 --- /dev/null +++ b/hugo-static/.gitignore @@ -0,0 +1,2 @@ +public +resources/_gen diff --git a/hugo-static/archetypes/default.md b/hugo-static/archetypes/default.md new file mode 100644 index 0000000..00e77bd --- /dev/null +++ b/hugo-static/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +--- + diff --git a/hugo-static/config.toml b/hugo-static/config.toml new file mode 100644 index 0000000..8ac4e34 --- /dev/null +++ b/hugo-static/config.toml @@ -0,0 +1,22 @@ +baseURL = "https://blastmud.org/" +languageCode = "en-us" +title = "Blastmud" + +[markup] + [markup.goldmark] + [markup.goldmark.renderer] + unsafe = true + +[params] +BookTheme = 'light' +BookToC = true +BookSection = 'none' +BookRepo = 'https://git.blastmud.org/blasthavers/blastmud-site' +BookCommitPath = 'commit' +BookEditPath = '_edit/main/blastmud-site/hugo-static' +BookDateFormat = 'January 2, 2006' +BookSearch = true +BookComments = true +BookPortableLinks = true +BookServiceWorker = false +BookTranslatedOnly = false diff --git a/hugo-static/content/_index.md b/hugo-static/content/_index.md new file mode 100644 index 0000000..ea47470 --- /dev/null +++ b/hugo-static/content/_index.md @@ -0,0 +1,24 @@ +--- +date: 2023-02-18T16:04:43+11:00 +draft: false +--- + +# Blastmud + +Blastmud is a multi-player text-based post-apocalyptic game (MUD) for adults only. +It has player-vs-enemy and opt-in player-vs-player (coming soon) fighting. +You can play it with a MUD client (or telnet), in your web browser, or on your Android +device. Your aim is to survive and thrive in a harsh world filled with things +that want to kill you. + +Unlike many MUDs, Blastmud is completely Free / Open Source software (including content), +and is written in Rust, with contributions from the community encouraged. + +# Get started + +* Mud client: game.blastmud.org port 2300 (not yet open). +* [ Play in browser](game.html) (not yet open). +* [ Play on Android](https://play.google.com/store/apps/details?id=org.blastmud.game) (coming soon). +* [ Our theme](theme) +* [ Developer guide & source](developer) +* [ Contact staff](mailto:staff@blastmud.org) diff --git a/hugo-static/content/developer.md b/hugo-static/content/developer.md new file mode 100644 index 0000000..3afb18a --- /dev/null +++ b/hugo-static/content/developer.md @@ -0,0 +1,144 @@ +--- +menu: + after: + name: Developer docs + weight: 5 +title: Developer docs +--- +# Contributing to Blastmud + +## Get the source + +* [Main Blastmud game](https://git.blastmud.org/blasthavers/blastmud) - includes the listener that accepts connections, and the gameserver. +* [This website (including WebSocket play interface)](https://git.blastmud.org/blasthavers/blastmud-site) +* [Android app](https://git.blastmud.org/blasthavers/blastmud-android) + +## Making changes + +Make changes and test them locally (see dev env setup). If everything works correctly, +submit a PR. + +Feel free to discuss in an issue first before starting work - we can tell you if we +think your idea is a good idea. + +PRs are reviewed, and if we think it is appropriate for the game, it will be merged to main +by a member of the core (Wizards) team. Merged PRs are tested, and if tests pass, they are +automatically deployed. You can watch the status of the deployment over at +[https://concourse.blastmud.org/]. + +Note that changes to the gameserver can be made without disconnecting all users, +due to the design of the game. Changing the listener is a larger affair because +it involves disconnecting all users. Confining your changes to the gameserver part +of the code will mean we need to do less coordination to deploy it. + +If you propose a change to us, you agree that unless you explicitly state otherwise, +you grant everyone a licence to use it under the same licence terms (as documented in +the LICENSE file) as the other code in the repository you are contributing to. + +## Rules to increase the chances your change will be accepted + +* The game must stay within [the guidelines](https://www.legislation.gov.au/Details/F2012L01934) to be rated as R18 in Australia, rather than Refused Classification (i.e. illegal to distribute in Australia). No content that would make it RC can be accepted - this includes any content about any form of sexual violence, characters under 18 years of age (due to the interaction with the nature of this game), detailed instruction or promotion in crime or violence, incest or hard fetishes, or incentivised drug use (including any kind of buff from anything that could be construed as drugs). No PRs or other content of the kind described under this point may be submitted to any Blastmud resource (i.e. this restriction does not apply solely to PRs for the main branch). +* Your change shouldn't compromise security or privacy. It shouldn't create a risk that users can execute arbitrary code, access confidential information, misuse resources, or deny service to users. It should respect the privacy of users and not use personally-linked information for any purpose not mentioned in the privacy policy. It should not leak secrets such as deployment keys or the actual IP addresses of the systems on which Blastmud is deployed (other than the public proxy). +* Your change should be appropriate to the theme of the game. +* Your change should be safe to roll-back if it doesn't work correctly (if this is genuinely not possible, please discuss it with us). +* Your game should ensure the game remains balanced and fair both for players who primarily want to engage in PvE play, and those who want to engage in PvP with other willing participants. +* Your change should not promote play by people under 18, nor help people under 18 circumvent any restrictions on their access to the game. Note: such content is unacceptable on any Blastmud hosted resource, not just as a PR submission to the main branch. + +## Setting up a blastmud development environment + +* Check it out locally with git. `git clone https://git.blastmud.org/blasthavers/blastmud.git`. +* Ensure you have Rust installed. Visit [https://rustup.rs/] for help getting started. +* Run `cargo test && cargo build` to test and install the code. +* Setup postgresql. See [the Postgres docs](https://www.postgresql.org/docs/current/tutorial-install.html) for help. Create a postgresql database (in these instructions, I assume you call it blast) and user (called `blast` in these instructions as well) for Blastmud. +* Run `psql -d template1 <schema/schema.sql` as a user with access to create databases. +* Install migra - `pip3 install migra`. +* Diff the blast DB from the temporary blast_schemaonly DB with `migra "postgres:///blast" "postgres:///blast_schemaonly" > /tmp/update.sql` +* Check `/tmp/update.sql` and if it looks good, apply it with `psql -U blast -d blast </tmp/update.sql` +* Create a config directory under the blastmud directory you checked out, and put a listener.conf and gameserver.conf in it, with the content below. Also make a run directory under config. +* Email [staff@blastmud.org](mailto:staff@blastmud.org) and ask for a personal age-verification.yml file. You must provide your decade of birth if it is 90s or earlier. If you were born in the 21st century and didn't turn 18 this year, you must provide your year of birth. If you turned 18 this year but not this month, you must provide your month and year of birth. If you turned 18 this month, you must provide your full birth date in the email. Your personal age-verification.yml file must not be published on the Internet or shared with anyone else. Put age-verification.yml in the same config directory with the other files. +* From the config directory, run `../target/debug/blastmud_listener`. In another tab, run `../target/debug/blastmud_game`. +* Connect to port 1234 on localhost to test it out locally. + +### listener.conf +``` +listeners: + - 127.0.0.1:1234 +gameserver: 127.0.0.1:1235 +ws_listener: 127.0.0.1:1236 +pidfile: ./run/listener.pid +``` + +### gameserver.conf +``` +listener: 127.0.0.1:1235 +pidfile: ./run/gameserver.pid +database_conn_string: host=/var/run/postgresql user=blast password=blastuserpasswordhere dbname=blast +``` + +Adjust password for the database, and the path to the postgresql socket accordingly (you can also put host=localhost to connect over TCP if you prefer, but this is less efficient). + +## Getting around the Blastmud codebase +### Listener + +The listener lives under `blastmud_listener/` accepts WebSocket and telnet connections. It +establishes and maintains a connection to the gameserver, and sends information +about new connections and user commands (lines of input) to the gameserver. It +accepts commands from the gameserver. + +Restarting it will disconnect all users. + +### blastmud_interfaces + +These live under `blastmud_interfaces/` and define the contract between the listener and +the gameserver. + +Since it is a dependency for the listener, changing it will require restarting +the listener and disconnecting all users. + +### Gameserver + +This lives under `blastmud_game`. It is stateless (other than temporary caches that +can be replaced at any time), with all state living in the database, so that it can +be restarted at any time without impacting users. + +It is further divided up as follows: + +`main.rs` is the entrypoint. + +`version_cutover.rs` handles seamless cutovers - the new version starts up, +finds the existing version, and sends it `SIGUSR1` to tell it to shut down +gracefully. Users will not notice any impact on thier game session. + +The `static_content` module has submodules for npcs, rooms, species, +possession_types (including weapons), and fixed_items (features within +rooms that can be looked at for example). + +The `regular_tasks` module has the infrastructure for anything that happens +repeatedly (although most actual task logic is in other modules - e.g. +NPC movement is in `static_content/npc`). + +The `models` module defines the structure of the content that is stored as +BSON within the database. This for example defines all the fields on +users and items. + +The `listener` module defines the interaction with the listener. + +The `services` module provides common calculations (e.g. around combat, capacity +limits, skill checks, and broadcasting to everyone in a room). + +The `db` module provides support for interacting with the database. + +The `message_handler` module handles messages from the listener. +`message_handler/user_commands` in particular has all the logic for +handling commands sent by users. + +#### Key models within the gameserver +* A `Session` represents a connected (but possibly unregistered) session. +* A `User` represents a particular registered user of the game. Sessions get +attached to users on login. Note that every `User` has an `Item` of type player +as well - `User` has the (often OOC) details that only make sense for a real +player, such as their password, while everything common to players and NPCs lives +on the item. +* An `Item` represents something that can be seen in the game - a player, NPC, + possession, room, and so on. +* A `Task` represents something that will happen in the future, either as a once-off or recurring. diff --git a/hugo-static/content/menu/index.md b/hugo-static/content/menu/index.md new file mode 100644 index 0000000..dcf6b5d --- /dev/null +++ b/hugo-static/content/menu/index.md @@ -0,0 +1,11 @@ +--- +headless: true +--- +* [Welcome page](/) +* [ Play in browser](game.html) +* [ Play on Android](https://play.google.com/store/apps/details?id=org.blastmud.game) +* [ Our theme](theme) +* [ Developer guide & source](developer) +* [ Contact staff](mailto:staff@blastmud.org) + +
diff --git a/hugo-static/content/theme.md b/hugo-static/content/theme.md new file mode 100644 index 0000000..427944b --- /dev/null +++ b/hugo-static/content/theme.md @@ -0,0 +1,96 @@ +--- +menu: + after: + weight: 5 +--- +# Theme + +## The Empire (300-50 years ago) +About 300 years ago, a group of powerful tech corporation CEOs from around the world grew dissatisfied with the state of the +world. Nations were always fighting, wasting resources and creating an unstable business environment. Some countries decided +to nationalise assets, and others imposed heavy taxes to help the poor (which was a bad thing from the perspective of the +wealthy CEOs). + +They formed an initially secret cabal called Gazos-Murlison Enterprises, with the goal of using their combined powers to take +over rule of the world. Cabal members already controlled the companies running most of the world's infrastructure, including +that used by the current ruling class to communicate - so they had visibility and control over nearly everything. They also +had control over nearly all weapons manufacturing, although Gazos-Murlison aimed to take power with minimal bloodshed. Through +manipulation of tech, and a small amount of blackmailing and threatening to get the hold-outs, within 5 years the entire world +was under the rule of the Gazos-Murlison Empire. + +The Empire set out to reform society drastically through tech. To complete their social engineering initiatives, +they first incentivised and eventually mandated that every person have a wrist pad installed at birth. +The wrist-pad is far more than a wrist-watch; as well as the watch-like external unit, it has an implanted module embedded +under the skin that manufactures nanites. The nanites travel through the body and can influence skills, and could put a hard +stop to behaviours the Empire didn't like. + +In particular, no one with a wristpad can attack anyone with a wristpad, or enter their land, unless they have consented to +fight or allow visitors respectively. If they were to attempt it, the nanites would stop the thought and it would be +physically impossible to proceed with the plan. + +The Empire instituted a single global currency, called credits (denoted with the $ symbol). The wristpads securely store +credits a person has, and allows for seamless transfers. Credits can never be stolen. + +The Empire used technology to effectively erase the concept of childhood entirely. They built a series of Tachyon-Accelerated +Reproduction and Education Vats (TAREVs) that takes babies and turns them into homogenised 18 year old fully educated bodies +that have been through a fully automated training process. The use of tachyon rays means that while 18 years passes inside the +vat, from outside it only takes about a minute. It is also possible for the vats to recreate an existing person with a new +body (the Empire presented this as immortality). + +In order to produce enough babies for the TAREVs, the Empire instituted significant social change. Sex became much more +normalised, and the Empire would pay credits to both partners who conceive a baby. The wristpad system greatly +accelerates pregnancy, to the point where it only takes a few minutes. As soon as a baby is born, an automated drone +flies in and takes the baby to the nearest vat; citizens are not allowed to raise their own babies. + +The Empire signifcantly reformed society. Due to the standardised education, local cultures and religion were effectively +completely erased during the Empire, in favour of a global set of traditions. All races intermingled, to the point where +there were not separate races any more. With no national boundaries or nationalities, everyone was free to travel. + +The Empire mostly allowed people to do their own thing, subject to the rules enforced by the wrist-pad and by a network +of automated defence systems that make AI-driven judgements and dispensed lethal justice. + +## The Smiting Shadows (50-70 years ago) +About 70 years ago, a group of hackers discovered an archive of radical right-wing videos from before the Empire years, +and circulated them (which was not initially against the rules). They became radicalised by the videos, but were +frustrated by their inability to act to violently take down the Empire due to their wristbands. After years of +trying, they found a way to modify the wristpads to make them think everyone had consented to fight with them, +and hence allow violence against anyone. + +They immediately started building an underground city, and building and stockpiling conventional and nuclear +weapons, ready to take down the Empire. + +About 51 years ago, the Emperor learned of the plans, and ordered that all wristpads be updated to block +the exploit, and also that those with already exploited wristpads be killed. The Smiting Shadows, now exposed, +went full on aggressive, but was losing the battle. Finally, backed into a corner, the Grand Umbra of the +Smiting Shadows (i.e. the leader) ordered that a barrage of nuclear warheads be launched to their targets all +over the world. Many of these were salted bombs designed to leave vast areas uninhabitable for years. + +The Smiting Shadows succeeded in destroying the Emperor, and the result was that the empire was fragmented +and previous regional prefects who worked together under the Empire took control of their little regions, +and even fought against each other. Other regions were left completely devoid of leadership and became +total anarchies. + +The Smiting Shadows, greatly reduced in numbers, and out of supplies to sustain +itself, died out as a movement. The remaining members, now lacking belief in their own movement, +moved away and took up many roles in the game (they can re-clone and preserve their ability to attack +PCs). The ability to create new hacked wristpads for someone who doesn't already have it was lost due +to the patches released by the Empire in its last days (i.e. no player can have it), but many hostile +NPCs derive from these scattered Smiting Shadow members. + +## The post-apocalyptic period (50 years ago - present) +The Empire was smashed, and some smaller relatively disorganised governments rule local regions. +Much of the world is radioactive. + +Remarkably, some of the Empire era tech survived. The wristpad and credit system was still operational, +and the smaller governments continued to maintain their TAREVs so people could reclone. Many cities +also kept their AI-based defence systems to protect against those with hacked wristpads, and any +wandering animals coming in. + +A series of corporations formed, trading and looking after their members. Life went on. + +Some of the formed smiting shadows formed sub-cultures and subgroups. One group discovered an ancient +virus that grants super-human strength in an abandoned warehouse, and started the vampire movement. + +Another found a way to zombify themselves in ancient Voodoo texts, and started the zombie movement. +Some became aggressive beggars, and others fused their DNA with sewer rats to become canniballistic +chuds. diff --git a/hugo-static/layouts/home.html b/hugo-static/layouts/home.html new file mode 100644 index 0000000..4deb74b --- /dev/null +++ b/hugo-static/layouts/home.html @@ -0,0 +1,17 @@ + + + + Blastmud + + + + +
+ {{- .Content -}} +
+
Propose changes:
+ + diff --git a/hugo-static/static/background.jpeg b/hugo-static/static/background.jpeg new file mode 100644 index 0000000..c8dc779 Binary files /dev/null and b/hugo-static/static/background.jpeg differ diff --git a/hugo-static/static/favicon.png b/hugo-static/static/favicon.png new file mode 100644 index 0000000..b575a5c Binary files /dev/null and b/hugo-static/static/favicon.png differ diff --git a/hugo-static/themes/hugo-book b/hugo-static/themes/hugo-book new file mode 160000 index 0000000..036e037 --- /dev/null +++ b/hugo-static/themes/hugo-book @@ -0,0 +1 @@ +Subproject commit 036e037a63ba06ca366adb1a0c3a005d1a0b15b8