Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

13.06.2014, 11:14

Wie behalte ich den Überblick über mein Projekt?

Hallo zusammen,

seit einigen Wochen programmiere ich nun an einem neuen Projekt (ein 4X-Game mit komplexen Funktionsberechnungen bei minimaler Grafik). Das Projekt wächst derzeit um ca. 1000 Zeilen Quellcode pro Woche, es ist in C++ geschrieben und hauptsächlich objektorientiert gehalten. Derzeit greife ich ausschließlich allein auf den Quellcode zu. Ich rechne insgesamt mit einem Kern-Quellcode von ca. 50.000 Zeilen.
Mein Problem trotz aller Struktur: Langsam verliere ich den Überblick über das, was ich mache.

Meine Maßnahmen seit Beginn der Programmierung:
  • Unterteilung in mehrere Header- & Sourcefiles. Jedes File ist für eine einzelne Funktion zuständig. Auf Grund der Komplexität erreichen einzelne Files dennoch über 1.000 Zeilen Quellcode.
  • Effizienter Code, weitgehend ohne Wiederholungen (dank OOP)
  • Sprechende Bezeichnungen für alle Variablen, Objekte und deren Funktionen
  • Ausführliche Kommentare, sowohl im Datei-Header als auch bei der Objekt-Definition und einzelnen Funktionsschritten
  • Programmierung soweit wie möglich in Sinn-Abschnitten, also jede Szession konzentriert sich auf eine Funktion
  • TODO-Anweisungen für spätere Verfeinerungen in den Quellcode integriert
  • Variablen werden über externe XML-Files eingelesen
  • Die Konzeption ist unabhängig vom Quellcode (Roadmap, ToDo-Listen, Brainstorming, mathematische Entwürfe, Flussdiagramme & Schemata)
  • Nutzung der Auto-Vervollständigungs-Funktion und Suchfunktionen der IDE (hier: MSVS2010).
Gegenläufige Entwicklungen:
  • Ich habe eine sehr gute Vorstellung dessen, was das Programm einmal leisten soll. Die meisten Funktionen entstehen aus einer Top-Down-Überlegung. An manchen Punkten stelle ich aber fest, dass Änderungen notwendig sind, z.B. dass ich weitere Variablen oder differenzierte Sub-Funktionen brauche. Dadurch entstehen nachgelieferte Code-Bausteine.
Meine Fragen:
  • Welche Maßnahmen und Methoden würdet Ihr mir empfehlen, um so weit wie möglich den Überblick zu behalten?
  • Gibt es Tools für das Projekt-Management?
Vielen Dank für Euer Input!
- Corak

Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

13.06.2014, 12:24

Unterteilung in mehrere Header- & Sourcefiles. Jedes File ist für eine einzelne Funktion zuständig. Auf Grund der Komplexität erreichen einzelne Files dennoch über 1.000 Zeilen Quellcode.

Hohe Komplexität und viel Code auf einem Haufen deutet für mich darauf hin, dass es noch nicht gut genug unterteilt wurde.

Manchmal macht es Sinn Dinge auszulagern, ohne das man dies aus Gründen der Wiederverwendbarkeit bzw. Vermeidung von Wiederholungen macht. Einfach nur um ihnen einen Namen zu geben. Um in einer Funktion mit 100 Zeilen etwas anzupassen, muss man diese erstmal lesen und die richtige Stelle finden. Besteht die gleiche Funktion aber nun aus 5 Funktionsaufrufen (natürlich mit möglichst sprechendem Namen), erkennt man auf den ersten Blick was die Funktion tut und wo die Anpassung vermutlich nötig ist. Man darf das natürlich auch nicht übertreiben. Obwohl man mit heutigen IDEs problemlos Referenzen folgen kann und überall hin springen kann, ist irgendwann der Punkt gekommen, wo man dem geistig nicht mehr folgen kann.

3

13.06.2014, 14:26

Hallo,
Ich würde dir empfehlen das du bei solch einem großen Project alles mit notierst, damit meine ich das zu z.B Microsoft Word oder andere Editoren benutzt, und dir alles notierst was du machst was mit einnander verbunden
ist und was, was bedeutet.

Ich hoffe ich konnte dir mit mit diesen Tipp ein wenig helfen.

MFG
Sceiwen

4

13.06.2014, 14:50

  • Dokumentation
  • unabhängige "Units", sodass man an Teilen des Projekts arbeiten kann, ohne dass man unbedingt wissen muss, was der andere Teil alles konnte. So kann man einzelne Module in eigene Projekte auslagern und brauch sie über längere Zeit nicht anfassen. Außerdem springen dann gleich die Unit-Tests mit ein und erleichtern auch einiges.
  • Abstraktes Konzept
  • Ausführliche Task-Backlogs / Todo-Lists
  • Comments lieber minimal halten, dafür bessere Dokumentation schreiben, evtl. auch Doxygen oder ähnliches nutzen
  • Code nicht in zu viele Dateien auslagern (Aggressive splitting). Meiner Erfahrung nach muss es nicht unbedingt ein Vorteil sein, wenn alle Sourcefiles maximal 500 Zeilen lang sind o.ä.
  • VCS mit Branches (git / Mercury / TFS)

Im Großen und Ganzen sieht es mir bei dir eher nach Mängeln im Design aus - daran könntest du arbeiten und etwas refactorn :)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »iSmokiieZz« (13.06.2014, 14:57)


@zimmer

Alter Hase

Beiträge: 1 135

Wohnort: NRW Germany

  • Private Nachricht senden

5

13.06.2014, 15:14

Ich stimme Smoki zu, ich programmiere die Module auch einzeln und habe dann noch ein extra Project in dem ich dann alles zusammen setze. Wenn dann unerklärliche Fehler auftauchen , beschrenkt sich die Suche auf das Modul und dass testen geht schneller

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

13.06.2014, 15:22

Äh? Versionierung?

Git oder SVN -> google.

7

13.06.2014, 20:09

Hallo zusammen,

herzlichen Dank für Euer gesammeltes Feedback!

Zitat

Naja man muss aber auch der Tatsache ins Gesicht sehen, dass man bei großen Projekten iwann eben nicht mehr genau weiß, wie alles im Detail funktioniert.
Das werde ich einmal beherzigen. Ist irgendwie nicht vermeidbar, auch wenn ich gerne immer über alles die Kontrolle haben würde. :) Danke, LetsGo!

CMake, Packaging und Versionierung sind momentan (noch) nicht meine Probleme. Ich meinte eher den generellen Überblick über meine Programmteile. Die Idee der unabhängigen Units passt da gut, das Konzept wird übernommen.

Eine Dokumentation außerhalb des Quellcodes wüsste ich derzeit nicht, wie ich strukturieren soll - und vor allem mit dem Quellcode synchron zu halten (für den Fall, dass ich eine Funktion von X nach Y verschiebe). Doxygen habe ich schon einmal gehört (aber noch nicht damit gearbeitet). Ich werde dazu einmal recherchieren. Danke für den Hinweis.

Der Begriff "Backlog" ist mir neu. Der Anregung gehe ich ebenfalls gerne einmal nach. :)

@Smoki
Was meinst Du mit einem "abstakten Konzept"?


Allen ein schönes Wochenende!
- Corak

8

14.06.2014, 13:26

den Begriff backlog hab ich mir einfach mal aus scrum geliehen. Man kann das Prinzip meiner Meinung nach aber auch gut auf eigene Projekte anwenden ;)

Mit einem abstrakten Konzept meine ich, dass man so viele Details wie möglich weg lasst. Wie möglich bedeutet dabei, dass man gerade so noch weiß, was gemeint ist. Man sollte sich dann ein Feature herausnehmen können und die Details erarbeiten. Sprich Top-down entwicklung.
Das könnte dann in etwa so aussehen:

Quellcode

1
2
3
4
5
6
7
Game Engine
- Time based approach -> Pipelines
- Due to multiple components of a game engine:
    - Rendering Pipeline
    - Ai Pipeline
    - physics pipeline
    ...

In dem Beispiel wirst du aber auch schnell an einen Knackpunkt kommen, wo du merkst: Oh shit, das ist noch viel zu umfangreich gefasst. In dem Fall weiter ins Detail gehen.
Wenn du dann eine neue Arbeitssession beginnst, kannst du dir ein Feature rausnehmen, gucken ob du es evtl. Noch weiter unterteilen musst und dann kannst du dir detaillierte tasks dazu ausdenken. Willkommen bei Agile :D
Dadurch hast du dann letztendlich immer den Überblick über das gesamte Projekt und weißt sofort woran du noch arbeiten musst. Die Übersicht solltest du dir auch dementsprechend leicht zugänglich machen.
Aber das sind auch nur Tipps. Du musst schauen, wie du am besten klarkommst. Dazu einfach ausprobieren :)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

9

14.06.2014, 15:08

Ein Punkt der meiner Meinung nach auch oft vernachlässigt wird ist die Einheitlichkeit. Einheitlichkeit reduziert sehr stark den Informationsgehalt des Quellcodes. Dies führt zu einem deutlich reduzierten Bedarf an genereller Übersicht da diese durch Systematik ersetzt wird. Um mal Schlagworte zu nennen “convention driven design”.

Erstellen eines “code design/layout documents”, eines Wörterbuchs in dem man die verwendeten Worte definiert und eingrenzt z.B. für Methodennamen usw.

Auch das halten an das “Single-Responsibility-Prinzip” ist ansich und insbesondere im zusammenarbeit mit einem “convention driven design” sehr hilfreich.

Generell gillt zu versuchen sich die Überraschungen im Code und Aufbau zu gut wie möglich zu reduzieren.
:love: := Go;

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

17.06.2014, 14:46

Es wurden ja schon einige gute Tipps gegeben. Es wurde aber gesagt, irgendwann verliert man nun mal den Überblick über ein großes Projekt. Das würde ich so nicht unterschreiben. Man sollte das etwas genauer verfeinern. Wenn du dein Projekt vernünftig designst und konzipierst, dann weißt du zwar am Ende nicht mehr unbedingt was genau wie funktioniert, du solltest aber wissen welche Komponenten was tun. Das ist im Prinzip auch das was du eigentlich willst. Du willst bei einer Funktion nicht genau wissen welche Schritte genau ausgeführt werden, sondern was du rein steckst und was am Ende das Ergebnis der Funktion ist, bzw wie sie den Zustand deiner Anwendung verändert. Hilfreich ist es dazu wenn du dir deiner einzelnen Schichten bewusst wirst. Software bzw vieles in der Informatik ist in verschiedene Schichten eingeteilt. Eine Schicht selbst muss nicht wissen wofür sie letzten Endes eingesetzt wird. Außerdem muss sie auch nicht wissen wie die Schichten darunter funktionieren. Eine Schicht akzeptiert dass die unterliegenden Schichten funktionieren und das wars. Im Prinzip guckst du bei jeder Klasse, in welche Schicht du sie in dein Programm einfügen kannst/sollst/musst. Dazu gehört halt ein wenig Erfahrung, das kommt aber mit der Zeit. Ein Beispiel für ein Schichtensystem wäre MVC. Das ist relativ weit verbreitet und dazu solltest du einiges im Internet finden. Das kann man beliebig erweitern, aber auch eigene Konzepte entwickeln. Mal ein ganz einfaches Beispiel zum Thema Image Viewer, also ein Programm womit du Bilder betrachten kannst.
Nehmen wir mal klassisch die Schichten Model, View und Control an. Zur Modelschicht gehört dann zum Beispiel eine abstrakte Klasse für eine Grafik sowie ein paar konkrete Implementierungen. Dazu gibts dann noch eine DAO Klasse um die Arbeit der benutzenden Schicht zu vereinfachen. Die Controlschicht benötigt in diesem einfachen Beispiel einfach die Funktionalität ein Bild zu laden. Dazu benutzt die Controlschicht dann die Modelschicht und nutzt da konkret unsere DAO Klasse. In der Viewschicht, also im Prinzip unserer IO-Schicht gibt es dann von mir aus einen Button um ein Bild anzuzeigen. Die View holt die Daten nicht selbst sondern nutzt die Controlschicht. Diese nutzt wie schon gesagt die Modelschicht um über unser DAO auf eine konkrete Implementierung eines Bildes zuzugreifen. Das wird an die View gereicht und kann nun angezeigt werden. View und Controller wissen also im Prinzip nicht wie man konkret ein Bild lädt, wissen aber dass die Modelschicht genau das kann. Wie es intern funktioniert ist egal. Das ist jetzt hier natürlich ein stark vereinfachtes Beispiel, zeigt aber denke ich schon mal das Prinzip dahinter. Versionierungssoftware würde ich auch eindeutig empfehlen. Vor allem bei größeren Projekten hilft es dir ungemein weiter. Alleine fürs Refactoring. Du kannst wild deinen Code ändern und wenn du mal Mist baust kannst du deine alte Version wieder holen. Das hilft einfach stark dabei gutes Design zu entwickeln da man nicht alles durchplanen kann. Was deine Flussdiagramme etc angeht, das kann ganz nett sein, aber bei gutem Design musst du eigentlich wie gesagt nicht wissen was in welchen Methoden passiert. Meiner Meinung nach wäre eine Dokumentation deiner Schnittstellen da sinnvoller. Und da finde ich die Schnittstellen zwischen einzelnen Schichten am wichtigsten, da du diese wohl am meisten gebrauchen wirst, danach kommen dann interne. Wie genau du alles Dokumentierst hängt natürlich von dir ab. Ich will dir auch keine gute Dokumentation ausreden. Nur für den privaten Gebrauch ist es halt wichtig dass zuerst die für dich wichtigen Dinge dokumentiert sind.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige