diff --git a/README.md b/README.md index 5f97b85..fbbe09e 100755 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Project Symmetry +![alt-text](screenshots/project_symmetry.jpg "Project Symmetry") + ## About A simple first person shooter that may or may not have anything to do with the concept of symmetry. -The game has a similar struct to older games like Quake where the objective is usually to survive and get to end of the level while killing monsters/demons. +The game has a similar structure to older games like Quake where the objective is usually to survive and get to end of the level while killing monsters/demons. The purpose of this project is to serve as an exercise in creating a game from the ground up using as few libraries as possible. The game uses the following libraries: @@ -56,87 +58,151 @@ All the code in this repository is under GPLv3, see LICENSE for more information ## File format specifications - ### Entity + The following example shows an entity definition. When saved into a separate file, this forms the blueprint for + an entity which can be used to create multiple entities that follow the same definition. + + ```JSON + Entity + { + # Comment, Sample entity definition in file, paremeters left out are set to defaults + type : 6 + material : 0 + diffuse_color : 1.000 1.000 1.000 1.000 + geometry : sponza.symbres + specular : 1.0000 + active : true + diffuse_texture : default.tga + diffuse : 1.0000 + specular_strength : 1.0000 + name : Sponza + } - ```bash - # Comment, Sample entity definition in file, paremeters left out are set to defaults - # Empty line at the end specifies end of entity definition - entity: "Something" - position: 0 0 0 - scale: 1 1 1 - rotation: 0 0 0 1 - model: "suzanne.pamesh" - material: "blinn_phong" - diffuse_color: 1 0 0 1 - diffuse_texture: "checkered.tga" - specular: 0.55 + ``` + When saving a scene that contains entities created from entity archetypes, each of those entities are saved as a "Scene_Entity_Entry" + to signify that these are to be loaded from a separate file. Example of a scene entity entry for the entity defined above might + look like this + + ```JSON + Scene_Entity_Entry + { + scale : 3.000 3.000 3.000 + rotation : 0.000 0.000 0.000 1.000 + position : -13.000 1.000 1.000 + filename : Sponza + name : Sponza + } ``` -- ### Configuration Variables a.k.a cfg-vars - - ```bash - # Comment - render_width: 1024 - render_height: 1024 - debug_draw_enabled: true - fog_color: 0.5 0.2 0.2 1 - # There can be comments or empty newlines in between unlike entity definitions - ambient_light: 0.1 0.1 0.1 1 - msaa: true - msaa_levels: 8 +- ### Configuration Variables + + ```JSON + Config + { + # Comment + render_width: 1024 + render_height: 1024 + debug_draw_enabled: true + fog_color: 0.5 0.2 0.2 1 + ambient_light: 0.1 0.1 0.1 1 + msaa: true + msaa_levels: 8 + } ``` - ### Keybindings - ```bash - # All keys are parsed by comparing the output of SDL_GetKeyname - # Each line represents a keybinding - Move_Forward: W - # Multiple keys to a single binding are specified with commas - Move_Backward: S,Down - # Combinations are specified with a hyphen/dash - # When specifing combinations, modifiers(shift, alt, ctrl) always come before - # the hyphen and the actual key comes afterwards. At the moment modifier keys are - # forced to be on the left side i.e. Left Control, Left Shift and Left Alt. - Quit: Left Ctrl-Q - # Single modifier keys are allowed but multiple modifier keys without corresponding - # non-modifier key are not allowed - Sprint: Left Shift + Keybindings file contains the definition of all keybindings. Each "Key" block contains definition for + a named input mapping. The mapping can have two keys which can activate it. All keys are parsed by comparing the output of SDL_GetKeyname. + + The following example shows an input mapping called "Move_Down": + + ```JSON + Key + { + mods_secondary_alt : false + key_primary : E + mods_primary_ctrl : false + mods_secondary_shift : false + key_secondary : NONE + mods_secondary_ctrl : false + mods_primary_shift : false + name : Move_Down + mods_primary_alt : false + } + ``` + This can then be used from within the game with: + + ```C + enum Key_State + { + KS_INACTIVE, + KS_PRESSED, + KS_RELEASED + }; + + // Returns true if the state of the input mapping matches the parameter 'state' + // which should be a value from the enum "Key_State" + bool input_map_state_get(const char* map_name, int state); ``` + If no keybindings are found when the game launches, the game generates a file with default key mappings. - ### Level/Scene - - A Binary format with header attached at the top - - Save child entities first - - Copy paste all entites in the file one by one. Since the entites all look - the same in memory and are made up of tagged unions, a simple memcpy approach - should suffice. The problem is entity heirarchies. There are multiple approaches to - solve this problem. - - Save a sorted list of entites to file i.e. before saving create a new list that does - not have the empty array slots in the entity list and then just copy and paste. This - is the simplest way to solve the problem as we don't have to worry about indexes of - parent/child entites in heirarchy. We can take the whole array and paste it to the - file but creating a copy of entity list for this purpose only would be slow and consume a lot of memory. - - Instead of creating a copy of the entity list for sorting and saving, sort the actual entity list - and update all references as necessary then save the array to file. - - Just write the name of the parent entity as parent. Make sure that all entity names are unique. - - Use separate EntityDefinition file that serves as a blueprint/prefab for the entity - to load/save. When the entity is saved in a scene file, the scene file only needs to - refer to the entity's EntityDefinition file/asset along with it's parent and children - - This approach requires seperating a scene into mutable/immutable parts. - Meaning, entities that can change their state during the duaration of the level are - mutable and those that remain the same as they were defined in their EntityDefinition - file are immutable. - - In each level there going to be mutable entites i.e player and player's position/orientation, objectives - cleared/remaining, doors opened and puzzles solved etc. Instead of handling all of these in the - scene file, we save all the mutable state in the savegame files. When restoring game's state from a save name we will need - to handle loading of a scene and then applying the mutable state to entites after loading. - - Entities can have (a fixed number of?) properties. Each property has a name and a corresponding - variant value like, health or ammo etc. But, how to save/load all of that? - -- ### Materials - - *TODO* - -- ### Mesh/Geometry - - *TODO* + A scene file consists of definition of global scene parameters in a "Scene_Config" block along with the player definition. + This is then followed by entities which can either be a Scene_Entity_Entry or just a plain Entity. + Scene_Entity_Entry refers to the filename from where the entity should be loaded first and then have the parameters + within the Scene_Entity_Entry block applied to it. + + Every scene alwas contains a default player which is defined in code however a Player block contains definitions + for player attributes that are applied to player when the scene is loaded. + + The following example shows a scene with the player and a light entity called "Test_Light": + + ```JSON + Scene_Config + { + debug_draw_color : 0.800 0.400 0.100 1.000 + fog_type : 1 + fog_density : 0.1000 + fog_color : 0.170 0.490 0.630 + debug_draw_physics : false + fog_start_distance : 10.0000 + fog_max_distance : 450.0000 + debug_draw_enabled : false + debug_draw_mode : 0 + ambient_light : 0.100 0.100 0.100 + } + + Player + { + type : 2 + scale : 1.000 1.000 1.000 + rotation : 0.000 0.771 0.000 0.636 + active : true + position : 21.479 5.660 -3.077 + name : Player + camera_clear_color : 0.600 0.600 0.900 1.000 + } + + Entity + { + type : 5 + scale : 1.000 1.000 1.000 + inner_angle : 20.0000 + falloff : 1.5000 + light_type : 2 + depth_bias : 0.0005 + rotation : 0.000 0.000 0.000 1.000 + cast_shadow : false + intensity : 1.0000 + color : 1.000 1.000 1.000 + active : true + radius : 20.0000 + position : 0.000 5.000 0.000 + outer_angle : 30.0000 + name : Test_Light + pcf_enabled : false + valid : true + } + ``` + diff --git a/screenshots/project_symmetry.jpg b/screenshots/project_symmetry.jpg new file mode 100755 index 0000000..fad249d Binary files /dev/null and b/screenshots/project_symmetry.jpg differ