Skip to content

MBurchard/project-daystrom

Repository files navigation

Project Daystrom

Crafted with Rust Crafted with TypeScript License: GPL v3 CI

An assistant app and extended mod for Star Trek Fleet Command, built on top of the STFC Community Mod by netniV and contributors.

Acknowledgements

This project would not exist without the work of netniV, tashcan, and the entire STFC Community Mod team. The mod code in stfc-mod/ is imported from netniV/stfc-mod and kept as close to upstream as practical, so that improvements can be shared with the community.

What is this?

Project Daystrom picks up where the Community Mod leaves off. The mod already provides essential quality-of-life improvements — hotkeys, UI tweaks, zoom presets, data sync, and more. Project Daystrom builds on that foundation and adds:

  • A native app (Tauri 2 + Vue 3) that runs alongside the game on macOS and Windows
  • A cross-platform launcher replacing the platform-specific launchers (Swift on macOS, proxy DLL on Windows) with a single unified solution that handles entitlement patching, mod injection, and game launch
  • Game update detection via the Scopely update API, with in-app update prompts
  • Process monitoring that automatically detects game and launcher activity
  • System tray integration with minimize-to-tray and quit protection
  • Dashboard, alerts, and advisor plugins (planned) for live fleet overview, event notifications, and upgrade recommendations

The mod code lives in stfc-mod/ and is kept in sync with the upstream Community Mod. Improvements and bug fixes flow both ways — anything useful to the broader community gets contributed back.

Built with

Project Structure

project-daystrom/
├── package.json            # Workspace root (orchestrating scripts)
├── pnpm-workspace.yaml     # Workspace config (members: app, scripts)
├── eslint.config.js        # Shared ESLint config (lints entire project)
├── tsconfig.base.json      # Shared TypeScript base config
├── scripts/                # Build and tooling scripts
│   ├── build.ts            #   Mod + app build orchestration
│   └── package.json        #   Script dependencies
├── stfc-mod/               # STFC Community Mod (from netniV/stfc-mod)
│   ├── mods/               #   Mod patches (C++23, IL2CPP hooks)
│   ├── macos-launcher/     #   Original Swift launcher (being replaced)
│   ├── macos-dylib/        #   macOS injection helper
│   ├── win-proxy-dll/      #   Windows proxy DLL loader
│   └── xmake.lua           #   Build configuration
├── app/                    # Project Daystrom app (Tauri 2 + Vue 3)
│   ├── modules/
│   │   ├── app/            #   Vue 3 frontend
│   │   ├── backend/        #   Tauri/Rust backend
│   │   └── plugins/        #   Feature plugins (dashboard, alerts, advisor)
│   ├── resources/          #   Shared assets (logo, icons)
│   └── package.json        #   App dependencies + app-local scripts
└── README.md

Prerequisites

  • Node.js >= 24
  • pnpm >= 10
  • Rust (stable)
  • XMake (for building the mod)
  • CMake (required by xmake to build C++ dependencies like spud)

macOS

  • Apple Silicon — local development assumes arm64; the CI handles universal builds
  • Xcode Command Line Tools (xcode-select --install)

Windows

  • Visual Studio Build Tools 2022 (or VS Community) — workload "Desktop development with C++" including a Windows SDK (not installed by default!)
  • xmake: irm https://xmake.io/psget.text | iex in PowerShell
  • Rust: standard installation via rustup-init.exe (option 1 selects MSVC toolchain)

Setup

nvm use
pnpm install

All commands run from the workspace root unless noted otherwise.

Building the mod

The mod code lives in stfc-mod/ and produces a shared library that gets injected into the game (libstfc-community-patch.dylib on macOS, stfc-community-patch.dll on Windows).

pnpm build:mod

This configures xmake for the current platform, builds only the mod target (stfc-community-patch), and copies the result to app/resources/mod/. The full xmake build would also try to build the original Swift launcher, which we don't need — Project Daystrom replaces it.

Scripts

Workspace root (run from the project root)

Script Description
pnpm install:all Force-install all workspace dependencies
pnpm lint Run ESLint across the entire project
pnpm lint:fix Run ESLint with auto-fix
pnpm typecheck TypeScript + Rust type checks
pnpm test Run all tests (frontend + backend)
pnpm test:app Run all app tests (frontend + backend)
pnpm test:app:frontend Run frontend tests only (vitest)
pnpm test:app:backend Run backend tests only (cargo test + ts-rs bindings)
pnpm test:app:frontend:watch Run frontend tests in watch mode
pnpm test:app:frontend:coverage Run frontend tests with v8 coverage
pnpm test:app:backend:coverage Run backend tests with llvm-cov coverage
pnpm build Build everything (mod dylib → Tauri app)
pnpm build:mod Build mod dylib and copy to app/resources/mod/
pnpm build:app Build mod dylib + Tauri app bundle
pnpm icons Generate Tauri icons from resources/daystrom.png
pnpm dev Build mod + start Tauri app with hot reload

Path Aliases

Alias Resolves to
@app/* modules/app/src/*
@generated/* modules/app/src/generated/*
@resources/* resources/*

Windows Code Signing (optional)

The GitHub workflow supports optional code signing for the NSIS installer. It requires a self-signed code signing certificate and two repository secrets.

Create a self-signed certificate

New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=Your Name, Code Signing" `
  -CertStoreLocation Cert:\CurrentUser\My -NotAfter (Get-Date).AddYears(5)

Export as PFX

The thumbprint is shown when creating the certificate. You can also find it via:

Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
$cert = Get-ChildItem Cert:\CurrentUser\My\<thumbprint>
$pw = Read-Host -AsSecureString "PFX password"
Export-PfxCertificate -Cert $cert -FilePath daystrom.pfx -Password $pw

Verify the PFX

certutil -dump daystrom.pfx

Configure GitHub Secrets

Encode the PFX as Base64 and copy to the clipboard.
Note that PowerShell resolves relative paths from the user's home directory, not from the current working directory.
Use an absolute path to avoid surprises.\

[Convert]::ToBase64String([IO.File]::ReadAllBytes("<path-to-pfx>")) | Set-Clipboard

Then set these repository secrets in GitHub:

Secret Value
WINDOWS_PFX_BASE64 Base64-encoded PFX (clipboard)
WINDOWS_PFX_PASSWORD The password from the export

App (Tauri + Vue 3 + Vite)

Type generation (ts-rs)

Shared types between Rust backend and TypeScript frontend are auto-generated by ts-rs. Rust structs annotated with #[derive(TS)] produce TypeScript interfaces in app/modules/app/src/generated/ whenever pnpm test:app:backend runs. Rust doc comments are carried over as JSDoc.

#[derive(Serialize, TS)]
#[ts(export)]
pub struct GameStatus { /* ... */ }
import type {GameStatus} from '@generated/GameStatus';

Plugins live in modules/plugins/ and are loaded by the main app. The architecture is intentionally modular so that individual plugins can be developed and published independently.

Environment Variables

Variable Default Description
DAYSTROM_DEVTOOLS 1 Set to 0 to suppress DevTools in debug builds

License

This project is licensed under the GNU General Public License v3.0.

About

Assistant app and extended mod for Star Trek Fleet Command, built on the STFC Community Mod

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors