magmacrunch 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- magmacrunch-0.1.0/.gitattributes +10 -0
- magmacrunch-0.1.0/.github/workflows/ci.yml +40 -0
- magmacrunch-0.1.0/.github/workflows/release.yml +72 -0
- magmacrunch-0.1.0/.gitignore +9 -0
- magmacrunch-0.1.0/AGENTS.md +56 -0
- magmacrunch-0.1.0/LICENSE +75 -0
- magmacrunch-0.1.0/NOTICE +33 -0
- magmacrunch-0.1.0/PKG-INFO +140 -0
- magmacrunch-0.1.0/README.md +120 -0
- magmacrunch-0.1.0/magmacrunch/__init__.py +20 -0
- magmacrunch-0.1.0/magmacrunch/__main__.py +101 -0
- magmacrunch-0.1.0/magmacrunch/app.py +100 -0
- magmacrunch-0.1.0/magmacrunch/banner.py +172 -0
- magmacrunch-0.1.0/magmacrunch/cards.py +174 -0
- magmacrunch-0.1.0/magmacrunch/scenes.py +284 -0
- magmacrunch-0.1.0/magmacrunch/theme.py +96 -0
- magmacrunch-0.1.0/pyproject.toml +62 -0
- magmacrunch-0.1.0/tests/test_cabinet.py +849 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# No eol pin for the tree at large: both this repo and its siblings normalise
|
|
2
|
+
# to LF in the index, so what is committed is LF whatever a clone's
|
|
3
|
+
# core.autocrlf does on disk.
|
|
4
|
+
#
|
|
5
|
+
# Pinned below are the files CRLF breaks outright on Linux rather than merely
|
|
6
|
+
# making untidy: a trailing \r on a shebang gives "bad interpreter", and a
|
|
7
|
+
# workflow's `run:` block is handed to a Linux shell verbatim.
|
|
8
|
+
*.sh text eol=lf
|
|
9
|
+
*.yml text eol=lf
|
|
10
|
+
*.yaml text eol=lf
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# The launcher's suite, run against fake cabinets on a GitHub-hosted runner.
|
|
2
|
+
#
|
|
3
|
+
# Deliberately installed WITHOUT the games it depends on. `ArcadeGame` is a
|
|
4
|
+
# structural protocol, so the tests satisfy it with fakes — and a suite that
|
|
5
|
+
# only passed when two unrelated packages happened to be installed would be a
|
|
6
|
+
# worse suite. Running with nothing installed also exercises the empty-floor
|
|
7
|
+
# case for free, and is what proves the launcher imports no game.
|
|
8
|
+
|
|
9
|
+
name: CI
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [main]
|
|
14
|
+
pull_request:
|
|
15
|
+
branches: [main]
|
|
16
|
+
# Lets CI be run against a branch without opening a pull request first.
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
tests:
|
|
21
|
+
name: tests (no cabinets)
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
# --no-deps because pyproject lists the cabinets, and installing them
|
|
30
|
+
# would defeat the point of the job.
|
|
31
|
+
- name: Install the launcher, without its cabinets
|
|
32
|
+
run: |
|
|
33
|
+
pip install "texastoast[tui]>=0.10.0" pytest ruff
|
|
34
|
+
pip install --no-deps -e .
|
|
35
|
+
|
|
36
|
+
- run: python -m pytest -q
|
|
37
|
+
- run: ruff check .
|
|
38
|
+
|
|
39
|
+
- name: An empty arcade still runs
|
|
40
|
+
run: magmacrunch --list
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Publishes the launcher to PyPI as `magmacrunch`.
|
|
2
|
+
#
|
|
3
|
+
# One package built from the repo root, so the tag is a plain `v0.1.0` — the
|
|
4
|
+
# games prefix theirs with `tui-` because their repos hold three versions and
|
|
5
|
+
# a tag there has to say which one it releases. This repo holds one thing.
|
|
6
|
+
#
|
|
7
|
+
# Trusted Publishing: GitHub mints a short-lived identity token that PyPI
|
|
8
|
+
# verifies against a publisher configured for this repo. No API token, no
|
|
9
|
+
# repository secret, nothing to rotate. The publisher has to exist on PyPI
|
|
10
|
+
# before the first run — for a project that does not exist yet that means a
|
|
11
|
+
# "pending publisher" (pypi.org → Your account → Publishing), naming this
|
|
12
|
+
# repository and this workflow file.
|
|
13
|
+
#
|
|
14
|
+
# Release this one LAST. It depends on both cabinets, so a `pip install
|
|
15
|
+
# magmacrunch` before they are on PyPI is an unresolvable dependency.
|
|
16
|
+
|
|
17
|
+
name: Release
|
|
18
|
+
|
|
19
|
+
on:
|
|
20
|
+
push:
|
|
21
|
+
tags: ["v*"]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
publish:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
permissions:
|
|
28
|
+
contents: write
|
|
29
|
+
id-token: write
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
- uses: actions/setup-python@v5
|
|
33
|
+
with:
|
|
34
|
+
python-version: "3.12"
|
|
35
|
+
|
|
36
|
+
# A tag that disagrees with the packaged version publishes something
|
|
37
|
+
# nobody can find again. Cheaper to fail here than to yank a release.
|
|
38
|
+
- name: Verify the tag matches the package version
|
|
39
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
40
|
+
run: |
|
|
41
|
+
TAG="${GITHUB_REF_NAME#v}"
|
|
42
|
+
PKG=$(python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
|
|
43
|
+
if [ "$TAG" != "$PKG" ]; then
|
|
44
|
+
echo "Tag $TAG does not match pyproject version $PKG"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Deliberately installed WITHOUT its game dependencies. The suite runs
|
|
49
|
+
# against fake cabinets, and an arcade with nothing installed is a case
|
|
50
|
+
# it has to handle anyway — so this doubles as proof that the launcher
|
|
51
|
+
# imports no game, which is the rule the whole design rests on.
|
|
52
|
+
- name: Test, with no cabinets on the machine
|
|
53
|
+
run: |
|
|
54
|
+
pip install "texastoast[tui]>=0.10.0" pytest ruff
|
|
55
|
+
pip install --no-deps -e .
|
|
56
|
+
python -m pytest -q
|
|
57
|
+
ruff check .
|
|
58
|
+
|
|
59
|
+
- run: pip install build twine
|
|
60
|
+
- run: python -m build
|
|
61
|
+
- run: twine check dist/*
|
|
62
|
+
|
|
63
|
+
- name: Publish to PyPI
|
|
64
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
65
|
+
with:
|
|
66
|
+
skip-existing: true
|
|
67
|
+
|
|
68
|
+
- name: Create GitHub Release
|
|
69
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
70
|
+
env:
|
|
71
|
+
GH_TOKEN: ${{ github.token }}
|
|
72
|
+
run: gh release create ${{ github.ref_name }} --generate-notes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# magmacrunch — agent brief
|
|
2
|
+
|
|
3
|
+
The terminal arcade: the `magmacrunch` command, a menu of every installed
|
|
4
|
+
cabinet, and the wiring that seats one on the terminal it is already holding.
|
|
5
|
+
|
|
6
|
+
The engine is [texastoast](https://pypi.org/project/texastoast/) and its `[tui]`
|
|
7
|
+
backend. `texastoast.arcade` defines the seam this consumes — `GameInfo`,
|
|
8
|
+
`Host`, `ArcadeGame`, `discover` — and `texastoast.core.tui_host.TuiHost` is the
|
|
9
|
+
host that owns the terminal. Neither is reimplemented here.
|
|
10
|
+
|
|
11
|
+
## AI Attribution
|
|
12
|
+
|
|
13
|
+
**No AI attribution.** Do not append `Co-Authored-By: Claude …`, "Generated with
|
|
14
|
+
…", or any similar trailer to commit messages, PR bodies, or release notes. If
|
|
15
|
+
your tooling adds such a line by default, remove it before committing.
|
|
16
|
+
|
|
17
|
+
## Games are never vendored here, and this package imports none of them
|
|
18
|
+
|
|
19
|
+
Each game lives in its own repo with its `web/`, `wii/` and `tui/` versions
|
|
20
|
+
together, and publishes its own wheel built from `tui/`. This repo holds the
|
|
21
|
+
launcher and nothing else.
|
|
22
|
+
|
|
23
|
+
The relationship runs in two directions that must not be confused:
|
|
24
|
+
|
|
25
|
+
- **Distribution:** `pyproject.toml` lists the games as dependencies, so
|
|
26
|
+
`pip install magmacrunch` installs an arcade with cabinets in it.
|
|
27
|
+
- **Runtime:** games are found by enumerating the `magmacrunch.games` entry
|
|
28
|
+
point group. `magmacrunch` never imports `boole`, `lavadome`, or any other
|
|
29
|
+
game module.
|
|
30
|
+
|
|
31
|
+
There is therefore no import edge in either direction, which is what makes an
|
|
32
|
+
arcade with its games uninstalled a working program that says the floor is
|
|
33
|
+
empty rather than an `ImportError`. `tests/test_cabinet.py` guards this.
|
|
34
|
+
|
|
35
|
+
It is also what lets a game published later appear in the menu without a
|
|
36
|
+
`magmacrunch` release — install it and it is there, uninstall it and it is gone.
|
|
37
|
+
|
|
38
|
+
## Adding a cabinet
|
|
39
|
+
|
|
40
|
+
Nothing changes here except the dependency list. A game declares:
|
|
41
|
+
|
|
42
|
+
```toml
|
|
43
|
+
[project.entry-points."magmacrunch.games"]
|
|
44
|
+
george-boole = "boole.arcade:GAME"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
pointing at an object with `info: GameInfo` and `start(host) -> scene`. See
|
|
48
|
+
`texastoast.arcade` for the contract and `george-boole/tui/boole/arcade.py` for
|
|
49
|
+
a worked example. `magmacrunch --list` says what was found and why anything was
|
|
50
|
+
skipped.
|
|
51
|
+
|
|
52
|
+
## Licence
|
|
53
|
+
|
|
54
|
+
PolyForm Noncommercial 1.0.0, because it depends on Noncommercial games. The
|
|
55
|
+
engine underneath stays Apache-2.0; a permissive dependency under a restrictive
|
|
56
|
+
package is fine, the reverse would not be.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Required Notice: Copyright 2026 magmacrunch media (https://magmacrunch.com)
|
|
2
|
+
|
|
3
|
+
# PolyForm Noncommercial License 1.0.0
|
|
4
|
+
|
|
5
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
|
|
14
|
+
|
|
15
|
+
## Distribution License
|
|
16
|
+
|
|
17
|
+
The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
|
|
18
|
+
|
|
19
|
+
## Notices
|
|
20
|
+
|
|
21
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
|
|
22
|
+
|
|
23
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
24
|
+
|
|
25
|
+
## Changes and New Works License
|
|
26
|
+
|
|
27
|
+
The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
|
|
28
|
+
|
|
29
|
+
## Patent License
|
|
30
|
+
|
|
31
|
+
The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
|
|
32
|
+
|
|
33
|
+
## Noncommercial Purposes
|
|
34
|
+
|
|
35
|
+
Any noncommercial purpose is a permitted purpose.
|
|
36
|
+
|
|
37
|
+
## Personal Uses
|
|
38
|
+
|
|
39
|
+
Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
|
|
40
|
+
|
|
41
|
+
## Noncommercial Organizations
|
|
42
|
+
|
|
43
|
+
Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
|
|
44
|
+
|
|
45
|
+
## Fair Use
|
|
46
|
+
|
|
47
|
+
You may have "fair use" rights for the software under the law. These terms do not limit them.
|
|
48
|
+
|
|
49
|
+
## No Other Rights
|
|
50
|
+
|
|
51
|
+
These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
|
|
52
|
+
|
|
53
|
+
## Patent Defense
|
|
54
|
+
|
|
55
|
+
If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
56
|
+
|
|
57
|
+
## Violations
|
|
58
|
+
|
|
59
|
+
The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
|
|
60
|
+
|
|
61
|
+
## No Liability
|
|
62
|
+
|
|
63
|
+
***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
|
|
64
|
+
|
|
65
|
+
## Definitions
|
|
66
|
+
|
|
67
|
+
The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
|
|
68
|
+
|
|
69
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
70
|
+
|
|
71
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
72
|
+
|
|
73
|
+
**Your licenses** are all the licenses granted to you for the software under these terms.
|
|
74
|
+
|
|
75
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
magmacrunch-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
magmacrunch — the terminal arcade
|
|
2
|
+
Copyright 2026 magmacrunch media
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
THE LICENCE
|
|
6
|
+
|
|
7
|
+
Everything in this repository -- the launcher, the tests, the build files and
|
|
8
|
+
the documentation -- is licensed under the PolyForm Noncommercial License
|
|
9
|
+
1.0.0, in the LICENSE file beside this one.
|
|
10
|
+
|
|
11
|
+
Read it, learn from it, build on it, play with it. Any noncommercial purpose is
|
|
12
|
+
permitted, and that includes personal projects, teaching and research. What is
|
|
13
|
+
not permitted is commercial use: selling it or a derivative of it, shipping it
|
|
14
|
+
inside a product, or running it as part of a business.
|
|
15
|
+
|
|
16
|
+
It is Noncommercial because the games it seats are. This package contains no
|
|
17
|
+
game code -- it finds installed games by entry point and never imports one --
|
|
18
|
+
but it depends on them, and a package cannot be more permissive than what it
|
|
19
|
+
depends on.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
WHAT THIS DEPENDS ON
|
|
23
|
+
|
|
24
|
+
texastoast, the engine, with its terminal backend. Apache License 2.0,
|
|
25
|
+
copyright 2026 magmacrunch media. https://pypi.org/project/texastoast/
|
|
26
|
+
|
|
27
|
+
texastoast's terminal backend depends in turn on Textual, and through it on
|
|
28
|
+
Rich (MIT, copyright Will McGugan). Both carry their own licences in the
|
|
29
|
+
installed distributions.
|
|
30
|
+
|
|
31
|
+
The cabinets -- magmacrunch-george-boole, magmacrunch-thld -- are each
|
|
32
|
+
PolyForm Noncommercial 1.0.0, copyright 2026 magmacrunch media, and carry
|
|
33
|
+
their own NOTICE files.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: magmacrunch
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The magmacrunch terminal arcade - a menu of every installed cabinet
|
|
5
|
+
Project-URL: Homepage, https://magmacrunch.com/arcade/
|
|
6
|
+
Author: magmacrunch media
|
|
7
|
+
License-Expression: PolyForm-Noncommercial-1.0.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: NOTICE
|
|
10
|
+
Keywords: arcade,games,launcher,terminal,tui
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Requires-Dist: magmacrunch-george-boole>=0.1.0
|
|
13
|
+
Requires-Dist: magmacrunch-moonlight-drift>=0.1.0
|
|
14
|
+
Requires-Dist: magmacrunch-thld>=0.1.0
|
|
15
|
+
Requires-Dist: texastoast[tui]>=0.10.0
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# magmacrunch
|
|
22
|
+
|
|
23
|
+
The terminal arcade. One command, a menu of every cabinet installed on the
|
|
24
|
+
machine, and a way into one.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pip install magmacrunch
|
|
28
|
+
magmacrunch
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
__
|
|
33
|
+
.--------.---.-.-----.--------.---.-.----.----.--.--.-----.----.| |--.
|
|
34
|
+
| | _ | _ | | _ | __| _| | | | __|| |
|
|
35
|
+
|__|__|__|___._|___ |__|__|__|___._|____|__| |_____|__|__|____||__|__|
|
|
36
|
+
|_____|
|
|
37
|
+
EVERY CABINET ON THIS MACHINE
|
|
38
|
+
INSERT COIN
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
┌──────────────────────────────┐ ┌──────────────────────────────┐
|
|
42
|
+
│ George Boole Has Entered The │ │ Texas Hold'Em Lava Dome │
|
|
43
|
+
│ Chat │ │ │
|
|
44
|
+
│ │ │ Solo hold'em against a │
|
|
45
|
+
│ 2048 played with logic gates │ │ threshold that climbs every │
|
|
46
|
+
│ — merge, invert, overflow. │ │ round. │
|
|
47
|
+
│ │ │ │
|
|
48
|
+
│ ▶ ENTER_ │ │ ▶ ENTER │
|
|
49
|
+
└──────────────────────────────┘ └──────────────────────────────┘
|
|
50
|
+
|
|
51
|
+
↑↓←→ CHOOSE ENTER PLAY Q QUIT
|
|
52
|
+
© 2026 magmacrunch media · magmacrunch.com
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
It is `magmacrunch.com/arcade` in a shell — the same palette, the same card
|
|
56
|
+
grid, the same blinking cursor on the card you are about to start. The one
|
|
57
|
+
thing that could not come across is the typography: `arcade.css` sets
|
|
58
|
+
`Press Start 2P` on nearly every string, and a terminal program does not
|
|
59
|
+
choose its font. Pixel lettering has to be *drawn*, out of block glyphs, which
|
|
60
|
+
is what the narrow title variant does — and what the web page's own title art
|
|
61
|
+
does too, in Courier Prime rather than Press Start 2P, for the same reason.
|
|
62
|
+
|
|
63
|
+
The title art stands down as the window grows or shrinks, and always before
|
|
64
|
+
the cabinets have to — which is what keeps the floor as low as it is:
|
|
65
|
+
|
|
66
|
+
| window | banner |
|
|
67
|
+
|---|---|
|
|
68
|
+
| 121×34 and up | the full site wordmark, MAGMACRUNCH over ARCADE, 119×19 |
|
|
69
|
+
| ~73×30 | the same two words in 71 columns instead of 119 |
|
|
70
|
+
| **80×24** | **MAGMACRUNCH alone, 71×5** |
|
|
71
|
+
| ~62–72 cols | the ARCADE wordmark alone, 60×8 |
|
|
72
|
+
| ~50 cols | a block-glyph MAGMACRUNCH, 48×2 |
|
|
73
|
+
| 36 cols | spaced capitals |
|
|
74
|
+
|
|
75
|
+
Art is measured rather than declared, so the 119-column piece can sit at the
|
|
76
|
+
top of the list without ever bothering someone on an ordinary terminal — it
|
|
77
|
+
is simply never the one that fits. Adding your own is one entry in `VARIANTS`
|
|
78
|
+
in [`banner.py`](magmacrunch/banner.py) and nothing else.
|
|
79
|
+
|
|
80
|
+
Choosing a cabinet starts it on the terminal the arcade is already holding.
|
|
81
|
+
Leaving the game brings you back here. Every game is also its own command
|
|
82
|
+
(`george-boole`, `lava-dome`, `moonlight-drift`) and plays identically either way — the arcade is
|
|
83
|
+
not a wrapper around them, it is the same host they run on.
|
|
84
|
+
|
|
85
|
+
## What is installed
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
magmacrunch --list
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Prints every cabinet found, what terminal size it wants, and how it wants
|
|
92
|
+
input. If a game you installed is not in the menu, this says why — a game that
|
|
93
|
+
fails to load is reported rather than silently skipped.
|
|
94
|
+
|
|
95
|
+
## How games get here
|
|
96
|
+
|
|
97
|
+
Games are **not** bundled. Each one lives in its own repo alongside its browser
|
|
98
|
+
and Wii versions, publishes its own wheel, and declares an entry point:
|
|
99
|
+
|
|
100
|
+
```toml
|
|
101
|
+
[project.entry-points."magmacrunch.games"]
|
|
102
|
+
george-boole = "boole.arcade:GAME"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
pointing at an object with `info: GameInfo` and `start(host) -> scene`. The
|
|
106
|
+
launcher enumerates that group at startup. **Installing a game makes it appear
|
|
107
|
+
here; uninstalling makes it vanish; neither needs a release of the arcade.**
|
|
108
|
+
|
|
109
|
+
Nothing in this package imports a game, so the arcade runs with none installed
|
|
110
|
+
and tells you how to get one. The contract lives in
|
|
111
|
+
[`texastoast.arcade`](https://pypi.org/project/texastoast/); the two cabinets
|
|
112
|
+
above are worked examples of it.
|
|
113
|
+
|
|
114
|
+
## Cabinets
|
|
115
|
+
|
|
116
|
+
| | |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `magmacrunch-george-boole` | 2048 played with logic gates |
|
|
119
|
+
| `magmacrunch-thld` | Solo hold'em against a climbing threshold |
|
|
120
|
+
| `magmacrunch-moonlight-drift` | Thread the columns; hold to climb |
|
|
121
|
+
|
|
122
|
+
Installing `magmacrunch` installs all three.
|
|
123
|
+
|
|
124
|
+
## Requires
|
|
125
|
+
|
|
126
|
+
Python 3.10+, and a terminal at least 36×17. Individual cabinets ask for more
|
|
127
|
+
(around 59×22); below that their card greys out, says the size it wants, and
|
|
128
|
+
cannot be started. The arcade's own floor is deliberately lower than any
|
|
129
|
+
game's, so getting to the floor is never the thing that fails.
|
|
130
|
+
|
|
131
|
+
Two cards sit side by side from 70 columns and stack into one below that. More
|
|
132
|
+
cabinets than fit are paged, not scrolled.
|
|
133
|
+
|
|
134
|
+
Truecolor helps but is not required.
|
|
135
|
+
|
|
136
|
+
## Licence
|
|
137
|
+
|
|
138
|
+
PolyForm Noncommercial 1.0.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
139
|
+
Noncommercial because the games it seats are. The engine underneath,
|
|
140
|
+
[texastoast](https://pypi.org/project/texastoast/), stays Apache-2.0.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# magmacrunch
|
|
2
|
+
|
|
3
|
+
The terminal arcade. One command, a menu of every cabinet installed on the
|
|
4
|
+
machine, and a way into one.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
pip install magmacrunch
|
|
8
|
+
magmacrunch
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
__
|
|
13
|
+
.--------.---.-.-----.--------.---.-.----.----.--.--.-----.----.| |--.
|
|
14
|
+
| | _ | _ | | _ | __| _| | | | __|| |
|
|
15
|
+
|__|__|__|___._|___ |__|__|__|___._|____|__| |_____|__|__|____||__|__|
|
|
16
|
+
|_____|
|
|
17
|
+
EVERY CABINET ON THIS MACHINE
|
|
18
|
+
INSERT COIN
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
┌──────────────────────────────┐ ┌──────────────────────────────┐
|
|
22
|
+
│ George Boole Has Entered The │ │ Texas Hold'Em Lava Dome │
|
|
23
|
+
│ Chat │ │ │
|
|
24
|
+
│ │ │ Solo hold'em against a │
|
|
25
|
+
│ 2048 played with logic gates │ │ threshold that climbs every │
|
|
26
|
+
│ — merge, invert, overflow. │ │ round. │
|
|
27
|
+
│ │ │ │
|
|
28
|
+
│ ▶ ENTER_ │ │ ▶ ENTER │
|
|
29
|
+
└──────────────────────────────┘ └──────────────────────────────┘
|
|
30
|
+
|
|
31
|
+
↑↓←→ CHOOSE ENTER PLAY Q QUIT
|
|
32
|
+
© 2026 magmacrunch media · magmacrunch.com
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
It is `magmacrunch.com/arcade` in a shell — the same palette, the same card
|
|
36
|
+
grid, the same blinking cursor on the card you are about to start. The one
|
|
37
|
+
thing that could not come across is the typography: `arcade.css` sets
|
|
38
|
+
`Press Start 2P` on nearly every string, and a terminal program does not
|
|
39
|
+
choose its font. Pixel lettering has to be *drawn*, out of block glyphs, which
|
|
40
|
+
is what the narrow title variant does — and what the web page's own title art
|
|
41
|
+
does too, in Courier Prime rather than Press Start 2P, for the same reason.
|
|
42
|
+
|
|
43
|
+
The title art stands down as the window grows or shrinks, and always before
|
|
44
|
+
the cabinets have to — which is what keeps the floor as low as it is:
|
|
45
|
+
|
|
46
|
+
| window | banner |
|
|
47
|
+
|---|---|
|
|
48
|
+
| 121×34 and up | the full site wordmark, MAGMACRUNCH over ARCADE, 119×19 |
|
|
49
|
+
| ~73×30 | the same two words in 71 columns instead of 119 |
|
|
50
|
+
| **80×24** | **MAGMACRUNCH alone, 71×5** |
|
|
51
|
+
| ~62–72 cols | the ARCADE wordmark alone, 60×8 |
|
|
52
|
+
| ~50 cols | a block-glyph MAGMACRUNCH, 48×2 |
|
|
53
|
+
| 36 cols | spaced capitals |
|
|
54
|
+
|
|
55
|
+
Art is measured rather than declared, so the 119-column piece can sit at the
|
|
56
|
+
top of the list without ever bothering someone on an ordinary terminal — it
|
|
57
|
+
is simply never the one that fits. Adding your own is one entry in `VARIANTS`
|
|
58
|
+
in [`banner.py`](magmacrunch/banner.py) and nothing else.
|
|
59
|
+
|
|
60
|
+
Choosing a cabinet starts it on the terminal the arcade is already holding.
|
|
61
|
+
Leaving the game brings you back here. Every game is also its own command
|
|
62
|
+
(`george-boole`, `lava-dome`, `moonlight-drift`) and plays identically either way — the arcade is
|
|
63
|
+
not a wrapper around them, it is the same host they run on.
|
|
64
|
+
|
|
65
|
+
## What is installed
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
magmacrunch --list
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Prints every cabinet found, what terminal size it wants, and how it wants
|
|
72
|
+
input. If a game you installed is not in the menu, this says why — a game that
|
|
73
|
+
fails to load is reported rather than silently skipped.
|
|
74
|
+
|
|
75
|
+
## How games get here
|
|
76
|
+
|
|
77
|
+
Games are **not** bundled. Each one lives in its own repo alongside its browser
|
|
78
|
+
and Wii versions, publishes its own wheel, and declares an entry point:
|
|
79
|
+
|
|
80
|
+
```toml
|
|
81
|
+
[project.entry-points."magmacrunch.games"]
|
|
82
|
+
george-boole = "boole.arcade:GAME"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
pointing at an object with `info: GameInfo` and `start(host) -> scene`. The
|
|
86
|
+
launcher enumerates that group at startup. **Installing a game makes it appear
|
|
87
|
+
here; uninstalling makes it vanish; neither needs a release of the arcade.**
|
|
88
|
+
|
|
89
|
+
Nothing in this package imports a game, so the arcade runs with none installed
|
|
90
|
+
and tells you how to get one. The contract lives in
|
|
91
|
+
[`texastoast.arcade`](https://pypi.org/project/texastoast/); the two cabinets
|
|
92
|
+
above are worked examples of it.
|
|
93
|
+
|
|
94
|
+
## Cabinets
|
|
95
|
+
|
|
96
|
+
| | |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `magmacrunch-george-boole` | 2048 played with logic gates |
|
|
99
|
+
| `magmacrunch-thld` | Solo hold'em against a climbing threshold |
|
|
100
|
+
| `magmacrunch-moonlight-drift` | Thread the columns; hold to climb |
|
|
101
|
+
|
|
102
|
+
Installing `magmacrunch` installs all three.
|
|
103
|
+
|
|
104
|
+
## Requires
|
|
105
|
+
|
|
106
|
+
Python 3.10+, and a terminal at least 36×17. Individual cabinets ask for more
|
|
107
|
+
(around 59×22); below that their card greys out, says the size it wants, and
|
|
108
|
+
cannot be started. The arcade's own floor is deliberately lower than any
|
|
109
|
+
game's, so getting to the floor is never the thing that fails.
|
|
110
|
+
|
|
111
|
+
Two cards sit side by side from 70 columns and stack into one below that. More
|
|
112
|
+
cabinets than fit are paged, not scrolled.
|
|
113
|
+
|
|
114
|
+
Truecolor helps but is not required.
|
|
115
|
+
|
|
116
|
+
## Licence
|
|
117
|
+
|
|
118
|
+
PolyForm Noncommercial 1.0.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
119
|
+
Noncommercial because the games it seats are. The engine underneath,
|
|
120
|
+
[texastoast](https://pypi.org/project/texastoast/), stays Apache-2.0.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""The magmacrunch terminal arcade.
|
|
2
|
+
|
|
3
|
+
A menu of every installed cabinet, and the wiring that seats one on the
|
|
4
|
+
terminal it is already holding.
|
|
5
|
+
|
|
6
|
+
Games are found by enumerating the ``magmacrunch.games`` entry point group -
|
|
7
|
+
see :mod:`texastoast.arcade` for the contract. **Nothing in this package
|
|
8
|
+
imports a game.** Installing one makes it appear here; uninstalling makes it
|
|
9
|
+
vanish; neither needs a release of the arcade.
|
|
10
|
+
|
|
11
|
+
Imports are kept out of this module so that ``import magmacrunch`` costs
|
|
12
|
+
nothing: the launcher's own screens pull in the engine's terminal backend, and
|
|
13
|
+
``magmacrunch --help`` should not pay for it.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
19
|
+
|
|
20
|
+
__all__ = ["__version__"]
|