Dieser Artikel ist für all diejenigen geschrieben, die Clonk Rage kennen und nun wissen möchten, was es in OpenClonk Neues gibt. Seit das Projekt Open Source ist, wurden einige experimentelle Features eingeführt. Im neuesten Teil der Clonk-Spieleserie haben wir alte Fesseln abgeworfen und etwas erschaffen, das weiter fortgeschritten ist als alles was ihr jemals in Clonk gesehen habt.
Man kann mit Sicherheit sagen, dass wir mit OpenClonk den größten Sprung machen, was neue Features und Änderungen seit Clonk 4 angeht.
Allgemein
Neu in OpenClonk ist die Möglichkeit zu Zoomen. Der Clonk kann jetzt in einer angemessenen Größe angezeigt werden, also größer als ein Mauszeiger ;-). Zoomen kann man mit dem Mausrad oder den Tasten F5/F6.
3D-Rendering
Auch neu ist, dass 3D-Modelle im Spiel dargestellt werden können. Im Gegensatz zu den klassischen Sprite-Grafiken sind 3D-Modelle wesentlich vielseitiger: Erstens, die Modelle verwaschen nicht und die Animationen sehen nicht abgehackt aus wenn hineingezoomt wird. Animationen werden direkt im Modell gespeichert. Man muss sie nicht mehr aus Einzelbildern der verschiedenen Animationsphasen zusammenpuzzlen (Tschüss, anigrab.exe). Das ermöglicht viel mehr Animationen als früher. Im Moment hat der Clonk mehr als 100 verschiedene!
Der Renderer lädt Modelle im Ogre3D-Format, einem leichtgewichtigen Format für 3D-Modelle, das speziell auf Echtzeit-Darstellung zugeschnitten ist. Modelle in der Landschaft werden orthogonal, Bilder von Objekten dagegen perspektivisch projiziert. Abgesehen vom Grundlegenden unterstützt der Renderer noch:
- Texturen mit UV-Maps (einschließlich Multi-Texturing)
- Transparente Texturen / Alpha-Maps
- Texturanimation
- Bones-Animation, einschließlich dem Mischen mehrerer Animationen gleichzeitig
- Backface Culling
- In Echtzeit Script-gesteuerte Mesh-Transformationen und Attachments
Siehe auch den Artists Guide dazu, wie man Modelle erstellt, die in Echtzeit gerendert werden sollen. Unser Ressourcen-Repository beinhaltet bereits viele solcher Modelle.
Neue Steuerung
Allerdings sind die meisten Änderungen, die wir gemacht haben und noch machen, nur deshalb möglich geworden, weil wir entschieden haben die Abwärtskompatibilität zu Clonk Rage über Bord zu werfen und alle Spielinhalte von Grund auf neu zu erstellen. Das ist auch der Grund, warum die Spielinhalte von OpenClonk noch weit davon entfernt sind, den Umfang derer von Clonk Rage zu erreichen.
Die Steuerung wurde komplett überarbeitet und wird jetzt komplett per Script bestimmt. Mit dem neuen Steuerungssystem ist es gleich viel einfacher und intuitiver seinen Clonk zu steuern. Für neue Spieler war die ungewöhnliche und unintuitive Steuerung schon immer eine große Hürde gewesen, bevor sie endlich in den Genuss des wuseligen Gameplays von Clonk kommen konnten.
Die Steuerung ist jetzt vollständig anzupassen und kann in jedem Szenario/Mod verändert werden. Die Standard-Steuerung basiert auf dem allgemein bekannten Schema vieler anderer Spiele: Bewegen mit WASD, werfen, zielen und Werkzeuge benutzen mit der Maus. Leertaste, um Objekte in der Landschaft zu benutzen (wie etwa ein Gebäude betreten oder ein Fahrzeug anpacken). Die neue Steuerung schöpft die Maus vollständig aus, und gibt euch damit präzise Kontrolle über alle Gegenstände und Waffen. Die neue Schaufel zum Beispiel kann auch beim Klettern und Hangeln benutzt werden, und der Clonk gräbt einfach genau in Richtung Mauszeiger, solang der Mausknopf gedrückt gehalten wird. Weitere Details zur neuen Steuerung werden in den ersten Tutorial-Missionen im Spiel erläutert.
Abgesehen von der Steuerung mit Maus+Tastatur kann man auch ein Gamepad benutzen. Allerdings ist dieses Feature noch experimentell, und so funktioniert im Moment von mehreren angeschlossenen Gamepads immer nur eins. Es ist ebenfalls noch nicht möglich, dessen Belegung zu ändern, aber das ist für die Zukunft geplant. Eine frühe Version der Gamepad-Steuerung wurde in einem Blog-Post vorgestellt.
Umfassende Dokumentation zur anpassbaren Spielsteuerung findet ihr in der C4Script-Dokumentation.
Insgesamt ist der Clonk viel agiler als zuvor: Er kann nicht nur herumlaufen und Sachen im Sprung benutzen, darüber hinaus helfen ihm eine Menge Werkzeuge dabei, durch die Welt zu kraxeln – zum Beispiel Enterhaken, Strickleitern, die verbesserte Schaufel und viele weitere.
Werkzeuge und HUD
Eng im Zusammenhang mit der Steuerung steht das Inventar-System des Clonks. Jeder Clonk hat jetzt einen Rucksack, in dem er fünf Sachen (Kapazität änderbar durch die Szenarien) tragen kann. Er kann seinen Rucksack öffnen und leicht Objekte aus dem Rucksack und aus seinem Inventar hin- und hertauschen.
Stark im Mittelpunkt stehen die Werkzeuge in OpenClonk. Der Clonk braucht zum Graben eine Schaufel, zum Bäume Fällen eine Axt, und zum Bauen einen Hammer. Als Ausgleich kann der Clonk nicht nur mehr Dinge tragen als der klassische Clonk, er kann auch jeden Gegenstand benutzen: Schwert, Bogen, Schaufel, Muskete, Zauberstab, etc. Der Bedarf an spezialisierten Clonks ist Geschichte, denn die Fähigkeiten eines Clonks werden jetzt rein durch seine Ausrüstung bestimmt. Durch die Nutzung der Maus sind Werkzeuge vielseitiger und einfacher zu bedienen.
Die neue Spielsteuerung geht auch Hand in Hand mit der gründlichen Überholung des HUD. Das minimalistische HUD war eine Sache, die wiederholt als Kritik an Clonk angebracht wurde.
Ab sofort wird das HUD vollständig per Script bestimmt (anstatt von der Engine), was mehr Flexibilität für Szenarien und Entwickler bedeutet. Die Standardoberfläche zeigt alle Clonks des Spielerteams am oberen Rand, jeweils mit einer Energie- und Atem-Leiste direkt unter ihrem Bild. Außerdem zeigt das Bild den Clonk live in Aktion, sprich, wenn er angegriffen wird oder gerade ertrinkt sieht man das dort.
Am unteren Bildschirmrand sieht man die zwei Gegenstände, die der Clonk in seinen Händen trägt.
Sie können mit Links- oder Rechtsklick benutzt werden. Darüber hinaus werden dort auch alle Objekte in der Landschaft angezeigt, die der Clonk gerade benutzen kann.
Alle Knöpfe die man im HUD sieht kann man anklicken, um sie auszulösen oder auszuwählen, und Gegenstände kann man per Drag&Drop sinnvoll herumziehen. Dieses Feature ist interessant für Mod-Autoren.
Neue Spielinhalte und Konzepte
Da der gesamte Spielinhalt von Grund auf neu ist, muss man die vielen neuen oder erneuerten Werkzeuge, Waffen, Gegenstände, Gebäude, Fahrzeuge und Tiere, Regeln, Ziele und Umweltobjekte unbedingt erwähnen. Abgesehen von den Objekten ersetzen wir vollständig die alten Grafiken, Sound-Effekte und Texturen. Texturen zum Beispiel sind keine Graustufenbilder mehr, die nachher nach Farbe des Materials getönt werden, sondern Farbbilder mit mehr Variation. Dadurch sieht die Landschaft besser und detaillierter aus. Neue Sound-Effekte suchen wir uns bei den verschiedenen freien (Creative Commons) Archiven, oder wir machen sie selbst.
Die Frage sollte also eher lauten, was ist denn nicht neu?
Nun ja, was den Spielinhalt angeht, gar nichts. Allerdings haben wir nicht einfach nur alte Objekte neu entworfen. Ein paar ganz neue Konzepte sind bereits im Spielinhalt zu sehen. Beispielsweise wurde der nervige automatische Clonk-zu-Clonk-Kampf beseitigt und wird durch den Kampf mit diversen Nahkampfwaffen ersetzt. Die klassischen Flints, die sich eigentlich nur in ihrer Explosionsgröße unterschieden haben, werden jetzt durch spezialisiertere Bergbau-Werkzeuge und Waffen ersetzt, wie etwa der Dynamitkiste. Aber anstatt jetzt alle neuen oder erneuerten Objekte hier aufzulisten empfehle ich euch, spielt einfach eine Runde und seht selbst :-P.
Für Entwickler
Viele vorgenommene Änderungen sind für Scripter und Szenario-Entwickler interessant:
C4DT
Ein Tool für die Clonk-Entwicklung soll hier besonders hervorgehoben werden: C4DT, die Clonk-Entwickler-Werkzeuge für Eclipse. Eclipse ist eine erweiterbare open-source Entwicklungsumgebung, die eine Vielzahl an Programmier- und Scriptsprachen unterstützt. Ab sofort auch C4Script: Das C4DT-Plugin erlaubt es euch, neue Inhalte für Clonk mit der mächtigen Eclipse-IDE zu entwickeln. Und da C4DT nicht versucht, eine eigenständige IDE zu sein, übernimmt sie jede Menge Features von Eclipse, und erleichtert die Entwicklung dadurch enorm. Unter den Features sind:
- Syntax-Highlighting für C4Script, Landscape.txt und Konfig-Dateien wie DefCore.txt und Scenario.txt
- Alle Referenzen auf gültige Identifier (Variablen, Funktionen) können wie Weblinks angeklickt werden, um zu ihren Deklarationen zu springen. Das funktioniert sogar mit den Platzhaltern für Einträge in den Stringtabellen.
- Schnell zur Objektdefinition springen, einfach indem man den Namen oder die ID des Objektes eintippt
- Kontextabhängige Hilfe und Hinweise zu Parametern und sonstigem Code beim Tippen(!) (siehe Bild unten)
- Hilfreiche Auto-Vervollständigung und -Einrückung
- Ein Überblick über das aktuell geöffnete Script
- Ein eingebauter Parser zeigt Errors und Warnings im Script auf, sodass man dazu die Engine nicht starten muss(!)
- Refactoring von Variablen und Funktionen
- Ein echter Debug-Modus für die Engine: Debug-Szenarien im Eclipse-Debugger(!)
Die alte editor.exe aus Clonk Rage-Zeiten wurde entfernt. C4DT ist der eindeutige Nachfolger des alten Freundes aller C4Script-Entwickler. Und eigentlich ist es ein mehr als würdiger Nachfolger, denn die Clonk-Entwicklung könnte wirklich kaum fortgeschrittener sein als mit diesem Eclipse-Plugin.
C4Script-Änderungen
Abgesehen davon wurden folgende große Änderungen an C4Script vorgenommen:
- Die ID eines Objekts ist nicht mehr auf 4 Großbuchstaben beschränkt. Zum Beispiel geht jetzt CreateObject(Musket); statt CreateObject(MSKT);
- Alle Funktionen, die mit Objektkontext arbeiten, wurden von ihrem Objektparameter befreit. Beispielsweise schreibt man jetzt clonk->GetX(); statt GetX(clonk);
- Ein paar veraltete Funktionen sind weg oder ersetzt. So verhält sich jetzt etwa FindObject() wie FindObject2() aus Clonk Rage, FindObject2() gibt es nicht mehr.
- Viele Funktionalitäten, wie das Klettern an Strickleitern, Seilphysik, Basisgebäude, Werkstatt oder Clonk-Steuerung wurden in einheitlichen Bibliotheks-Objekten thematisch zusammengefasst, und können jetzt von den konkreten Objekten genutzt werden. Das vereinfacht die Nutzung von Funktionalitäten anderer Objekte, ohne alles von ihnen erben zu müssen. Zum Beispiel haben alle Produktionsgebäude #include Library_Workshop in ihren Scripts stehen, um die Grundfunktionalitäten einer Werkstatt zu bekommen.
- Ein neuer Datentyp, genannt „Proplist“. Proplisten sind assoziative Arrays mit Prototypvererbung, wie bei Javascript-Objekten. Ein Beispiel: var info = { XP = 1200, Comment = "I'm new here." }; Log("%d",info.XP); gibt „1200“ im Log aus. Objekte und Objektdefinitionen sind jetzt ebenfalls Proplisten und Objekte erben von ihrer Definition: Log("%s",Bow.Name); gibt sprachabhängig den übersetzten Namen des Bogens aus. Lokale benannte Variablen sind jetzt Properties eines Objekts.
- ActMaps werden ebenfalls als Proplist in einer Property in der Objektdefinition gespeichert. Wahrscheinlich wird die DefCore.txt ihrem Beispiel folgen.
- Die Dateien DescXX.txt und Names.txt werden nicht mehr genutzt. Der Name wird per Script gesetzt und je nach Sprache aus der entsprechenden StringTblXX.txt gelesen. Nur noch wenige Objekte benötigen eine Beschreibung, und diese wird ebenfalls im Script definiert und in der String-Tabelle übersetzt.
- Die Steuerung wurde überarbeitet. Szenarien und Objekte können Tastatur, Maus und Gamepad beliebig nutzen und neu belegen. Das Script des Clonks definiert ein neues Interface (siehe ControlUse) für den Umgang mit Objekten.
- Variablen können jetzt den Wert nil haben, egal von welchem Typ sie sind. nil ist wie null in anderen Programmiersprachen, und wird in C4Script üblicherweise benutzt um anzuzeigen, dass etwas nicht gesetzt ist. Ob eine Variable 0 oder nil ist, ist beispielsweise nicht dasselbe. Sie ist 0, wenn sie die Zahl 0 enthält und nil, wenn sie nicht gesetzt ist. Für Funktionen hingegen kann nil benutzt werden, um einen optionalen Parameter nicht festzulegen (das ist, als ob man ihn ausgelassen hätte). Zum Beispiel spielt Sound("Water",true,nil,nil,+1) den Wasser-Sound endlos für alle Spieler, mit 100% Lautstärke (dem Standard), während dieser Sound mit Sound("Water",true,nil,0,+1) nur für Spieler 0 zu hören ist. Außerdem erlaubt nil es, zwischen Funktionen zu unterscheiden die keinen Rückgabewert (also nil) liefern und z.B. solchen, die die Zahl 0 zurück geben.
Unabhängig davon, ob eine Variable foo entweder nil, 0 oder false ist, dieser Ausdruck gibt immer noch „yay“ aus: if(!foo) Log("yay"); - #strict und #strict 2 wurden abgeschafft. #strict 2 gilt implizit für alle Scripts.
- Wie üblich gibt es einige neue Funktionen und Engine-Callbacks. Siehe dazu die Dokumentation.
Ursprünglicher Artikel von Newton im OpenClonk-Wiki, Stand: 16. September 2010
22 Antworten auf „OpenClonk: Neue Features seit Clonk Rage“
Soso, das klingt ja richtig gut. Seit dem letzten mal als ich OC getestet habe scheind sich ja ordentlich was getan zu haben.
Also das ändert meine Meinung zu Openclonk ins positive.
Finde es toll, das es endlich mal eine deutsche Übersicht über Änderungen und Neus gibt
Klingt insgesamt wirklich gut – auch wenn ich OC gegenüber eher skeptisch eingestellt bin, aber das zeigt sich noch.
Nur eins finde ich ziemlich… ‚doof‘: Die Unterschlagung des Objektparameters. Erstens sieht es imo hässlich aus, Pfeilketten zu haben (zB GetCrew(this->Contained()->GetOwner())->Contents()->RemoveObject()) und zumindest in Rage ist es unperformanter als die Unterbringung des Objekts als Parameter.
Und zu
Gibt es dann noch optional #strict 2?
Ich glaube kaum, dass wenn #strict abgeschafft wurde, #strict2 bestehen bleibt… ;)
Ich finde die nicht schlimmer als große Verschachtelung wie zuvor.
Hier verlängerst du die Kette aber – this-> macht keinen Sinn. Und ansonsten hättest du ein RemoveObject(Contents(0, GetCrew(GetOwner(Contained(this))))); – ich finde, die vielen „)“ sind wesentlich unübersichtlicher als eine Kette mit Pfeilen. Noch schlimmer wird es außerdem, wenn nach dem Objektparameter noch weitere normale Parameter kommen, die später hinzugefügt wurden. Wenn davor dann noch drei ) sind, verliert man den Überblick, was zu welcher Funktion gehört, noch vollständig.
Unwesentlich. Wenn du dir so große Sorgen um die Performace machst, solltest du vermutlich mit c4script aufhören.
Tatsächlich wurde #strict abgeschafft und #strict 2 wird implizit angenommen.
Nur weils dir nicht passt musst du nicht so einen unsachlichen Kommentar abgegeben. Wann ich wie und warum womit aufhöre ist immer noch meine Sache.
Vor allem in großen, scriptlastigen Packs ist es wichtig, Performance einzusparen. Das geht entweder durch geschicktes Scripten oder durch Ausnutzung der Vorteile, die die Engine anbietet. „->“ mag auch teilweise ein Vorteil sein, allerdings hat er den Nachteil dass es langsamer ist. Und „unwesentlich“ ist der Unterschied nicht, in dem Beispiel im Clonkforum wars ein Geschwindigkeitsvorteil von gut 9%.
Hm? Ich glaube, du kannst jede Menge Performance sparen, wenn du deine Objekte direkt in die Engine schreibst statt per c4script.
Wie kann man den reproduzieren?
Zeit lässt sich mit GetTime messen, und dann führt man das einfach x-mal aus.
Gut, beim Thema im CF gings um SetAction und ObjectSetAction, das sind schon wieder 2 verschiedene Funktionen. Inwiefern man die vergleichen kann ist fraglich.
Also hab ichs mal mit ObjectNumber probiert, einmal obj->ObjectNumber() und ObjectNumber(obj). Ist für die meisten anderen objektbezogenen Funktionen ähnlich. Nach mehreren Durchläufen ergibt sich
Parameter: 6.528 ms
Pfeil: 10.218 ms
(jeweils immer in unterschiedl. Reihenfolge, damit keinem Caching-Vorteile o.ä. vorgeworfen werden)
Das sind dicke 36% Unterschied. Liegt mal höher und mal niedriger, je nach Funktion.
Klar geht jetzt keiner her und fragt millionenfach Objektnummern ab. Aber in einem einzigen Frame wird ja auch nicht nur eine Funktion aufgrufen, sondern zig Funktionen in noch mehr Objekten. Und das summiert sich.
Vielleicht solltest Du die Tests mit OpenClonk, nicht mit Clonk Rage durchführen.
Naja, das ist eh schlechter Programmierstil. Dein Beispiel ist sogar ein außerordentlich gutes Beispiel dafür, warum es mit -> besser ist als mit Klammern. Ich sag dir auch wieso:
Mal angenommen, der Clonk des Besitzers des Objektes in dem das aufrufende Objekt drin ist, hat garkein Inventar dabei, was ja durchaus mal vorkommen kann. Also Contents() = nil. Was macht Dein Script RemoveObject(Contents(0, GetCrew(GetOwner(Contained(this))))); ?
Es löscht einfach das aufrufende Objekt, und zwar ohne auf diesen offensichtlichen Fehler im Code aufmerksam zu machen. So ein Verhalten kann zu nervenzerreibenden Debuggingsessions führen.
Wenn jedoch in OpenClonk der selbe Aufruf mit Pfeilen gemacht wird, und Contents(0) nicht existiert, dann loggt die Engine einen Fehler (Nullpointer) und löscht nicht etwa das aufrufende Objekt. Der Fehler/die Schlampigkeit im Code ist sofort gefunden.
In deinem Beispiel wäre es guter Programmierstil, dies so aufzuschreiben:
if(Contained()) {
var crew = GetCrew(Contained()->GetOwner());
// wenn der Owner = NO_OWNER ist, kann crew auch nil sein
if(crew) {
var toremove = crew->Contents();
if(toremove)
toremove->RemoveObject()
}
}
Klar dass es ziemlich riskant ist, so eine Zeile tatsächlich zu schreiben – es war auch nur ein Beispiel. Beide Versionen, mit Objektparameter und mit Pfeil, kommen ohne if-Abfragen nicht aus. Beim Pfeilstil sind diese Abfragen sogar ein Muss, während das bei Parametern nicht immer der Fall ist – verschenkte Performance.
Ein Beispiel wo so eine Abfrage standardmäßig wegfallen würde, ist das sicher allen bekannte Kontext-Hilfefenster: Da reicht ein
MessageWindow(GetDesc(Contents()), iPlr), wo bei OC dann schon das her müsste:
var obj = Contents();
if (!obj)
obj = this;
MessageWindow(obj->GetDesc(), iPlr);
Und das nur für den kleinen Kniff, bei leerem Inventar einfach die Clonkbeschreibung anzeigen zu lassen.
Klar ist es für die manche ein Segen, direkt die Errors sehen zu können, aber wer sich schon länger mit C4 befasst hat, wird gerade solche kleinen Kniffe, die der Objektparameter neben der besseren Performance zulässt, vermissen und sich stattdessen mit übermäßigen „ist-es-überhaupt-noch-da“-ifs rumplagen.
Mag sein dass ich das ein bisschen zu krass sehe und verdramatisiere, aber ja, mir gefällt das nicht. Nicht weil ich OC nicht mag, das bessert sich vielmehr. Aber gerade sowas hält mich dann eher davon ab, mich dann auch wirklich mit OC zu befassen und dort statt bei CR zu scripten.
MessageWindow((Contents() || this)->GetDesc(), iPlr);
.(Contents() || this) ist true, bei Aufrufen ohne Objektkontext 0 (oder nil?), also auch kein Objekt.
Falsch, das gibt entweder Contents() oder this zurück. Beim Aufruf ohne Objektkontext macht auch dein Script keinen Sinn.
Mein Fehler. || und && geben bei #strict immer true oder false zurück, bei #strict 2 kanns auch Zahlen und Objekte zurückgeben.
Es musste ja sein das der neuste Nigtly build bei mir nicht funktioniert -.-, und nein ich hab keine veraltete Software und keinen schlechten Pc. Man kann außerdem im Menü nur zwischen 16 und 32 bit umstellen obwohl ich die 64er version brauch/hab.
Am besten, du fragst mit etwas detaillierteren Informationen im Forum nach. In welchem Menü willst du überhaupt etwas mit 16/32bit umstellen? Außerdem funktionieren 32bit-Programme problemlos dank WoW64.
Ich habe den Artikel auf den neuesten Stand gebracht. Der Absatz über C4DT ist z.B. frisch hinzugekommen.
Find die Änderung supa, aber nur um genau zu sein, weil ich mir nicht sicher bin, was „Objektkontext“ ist:
Ihr meint damit doch einfach ALLE Funktionen, die nicht ohnehin schon keine Parameter hatten wie zB Throw() oder sowas (wo nix steht) haben jetzt ebenfalls keine Parameter mehr. Und nun ist alles einfach wie Throw() und es steht nie was in den Klammern bei den 1000 Funktionen in der docu auf clonk.de. Also Objektkontext=Klammerninhalt von Befehlen, oder?
Nein. Wenn eine Funktion „mit Objektkontext“ arbeitet, dann bedeutet das, dass sich diese Funktion auf ein bestimmtes Objekt bezieht. Dieses Objekt übergibst du in Clonk Rage als einen Parameter, und möglicherweise erwartet die Funktion noch andere. Es wird nur dieser eine Objekt-Parameter wegfallen, die anderen bleiben.
Nimm die Funktion GetX() als Beispiel. In Clonk Rage liefert GetX() dir die X-Position eines Objektes, das du als Parameter übergibst. In anderen Worten, GetX() bezieht sich auf dieses Objekt. Dieses Objekt ist dann der Kontext der Funktion. Eine andere Funktion mit Objektkontext wäre z.B. SetCon(), hier ist der zweite Parameter das Objekt, auf das sich SetCon() bezieht. Dagegen ist zum Beispiel Log() eine Funktion ohne Objektkontext.
In Clonk Rage konnte man dieses Objekt bei vielen Funktionen auf zwei Arten festlegen: Du konntest z.B. entweder
SetCon(50, someObject)
schreiben, odersomeObject->SetCon(50)
. In OpenClonk gibt’s nur noch die zweite Möglichkeit, da SetCon() den zweiten Parameter nicht mehr hat.Goil, Du hast mein Update übersetzt! Vielen Dank dafür, NAchtschatten!
Na so was, scheint sich doch was seit CR getan zu haben, werde mir das mal näher anschauen.