Journal Gamedev Framework 0.7.0 et 0.8.0

Posté par  (Mastodon) . Licence CC By‑SA.
Étiquettes :
29
15
avr.
2018

Gamedev Framework (gf) est un framework de développement de jeu vidéo 2D en C++14. Il est basé sur SDL et OpenGL ES 2.0 et s'inspire très largement de l'API du module graphique de SFML avec quelques différences mineures et surtout en ajoutant des fonctionnalités non-présentes dans SFML.

La version 0.7.0 est sortie il y a trois mois, le 14 janvier 2018. Elle contenait assez peu de nouveautés étant donné le peu de temps que j'avais pu y consacrer dans les trois mois précédents. On trouve toutefois un algorithme pour calculer des enveloppes convexes (Quickhull), et surtout un passage à C++14 au lieu de C++11. C++14 est une version mineure par rapport à C++11 qui améliore le quotidien (genre make_unique ou constexpr étendue) et les compilateurs majeurs permettent de compiler en C++14. C'est même la version par défaut dans les GCC et Clang récents. Donc aucune raison de ne pas l'utiliser.

La version 0.8.0 est sortie le 14 avril 2018. Il y a plusieurs gros morceaux dans cette version:

  1. Une bibliothèque de sérialisation basée sur le format MessagePack. L'idée est de ne plus avoir que ce format en entrée pour toutes les données structurées qu'on aurait plutôt tendance à écrire en JSON ou XML (ou autre). Du coup, j'ai déjà fait un petit outil qui permet de manger du JSON et qui crache du MessagePack. La sérialisation permet aussi de pouvoir créer des sauvegardes dans les jeux.
  2. Une triangulation de Delaunay basée sur l'algorithme de Bowyer-Watson. La triangulation de Delaunay peut être utilisée dans certains algorithmes de génération procédurale, notamment pour construire des cartes.
  3. Deux structure pour faire de l'indexation spatiale, c'est-à-dire organiser des objets de l'espace (ou du plan) pour pouvoir y accéder très rapidement. Ces deux structures sont Quadtree d'une part et une variante de R-tree d'autre part. Le code n'est sans doute pas encore suffisamment efficace mais c'est un début.
  4. Des widgets simples pour les interfaces à l'intérieur du jeu. Ce sont principalement des boutons qu'on peut appuyer. Il reste sans doute un peu de travail, y compris au niveau de l'API, mais la base est présente.

En prime, un nouveau jeu a été ajouté. Il a été conçu lors de la Global Game Jam 2018, et il s'appelle Krokodile. Le but est de croiser des espèces assez folkloriques pour obtenir un crocodile entièrement vert.

Krokodile

  • # bravo

    Posté par  . Évalué à 4.

    Un si beau travail, un beau post et zéro commentaires, c'est dommage. Mai c'est souvent comme ça, de mon expérience quand on post et qu'on n'a aucun commentaire. C'est qu'on a bien écrit et tout dit. Du coup il n'y a rien à troller et ni à critiquer.

    • [^] # Re: bravo

      Posté par  (Mastodon) . Évalué à 6.

      Ouais enfin, je suis un habitué du genre (voir les précédents journaux dans le même genre). Ceci dit, je te remercie beaucoup pour ton commentaire d'encouragement.

  • # Testé tous les jeux :)

    Posté par  (site web personnel) . Évalué à 5.

    Voilà, j'ai testé tous les jeux :) J'ai pas trop d'expérience en C++, mais j'aime bien les jeux 2D donc ça fait plaisir de voir des bibliothèques libres et qui plus est ça a l'air solide et pas gourmant en ressources.

    Juste deux petits soucis lors de la compilation (sous OpenBSD, clang 5.0.1), je ne saurais pas dire exactement pourquoi vu mon manque d'expérience en C++.

    diff --git a/include/gf/DataObject.h b/include/gf/DataObject.h
    index eae55da..ca4a1c5 100644
    --- a/include/gf/DataObject.h
    +++ b/include/gf/DataObject.h
    @@ -22,6 +22,7 @@
     #define GF_DATA_OBJECT_H
    
     #include <cstdint>
    +#include <cstddef>
    
     #include "Portability.h"
    
    diff --git a/library/Tmx.cc b/library/Tmx.cc
    index 85a070b..501c110 100644
    --- a/library/Tmx.cc
    +++ b/library/Tmx.cc
    @@ -488,7 +488,7 @@ inline namespace v1 {
           z_stream stream;
           std::memset(&stream, 0, sizeof(stream));
    
    -      stream.next_in = input.data();
    +      //stream.next_in = input.data(); // XXX
           stream.avail_in = input.size();
           stream.zalloc = Z_NULL;
           stream.zfree = Z_NULL;

    Première erreur :

    include/gf/DataObject.h:229:30: error: no type named 'nullptr_t' in namespace 'std'
        explicit DataObject(std::nullptr_t)
    

    Pour cette première erreur, j'imagine que glibc doit inclure <cstddef> dans un autre header de façon non standard.

    Deuxième erreur :

    gf/library/Tmx.cc:491:30: error: assigning to 'Bytef *' (aka 'unsigned char *') from incompatible type 'const
          std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >::value_type *' (aka 'const unsigned char *')
          stream.next_in = input.data();
    
    • [^] # Re: Testé tous les jeux :)

      Posté par  (Mastodon) . Évalué à 2.

      Merci pour ce retour !

      Pour la première erreur, je vais la corriger, c'est bien une vraie erreur.

      Pour la seconde, c'est un truc bizarre de zlib. Normalement, l'erreur ne devrait pas arriver. En fait, les fonctions et les structures de zlib sont définies sans const. Mais on peut ajouter des const partout où on veut simplement en définissant ZLIB_CONST à la compilation (via -D), ce que je fais dans mon CMakeLists.txt. Ici, j'ai l'impression que cette constante n'est pas définie, ce qui provoque une erreur. Est-ce que ça vient d'OpenBSD qui force à ce que la constante ne soit pas définie ? Je vais essayer d'investiguer.

      • [^] # Re: Testé tous les jeux :)

        Posté par  (Mastodon) . Évalué à 3.

        Du coup, j'ai trouvé. La version de zlib utilisée par OpenBSD est un peu trop vieille (version 1.2.3). La fonctionnalité avec le const a été introduite dans la 1.2.5 (en 2011).

        Si tu veux patcher proprement, tu peux remplacer la ligne par:

        stream.next_in = const_cast<Bytef*>(input.data());
        • [^] # Re: Testé tous les jeux :)

          Posté par  (site web personnel) . Évalué à 3.

          Du coup, j'ai trouvé. La version de zlib utilisée par OpenBSD est un peu trop vieille (version 1.2.3).

          Ah là là, c'est vraiment pas évident d'être portable ! Ceci dit, d'habitude j'ai souvent bien plus de problèmes lorsque j'essaie de compiler des jeux sous OpenBSD qui sont pas dans les ports, gf s'en sort plutôt bien :)

          • [^] # Re: Testé tous les jeux :)

            Posté par  (Mastodon) . Évalué à 3.

            Dans gf, la portabilité est assurée par SDL et Boost. Ils font le travail et après, je n'ai plus qu'à utiliser le résultat ;) J'oubliais OpenGL aussi. Ce qui fait que dans gf, je n'ai aucun code spécifique à une plateforme particulière. Et je suis très satisfait de savoir que sous OpenBSD, ça compile et ça fonctionne correctement.

            Tiens, d'ailleurs, si tu pouvais faire un petit gf_info et me coller le résultat histoire que j'enrichisse mes stats. Ce n'est pas obligatoire, ça donne des informations sur ton système (notamment les versions utilisées pour compiler), mais ça m'aidera à voir l'étendue des configurations possibles.

            • [^] # Re: Testé tous les jeux :)

              Posté par  (site web personnel) . Évalué à 3.

              Et je suis très satisfait de savoir que sous OpenBSD, ça compile et ça fonctionne correctement.

              Ça m'encourage aussi à penser qu'il y a probablement pas trop de bugs du genre buffer overflow — des logiciels qui tournent “normalement” sous Linux ont tendance à faire segfault sous OpenBSD du fait des protections mémoire du noyau (c'est le genre de trucs qui m'arrive parfois, par exemple à un moment une version d'inkscape était inutilisable sous OpenBSD).

              Et voilà le gf_info !

              Le seul truc qui m'a fait bugguer, c'est le Platform: Linux, mais j'ai découvert qu'en fait c'est normal :

              modify SDL_GetPlatform to pretend we are Linux which allows FNA based games to run before the upstreamed change trickles down to released games

              gf 0.8.0
              
              Dependencies:
              - Boost: 1.66.0
              - SDL: 2.0.8 [2.0.8]
              - Freetype: 2.8.1 [2.8.1]
              
              System:
              - Platform: Linux
              - CPU count: 2
              - RAM size: 3752 MiB
              - Cache line size: 64 kiB
              
              Paths:
              - Current path: /home/anaseto/local/bin
              - Base path: 
              - Temporary directory: /tmp
              
              Monitors (1):
              - Monitor '22M35 22"':
                  Physical size: 1920x1080
                  Position: 0x0
                  Modes (19):
                      1920x1080 | 24 bpp | 60 Hz
                      1680x1050 | 24 bpp | 60 Hz
                      1600x900 | 24 bpp | 60 Hz
                      1440x900 | 24 bpp | 60 Hz
                      1400x1050 | 24 bpp | 60 Hz
                      1280x1024 | 24 bpp | 75 Hz
                      1280x1024 | 24 bpp | 60 Hz
                      1280x800 | 24 bpp | 60 Hz
                      1280x720 | 24 bpp | 60 Hz
                      1152x864 | 24 bpp | 75 Hz
                      1024x768 | 24 bpp | 75 Hz
                      1024x768 | 24 bpp | 60 Hz
                      832x624 | 24 bpp | 75 Hz
                      800x600 | 24 bpp | 75 Hz
                      800x600 | 24 bpp | 60 Hz
                      800x600 | 24 bpp | 56 Hz
                      720x400 | 24 bpp | 70 Hz
                      640x480 | 24 bpp | 75 Hz
                      640x480 | 24 bpp | 60 Hz
                  Current mode: 1920x1080 | 24 bpp | 60 Hz
              
              GL:
              - Vendor: Intel Open Source Technology Center
              - Renderer: Mesa DRI Intel(R) Haswell Desktop 
              - Version: OpenGL ES 3.1 Mesa 13.0.6
              - Shading language version: OpenGL ES GLSL ES 3.10
              - Extensions (84):
                  GL_ANGLE_texture_compression_dxt3 GL_ANGLE_texture_compression_dxt5 GL_APPLE_texture_max_level 
                  GL_EXT_blend_func_extended GL_EXT_blend_minmax GL_EXT_buffer_storage 
                  GL_EXT_clip_cull_distance GL_EXT_color_buffer_float GL_EXT_discard_framebuffer 
                  GL_EXT_draw_buffers GL_EXT_draw_buffers_indexed GL_EXT_draw_elements_base_vertex 
                  GL_EXT_gpu_shader5 GL_EXT_map_buffer_range GL_EXT_multi_draw_arrays 
                  GL_EXT_polygon_offset_clamp GL_EXT_primitive_bounding_box GL_EXT_read_format_bgra 
                  GL_EXT_separate_shader_objects GL_EXT_shader_integer_mix GL_EXT_shader_io_blocks 
                  GL_EXT_shader_samples_identical GL_EXT_tessellation_point_size GL_EXT_tessellation_shader 
                  GL_EXT_texture_border_clamp GL_EXT_texture_buffer GL_EXT_texture_compression_dxt1 
                  GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_texture_rg 
                  GL_EXT_texture_sRGB_decode GL_EXT_texture_type_2_10_10_10_REV GL_EXT_unpack_subimage 
                  GL_INTEL_performance_query GL_KHR_blend_equation_advanced GL_KHR_context_flush_control 
                  GL_KHR_debug GL_KHR_robust_buffer_access_behavior GL_KHR_robustness 
                  GL_MESA_shader_integer_functions GL_NV_draw_buffers GL_NV_fbo_color_attachments 
                  GL_NV_read_buffer GL_NV_read_depth GL_NV_read_depth_stencil 
                  GL_NV_read_stencil GL_OES_EGL_image GL_OES_EGL_image_external 
                  GL_OES_EGL_sync GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth24 
                  GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_draw_buffers_indexed 
                  GL_OES_draw_elements_base_vertex GL_OES_element_index_uint GL_OES_fbo_render_mipmap 
                  GL_OES_get_program_binary GL_OES_gpu_shader5 GL_OES_mapbuffer 
                  GL_OES_packed_depth_stencil GL_OES_primitive_bounding_box GL_OES_rgb8_rgba8 
                  GL_OES_sample_shading GL_OES_sample_variables GL_OES_shader_image_atomic 
                  GL_OES_shader_io_blocks GL_OES_shader_multisample_interpolation GL_OES_standard_derivatives 
                  GL_OES_stencil8 GL_OES_surfaceless_context GL_OES_tessellation_point_size 
                  GL_OES_tessellation_shader GL_OES_texture_3D GL_OES_texture_border_clamp 
                  GL_OES_texture_buffer GL_OES_texture_float GL_OES_texture_float_linear 
                  GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_texture_npot 
                  GL_OES_texture_stencil8 GL_OES_texture_storage_multisample_2d_array GL_OES_vertex_array_object 
              - Compressed texture formats (15):
                  GL_COMPRESSED_RGB_S3TC_DXT1_EXT (0x83F0)
                  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT (0x83F1)
                  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT (0x83F2)
                  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT (0x83F3)
                  ETC1_RGB8_OES (0x8D64)
                  COMPRESSED_R11_EAC (0x9270)
                  COMPRESSED_SIGNED_R11_EAC (0x9271)
                  COMPRESSED_RG11_EAC (0x9272)
                  COMPRESSED_SIGNED_RG11_EAC (0x9273)
                  COMPRESSED_RGB8_ETC2 (0x9274)
                  COMPRESSED_SRGB8_ETC2 (0x9275)
                  COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 (0x9276)
                  COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 (0x9277)
                  COMPRESSED_RGBA8_ETC2_EAC (0x9278)
                  COMPRESSED_SRGB8_ALPHA8_ETC2_EAC (0x9279)
              - Shader binary formats (0):
              - Parameters:
                  GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 192
                  GL_MAX_CUBE_MAP_TEXTURE_SIZE: 8192
                  GL_MAX_FRAGMENT_UNIFORM_VECTORS: 4096
                  GL_MAX_RENDERBUFFER_SIZE: 8192
                  GL_MAX_TEXTURE_IMAGE_UNITS: 32
                  GL_MAX_TEXTURE_SIZE: 8192
                  GL_MAX_VARYING_VECTORS: 32
                  GL_MAX_VERTEX_ATTRIBS: 16
                  GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 32
                  GL_MAX_VERTEX_UNIFORM_VECTORS: 4096
                  GL_MAX_VIEWPORT_DIMS: 32768x32768
                  GL_SUBPIXEL_BITS: 4
              
              • [^] # Re: Testé tous les jeux :)

                Posté par  (Mastodon) . Évalué à 2.

                Super !

                Moi ce qui me chagrine là dedans, c'est le vide après «Base path». Mais bon, sur un système Unix, ce n'est pas très grave.

                • [^] # Re: Testé tous les jeux :)

                  Posté par  (site web personnel) . Évalué à 2.

                  Moi ce qui me chagrine là dedans, c'est le vide après «Base path». Mais bon, sur un système Unix, ce n'est pas très grave.

                  Sur OpenBSD il n'est en effet pas possible d'avoir accès au répertoire du binaire exécuté, du coup en général les packageurs patchent si nécessaire avec un chemin en dur.

                  • [^] # Re: Testé tous les jeux :)

                    Posté par  (Mastodon) . Évalué à 2.

                    Dans mon idée, cette fonctionnalité sert surtout pour les systèmes où l'installation est… chaotique. Sur un système Unix, tout est bien rangé donc on sait où on va retrouver ses assets. Mais sur un Windows, c'est plus compliqué et mettre tout dans le même répertoire est une solution à peu près correcte. Mais ça implique de savoir où se trouve le binaire.

                    Je ne savais pas que sur certains systèmes, cette fonctionnalité étaient absente.

                    • [^] # Re: Testé tous les jeux :)

                      Posté par  (site web personnel) . Évalué à 3. Dernière modification le 25 avril 2018 à 12:16.

                      Je ne savais pas que sur certains systèmes, cette fonctionnalité étaient absente.

                      La plupart des OS passent par procfs, mais pas tous, d'autres ont un syscall. Sur OpenBSD il n'y a ni l'un ni l'autre, même si il y a un moyen détourné d'y arriver : par exemple en Go ils récupèrent le dossier courant en début d'exécution, puis déduisent ensuite le chemin de l'exécutable à partir du premier argument du programme et suivant les cas déterminent s'il faut aller jusqu'à chercher dans $PATH (juste le nom de la commande, auquel cas c'est plus forcément fiable si l'environnement a changé) ou non (chemin complet ou relatif, auquel cas c'est fiable).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.