feat(homepage): add mod manager section and related content

- Introduced new strings for the mod manager feature in the English localization file.
- Updated the homepage to include a dedicated section for the GregModManager, featuring a description, download link, and hints for the latest release.
- Adjusted button styles for better consistency and user experience.

This commit enhances the homepage by providing users with direct access to the mod manager and its functionalities.
This commit is contained in:
Marvin
2026-04-10 03:26:13 +02:00
parent 3b245ee966
commit 8ad5acafda
7 changed files with 142 additions and 25 deletions

View File

@@ -0,0 +1,41 @@
---
title: Greg hooks showcase (sample mod)
sidebar_label: Greg hooks showcase
description: How to subscribe to greg.* hooks via GregShowcaseMod and gregFramework.Core APIs.
---
# Greg hooks showcase
The repository includes **GregShowcaseMod** (`mods/GregShowcaseMod/` in **gregFramework**): a minimal MelonLoader mod that logs one representative event per **GregDomain**, using only public APIs:
- `GregEventDispatcher.On` / `UnregisterAll`
- `GregHookName.Create(GregDomain.*, "Action")`
- `GregPayload.Get` / `GregPayload.Dump` for anonymous payloads
## Canonical hook strings
Runtime hook names look like `greg.<DOMAIN>.<Action>`, e.g. `greg.PLAYER.MoneyChanged`. Build the string with `GregHookName.Create` — do not concatenate raw strings in mods.
## Registry file
`greg_hooks.json` (shipped beside `FrikaModdingFramework.dll`) is generated from `MergedCode.md` by:
```bash
pwsh gregCore/scripts/Generate-GregHooksFromMergedCode.ps1
```
Options are passed through to `parse_merged_code.py` (e.g. `--no-hot-loops` to omit `Update`/`FixedUpdate` from the catalog). The dump is large; regeneration can take several minutes.
## Sample subscriptions
See `mods/GregShowcaseMod/Handlers/*.cs` — each file registers one hook for its domain (except **POWER**, where `GregPowerHooks` is still empty until Il2Cpp types are classified).
## Configuration
Copy `mods/GregShowcaseMod/modconfig.example.json` to `{Game}/Mods/GregShowcaseMod/modconfig.json` to toggle per-domain logging.
## See also
- [Mod developers (hub)](./overview)
- [System architecture principles](/wiki/meta/system-architecture-principles)
- [Framework](/wiki/mods/framework) — runtime overview

View File

@@ -8,6 +8,7 @@ description: Getting started, mod config, debugging — curated docs for FMF mod
**Mod authors** — build your own mods (hooks, configuration, debugging). Role overview: [By audience](/wiki/guides/players/audiences-overview).
- [Greg hooks showcase](/wiki/guides/mod-developers/greg-hooks-showcase) — sample mod (`GregShowcaseMod`) and `GregPayload` usage
- [System architecture & documentation principles](/wiki/meta/system-architecture-principles) — layer model **ModManager → Framework → Plugins → Mods**, priorities, wiki rules
- [By audience — intermediates](/wiki/audiences/intermediates) and [professionals](/wiki/audiences/professionals)
- [Framework overview](/wiki/mods/framework) — runtime capabilities and repo layout

View File

@@ -4,16 +4,11 @@ sidebar_label: MCP server
description: Model Context Protocol server bundled with the docs Docker image for assistants and IDEs.
---
# MCP server (FrikaMF modding)
# MCP server (gregFramework / gregCore)
The **gregCore** repository ships a **Model Context Protocol (MCP)** server at **`gregCore/mcp-server/`** that exposes:
The **gregCore** repository ships a **Model Context Protocol (MCP)** server at **`gregCore/mcp-server/`**. It lets assistants **ground** answers in your repo: documentation, **`greg.*`** hook catalog (`greg_hooks.json`), optional legacy **`fmf_hooks.json`**, and **CONTRIBUTING**.
- **Docs search & read** — Markdown under `docs/` (same source as Docusaurus).
- **Hook registry** — `fmf_hooks.json` (and the same registry path in the monorepo).
- **CONTRIBUTING** — conventions and workflow.
- **Repo layout** — static overview and a **`fmf_modding_context`** prompt for quick context.
Use it when you want an assistant (Cursor, Claude Code, or any MCP client) to **ground answers** in this repo instead of guessing APIs.
Use it when you want an assistant (Cursor, Claude Code, or any MCP client) to **not guess** APIs or hook names.
## Docker (single container)
@@ -42,20 +37,27 @@ Binding to `0.0.0.0` exposes the MCP endpoint on your network. Use only on trust
## Local (stdio) for Cursor
Source: **`gregCore/mcp-server/`** (see **`README.md`** in that folder). Install dependencies with `npm install`, then run `node src/index.mjs --stdio --data-root <root>`, where `<root>` is a directory that contains **`docs/`**, **`CONTRIBUTING.md`**, and **`FrikaModFramework/fmf_hooks.json`** (or a flat `fmf_hooks.json`). The READMEs example uses `--data-root ..` relative to `mcp-server/`; in a **split-repo** workspace you may need a different `<root>` or `FMF_MCP_DATA_ROOT` so all three paths resolve.
Source: **`gregCore/mcp-server/`** (see **`README.md`** in that folder). Install dependencies with `npm install`, then run `node src/index.mjs --stdio --data-root <root>`, where `<root>` is usually **`gregCore/`** (parent of `mcp-server/`). That folder should contain **`docs/`**, **`CONTRIBUTING.md`**, and preferably **`framework/gregFramework/greg_hooks.json`** (canonical **greg.*** hook list). Legacy **`fmf_hooks.json`** (flat or under `FrikaModFramework/`) is still supported via **`fmf_hook_registry`**.
Point your MCP client at this command (stdio transport).
Set **`GREG_MCP_DATA_ROOT`** (or **`FMF_MCP_DATA_ROOT`**) if your layout differs. Point your MCP client at the stdio command.
## Tools (summary)
## Tools (what each one does)
| Tool | Purpose |
|------|--------|
| `fmf_search_docs` | Substring search across `docs/**/*.md` |
| `fmf_read_doc` | Read one file by path under `docs/` |
| `fmf_list_doc_paths` | Discover Markdown paths |
| `fmf_hook_registry` | Raw `fmf_hooks.json` |
| `fmf_read_contributing` | `CONTRIBUTING.md` |
| `fmf_repo_layout` | Short monorepo overview |
| Tool | What it returns | When to use it |
|------|------------------|----------------|
| **`fmf_search_docs`** | Paths under `docs/` + short snippets around the match | Find a topic before reading a whole page |
| **`fmf_read_doc`** | Full Markdown for one `docs/` path | You already know the file path |
| **`fmf_list_doc_paths`** | List of `.md` paths (capped) | Discover what docs exist |
| **`greg_hook_registry`** | Entire **`greg_hooks.json`** (can be large) | Need the full generated hook catalog |
| **`greg_hook_search`** | Filtered `hooks[]` entries matching a query | Find specific `greg.*` hooks without loading the whole JSON |
| **`greg_hook_stats`** | `version`, `stats`, `generationOptions`, etc. (no `hooks` array) | Quick sanity check after regenerating hooks |
| **`fmf_hook_registry`** | Legacy **`fmf_hooks.json`** if present | Older FMF/FFM declarative lists |
| **`fmf_read_contributing`** | `CONTRIBUTING.md` | Conventions and workflow |
| **`fmf_repo_layout`** | Static Markdown overview of `gregCore` layout | Orientation before deeper reads |
**Resources:** `greg://repo/overview` (alias `fmf://repo/overview`) — same text as `fmf_repo_layout`.
**Prompt:** `fmf_modding_context` — short starter text + optional `topic`; always pair with tools for authoritative content.
## Related

View File

@@ -58,7 +58,11 @@ const sidebars = {
{
type: 'category',
label: 'Tools & operations',
items: ['meta/Steam-Workshop-and-Tooling', 'meta/devserver-betas', 'meta/IDEA_BACKLOG'],
items: [
'meta/Steam-Workshop-and-Tooling',
'meta/devserver-betas',
'meta/IDEA_BACKLOG',
],
},
{
type: 'category',
@@ -77,7 +81,7 @@ const sidebars = {
{
type: 'category',
label: 'Mod developers',
items: ['guides/mod-developers/overview'],
items: ['guides/mod-developers/overview', 'guides/mod-developers/greg-hooks-showcase'],
},
{
type: 'category',

View File

@@ -9,6 +9,13 @@ export const en: HomepageContent = {
heroSub2: 'Technical reference for authors lives under Developers in the wiki.',
ctaStart: 'HELP FOR PLAYERS',
ctaMods: 'MOD CATALOG',
ctaModManager: 'DOWNLOAD MOD MANAGER',
modManagerSectionTitle: 'GregModManager',
modManagerSectionBody:
'The Gregtools desktop app for Workshop browsing, uploads, dependency checks, and project metadata. Builds are published on GitHub — use the button below to open the latest release (the URL always tracks the newest version).',
modManagerDownloadLabel: 'Download latest release',
modManagerLatestHint:
'Uses GitHubs /releases/latest redirect so you always land on the current release assets.',
docsPaths: 'Documentation paths',
featureTitles: ['Play with mods', 'Workshop & updates', 'Clear docs', 'Community'],
featureDescriptions: [

View File

@@ -16,6 +16,11 @@ export type HomepageContent = {
heroSub2: string;
ctaStart: string;
ctaMods: string;
ctaModManager: string;
modManagerSectionTitle: string;
modManagerSectionBody: string;
modManagerDownloadLabel: string;
modManagerLatestHint: string;
knowledgeSectionTitle: string;
workflowSectionTitle: string;
codeSectionTitle: string;

View File

@@ -5,7 +5,18 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import {motion, type Variants, useReducedMotion} from 'framer-motion';
import {getHomepageContent} from '../i18n/homepage';
import gregImage from '../image.png';
import {FaArrowUpRightFromSquare, FaDiscord, FaGithub, FaLifeRing, FaShop} from 'react-icons/fa6';
import {
FaArrowUpRightFromSquare,
FaDiscord,
FaDownload,
FaGithub,
FaLifeRing,
FaShop,
} from 'react-icons/fa6';
/** Always resolves to the newest GitHub release (redirect). */
const GREG_MODMANAGER_LATEST =
'https://github.com/mleem97/GregToolsModmanager/releases/latest';
const viewport = {once: true, margin: '-90px'};
@@ -130,7 +141,7 @@ export default function HomePage(): JSX.Element {
</motion.p>
<motion.div
className="flex flex-wrap items-center justify-center gap-4"
className="flex flex-wrap items-center justify-center gap-3 sm:gap-4"
initial="hidden"
whileInView="show"
viewport={viewport}
@@ -139,13 +150,22 @@ export default function HomePage(): JSX.Element {
>
<Link
to="/wiki/guides/players/overview"
className="btn-primary hero-glow rounded-lg px-10 py-4 text-lg"
className="btn-primary hero-glow rounded-lg px-8 py-4 text-lg md:px-10"
>
{t.ctaStart}
</Link>
<Link to="/mods" className="btn-outline rounded-lg px-10 py-4 text-lg">
<Link to="/mods" className="btn-outline rounded-lg px-8 py-4 text-lg md:px-10">
{t.ctaMods}
</Link>
<a
href={GREG_MODMANAGER_LATEST}
target="_blank"
rel="noopener noreferrer"
className="btn-outline inline-flex items-center justify-center gap-2 rounded-lg border-primary/35 px-8 py-4 text-lg text-on-surface hover:border-primary md:px-10"
>
<FaDownload className="text-lg" aria-hidden />
{t.ctaModManager}
</a>
</motion.div>
</section>
@@ -226,6 +246,43 @@ export default function HomePage(): JSX.Element {
</motion.div>
</motion.section>
<motion.section
id="greg-modmanager"
className="px-4 py-20"
initial="hidden"
whileInView="show"
viewport={viewport}
variants={variants.section}
>
<div className="relative mx-auto max-w-4xl overflow-hidden rounded-3xl border border-outline-variant/20 bg-gradient-to-br from-surface-container-high to-surface-container p-10 text-center md:p-14">
<div
className="absolute -right-16 -top-20 h-56 w-56 rounded-full bg-secondary/10 blur-[90px]"
aria-hidden
/>
<div className="relative z-10">
<span className="material-symbols-outlined mb-4 text-5xl text-primary" aria-hidden>
download_for_offline
</span>
<h2 className="mb-4 font-headline text-3xl font-bold text-on-surface md:text-4xl">
{t.modManagerSectionTitle}
</h2>
<p className="mx-auto mb-8 max-w-2xl text-lg leading-relaxed text-on-surface-variant">
{t.modManagerSectionBody}
</p>
<a
href={GREG_MODMANAGER_LATEST}
target="_blank"
rel="noopener noreferrer"
className="btn-primary hero-glow mb-4 inline-flex items-center gap-2 rounded-lg px-10 py-4 text-lg"
>
<FaDownload className="text-xl" aria-hidden />
{t.modManagerDownloadLabel}
</a>
<p className="text-sm text-on-surface-variant/90">{t.modManagerLatestHint}</p>
</div>
</div>
</motion.section>
<motion.section
id="code"
className="section-surface-alt px-4 py-24"