Files
silent-fh/Documentation.md
T
2026-06-16 21:16:12 +02:00

16 KiB

Silent FH - Projektdokumentation

   SSSSS  III  L      EEEEE  N   N  TTTTT      FFFFF  H   H
   S       I   L      E      NN  N    T        F      H   H
   SSSSS   I   L      EEEE   N N N    T        FFFF   HHHHH
       S   I   L      E      N  NN    T        F      H   H
   SSSSS  III  LLLLL  EEEEE  N   N    T        F      H   H

Study. Survive. Submit your ECTS.

Inhaltsverzeichnis

Projektübersicht

Silent FH ist ein 2D Survival-Spiel, in dem eine Studentin oder ein Student über Nacht in der FH Joanneum eingeschlossen ist. Während der Nacht verwandeln sich Professoren in Monster und greifen die Räume an. Ziel ist es, möglichst lange zu überleben, ECTS zu sammeln und am Ende einen hohen Score im Leaderboard zu erreichen. Das Spiel wurde mit der Python Bibliothek PyGame geschrieben und es wurde der Package Manager "uv" benutzt.

Der Einstieg erfolgt über main.py. Die zentrale Spielsteuerung liegt in src/game.py. Von dort werden Startscreen, Endscreen, Karte, Player, Monster, Items, Shop, Tower, Sound, HUD und Highscore-System koordiniert.

Gruppenmitglieder

Die Namen und Rollen wurden aus der bestehenden README.md übernommen.

  • Baumgartner Kevin

    • UI
    • Startscreen
    • Endscreen
    • Highscore Display
  • Berger Lena

    • Sound Effects
    • HUD
    • ECTS-System
    • Türen
    • Items: Beer und Coffee
  • Kammerhofer Lukas

    • Tower
    • Map
    • Game Design
  • Haiden Niklas

    • Merge Requests
    • Sprites
    • Zombies / Monster
    • Game Loop Logic, Zusammenführen des Spiels
    • Dokumentation

Repository und Installation

Das Projekt liegt im Git-Repository:

  • Repository: git@git-iit.fh-joanneum.at:swd25-bootcamp/silent-fh.git
  • Branch-Konzept: Feature-Branches nach dem Muster feat/feature-name
  • Code-Review: Pull Requests mit Merge-Prozess
  • Commit-Stil: semantische Commits, z. B. feat(...), fix(...), docs(...), chore(...)

Installation und Start:

uv sync
source .venv/bin/activate
uv run main.py

Die Abhängigkeiten stehen in pyproject.toml, welches die Convention für den "uv" Package Manager ist.

Corporate Identity

Silent FH nutzt eine dunkle, leicht unheimliche FH-Nacht-Atmosphäre. Bilder und Audio sind KI generiert.

Farbwelt

Die Farben orientieren sich an den Konstanten in src/settings.py.

Einsatz Farbe RGB Wirkung
Hintergrund / Void #0A0A0F (10, 10, 15) dunkle Nacht, Gefahr
Wände #1E1428 (30, 20, 40) FH-Gebäude, Begrenzung
Räume #4B2837 (75, 40, 55) Seminar- und Lernräume
Gang #23412D (35, 65, 45) Fluchtweg, Orientierung
Türen #285A6E (40, 90, 110) Übergang zwischen Raum und Gang
Startscreen-Akzent #00FF00 (0, 255, 0) Retro-Game-UI
Warnung / Lose #FF0000 (255, 0, 0) Gefahr und Scheitern

Tonalität

  • Atmosphäre: dunkel, campusnah, leicht ironisch
  • Sprache: FH- und Studienbegriffe wie Matriculate, Exmatriculate, ECTS, Study, Coffee
  • UI-Stil: klare Buttons, Highscore-Tabelle, HUD mit Statusleisten
  • Game-Fantasy: Lernen bringt Ressourcen, Kaffee rettet die Tür, Bier steigert die ECTS-Produktion

Kurzbeschreibung

Der Spieler startet am Startscreen, gibt einen Namen oder eine ID ein und beginnt danach eine Survival-Runde. Die Spielfigur bewegt sich mit WASD oder den Pfeiltasten durch eine tilebasierte FH-Karte. Die Karte besteht aus Räumen, Gängen, Wänden, Startposition und Türen. In jedem Raum steht ein Tisch.

Sobald der Spieler an einem Tisch lernt, werden ECTS generiert. Gleichzeitig kann dadurch ein Raum-Encounter aktiviert werden: Die Tür schließt sich, Monster werden wach und bewegen sich im Gang zur passenden Raumtür. Die Monster greifen die geschlossene Tür in Intervallen an. Fällt die Tür-HP auf 0, ist das Spiel verloren und der Endscreen wird angezeigt.

Der Spieler kann länger überleben, indem er Items kauft und Ressourcen sinnvoll verwendet. Coffee heilt die aktive Tür, Beer erhöht die ECTS-Generierung. Nach ausreichend langer Tisch-Interaktion kann ein Tower entstehen, der Projektile auf das Monster schießt und es beschädigt.

Features und technische Lösungen

Steuerung und Screens

  • WASD oder Pfeiltasten: Spielfigur bewegen
  • E: Item kaufen, wenn der Spieler ein Item berührt und genug ECTS besitzt
  • Space: Spielerzustand umschalten und Transformationssound abspielen
  • ESC oder Q: Spiel beenden
  • ENTER: Spiel starten oder neu starten

Der Startscreen in src/startscreen.py bietet Namenseingabe, Startbutton, Quitbutton, Validierung und Highscore-Anzeige. Der Endscreen in src/endscreen.py zeigt Ergebnis, gesammelte ECTS, überlebte Zeit, Restart-Option und Leaderboard.

Karte und Räume

Die Map in src/map.py wird als Liste von Strings modelliert. Jedes Zeichen steht für einen Tile-Typ:

  • W: Wall
  • R: Room
  • S: Start
  • H: Hall
  • D: Door

Diese Struktur ist einfach lesbar und gut für PyGame geeignet. Zusätzlich speichert die Map Raumrechtecke für Room 102, Room 103 und Room 105. Pro Raum wird automatisch ein Tisch in der Mitte erzeugt. Die Funktion is_accessible() legt fest, welche Tiles betreten werden dürfen.

Player, Sprites und Monster

Die Actor-Logik in src/actors.py kapselt Position, Blickrichtung, Animation, good-/bad-Status und Kollisions-Rollback. Sprite-Sets werden automatisch aus Asset-Ordnern geladen und müssen sprite_01.png bis sprite_12.png enthalten. Die Frames werden nach Bewegungsrichtungen gruppiert.

Die Monsterlogik in src/monster.py spawnt Monster auf Gang-Tiles (H). Wenn ein Raum getriggert wird, wechseln die Monster in den angry-Zustand, suchen das Gang-Tile vor der Tür und bewegen sich über eine Breadth-First Search dorthin. Türen (D) sind für Monster kein begehbarer Pfad. Dadurch bleiben sie logisch im Gang und greifen nur die Tür an.

Türen, ECTS, Items und Tower

src/door.py beschreibt Türen mit Position, Größe, HP, is_closed, take_damage(), reset() und rect-Property. Die Game-Logik erstellt Türen dynamisch passend zu den D-Tiles eines Raums.

Das ECTS-System in src/ects.py ist die zentrale Ressource. ECTS werden nur generiert, wenn der Spieler an einem Tisch steht. Beer erhöht die ECTS-Rate, Shop und Tower können ECTS abziehen. Dadurch entsteht ein Risiko-Nutzen-Verhältnis: Am Tisch verdient man Ressourcen, aktiviert aber auch Gefahr.

Items werden in src/item.py verwaltet, Käufe in src/shop.py. Items spawnen in Räumen, laufen nach einem Timer ab und werden gegen Blocker-Rechtecke geprüft. Coffee heilt die aktive Tür um 20 HP, Beer erhöht die ECTS-Generierung um 2. Erfolgreiche und fehlgeschlagene Käufe haben Soundfeedback.

Der Tower in src/tower.py ist eine Verteidigungsmechanik:

  • Spawnkosten: 10 ECTS
  • Aktivierung nach 5000 ms Tischkontakt
  • Lebensdauer: 30000 ms
  • Projektilschaden: 2
  • Schussintervall: 1000 ms

Der Tower erscheint nur einmal pro Raum-Encounter, schießt auf das Monster und wird beim Raumwechsel zurückgesetzt.

HUD, Highscore und Sound

Das HUD in src/hud.py zeigt Spielername, Door HP, Zombie HP, ECTS, ECTS pro Sekunde und Überlebenszeit. Der Highscore in src/highscore.py speichert Ergebnisse in src/highscore.json. Sortiert wird nach gewonnenen Runs, höheren ECTS, längerer Überlebenszeit und Name als Tie-Breaker.

src/sounds.py kapselt Soundeffekte und Hintergrundmusik. Geladen werden u. a. Tower-Schuss, Monster-Hit, Kauf erfolgreich, Kauf fehlgeschlagen, Transformation sowie normale und gruselige Hintergrundmusik. Falls eine Sound-Datei fehlt, stürzt das Spiel nicht ab.

Architektur

Die zentrale Game Loop in src/game.py arbeitet mit den Zuständen startscreen, game und endscreen. Dadurch bleiben Menü, Gameplay und Ergebnisanzeige getrennt. Mehrere Systeme nutzen pygame.Rect für Kollisionen und Blocker-Listen. Zeitabhängige Ereignisse basieren auf pygame.time.get_ticks(), z. B. ECTS-Generierung, Item-Spawns, Monster-Angriffe, Tower-Aktivierung, Tower-Lebensdauer und Überlebenszeit.

Dokumentiertes Bugfixing

Die Bugfixes wurden aus Code und Git-Historie abgeleitet.

Commit Problem Lösung
dd1773e fix: fix buying logic for shop Die Shop-Logik gab bei ausreichendem ECTS-Guthaben fälschlich False zurück. Die Bedingung wurde auf if not self.ects.is_over_balance(cost): return False geändert. Danach wird der Betrag abgezogen und True zurückgegeben.
a218527 fix: readd missing file src/ects.py fehlte, wodurch Imports des ECTS-Systems brechen konnten. Die Datei mit ECTS-Kontostand, Rate, Timer und upgrade_rate() wurde wieder hinzugefügt.
810a44c fix: import error und ba0bb49 feat: fix endscreen imports Imports wie from settings import ... passten nicht zur Projektstruktur. Die Imports wurden auf from src.settings import ... und from src.button import Button geändert.
8c454ed feat(startscreen): change ui texts from german to english and fix button click event Button-Klicks und leere Namenseingaben waren nicht sauber behandelt. Der Button setzt nun einen internen clicked-Status, und der Startscreen validiert leere Namen.
ac1085f bugfixes/troubleshooting und 164e314 bugfixing Im Tower gab es falsche Attributnamen wie self.field.rect, einen falschen Methodennamen und eine falsch eingerückte clear()-Methode. Die Attribute wurden auf field_rect und tower_rect korrigiert, field_spawn() wird richtig aufgerufen, clear() ist wieder eine Instanzmethode.
80f6868 bugfix Beim Fehlerladen des Projektilsprites wurde versehentlich tower_image statt projectile_image auf None gesetzt. Nur projectile_image wird zurückgesetzt, der Tower-Sprite bleibt erhalten.
6fbd750 feat(endscreen): fix position of highscore table in endscreen Die Highscore-Tabelle überlagerte Inhalte am Endscreen. Die Position wurde von (560, 90) auf (800, 300) verschoben.
5149623 fix highscore implementation and decrease projectile damage Highscore-Speicherung und Sortierung waren nicht robust genug. Scores werden beim Endscreen gespeichert, JSON-Daten geprüft, Zeiten formatiert und Werte über safe_int() / parse_time() abgesichert.
3fcbd8c refactor: replace static door dimensions with dynamic sizing and add rect property Statische Türgrößen waren unflexibel. Türen werden aus den D-Tiles berechnet und stellen eine rect-Property bereit.
4faad9d feat: implement encounter reset mechanics for rooms and doors Beim Raumwechsel konnten alte Monster-, Tür- oder Tower-Zustände weiterlaufen. handle_room_change() setzt Items, Tower, Tür und Monsterzustand zurück.
bce77b8, d2b42c5, d6bdf22 Der Tower musste technisch und spielerisch ausbalanciert werden. Aktivierungszeit, Lebensdauer, Ablaufverhalten und Projektilschaden wurden angepasst.

Problembeschreibung und Learnings

Silent FH besteht aus vielen voneinander abhängigen Systemen. Wenn der Spieler am Tisch steht, laufen gleichzeitig ECTS-Generierung, Monster-Encounter-Logik, Tower-Timer, Monsterbewegung und HUD-Updates. Die wichtigste technische Lösung ist deshalb eine zentrale Orchestrierung in src/game.py, während die Einzelsysteme in eigenen Klassen bleiben.

Eine vollständige Monster-KI wäre für den Projektumfang zu groß gewesen. Stattdessen nutzt das Spiel den BFS Algorithmus um den kürzesten Pfad zum Spieler zu finden. Spawnlogik wurde so gelöst: Items, Monster und Tower prüfen Blocker-Rechtecke, damit sie nicht auf Tischen, Türen oder anderen Objekten erscheinen.

Balancing hatte mehrere Iterationen erfordert. Viele Werte in src/settings.py steuern Gameplay: Monster-HP, Tür-HP, Tower-Schaden, ECTS-Rate, Itemkosten, Spawnintervalle und Angriffsgeschwindigkeit. Die Git Historie zeigt, dass die Werte im Laufe der Entwicklung immer wieder angepasst werden mussten, um das Spiel fair und enjoyable zu machen.

Externe Referenzen

Assets im Projekt

  • assets/niklas_sprites: Player-Sprites
  • assets/normal_knoll, assets/angry_knoll: Monster-Sprites
  • assets/normal_krainz, assets/angry_krainz: Monster-Sprites
  • assets/normal_schwab, assets/angry_schwab: Monster-Spritepaar
  • assets/items: Beer, Coffee, Tower, Book
  • assets/furniture: Tischgrafik-Sprites
  • assets/sounds: Soundeffekte und Hintergrundmusik

Für die korrekte Ausformulierung und Überarbeitung wurde KI (ChatGPT 5.5) verwendet.