npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rithien/factorio-translate

v0.5.1

Published

Plugin Clusterio: ADAPTYWNE tłumaczenie czatu Factorio na języki połączonych graczy. Scenariusz emituje tag [FP-TRANSLATE] (zbiór locale graczy); plugin tłumaczy równolegle na każdy obecny język (LibreTranslate lub Google) i odsyła /fpo {speaker,original,

Downloads

689

Readme

@rithien/factorio-translate — adaptywny tłumacz czatu Factorio

Plugin Clusterio: adaptywnie tłumaczy czat na języki aktualnie połączonych graczy przez wybrany backend — LibreTranslate albo Google Cloud Translate (v2 Basic). Backend wybiera się jednym polem konfiguracji (translator_backend — dropdown w web panelu clusterio).

Model (scenario-only — wymaga scenariusza factorio-polska):

  1. Scenariusz hookuje on_console_chat, zbiera zbiór locale połączonych graczy i — gdy są ≥2 różne locale — emituje na stdout tag [FP-TRANSLATE]{speaker,text,locales}. Gdy wszyscy mają to samo locale, nic nie emituje („same locale → nie tłumaczymy" = zero kosztu API).
  2. Plugin czyta ten tag, wykrywa język źródła (/detect, confidence > min_confidence) i tłumaczy równolegle na każde obecne locale (≠ źródło) oraz na języki uniwersalnej linii czatu.
  3. Plugin odsyła JEDEN payload /fpo {speaker, original, t, chat}:
    • overhead — scenariusz renderuje nad głową każdego odbiorcy wariant t[jego locale] (fallback: oryginał), czyli każdy widzi wiadomość w swoim języku;
    • chat — jedna uniwersalna linia tłumaczenia na czacie dla wszystkich: segment per język z pola chat_languages (pl+en/pl/en), np. Banshee [pl] Cześć [en] Hello; segment języka == język źródła jest pomijany (oryginał i tak jest na czacie natywnie).

Fallback: brak detekcji / literówka / nazwa własna → nad głową leci oryginał; na czat zawsze oryginał.

Bez patchowania save'a — brak folderu module/, działa niezależnie od factorio.enable_save_patching. Komenda wyjścia /fpo to custom command (jak /fp) → w przeciwieństwie do /c//sc nie wyłącza achievementów.

Wymaga scenariusza factorio-polska z lib/translate_chat_emit.lua + kontraktem /fpo {speaker,original,t,chat} (wersja wprowadzająca adaptive). Plugin i scenariusz deployują się RAZEM — kontrakt /fpo zmienił się względem starego {pl,en}. Bez kompatybilnego scenariusza tłumaczenia nie pojawią się w grze (plugin nie ubije serwera — sytuacja jest logowana).

Opis kanałów komunikacji z grą: Plugin_comunication.md. Wytyczne implementacyjne: CLAUDE.md.

Struktura

factorio-translate/
├── index.js                 # eksport `plugin` (nazwa, entrypointy, instanceConfigFields)
├── instance.js              # InstancePlugin: onOutput ([FP-TRANSLATE]) -> detect + równoległe translate
│                            #   -> sendRcon(/fpo {speaker,original,t,chat}); factorioToCanonical, planTranslation
├── outputs/                 # warstwa wyjścia (scenario-only)
│   ├── index.js             #   re-eksport { buildFpoCommand, sanitizeText }
│   ├── scenario.js          #   buildFpoCommand(...) — /fpo <json>
│   └── util.js              #   sanitizeText(text, max)
├── translators/             # warstwa backendów (wspólny kontrakt: configured / detect / translate)
│   ├── index.js             #   createTranslator(opts) — fabryka wybierająca backend wg translator_backend
│   ├── http.js              #   wspólny postJson() — fetch + timeout + normalizacja błędów (nie loguje klucza)
│   ├── libretranslate.js    #   klient LibreTranslate (detect kanonizuje kod języka)
│   └── google.js            #   klient Google Cloud Translation v2 Basic (kanon → kod Google, np. zh→zh-CN)
├── controller.js            # ControllerPlugin — stub (na razie nic istotnego)
├── package.json             # Node >= 18 (globalny fetch)
├── test/plugin.js           # mocha
├── Plugin_comunication.md   # dokumentacja kanałów komunikacji z grą
├── CLAUDE.md                # wytyczne implementacyjne
└── (CELOWO brak module/)    # save NIE jest patchowany

Instalacja

Wymagania wstępne

  • Działający klaster Clusterio 2.x (kontroler + co najmniej jeden host z instancją Factorio).
  • Node.js ≥ 18 (plugin używa globalnego fetch).
  • Scenariusz factorio-polska z lib/translate_chat_emit.lua i kontraktem /fpo {speaker,original,t,chat} na danej instancji.
  • Dostęp do jednego z backendów tłumaczeń:
    • LibreTranslate — własna instancja albo publiczna/płatna z kluczem, lub
    • Google Cloud Translate — projekt Google Cloud z włączonym Cloud Translation API i kluczem API.
  • Plugin nie wymaga factorio.enable_save_patching — działa niezależnie od tej opcji.

1. Zainstaluj plugin z npm

W katalogu instalacji Clusterio (ten z node_modules/@clusterio/..., config-controller.json itd.):

npm install @rithien/factorio-translate

2. Zarejestruj plugin w każdym komponencie

npx clusteriocontroller plugin add @rithien/factorio-translate
npx clusteriohost       plugin add @rithien/factorio-translate
npx clusterioctl        plugin add @rithien/factorio-translate

3. Zrestartuj kontroler i hosta

Zatrzymaj i uruchom ponownie procesy kontrolera oraz hosta, żeby załadowały plugin. Plugin „wejdzie" do działającej instancji dopiero przy jej restarcie (krok 5).

4. Skonfiguruj instancję

Wybierz backend polem factorio-translate.translator_backend (libretranslate — domyślny — albo google) i uzupełnij pola odpowiednie dla wybranego backendu.

Backend LibreTranslate (minimum to translator_api_url):

npx clusterioctl instance config set <instancja> factorio-translate.translator_backend libretranslate
npx clusterioctl instance config set <instancja> factorio-translate.translator_api_url https://libretranslate.example
# jeśli Twoja instancja LibreTranslate wymaga klucza:
npx clusterioctl instance config set <instancja> factorio-translate.translator_api_key <klucz>

Backend Google Cloud Translate (minimum to google_api_key):

npx clusterioctl instance config set <instancja> factorio-translate.translator_backend google
npx clusterioctl instance config set <instancja> factorio-translate.google_api_key <klucz-google-cloud>

Języki uniwersalnej linii czatu (pl+en = segmenty [pl] i [en] w jednej linii, albo tylko pl / tylko en):

npx clusterioctl instance config set <instancja> factorio-translate.chat_languages pl+en

Zmiany backendu / URL / kluczy / timeoutu są podchwytywane na żywo (bez restartu instancji).

5. Uruchom (lub zrestartuj) instancję ze scenariuszem factorio-polska

npx clusterioctl instance start <instancja>

Aktualizacja / odinstalowanie

  • Aktualizacja: npm install @rithien/factorio-translate@latest, restart kontrolera i hosta, restart instancji. Deployuj razem z kompatybilnym scenariuszem (kontrakt /fpo).
  • Odinstalowanie: plugin remove @rithien/factorio-translate w każdym komponencie, restart kontrolera i hosta.

Konfiguracja (instancja, prefiks factorio-translate.)

| Pole | Typ | Domyślnie | Opis | |---|---|---|---| | enabled | boolean | true | Master kosztowy: gdy ON plugin woła płatne API. Wyłącz, by zatrzymać koszty | | chat_languages | enum | pl+en | Języki JEDNEJ uniwersalnej linii na czacie (pl+en/pl/en); segment == język źródła pomijany. Niezależne od overheadu (per-widz) | | translator_backend | enum | libretranslate | Backend tłumaczeń: libretranslate lub google (dropdown) | | translator_api_url | string | "" | [libretranslate] Bazowy URL, bez końcowego /. Puste = backend nieaktywny | | translator_api_key | string | "" | [libretranslate] Klucz API; puste = bez klucza. Nie jest logowany | | google_api_key | string | "" | [google] Klucz Google Cloud (Cloud Translation API). Puste = nieaktywny. Nie jest logowany | | min_confidence | number | 90 | Próg confidence z /detect (0–100); tłumaczymy gdy > min_confidence. Google: 0–1 → ×100, brak → 100 | | request_timeout_ms | number | 5000 | Timeout pojedynczego żądania HTTP | | min_message_length | number | 1 | Minimalna długość wiadomości, by ją tłumaczyć | | max_output_length | number | 500 | Sanity-cap na długość każdego pola tekstowego payloadu /fpo (anti-flood + RCON line) |

Zmiana translator_backend / translator_api_url / translator_api_key / google_api_key / request_timeout_ms jest podchwytywana na żywo (bez restartu instancji).

Jak to działa (przepływ jednej wiadomości)

  1. Scenariusz (on_console_chat) emituje [FP-TRANSLATE]{speaker,text,locales} — tylko gdy ≥2 różne locale wśród połączonych graczy.
  2. Plugin onOutput matchuje tag i parsuje JSON.
  3. POST /detect → kanoniczny kod języka źródła; confidence <= min_confidence → forward samego oryginału.
  4. Cele = (kanoniczne locale obecnych ≠ źródło) ∪ (chat_languages \ {źródło}). Tłumaczenie celów równolegle (POST /translate, z cache).
  5. sendRcon('/fpo ' + JSON({speaker, original, t, chat}), true) — jeden payload na wiadomość.
  6. Scenariusz: nad głową każdego odbiorcy t[jego locale] (fallback oryginał) i/lub uniwersalna linia chat na czacie (togglowane w admin-panelu: translate_overhead / translate_chat).

Błąd backendu (sieć, timeout, 4xx/5xx) → log warn, dane locale lecą bez tego tłumaczenia (fallback oryginał); serwer nieruszony. Mapowanie kodów: Factorio zh-CN→kanon zh w pluginie; mapa t pozostaje kluczowana surowym locale (scenariusz robi t[p.locale]); specyfikę backendu (Google chce zh-CN) obsługują translators/*.js.

Dlaczego /fpo (custom command)

Wbudowane /sc (silent-command) i /c ustawiają trwałą flagę "Cheats have been enabled" na save'ie — permanentnie wyłączają achievementy. Custom commandy zarejestrowane przez commands.add_command w Lua nie liczą się jako cheats. Scenariusz factorio-polska rejestruje /fpo (server-only, RCON-only) jako parser JSON-payloadu (scenario/commands/fpo.lua). Plugin wysyła /fpo <json> i treść trafia do gry bez setowania cheat flagi.

Uwagi

  • Plugin nie kasuje oryginalnej wiadomości — oryginał jest na czacie natywnie; plugin dokłada overhead per-widz + jedną uniwersalną linię tłumaczenia.
  • Kolejność wysłanych tłumaczeń między wiadomościami może odbiegać od kolejności wpisania (różna latencja API). W obrębie jednej wiadomości payload jest atomowy (jeden /fpo).
  • LibreTranslate: dla sensownego limitu zapytań użyj własnej instancji albo płatnego klucza — publiczne instancje bywają mocno rate-limitowane (HTTP 429 → dane tłumaczenie pominięte).
  • Google Cloud Translate: API v2 (Basic), uwierzytelnianie kluczem API (?key=), nie v3. Cloud Translation to usługa płatna — pilnuj limitów/budżetu. Klucz najlepiej ogranicz do Cloud Translation API.

Testy

npm install
npm test