Harald Hoppelhase
Harald Hoppelhase
Version 0.2.4
Die aktuelle, mehr oder weniger fertige, Version:
https://jonathank.de/games/hase/index.html
Zuletzt geändert von Jonathan am 08.04.2024, 01:03, insgesamt 3-mal geändert.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Harald Hoppelhase
Tjaa, leider bin ich auch nicht wirklich fertig geworden. Die nächsten Tage sind auch voll, daher kommt jetzt erstmal der aktuelle Zwischenstand, innerhalb der nächsten 1-2 Wochen wirds dann hoffentlich fertig.
Erstmal zum Konzept: Ich wollte gerne ein Oster-Spiel machen, am besten irgendwas süßes und knuffiges. Ich habe ein paar frische Tulpen und andere Blumen gesehen und mir gefielen die frischen, etwas gedeckten Farben sehr und ich wollte irgendetwas in diesem Look machen. Bunte, freundliche Farben und dazu irgendein simples, aber interessantes Spielkonzept.
Ich habe mir also Krita installiert und ein bisschen mit Digital Painting experimentiert. Als ich einmal die richtigen Pinsel gefunden und ein bisschen experimentiert hatte, war ich mit dem Ergebnis relativ schnell recht happy:
Ein Hase als Protagonist erschien naheliegend, er sammelt dann im Spiel Ostereier ein, und damit hat man auch die Klau-Thematik irgendwie abgedeckt. Passt also soweit. Ich wollte irgendetwas Richtung Jump-and-Run machen, die habe ich früher immer sehr gerne gespielt, mich aber nie wirklich selber dran versucht. Durch meine Krita-Experimente war dann eigentlich auch schon klar, dass es 2D werden würde.
Der erste Tag ging im Wesentlichen dafür drauf die Szene mit der Blume und den Hasen zu malen. Der Hase hat ewig gedauert, er sieht auch irgendwie etwas platt aus, aber insgesamt war ich doch recht zufrieden mit meinen ersten Experimenten und recht motiviert, weiter zu machen. Ich wollte nicht nur diese hübschen handgemalt-Look sondern auch weiche Animationen - Animationsstufen von Hand malen schloss ich sehr schnell aus. Stattdessen habe ich den Hasen in Körperteile zerlegt, in Blender eingefügt und ein 2D-Modell mit Skelettanimationen daraus gemacht.
Ich kann Blender eigentlich. Aber das ganze rein in 2D zu machen erforderte doch nochmal eine neue Pipeline, ich musste ein wenig experimentieren bis ich den besten Weg gefunden hatte. Außerdem hab ich ewig keine Animationen per Hand gebaut. Und Hasengehoppel ist auch was anderes als ein normaler Walk-Cycle, weil die Bewegung ziemlich ungleichmäßig ist und z.B. die Hinterläufe recht "sprunghaft" nach vorne gezogen werden, während sie die Vorderläufe gleichmäßiger bewegen. Also erstmal Videos gucken, ein IK-Rig aufsetzen, Animation bauen, merken, dass es kaputt ist, ein neues, verbessertes Rig bauen, neu animieren, drüber iterieren, usw. Und dann Exportprobleme fixen bis alles auch in meiner Engine fehlerfrei läuft. Ugh.
Die Woche war schon über die Hälfte rum und es gab noch kein Spiel, nur ein paar Elemente und einen animierten Hasen. Ich wollte eigentlich kleinere, etwa Bildschirmgroße Level bauen in denen man den Ausgang finden muss, nachdem man Eier eingesammelt, Schalter umgelegt, Gegner besiegt und, ach, das wird doch eh nix. Als ich darüber nachdachte, auch Levelelemente hübsch zu animieren dachte ich über den Wachstum von Pflanzen nach, und da kam mir die Idee: In der Mitte des Levels ist eine riesige Pflanze die unendlich hoch nach oben wächst und man muss sie emporklettern in dem man von Blatt zu Blatt spring und nebenbei Eier einsammeln. Kein Leveleditor, relativ wenig Spielelemente, keine Gegner, Highscorejagt, oder anders gesagt, das perfekte Spielprinzip für so ein Minigame. Nun gut. Hier mal ein Video vom aktuellen Stand:
Eigentlich bin ich ziemlich weit gekommen. Es gibt den Hasen, die Pflanze, man sammelt Eier und bekommt Punkte. Große Baustellen:
Ich hatte noch mehr Ideen, etwa das es verschiedene Eier gibt. Die Idee war auch, dass Eier ein Stück tiefer erscheinen, aber die Spitze manchmal so schnell wächst, dass man neue Blätter nicht mehr erreichen kann, wenn man zu lange zu weit unten war. Man muss also dann nach Risiko entscheiden ob man versucht ein tiefes Ei für fette Bonuspunkte zu holen und dann vielleicht nicht mehr nach oben kommt. Zweispieler Couch-Coop mit Gamepad-Steuerung reizt mich eigentlich auch ziemlich.
Wie gesagt, ich versuche es noch fertig zu machen, für diese Woche wars das aber erstmal.
Erstmal zum Konzept: Ich wollte gerne ein Oster-Spiel machen, am besten irgendwas süßes und knuffiges. Ich habe ein paar frische Tulpen und andere Blumen gesehen und mir gefielen die frischen, etwas gedeckten Farben sehr und ich wollte irgendetwas in diesem Look machen. Bunte, freundliche Farben und dazu irgendein simples, aber interessantes Spielkonzept.
Ich habe mir also Krita installiert und ein bisschen mit Digital Painting experimentiert. Als ich einmal die richtigen Pinsel gefunden und ein bisschen experimentiert hatte, war ich mit dem Ergebnis relativ schnell recht happy:
Ein Hase als Protagonist erschien naheliegend, er sammelt dann im Spiel Ostereier ein, und damit hat man auch die Klau-Thematik irgendwie abgedeckt. Passt also soweit. Ich wollte irgendetwas Richtung Jump-and-Run machen, die habe ich früher immer sehr gerne gespielt, mich aber nie wirklich selber dran versucht. Durch meine Krita-Experimente war dann eigentlich auch schon klar, dass es 2D werden würde.
Der erste Tag ging im Wesentlichen dafür drauf die Szene mit der Blume und den Hasen zu malen. Der Hase hat ewig gedauert, er sieht auch irgendwie etwas platt aus, aber insgesamt war ich doch recht zufrieden mit meinen ersten Experimenten und recht motiviert, weiter zu machen. Ich wollte nicht nur diese hübschen handgemalt-Look sondern auch weiche Animationen - Animationsstufen von Hand malen schloss ich sehr schnell aus. Stattdessen habe ich den Hasen in Körperteile zerlegt, in Blender eingefügt und ein 2D-Modell mit Skelettanimationen daraus gemacht.
Ich kann Blender eigentlich. Aber das ganze rein in 2D zu machen erforderte doch nochmal eine neue Pipeline, ich musste ein wenig experimentieren bis ich den besten Weg gefunden hatte. Außerdem hab ich ewig keine Animationen per Hand gebaut. Und Hasengehoppel ist auch was anderes als ein normaler Walk-Cycle, weil die Bewegung ziemlich ungleichmäßig ist und z.B. die Hinterläufe recht "sprunghaft" nach vorne gezogen werden, während sie die Vorderläufe gleichmäßiger bewegen. Also erstmal Videos gucken, ein IK-Rig aufsetzen, Animation bauen, merken, dass es kaputt ist, ein neues, verbessertes Rig bauen, neu animieren, drüber iterieren, usw. Und dann Exportprobleme fixen bis alles auch in meiner Engine fehlerfrei läuft. Ugh.
Die Woche war schon über die Hälfte rum und es gab noch kein Spiel, nur ein paar Elemente und einen animierten Hasen. Ich wollte eigentlich kleinere, etwa Bildschirmgroße Level bauen in denen man den Ausgang finden muss, nachdem man Eier eingesammelt, Schalter umgelegt, Gegner besiegt und, ach, das wird doch eh nix. Als ich darüber nachdachte, auch Levelelemente hübsch zu animieren dachte ich über den Wachstum von Pflanzen nach, und da kam mir die Idee: In der Mitte des Levels ist eine riesige Pflanze die unendlich hoch nach oben wächst und man muss sie emporklettern in dem man von Blatt zu Blatt spring und nebenbei Eier einsammeln. Kein Leveleditor, relativ wenig Spielelemente, keine Gegner, Highscorejagt, oder anders gesagt, das perfekte Spielprinzip für so ein Minigame. Nun gut. Hier mal ein Video vom aktuellen Stand:
Eigentlich bin ich ziemlich weit gekommen. Es gibt den Hasen, die Pflanze, man sammelt Eier und bekommt Punkte. Große Baustellen:
- Die Pflanze besteht aus Linien. Ich hab schon Texturen für Stamm und Blätter gemalt aber muss noch dynamisch die Geometrie dafür generieren und in jedem Frame anpassen.
- Die Wachstumsparameter sind mies. Ich habe Splines und kann damit alles irgendwie nett machen, aber die Kurven sehen super unnatürlich und nicht sehr pflanzig aus. Außerdem sollte alles so wachsten, dass das Level immer schafbar aber dennoch herausfordernd ist.
- Man kann nicht wirklich sterben und es gibt keine Highscore.
- Schöne Hintergründe mit Gras und Blumen sind zwar nett, aber nach 5 Sekunden Spielzeit sieht man nur noch die große Pflanze und den Himmel. Irgendwie schade wenn die ersten 5 Sekunden die mit Abstand schönste Grafik haben...
Ich hatte noch mehr Ideen, etwa das es verschiedene Eier gibt. Die Idee war auch, dass Eier ein Stück tiefer erscheinen, aber die Spitze manchmal so schnell wächst, dass man neue Blätter nicht mehr erreichen kann, wenn man zu lange zu weit unten war. Man muss also dann nach Risiko entscheiden ob man versucht ein tiefes Ei für fette Bonuspunkte zu holen und dann vielleicht nicht mehr nach oben kommt. Zweispieler Couch-Coop mit Gamepad-Steuerung reizt mich eigentlich auch ziemlich.
Wie gesagt, ich versuche es noch fertig zu machen, für diese Woche wars das aber erstmal.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Harald Hoppelhase
Sieht echt total niedlich aus. Spielelemente präzise und knackig definiert. Highscore? Skripte kann ich liefern ;)
Re: Harald Hoppelhase
Klasse Anfang, und Respekt mit der 2D-Animation :)
Ich habe auch seit kurzem Krita, Photoshop seit Dezember gecancelt. Zum Painten ist es wohl ziemlich das Nächstbeste. Ich hoffe ja eines Tages noch auf einen Procreate-Klon :)
Ich habe auch seit kurzem Krita, Photoshop seit Dezember gecancelt. Zum Painten ist es wohl ziemlich das Nächstbeste. Ich hoffe ja eines Tages noch auf einen Procreate-Klon :)
Re: Harald Hoppelhase
Vielen Dank :)
Ich hatte noch ein paar Baustellen vergessen. Das eine ist vernünftiges Alphablending. Das Video ist ein bisschen zu Tode komprimiert aber wenn man die Tulpe im Video mit der aus dem ersten Bild vergleicht sieht man (in etwas verstärkter Form) das selbe Problem, was auch im Spiel auftritt: Statt Alphablending zu machen werden einfach Pixel ab 0.2 Alpha discarded.
Das war notwendig, weil die Reihenfolge kniffelig ist. Das Level zum Beispiel (Boden, Gras und Blumen) ist in Blender in mehreren Ebenen gebaut und als 3D Modell exportiert. das ist echt nett, weil so der Hase automatisch hinter dem Gras aber vor den Blumen ist, man braucht nicht irgendwie extra z-Ebenen speichern oder so, alles funktioniert direkt automatisch. Das selbe gilt für den Hasen selber, die Beine sind einfach im 3D Raum vor dem Bauch, was den Code viel einfacher macht. Doch leider muss ich jetzt für korrektes Alphablending meine Dreiecke manuell nach Z-Wert sortieren, etwas worauf meine Engine absolut nicht vorbereitet ist. Ich könnte vermutlich eine zeitlang auf Sortierung auf Renderjob-Ebene ausweichen, weil meistens unterschiedliche Texturen verwendet werden oder man die Modelle aufteilen könnte, aber wirklich toll ist das nicht. Ich hatte auch mal überlegt statt Alphablending Dithering zu verwenden, in der Hoffnung, dass man auf 4k Monitoren eh keinen Unterschied mehr sieht und man dann auf die Renderreihenfolge überhaupt nicht mehr achten muss. Aber dabei stieß ich auf das Problem mit den Texturarrays, was ich noch nicht gelöst habe. Es gibt auch sicherlich hundert andere Lösungen für Order-Independent-Transparency, aber das ist auch einfach genau die Art von nervigen technischen Problemen die man für so ein 1-Wochen Projekt eigentlich lieber ignorieren als lösen will...
Das zweite Problem ist eher Spieldesign: Ich hab früher viel Icy Tower gespielt, das hier ist ja sehr ähnlich. Und natürlich ist es auch ähnlich zu Rum Barrel Run, was dann natürlich auch meine Hauptmotivation für die Online-Highscore war ;). Aber bei diesen Spielen geht es ja um Geschwindigkeit und Flow, das Springen und Hüpfen muss sich halt gut und richtig anfühlen damit es Spaß machen kann, einfach immer weiter nach oben zu klettern. Man macht die ganze Zeit immer nur genau das selbe, also muss das richtig gut sein. Und wie oben schon kurz angemerkt, süßes Rumhoppeln und Möhrenmümmeln passt da irgendwie so gar nicht rein. Überhaupt sind schon vierbeinige Charaktere für diese Art Spiel irgendwie etwas schwierig.
Man erkennt das auch im Video ganz gut, mir gefallen die ersten paar Sekunden, wo der Hase das Ei einsammelt, aber sobald er anfängt zu springen, sieht es leicht albern aus. Der Sprung ist halt irgendwie viel zu hoch und passt kaum zum eher realistischen Hasenlook. Aber der Sprung muss halt so hoch sein, damit das Spiel funktioniert.
Naja. Ich mach die technischen Baustellen fertig und kümmere mich dann ums Balancing. Vielleicht kann die Pflanze ja auch etwas langsamer wachsen, so dass man mehr von Links nach rechts hüpfen muss, mal schauen. Vielleicht akzeptiere ich auch einfach, dass es keine sehr gute Kombination aus Spielprinzip und Charakter war und baue doch noch die erste Idee mit den eher langsameren normalen Leveln mit Puzzelelementen ein (was dann vom Feeling etwas Richtung Braid (nur ohne die innovative Zeitmechanik) geht).
Ich hatte noch ein paar Baustellen vergessen. Das eine ist vernünftiges Alphablending. Das Video ist ein bisschen zu Tode komprimiert aber wenn man die Tulpe im Video mit der aus dem ersten Bild vergleicht sieht man (in etwas verstärkter Form) das selbe Problem, was auch im Spiel auftritt: Statt Alphablending zu machen werden einfach Pixel ab 0.2 Alpha discarded.
Das war notwendig, weil die Reihenfolge kniffelig ist. Das Level zum Beispiel (Boden, Gras und Blumen) ist in Blender in mehreren Ebenen gebaut und als 3D Modell exportiert. das ist echt nett, weil so der Hase automatisch hinter dem Gras aber vor den Blumen ist, man braucht nicht irgendwie extra z-Ebenen speichern oder so, alles funktioniert direkt automatisch. Das selbe gilt für den Hasen selber, die Beine sind einfach im 3D Raum vor dem Bauch, was den Code viel einfacher macht. Doch leider muss ich jetzt für korrektes Alphablending meine Dreiecke manuell nach Z-Wert sortieren, etwas worauf meine Engine absolut nicht vorbereitet ist. Ich könnte vermutlich eine zeitlang auf Sortierung auf Renderjob-Ebene ausweichen, weil meistens unterschiedliche Texturen verwendet werden oder man die Modelle aufteilen könnte, aber wirklich toll ist das nicht. Ich hatte auch mal überlegt statt Alphablending Dithering zu verwenden, in der Hoffnung, dass man auf 4k Monitoren eh keinen Unterschied mehr sieht und man dann auf die Renderreihenfolge überhaupt nicht mehr achten muss. Aber dabei stieß ich auf das Problem mit den Texturarrays, was ich noch nicht gelöst habe. Es gibt auch sicherlich hundert andere Lösungen für Order-Independent-Transparency, aber das ist auch einfach genau die Art von nervigen technischen Problemen die man für so ein 1-Wochen Projekt eigentlich lieber ignorieren als lösen will...
Das zweite Problem ist eher Spieldesign: Ich hab früher viel Icy Tower gespielt, das hier ist ja sehr ähnlich. Und natürlich ist es auch ähnlich zu Rum Barrel Run, was dann natürlich auch meine Hauptmotivation für die Online-Highscore war ;). Aber bei diesen Spielen geht es ja um Geschwindigkeit und Flow, das Springen und Hüpfen muss sich halt gut und richtig anfühlen damit es Spaß machen kann, einfach immer weiter nach oben zu klettern. Man macht die ganze Zeit immer nur genau das selbe, also muss das richtig gut sein. Und wie oben schon kurz angemerkt, süßes Rumhoppeln und Möhrenmümmeln passt da irgendwie so gar nicht rein. Überhaupt sind schon vierbeinige Charaktere für diese Art Spiel irgendwie etwas schwierig.
Man erkennt das auch im Video ganz gut, mir gefallen die ersten paar Sekunden, wo der Hase das Ei einsammelt, aber sobald er anfängt zu springen, sieht es leicht albern aus. Der Sprung ist halt irgendwie viel zu hoch und passt kaum zum eher realistischen Hasenlook. Aber der Sprung muss halt so hoch sein, damit das Spiel funktioniert.
Naja. Ich mach die technischen Baustellen fertig und kümmere mich dann ums Balancing. Vielleicht kann die Pflanze ja auch etwas langsamer wachsen, so dass man mehr von Links nach rechts hüpfen muss, mal schauen. Vielleicht akzeptiere ich auch einfach, dass es keine sehr gute Kombination aus Spielprinzip und Charakter war und baue doch noch die erste Idee mit den eher langsameren normalen Leveln mit Puzzelelementen ein (was dann vom Feeling etwas Richtung Braid (nur ohne die innovative Zeitmechanik) geht).
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- grinseengel
- Establishment
- Beiträge: 885
- Registriert: 29.03.2011, 13:47
- Echter Name: Andreas
Re: Harald Hoppelhase
Harald hoppelt ja schon kräftig umher. Ein Highscore wäre schon cool. So hat man ggf. eine höhere Motivation sich mit dem Spiel länger zu beschäftigen. Respekt für das "ich mache alles selber". So einen Hasen würde ich z.B, selber nicht hinbekommen. Im Malen bekomme ich eine glatte 6. Da helfen auch keine digitalen Helfer bei denen ich selber noch malen muss.
Website: http://www.pchobbyspieleschmiede.de/
Discord: https://discord.gg/PHZFBptfxJ
Fertige Projekte: https://grinseengel.itch.io/
Discord: https://discord.gg/PHZFBptfxJ
Fertige Projekte: https://grinseengel.itch.io/
- Schrompf
- Moderator
- Beiträge: 5040
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Harald Hoppelhase
Interessantes Konzept, und der Hase sieht schon echt gut aus! Bin mal gespannt, ob das Gameplay trägt.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Re: Harald Hoppelhase
Mir gefällt die Idee mit der wachsenden Pflanze echt gut und auch die Umsetzung weiß im Video schon zu gefallen. Das passt doch prima für einen vertikalen Endless Runner.
Das Grün ist mir etwas zu blass, aber das ist sicher eine Geschmacksfrage. Insgesamt machen die selbst gemalten Grafiken und der hoppelnde Hase dein Spiel sehr sympathisch.
Das Grün ist mir etwas zu blass, aber das ist sicher eine Geschmacksfrage. Insgesamt machen die selbst gemalten Grafiken und der hoppelnde Hase dein Spiel sehr sympathisch.
Das finde ich tatsächlich nicht schlimm, denn wenn du die Pflanze noch etwas aufmotzt, gleicht es sich wieder aus. Es könnten z.B. nach und nach bunte Blüten an ihr aufploppen. Vielleicht sind manche davon sogar giftig und verzerren das Bild, wenn Harald in sie hineinspringt? Jedenfalls kann ich mir gut vorstellen, dass die Pflanze mindestens genauso ansehnlich wird wie der Boden, aus dem sie wächst.
Re: Harald Hoppelhase
Bin schon ein gutes Stück weiter, aber leider frisst das ganze Drumherum übermäßig viel Zeit.
Da brauchts ein Hauptmenü von dem aus man das Spiel starten kann, im Spiel selber muss nach dem Sterben irgendetwas sinnvolles passieren, es braucht eine Bestenliste (die Punktejagt ist ja zentrale Motivation), Übergänge zwischen all diesen Zuständen und so weiter. Eigentlich hat meine Engine ja ein paar nette GUI-Klassen die ich natürlich dann auch gerne verwenden will, bloß fehlt da mal wieder was. Bisher kann man Menüs nur per Maus bedienen, aber für ein Spiel das eigentlich bloß die Pfeiltasten braucht und in dem man potentiell nach 15 Sekunden neu startet, will man ja nicht immer umgreifen. Außerdem muss man seinen Namen ja irgendwie in die Highscore eingeben können. Maßgeblich erschwert wird das ganze dadurch, dass ich kein vernünftiges Fokus-System habe - Buttons sind halt aktiv, wenn man sie anklickt, sonst nicht.
Insgesamt steck in so einem kleinen Spiel ungefähr gleich viel Logik in der Benutzeroberfläche wie im Spiel selber. Was ein stückchen pervers ist. Aber was soll man machen...
Immerhin sieht die Pflanze jetzt schon viel besser aus:
Da brauchts ein Hauptmenü von dem aus man das Spiel starten kann, im Spiel selber muss nach dem Sterben irgendetwas sinnvolles passieren, es braucht eine Bestenliste (die Punktejagt ist ja zentrale Motivation), Übergänge zwischen all diesen Zuständen und so weiter. Eigentlich hat meine Engine ja ein paar nette GUI-Klassen die ich natürlich dann auch gerne verwenden will, bloß fehlt da mal wieder was. Bisher kann man Menüs nur per Maus bedienen, aber für ein Spiel das eigentlich bloß die Pfeiltasten braucht und in dem man potentiell nach 15 Sekunden neu startet, will man ja nicht immer umgreifen. Außerdem muss man seinen Namen ja irgendwie in die Highscore eingeben können. Maßgeblich erschwert wird das ganze dadurch, dass ich kein vernünftiges Fokus-System habe - Buttons sind halt aktiv, wenn man sie anklickt, sonst nicht.
Insgesamt steck in so einem kleinen Spiel ungefähr gleich viel Logik in der Benutzeroberfläche wie im Spiel selber. Was ein stückchen pervers ist. Aber was soll man machen...
Immerhin sieht die Pflanze jetzt schon viel besser aus:
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Harald Hoppelhase
MUHAHAHAH...das kenne ich. Das Drumherum kann sehr viel Zeit fressen. DEVLOG
Zuletzt geändert von gombolo am 17.06.2023, 11:25, insgesamt 1-mal geändert.
- MEIN AKTELLES PROJEKT -> FirstStrike (PLAY THE DEMO) -> NEUER ENDBOSS -> schau dir das Video an
- WAS ICH SONST SO MACHEN -> Grafik und Design
- KUGELN FÜR ALLE -> BulletEmitter für Unity
- ICH MACH MAL SCHNELL EINE 3D ENGINE -> oyname 3DEngine
Re: Harald Hoppelhase
Nichts geht einfach... ist schon krass wie viel Zeit für die Sachen gebraucht wird die keiner wirklich wahrnimmt, aber alle erwarten. Der Hase müsst sich noch ein bisschen drehen, sieht etwas steif aus.
Discord: https://discord.gg/AWhsvN3 für Devader: http://devader.space
Re: Harald Hoppelhase
DASISTDOCHQUATSCHDASSMANANHANDEINESEINZELNENBILDESFEEDBACKZUANIMATIONENGEBENKANN oh warte...
Ja, gute Idee: Das Problem ist ja eigentlich, dass man nicht einfach eine Sprunganimation (für die ganze Zeit in der Luft) bauen kann, weil man ja nie weiß, wie lange der Sprung dauert (man kann ja unterschiedlich hoch springen, oder auch einfach nur ein bisschen (oder sehr viel) runterfallen, ganz ohne gesprungen zu sein.
Aber ich könnte Harald gemäß seiner Y-Geschwindigkeit rotieren. Mit einer passenden Abbildung (also nicht einfach stumpf linear, sondern z.B. gegen Maximalwinkel konvergierend) sollte das eigentlich ganz gut aussehen. Ich werds mal ausprobieren!
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- grinseengel
- Establishment
- Beiträge: 885
- Registriert: 29.03.2011, 13:47
- Echter Name: Andreas
Re: Harald Hoppelhase
Ja das mit dem UI ist schon immer eine Sache für sich. Wir wissen aber alle, wie wichtig die ist und wieviel Zeit und Testen da drauf geht. Aber im Grunde benötigt ja alles viel Zeit und was ist jetzt wichtiger als etwas Anderes. Ich glaube bei einen Spielprojekt ist da alles irgendwie wichtig, sonst wird es einem um die Ohren gehauen.Insgesamt steck in so einem kleinen Spiel ungefähr gleich viel Logik in der Benutzeroberfläche wie im Spiel selber. Was ein stückchen pervers ist. Aber was soll man machen...
Website: http://www.pchobbyspieleschmiede.de/
Discord: https://discord.gg/PHZFBptfxJ
Fertige Projekte: https://grinseengel.itch.io/
Discord: https://discord.gg/PHZFBptfxJ
Fertige Projekte: https://grinseengel.itch.io/
Re: Harald Hoppelhase
Da das Thema hier ja zuletzt angesprochen wurde, stelle ich hier mal meine "ziemlich sichere" Highscore-Implementierung vor. Das "ziemlich" bezieht sich darauf, dass ich mit beinahe minimalen Aufwand ein recht gutes Schutzniveau erreichen wollte. Aber seht selbst:
Jeder Eintrag besteht aus folgenden Elementen:
Der Online-Teil (an dem ich gerade noch arbeite) ist ein simples php Script, das zwei Modi hat: "Auslesen" gibt die gesamte Highscore-Liste als json-Datei zurück (die einfach so auf dem Server liegt), "Eintragen" nimmt alle 5 Werte als Parameter entgegen, überprüft ob der Eintrag "gültig" ist und schreibt sie dann in die besagte json-Datei.
Der Client speicher die Liste zunächst lokal (auch wieder als json, dann braucht man nur eine Lese-Funktion), überprüft aber auch, ob der Server erreichbar ist und lädt die Liste von dort runter. Beide Dateien werden Eintrag für Eintrag verarbeitet und dabei entsprechend sortiert und nur die besten x Einträge werden behalten.
Zum Synchronisieren muss man also einfach nur alle Einträge vom Server runterladen und danach alle Einträge zurück an den Server schicken (oder umgekehrt), beim hochladen muss man nicht zwischen eigenen und fremden Einträgen unterscheiden, weil ja beide "gültig" sind.
Was das ganze hoffentlich "ziemlich sicher" machen sollte: Der Hash ist ein SHA-256 Wert, berechnet mit PicoSHA2:
SHA-256 gilt, soweit ich weiß, als nicht praktikabel angreifbar, im Gegensatz zum alten MD5, das "ein bisschen" angreifbar ist. Die Implementierung habe ich in diesem Falle nicht weiter validiert (im Sinne von: Ist das eine von Crypto-Experten empfohlene Implementierung); wenn der Client und der PHP Server den selben Hash berechnen wird das schon passen.
time ist der Zeitstempel (Sekunden seit 1970 etc.) und hat 2 Zwecke: Einerseits möchte man den vielleicht mal anzeigen, andererseits verhindert er Duplikate. Der Server kann 2 identische Einträge einfach ignorieren. Aber was, wenn ein Spieler mehrmals genau 96 Punkte erreicht hat? Dann ist der Zeitstempel unterschiedlich und beide Einträge können angenommen werden. Der Clienten-Uhr kann man natürlich nicht wirklich vertrauen, weswegen Dinge wie "Nur Einträge der letzten 5 Sekunden zulassen" nicht sinnvoll sind. Man braucht sowas aber auch nicht wirklich, selbst wenn man sich auf die korrekte Zeit verlassen könnte. Alternativ kann der Server ja auch noch seinen eigenen Timestamp dazu packen, wenn man sich wirklich darauf verlassen muss.
An dieser Stelle steht und fällt natürlich alles mit dem "Salt" (das "magische zauberwort" oben im Code), weil der das einzige ist, was man kennen muss, um selber Hashwerte zu berechnen. Aber es ist ja ein prinzipielles Problem, dass das Spiel irgendwie Highscores "signieren" muss. Der Schlüssel um diese zu erzeugen (in diesem Falle der Salt) muss also beim Clienten sein, kann also vermutlich immer irgendwie missbraucht bzw. ausgelesen werden. Deswegen rede ich nur von "ziemlich sicher". In diesem Beispiel könnte ein Angreifer vermutlich alle Strings aus der exe Auslesen und dann alle Kombinationen ausprobieren um damit einen Hash zu basteln. Etwas sicherer wäre es vermutlich, den Salt zur Laufzeit zusammen zu bauen und das auf eine Art, die vom Compiler nicht direkt rausoptimiert wird. Alles was darüber hinaus geht ist mir als Entwickler dann schon wieder zu viel Arbeit. Die wirklich sichere Herangehensweise wäre es wohl, sämtliche Eingaben an den Server zu schicken, und die Spiellogik dort berechnen zu lassen. Inklusive Analyse ob die Eingaben von einem menschlichen Spieler oder einem Bot kommen; aber an dieser Stelle ist man dann bei Anti-Cheat Maßnahmen angekommen, wie sie die richtig großen Spiele (bei denen es auch um Echtgeld geht) betreiben. Und darauf hab ich keinen Bock.
Oh, die Versionsnummer ist übrigens wichtig, da sich mit unterschiedlichen Versionen ja die Spielbalance ändern kann. 100 Punkte in Version 1.0 kann ja schwieriger oder leichter sein als 100 Punkte in Version 1.1. Anhand der Versionsnummer kann der Server also einfach mehrere Highscores parallel führen.
Zusammengefasst:
- Manipulation von Einträgen wird verhindert.
- Mehrfacheinreichungen (Replay-Attacke) wird verhindert
- Validierung von Einträgen kann beim Server oder beim Clienten (aber wohl am besten bei beiden) stattfinden
Was meint ihr? Wurde irgendetwas offensichtliches übersehen? Mir erscheint dies ein ziemlich guter Kompromiss aus Sicherheit und Einfachheit der Implementierung, was ich immer irgendwie nett finde.
Jeder Eintrag besteht aus folgenden Elementen:
Code: Alles auswählen
struct Entry
{
string game_version;
string name;
int score;
std::time_t time;
string hash;
};
Der Client speicher die Liste zunächst lokal (auch wieder als json, dann braucht man nur eine Lese-Funktion), überprüft aber auch, ob der Server erreichbar ist und lädt die Liste von dort runter. Beide Dateien werden Eintrag für Eintrag verarbeitet und dabei entsprechend sortiert und nur die besten x Einträge werden behalten.
Zum Synchronisieren muss man also einfach nur alle Einträge vom Server runterladen und danach alle Einträge zurück an den Server schicken (oder umgekehrt), beim hochladen muss man nicht zwischen eigenen und fremden Einträgen unterscheiden, weil ja beide "gültig" sind.
Was das ganze hoffentlich "ziemlich sicher" machen sollte: Der Hash ist ein SHA-256 Wert, berechnet mit PicoSHA2:
Code: Alles auswählen
picosha2::hash256_hex_string(
e.game_version +
e.name +
to_string(e.score) +
to_string(e.time) +
"magisches zauberwort",
output);
time ist der Zeitstempel (Sekunden seit 1970 etc.) und hat 2 Zwecke: Einerseits möchte man den vielleicht mal anzeigen, andererseits verhindert er Duplikate. Der Server kann 2 identische Einträge einfach ignorieren. Aber was, wenn ein Spieler mehrmals genau 96 Punkte erreicht hat? Dann ist der Zeitstempel unterschiedlich und beide Einträge können angenommen werden. Der Clienten-Uhr kann man natürlich nicht wirklich vertrauen, weswegen Dinge wie "Nur Einträge der letzten 5 Sekunden zulassen" nicht sinnvoll sind. Man braucht sowas aber auch nicht wirklich, selbst wenn man sich auf die korrekte Zeit verlassen könnte. Alternativ kann der Server ja auch noch seinen eigenen Timestamp dazu packen, wenn man sich wirklich darauf verlassen muss.
An dieser Stelle steht und fällt natürlich alles mit dem "Salt" (das "magische zauberwort" oben im Code), weil der das einzige ist, was man kennen muss, um selber Hashwerte zu berechnen. Aber es ist ja ein prinzipielles Problem, dass das Spiel irgendwie Highscores "signieren" muss. Der Schlüssel um diese zu erzeugen (in diesem Falle der Salt) muss also beim Clienten sein, kann also vermutlich immer irgendwie missbraucht bzw. ausgelesen werden. Deswegen rede ich nur von "ziemlich sicher". In diesem Beispiel könnte ein Angreifer vermutlich alle Strings aus der exe Auslesen und dann alle Kombinationen ausprobieren um damit einen Hash zu basteln. Etwas sicherer wäre es vermutlich, den Salt zur Laufzeit zusammen zu bauen und das auf eine Art, die vom Compiler nicht direkt rausoptimiert wird. Alles was darüber hinaus geht ist mir als Entwickler dann schon wieder zu viel Arbeit. Die wirklich sichere Herangehensweise wäre es wohl, sämtliche Eingaben an den Server zu schicken, und die Spiellogik dort berechnen zu lassen. Inklusive Analyse ob die Eingaben von einem menschlichen Spieler oder einem Bot kommen; aber an dieser Stelle ist man dann bei Anti-Cheat Maßnahmen angekommen, wie sie die richtig großen Spiele (bei denen es auch um Echtgeld geht) betreiben. Und darauf hab ich keinen Bock.
Oh, die Versionsnummer ist übrigens wichtig, da sich mit unterschiedlichen Versionen ja die Spielbalance ändern kann. 100 Punkte in Version 1.0 kann ja schwieriger oder leichter sein als 100 Punkte in Version 1.1. Anhand der Versionsnummer kann der Server also einfach mehrere Highscores parallel führen.
Zusammengefasst:
- Manipulation von Einträgen wird verhindert.
- Mehrfacheinreichungen (Replay-Attacke) wird verhindert
- Validierung von Einträgen kann beim Server oder beim Clienten (aber wohl am besten bei beiden) stattfinden
Was meint ihr? Wurde irgendetwas offensichtliches übersehen? Mir erscheint dies ein ziemlich guter Kompromiss aus Sicherheit und Einfachheit der Implementierung, was ich immer irgendwie nett finde.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Harald Hoppelhase
Mein bester Rat ist: lass die Online-Highscore weg.
Du musst ja den Highscore-Server bis in alle Ewigkeit betreiben und immer kontrollieren, ob mit dem Highscore-System quatsch gemacht wird.
Mach erstmal die Highscores nur lokal und mach erstmal das Game fertig/interessanter.
Wenn du die aber unbedingt haben willst:
1)
Du könntest beim ersten Start des Spiels für die Installation eine GUID erzeugen. Die packst du mit in die Daten rein und weißt dann so, von welchem User der Eintrag kommt. Wenn dann ein User quatsch macht, kannst du alle seine Einträge aus der Highscore-Liste löschen und den User sperren. (Also der Upload einer Highscore wird einfach vom Server ignoriert, wird aber mit "ok, passt" beantwortet)
2)
Du könntest das ganze zusätzlich mit einem Pepper verschlüsseln. Da kannst du einfach als Key den Hash der Executable nehmen.
Dann musst du Server-Seitig jede Release-Version eintragen, das ist erstmal ein Nachteil, aber du kannst dann erkennen ob die Clients auf der aktuellen Version sind. Zudem wird das dann nicht als String irgendwo gespeichert, das macht ein Reverse-Engineering frickelig.
Eine gute Verschlüsselung dafür wäre XChacha20.
3)
Für den Timestamp kannst du Beginn und Ende des Spiels nehmen.
Den Timestamp solltest du auf jeden Fall auch server-seitig kontrollieren (z.B. ob das Ende +/- 5 min ist und ob die Gesamt-Spielzeit sinnvoll ist)
Diese 3 Schritte würde ich auf jeden Fall noch machen.
Aber wie du schon gesagt hast:
eigentlich müsste die Physik-Engine (du hast ja wahrscheinlich/hoffentlich fixed steps) den Spielverlauf speichern und mit hochladen - und den müsstest du Serverseitig auswerten um auch nur annähernd sicher zu sein dass da nix gecheatet wurde.
Du musst ja den Highscore-Server bis in alle Ewigkeit betreiben und immer kontrollieren, ob mit dem Highscore-System quatsch gemacht wird.
Mach erstmal die Highscores nur lokal und mach erstmal das Game fertig/interessanter.
Wenn du die aber unbedingt haben willst:
1)
Du könntest beim ersten Start des Spiels für die Installation eine GUID erzeugen. Die packst du mit in die Daten rein und weißt dann so, von welchem User der Eintrag kommt. Wenn dann ein User quatsch macht, kannst du alle seine Einträge aus der Highscore-Liste löschen und den User sperren. (Also der Upload einer Highscore wird einfach vom Server ignoriert, wird aber mit "ok, passt" beantwortet)
2)
Du könntest das ganze zusätzlich mit einem Pepper verschlüsseln. Da kannst du einfach als Key den Hash der Executable nehmen.
Dann musst du Server-Seitig jede Release-Version eintragen, das ist erstmal ein Nachteil, aber du kannst dann erkennen ob die Clients auf der aktuellen Version sind. Zudem wird das dann nicht als String irgendwo gespeichert, das macht ein Reverse-Engineering frickelig.
Eine gute Verschlüsselung dafür wäre XChacha20.
3)
Für den Timestamp kannst du Beginn und Ende des Spiels nehmen.
Den Timestamp solltest du auf jeden Fall auch server-seitig kontrollieren (z.B. ob das Ende +/- 5 min ist und ob die Gesamt-Spielzeit sinnvoll ist)
Diese 3 Schritte würde ich auf jeden Fall noch machen.
Aber wie du schon gesagt hast:
eigentlich müsste die Physik-Engine (du hast ja wahrscheinlich/hoffentlich fixed steps) den Spielverlauf speichern und mit hochladen - und den müsstest du Serverseitig auswerten um auch nur annähernd sicher zu sein dass da nix gecheatet wurde.
Re: Harald Hoppelhase
Ich frag mich bei so manchen IT-Sicherheitsmaßnahmen, was eigentlich das schlimme Horrorszenario ist, das hier versucht wird zu verhindern. Im echten Leben schließt man ja auch seine Haustür ab, obwohl man weiß, dass absolut jeder Einbrecher einen Stein durchs Fenster werfen kann. Man lädt Einbrecher nicht ein, indem man die Tür offen stehen lässt, aber eigentlich erwartet man nicht, dass überhaupt jemand kommt. Im Gegensatz zu einer Bank, wo man fest davon ausgeht, dass Leute angreifen und deshalb der Tresorraum keine Glasfenster zur Straße hin hat.
Das Spiel werden vielleicht 50 Leute runterladen und ausprobieren, über die Jahre stolpern vielleicht noch ein paar mehr darüber. Klar könnte man aus Spaß ausprobieren, ein bisschen was kaputt zu machen. Aber wenn man halt ein Arsch ist, dann kann man auch im echten Leben an vielen Stellen Dinge kaputt machen, ohne gleich erwischt zu werden. Und trotzdem besteht nicht das ganze öffentliche Leben aus Hochsicherheitsbereichen.
Ehrlich gesagt ist vermutlich der schlimmere Vandalismus, dass jemand statt seines Namens irgendwelche fragwürdigen Phrasen eintippt. Aber selbst wenn, was dann? Dann sind eine handvoll Spieler "offended" oder "getriggert" (gibt ja heutzutage gefühlt nichts schrecklicheres was man jemanden antun kann) und verpetzen mich bei der Internetpolizei? Ehh.
Aber zu den Punkten:
1) GUID klingt gut. Wie mache ich, dass die anonym aber gerätespezifisch ist? Und z.B. nach einer Neuinstallation gleich bleibt? Trivial könnte ich beim ersten Start eine Zufallszahl generieren und speichern, ggf. noch mit einem Hash abgesichert, damit man sie nicht ändern kann. Besser wäre es natürlich z.B. eine Gerätenummer auszulesen und zu hashen (damit sie anonym ist), aber was konkret nimmt man da und wie krieg ich das in 5 Zeilen in mein Programm rein?
2) Pepper verstehe ich nicht. Im Sinne von "Secret Hash" ist ja das was ich jetzt schon benutze eher Pepper als Salt. Damit signiere ich ja die Nachricht. Warum den Hash der Executable? Damit man selbige nicht manipulierne kann? Aber wenn jemand eh schon die Exe ändert, wie wahrscheinlich ist es dann, dass er nicht auch den Teil wo der Hash berechnet wird ändert und entsprechend den Hash der unmodifizierten Version verwendet? Aktuell ist die Versionsnummer ein simpler String, per Hash vor Manipulation geschützt. Den Hash der Exe zu nehmen erscheint mir komplizierter aber nicht offensichtlich sicherer (außerdem ist der Hash ja auch für die lokale Highscore, und es könnte ja durchaus Updates geben, die die Exe verändern, aber die selben Highscores erlauben. Dann müsste ich in der Exe eine Liste an Hashs aller bisherigen Versionen speichern, da wirds dann langsam recht kompliziert).
Und was konkret ist der Vorteil von XChacha20? Was wird dadurch besserer / sicherer als es aktuell ist? Ich brauche ja nichtmal Transportverschlüsselung zum Server: Wenn die Nachricht geändert wird, wird sie verworfen. Wird die Nachricht ausgelesen dann, uhm, also du schickst deinen Namen gerade an eine öffentliche Highscore-Liste, du willst also gerade schon, dass jeder deinen Eintrag lesen kann...
3) Die Timestamps verstehe ich auch nicht. Entweder man geht davon aus, dass die Daten durch den Hash vor Manipulation geschützt sind, oder eben nicht. Wenn die Punktzahl geschützt ist, brauche ich keine weiteren Maßnahmen, sind die Daten nicht geschützt kann man genau so gut Beginn und Ende der Timestamps manipulieren. Was gewinnt man hier?
Aktuell ist der timestamp eigentlich wirklich eher eine einmalige "Zufallszahl" als Schutz vor Replay-Attacken. Für die Online-Highscore sollte man wirklich die Serverzeit nehmen, aber für die lokale Highscore ist ein gespeicherter Timestamp dann doch ganz nett. Aktuell wird das Datum aber eh nicht angezeigt.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Harald Hoppelhase
Meiner Meinung nach das Rechtsrisiko. Du erlaubst Leuten praktisch beliebige Inhalte (ich gehe davon aus deine Highscores haben ein Username Freitext) auf deinem Webserver zu platzieren und die Leute können das insbesondere nutzen um Völker zu verhetzen oder Jugenden zu gefährden und ich hätte kein Bock auf den Stress (auch wenn ich die Rechtslage nicht genau kenne, was natürlich selbst schon ein Hindernis ist). Du tust das weiter unten als lustig ab, aber tatsächlich sind das Straftatbestände und die Ermittlungen werden in erster Näherung mal gegen dich als Betreiber laufen, selbst wenn das am Ende für dich ausgeht, den Stress hattest du trotzdem.
Technisch ist das Risiko praktisch nonexistent. Häng den Server halt nicht in ein Netzwerk mit irgendwas, was du nochmal brauchen könntest und wenn es schief geht hältst du ein metaphorisches Feuerzeug dran.
Auf dem Niveau ist dein Vorschlag sinnvoll und alles weitere ist ein Arms Race, das dir nichts bringen wird. Wie du richtig erkannt hast muss der Client das Secret kennen, egal welchen coolen Algorithmus du sonst verwendest und das bedeutet dass ein Angreifer das Secret aus dem Client reversen kann. Wer dir etwas anderes erzählt verarscht dich. Die Gleichung geht nur darüber wer schneller für den anderen nervig werden kann, du für den Angreifer oder der Angreifer für dich.Im echten Leben schließt man ja auch seine Haustür ab, obwohl man weiß, dass absolut jeder Einbrecher einen Stein durchs Fenster werfen kann. Man lädt Einbrecher nicht ein, indem man die Tür offen stehen lässt, aber eigentlich erwartet man nicht, dass überhaupt jemand kommt.
Re: Harald Hoppelhase
-PHP - bad word filter drauf
-Dummyplayername, bis neue Scores, bzw deren Username durch Admin freigeschaltet werden?
-"Melden"-Button
Aber mal ehrlich... unter der Prämisse dürftest Du wirklich gar keine UGC Websachen mehr anbieten.
-Dummyplayername, bis neue Scores, bzw deren Username durch Admin freigeschaltet werden?
-"Melden"-Button
Aber mal ehrlich... unter der Prämisse dürftest Du wirklich gar keine UGC Websachen mehr anbieten.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Harald Hoppelhase
Korrekt. Das (damals) sogenannte Web 2.0 ist entstanden als das Internet noch famously ein rechtsfreier Raum war. Wenn es das Web in seiner jetzigen Form noch nicht geben würde, wohl aber die Regularien, würde es sich in Deutschland niemals durchsetzen.
Deswegen sind die Leute ja so geil auf Krypto (und nennen das Web 3), weil sie es als unreguliert wahrnehmen.
Re: Harald Hoppelhase
Hab jetzt nochmal ein älteres Urteil bzgl Foren und Gästebücher nachgeschaut.
Du hast schon Recht, dass man mit in der Haftung ist, jedoch erst, wenn man über einen rechtswidrigen Eintrag informiert worden ist, bzw. nicht in regelmäsigen Abständen den Inhalt kontrolliert.
Man kann sich ja noch jeden Tag eine Liste der Neueintragungen zum Review per eMail schicken lassen. Damit dürfte man dann ziemlich safe sein.
EDIT: Ich verstehe auch total, dass man Betreiber hier in die Pflicht nehmen muss, da man als geschädigte Person sonst keine Handhabe hätte. Jedoch muss man auch je nach Schwere differenzieren. Bin mir ziemlich sicher, dass ein Gericht bewerten kann, ob man -wie hier in einem Forum- einen beliebigen Klartext verfassen kann, oder in einer Highscore iwie kryptische Nachrichten abgesetzt werden.
Du hast schon Recht, dass man mit in der Haftung ist, jedoch erst, wenn man über einen rechtswidrigen Eintrag informiert worden ist, bzw. nicht in regelmäsigen Abständen den Inhalt kontrolliert.
Man kann sich ja noch jeden Tag eine Liste der Neueintragungen zum Review per eMail schicken lassen. Damit dürfte man dann ziemlich safe sein.
EDIT: Ich verstehe auch total, dass man Betreiber hier in die Pflicht nehmen muss, da man als geschädigte Person sonst keine Handhabe hätte. Jedoch muss man auch je nach Schwere differenzieren. Bin mir ziemlich sicher, dass ein Gericht bewerten kann, ob man -wie hier in einem Forum- einen beliebigen Klartext verfassen kann, oder in einer Highscore iwie kryptische Nachrichten abgesetzt werden.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Harald Hoppelhase
Alexander Kornrumpf hat geschrieben: ↑15.05.2023, 11:55 selbst wenn das am Ende für dich ausgeht, den Stress hattest du trotzdem.
Re: Harald Hoppelhase
Evtl kannst du den Hasen leicht schief in die Luft schicken, er sollte sich mit den Hinterbeinen abstossen. Die Schräge lage könntest du dann so belassen. Vorder-/Hinterfüsse könnten seperat gehandhabt werden, aber das wird schon wieder komplizierter ;)Jonathan hat geschrieben: ↑13.05.2023, 16:21 DASISTDOCHQUATSCHDASSMANANHANDEINESEINZELNENBILDESFEEDBACKZUANIMATIONENGEBENKANN oh warte...
Ja, gute Idee: Das Problem ist ja eigentlich, dass man nicht einfach eine Sprunganimation (für die ganze Zeit in der Luft) bauen kann, weil man ja nie weiß, wie lange der Sprung dauert (man kann ja unterschiedlich hoch springen, oder auch einfach nur ein bisschen (oder sehr viel) runterfallen, ganz ohne gesprungen zu sein.
Aber ich könnte Harald gemäß seiner Y-Geschwindigkeit rotieren. Mit einer passenden Abbildung (also nicht einfach stumpf linear, sondern z.B. gegen Maximalwinkel konvergierend) sollte das eigentlich ganz gut aussehen. Ich werds mal ausprobieren!
Discord: https://discord.gg/AWhsvN3 für Devader: http://devader.space
Re: Harald Hoppelhase
Kurz zu den Punkten:
1)
brauchst du garnicht gerätespezifisch machen, denke ich. Einfach beim ersten Aufruf der App einen erzeugen (ich glaube jedes OS hat eine getGUID() funktion irgendwo) und fortan verwenden. Ist quasi eine Random UserID mit der Eigenschaft, dass kaum 2 Rechner die gleiche ID erzeugen.
2)
im Prinzip ist es gleich wie dein Hash, und viel zusätzlichen Schutz bietet es nicht, aber wenn man halt den hash der exe benutzt, ist es (ein wenig) schwieriger das zu manipulieren und du hast halt keinen festen "Key" der irgendwo in der .text Section der exe steht.
Es geht ja nur darum den Angreifer zu ärgern und davon zu überzeugen, dass der Aufwand es nicht wert ist. Wenn jemand bei 2 Verschlüsselungen (Hash und Encryption) dann immer noch davon überzeugt ist, dass er das manipulieren will, hast du wenig Chancen das aufzuhalten.
Ganz konkret: erhöht den Schwierigkeitsgrad von "cat harald.exe" zu "win32dasm harald.exe" plus ein wenig Nachforschung, wo der Hash herkommt.
Die Hürde ist denke ich schon signifikant höher.
Und ja, stimmt, du müsstest Serverseitig alle Exe-hashes speichern/kennen. Oder du speicherst nur den aktuellsten Hash und bittest den User bei allen anderen Hashes die Version zu updaten ("Für den Upload der Highscore ist eine aktuelle Version des Programms notwendig").
Aber damit kannst du halt verhindern, dass Manipulierte exe einfach durchgehen (und die User zum Updaten zwingen ;-P).
Aber da musst du selbst entscheiden, ob es den Aufwand wert ist. Vielleicht nicht.
3)
Wenn man die "Full-Blown" Version nehmen würde, müsste man wie gesagt die Physiksimulation (ein Replay) speichern und mitsenden, und dann Serverseitig auswerten. Das ist vermutlich zu komplex.
Mein Vorschlag wäre einfach eine "kleine" Version davon. Bei einem Ende-Beginn < 0 ist schonmal was komisch, bei Ende-Beginn=10 Sekunden und gleichzeitig ein Score von 10.000 stimmt auch was nicht. Du kannst halt eine simple Logik fahren und schauen obs grob hinkommt.
Vielleicht fällt dir da auch noch was besseres ein, wie du mit minimalsten Daten schon das ein oder andere auf Konsistenz prüfen kannst.
Das Beste daran ist halt, dass du falsche Sachen serverseitig ignorieren kannst.
D.h. der Angreifer muss mühselig testen, ob und wann seine Manipulation Erfolg hat oder nicht. Er kennt ja deine serverseitigen Regeln nicht.
Aber auch da: Ist es den Aufwand wert? Keine Ahnung, fand jetzt einen 2. Timestamp super einfach und besser als gar keine Konsistenz-Prüfung, aber YMMV :-)
1)
brauchst du garnicht gerätespezifisch machen, denke ich. Einfach beim ersten Aufruf der App einen erzeugen (ich glaube jedes OS hat eine getGUID() funktion irgendwo) und fortan verwenden. Ist quasi eine Random UserID mit der Eigenschaft, dass kaum 2 Rechner die gleiche ID erzeugen.
2)
im Prinzip ist es gleich wie dein Hash, und viel zusätzlichen Schutz bietet es nicht, aber wenn man halt den hash der exe benutzt, ist es (ein wenig) schwieriger das zu manipulieren und du hast halt keinen festen "Key" der irgendwo in der .text Section der exe steht.
Es geht ja nur darum den Angreifer zu ärgern und davon zu überzeugen, dass der Aufwand es nicht wert ist. Wenn jemand bei 2 Verschlüsselungen (Hash und Encryption) dann immer noch davon überzeugt ist, dass er das manipulieren will, hast du wenig Chancen das aufzuhalten.
Ganz konkret: erhöht den Schwierigkeitsgrad von "cat harald.exe" zu "win32dasm harald.exe" plus ein wenig Nachforschung, wo der Hash herkommt.
Die Hürde ist denke ich schon signifikant höher.
Und ja, stimmt, du müsstest Serverseitig alle Exe-hashes speichern/kennen. Oder du speicherst nur den aktuellsten Hash und bittest den User bei allen anderen Hashes die Version zu updaten ("Für den Upload der Highscore ist eine aktuelle Version des Programms notwendig").
Aber damit kannst du halt verhindern, dass Manipulierte exe einfach durchgehen (und die User zum Updaten zwingen ;-P).
Aber da musst du selbst entscheiden, ob es den Aufwand wert ist. Vielleicht nicht.
3)
Wenn man die "Full-Blown" Version nehmen würde, müsste man wie gesagt die Physiksimulation (ein Replay) speichern und mitsenden, und dann Serverseitig auswerten. Das ist vermutlich zu komplex.
Mein Vorschlag wäre einfach eine "kleine" Version davon. Bei einem Ende-Beginn < 0 ist schonmal was komisch, bei Ende-Beginn=10 Sekunden und gleichzeitig ein Score von 10.000 stimmt auch was nicht. Du kannst halt eine simple Logik fahren und schauen obs grob hinkommt.
Vielleicht fällt dir da auch noch was besseres ein, wie du mit minimalsten Daten schon das ein oder andere auf Konsistenz prüfen kannst.
Das Beste daran ist halt, dass du falsche Sachen serverseitig ignorieren kannst.
D.h. der Angreifer muss mühselig testen, ob und wann seine Manipulation Erfolg hat oder nicht. Er kennt ja deine serverseitigen Regeln nicht.
Aber auch da: Ist es den Aufwand wert? Keine Ahnung, fand jetzt einen 2. Timestamp super einfach und besser als gar keine Konsistenz-Prüfung, aber YMMV :-)
Re: Harald Hoppelhase
Neue Frage: Wie mache ich am besten ein HTTP Request in C++?
Ein Standard HTTP 1.0 (oder was auch immer) sollte man ja recht leicht von Hand machen können. Dafür sollte es also auch entsprechend kleine und kompakte Codeschnipsel geben, die man einfach verwenden kann. Aber vielleicht will man keine uralten Protokolle verwenden, sondern etwas halbwegs aktuelles. Ich brauche eigentlich kein https, die Daten selbst sind ja ohnehin signiert und öffentlich (Benutzer wollen ja gerade, dass jeder weiß, wie viele Punkte sie haben), aber ich mache mir ein wenig Gedanken über Firewalls und so. Es sieht heutzutage im Netzwerk vielleicht einfach nicht gut aus, Dinge nicht zu verschlüsseln. Aber ist das wirklich eine relevante Überlegung bezüglich Robustheit?
Für HTTP gibt es tonnenweise Optionen:
- https://superpowered.com/network-library-list
- https://en.cppreference.com/w/cpp/links/libs (unter Communication)
Mein Problem ist: Ich brauche das ja nur an einer kleinen Stelle, ich programmiere hier ja kein Online-Spiel. Ich will eigentlich keine dicke Abhängigkeit haben, die ich erst mit CMake kompillieren und dann irgendwie reinlinken muss. Ich hätte am liebsten etwas, wo ich eine handvoll Dateien habe, die ich ohne weitere Einstellungen in meinen Projektordner schmeiße und mitkompilliere und dann einfach benutzen kann.
Viele der Bibliotheken bieten dir gleich einen ganzen Haufen von Funktionen, z.B. ein HTTP-Server der 5 Millionen Verbindungen verarbeiten kann. Eine andere sah klein und nett aus, modernes C++ und alles, aber dann stellt sich heraus, dass es einfach ein kleiner Wrapper über Curl ist, was ja auch wieder eine Mammut-Abhängigkeit ist. Wieder andere sehen eigentlich klein und nett und self-contained aus, aber irgendwie auch veraltet und nicht mehr gepflegt. Ich hab ein bisschen Angst dass beispielsweise mein Webserver irgendwann ein Upgrade bekommt, dann eine alte Protokollversion deprecated ist und dann die Online-Highscore direkt kaputt geht. Hmg.
Und wenn es richtung SSL geht, findet man gleich gar nichts mehr, was behauptet selfcontained zu sein. Gut, macht Sinn, SSL hat ja ein Dutzend unterschiedlicher Algorithmen und die wollen sauber implementiert sein, das ist halt einfach eine ganze Menge an Komplexität. Da sollte man vermutlich wirklich auf eine der großen, etablierten Bibliotheken zurückgreifen.
Aktuell ist meine beste Idee, Boost.Beast zu benutzen. Boost ist zwar auch ein Klotz, aber wenigstens ziemlich etabliert und macht in der Regel keinen Ärger. Vermutlich auch erstmal ohne SSL, außer jemand überzeugt mich noch, dass man das aus Robustnessgründen wirklich dringend verwenden sollte.
Hat jemand noch andere Ideen?
Ein Standard HTTP 1.0 (oder was auch immer) sollte man ja recht leicht von Hand machen können. Dafür sollte es also auch entsprechend kleine und kompakte Codeschnipsel geben, die man einfach verwenden kann. Aber vielleicht will man keine uralten Protokolle verwenden, sondern etwas halbwegs aktuelles. Ich brauche eigentlich kein https, die Daten selbst sind ja ohnehin signiert und öffentlich (Benutzer wollen ja gerade, dass jeder weiß, wie viele Punkte sie haben), aber ich mache mir ein wenig Gedanken über Firewalls und so. Es sieht heutzutage im Netzwerk vielleicht einfach nicht gut aus, Dinge nicht zu verschlüsseln. Aber ist das wirklich eine relevante Überlegung bezüglich Robustheit?
Für HTTP gibt es tonnenweise Optionen:
- https://superpowered.com/network-library-list
- https://en.cppreference.com/w/cpp/links/libs (unter Communication)
Mein Problem ist: Ich brauche das ja nur an einer kleinen Stelle, ich programmiere hier ja kein Online-Spiel. Ich will eigentlich keine dicke Abhängigkeit haben, die ich erst mit CMake kompillieren und dann irgendwie reinlinken muss. Ich hätte am liebsten etwas, wo ich eine handvoll Dateien habe, die ich ohne weitere Einstellungen in meinen Projektordner schmeiße und mitkompilliere und dann einfach benutzen kann.
Viele der Bibliotheken bieten dir gleich einen ganzen Haufen von Funktionen, z.B. ein HTTP-Server der 5 Millionen Verbindungen verarbeiten kann. Eine andere sah klein und nett aus, modernes C++ und alles, aber dann stellt sich heraus, dass es einfach ein kleiner Wrapper über Curl ist, was ja auch wieder eine Mammut-Abhängigkeit ist. Wieder andere sehen eigentlich klein und nett und self-contained aus, aber irgendwie auch veraltet und nicht mehr gepflegt. Ich hab ein bisschen Angst dass beispielsweise mein Webserver irgendwann ein Upgrade bekommt, dann eine alte Protokollversion deprecated ist und dann die Online-Highscore direkt kaputt geht. Hmg.
Und wenn es richtung SSL geht, findet man gleich gar nichts mehr, was behauptet selfcontained zu sein. Gut, macht Sinn, SSL hat ja ein Dutzend unterschiedlicher Algorithmen und die wollen sauber implementiert sein, das ist halt einfach eine ganze Menge an Komplexität. Da sollte man vermutlich wirklich auf eine der großen, etablierten Bibliotheken zurückgreifen.
Aktuell ist meine beste Idee, Boost.Beast zu benutzen. Boost ist zwar auch ein Klotz, aber wenigstens ziemlich etabliert und macht in der Regel keinen Ärger. Vermutlich auch erstmal ohne SSL, außer jemand überzeugt mich noch, dass man das aus Robustnessgründen wirklich dringend verwenden sollte.
Hat jemand noch andere Ideen?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: Harald Hoppelhase
kA ob dir das was bringt. Ist wohl eher straight http.
Das meint chatgpt:
Das meint chatgpt:
To make a simple HTTP request in C++ without using an external library, you can use the standard C++ networking library introduced in C++11. Here's an example of a basic HTTP GET request function:
Code: Alles auswählen
#include <iostream>
#include <string>
#include <sstream>
#include <istream>
#include <ostream>
#include <memory>
#include <array>
#include <vector>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
const int kBufferSize = 4096;
// HTTP GET Request
std::string httpRequest(const std::string& url) {
std::string response;
// Parse the URL
std::size_t hostStart = url.find("://");
if (hostStart == std::string::npos) {
std::cerr << "Invalid URL format" << std::endl;
return response;
}
hostStart += 3; // Move past "://"
std::size_t pathStart = url.find('/', hostStart);
std::string host = url.substr(hostStart, pathStart - hostStart);
std::string path = url.substr(pathStart);
// Create a socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
std::cerr << "Failed to create socket" << std::endl;
return response;
}
// Resolve the host IP address
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr(host.c_str());
server.sin_family = AF_INET;
server.sin_port = htons(80);
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
std::cerr << "Connection failed" << std::endl;
return response;
}
// Create the HTTP GET request
std::ostringstream requestStream;
requestStream << "GET " << path << " HTTP/1.1\r\n"
<< "Host: " << host << "\r\n"
<< "Connection: close\r\n"
<< "\r\n";
std::string httpRequest = requestStream.str();
// Send the request
if (send(sock, httpRequest.c_str(), httpRequest.length(), 0) < 0) {
std::cerr << "Failed to send request" << std::endl;
close(sock);
return response;
}
// Receive and process the response
std::array<char, kBufferSize> buffer;
while (true) {
ssize_t bytesRead = recv(sock, buffer.data(), buffer.size(), 0);
if (bytesRead <= 0)
break;
response.append(buffer.data(), bytesRead);
}
close(sock);
return response;
}
int main() {
std::string url = "http://example.com";
std::string response = httpRequest(url);
std::cout << "Response:\n" << response << std::endl;
return 0;
}
Re: Harald Hoppelhase
Das war ja klar: Mein sehr guter und extrem sinnvoll vorkonfigurierter angemietete Webserver macht eine Zwangsumleitung von HTTP auf HTTPS. So komme ich erstmal nicht weiter. Jetzt kann ich entweder schauen, wie ich den Server umkonfigurieren kann (aber eigentlich klingt das ja modern und sinnvoll), oder halt doch SSL einbauen und es gleich "richtig" machen.
Übrigens: boost::beast ist genau das, was von man boost zu erwarten hat. Ein endloses Template- und Vererbungsgewichse ohne einen verschwendeten Gedanken an Usability. Ich programmiere jetzt seit, uhm, 20 Jahren C++ und habe trotzdem 10 Minuten gebraucht um zu verstehen, wie man die HTTP-Version übergeben muss. Weil weder der Quellcode lesbar, noch die Dokumentation nützlich ist.
Sorry, aber ein HTTP Get ist eine triviale Operation, also aus Benutzersicht: String rein (Webadresse) - String raus (Webseiteninhalt). Wieso brauche ich eine halbe Stunde um das mit boost umzusetzen? Vermutlich ist die oberste Designphilosophie einfach nicht Benutzbarkeit sondern "möglichst elegante (gemessen in Komplexität der Vererbungshierarchien und der Templateparameter) C++ Implementierung". Schade...
Übrigens: boost::beast ist genau das, was von man boost zu erwarten hat. Ein endloses Template- und Vererbungsgewichse ohne einen verschwendeten Gedanken an Usability. Ich programmiere jetzt seit, uhm, 20 Jahren C++ und habe trotzdem 10 Minuten gebraucht um zu verstehen, wie man die HTTP-Version übergeben muss. Weil weder der Quellcode lesbar, noch die Dokumentation nützlich ist.
Sorry, aber ein HTTP Get ist eine triviale Operation, also aus Benutzersicht: String rein (Webadresse) - String raus (Webseiteninhalt). Wieso brauche ich eine halbe Stunde um das mit boost umzusetzen? Vermutlich ist die oberste Designphilosophie einfach nicht Benutzbarkeit sondern "möglichst elegante (gemessen in Komplexität der Vererbungshierarchien und der Templateparameter) C++ Implementierung". Schade...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Schrompf
- Moderator
- Beiträge: 5040
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Harald Hoppelhase
Ein HTTP-request ist ja erstmal nur ein Text nach ner Konvention. Ich habe das in meiner Highscore-Lib damals genau so gemacht. SSL hingegen... Da isses vorbei mit Selberbauen. Auch wenn man sicher in den Wochen ne Menge lernen würde :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Harald Hoppelhase
Weiß nicht ob dir das jetzt als Datenpunkt hilft, da völlig orthogonal zu deinem Problem, aber ich hätte das als AWS Lambda (oder äquivalent bei einem anderen Anbieter) implementiert.Jonathan hat geschrieben: ↑18.05.2023, 23:57 Das war ja klar: Mein sehr guter und extrem sinnvoll vorkonfigurierter angemietete Webserver macht eine Zwangsumleitung von HTTP auf HTTPS. So komme ich erstmal nicht weiter. Jetzt kann ich entweder schauen, wie ich den Server umkonfigurieren kann (aber eigentlich klingt das ja modern und sinnvoll), oder halt doch SSL einbauen und es gleich "richtig" machen.
Re: Harald Hoppelhase
Ist sicherlich eine gute eigenständige Lösung. Aber meine Beweggründen sind, dass ich für meine Webseite, wo man das Spiel ja auch runterladen können wird, schon einen Webserver angemietet habe der halt schon läuft und ok konfiguriert ist und bezahlt wird und für den ich schon eine Quick-Connect Verknüpfung in meinem Lieblings FTP Programm habe. Ich benutze nichtmal eine Datenbank, einfach 2 PHP-Dateien (get und submit) und eine json-Datei im selben Verzeichnis. Das läuft absolut überall und wenn ich mit der Webseite mal umziehe muss ich nur die Dateien kopieren und ggf. die URL anpassen aber sonst nix machen. Und das erschien mir irgendwie nett.Alexander Kornrumpf hat geschrieben: ↑19.05.2023, 19:18 Weiß nicht ob dir das jetzt als Datenpunkt hilft, da völlig orthogonal zu deinem Problem, aber ich hätte das als AWS Lambda (oder äquivalent bei einem anderen Anbieter) implementiert.
Ich probiere btw. gerade mein Glück mit POCO. Angeblich ist OpenSSL unter Linux und Mac einfach zu installieren und für Windows scheint es ein Szstemeigenes Fallback zu geben, das POCO benutzen kann und ansonsten könnte es reichen, einfach eine passende OpenSSL.dll ins Verzeichnis zu legen. Somit würde SSL nur so halb als Abhängigkeit zählen, was die Situation für mich ein wenig erträglicher macht. Aber mal schauen, ich werde berichten sobald etwas funktioniert.
(Aber ich bin immer noch enttäuscht, dass es in C++ hundertmal schwieriger ist, einen Text von einer Webseite zu laden als einen Text aus einer Datei zu laden.)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Harald Hoppelhase
Moment, hattest du oben gesagt, dass du dem Client erlauben willst die Datei runterzuladen, zu ändern und wieder hochzuladen? Falls ja hatte ich das übersehen. Das geht natürlich in der echten Welt nicht (hier ist es egal). Du darfst dem Client nur erlauben Daten anzuhängen um die Art möglichen Vandalismus einzuschränken. Siehe auch z. B. Wikipedia, da ist eine "Änderung" technisch gesehen auch ein Append.