Jump to content
  • Advertisement

cpfr

Member
  • Content Count

    20
  • Joined

  • Last visited

Community Reputation

26 Neutral

About cpfr

  • Rank
    Member

Personal Information

  • Interests
    Art
    Audio
    Business
    Design
    DevOps
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. What do we do inside a dungeon? Hi everybody. Again, it's been a long time, but now the summer is finally over and I can show you some updates to the game. After completing the collision-handling code overhaul and while filling the lower dungeon section with life, I literally wondered what the player should do inside the dungeon -- besides walking around and killing monsters. For the upper dungeon part, it was okay to use find-the-right-key tasks. For the lower part, however, I wanted a little more RPG-like mechanics, so I added two non-monster NPCs in order to deepen the story (albeit a rather weak story). Together with the story elements, there is a puzzle that can be solved in order to gain a bonus on the sword. The puzzle consists of a couple of stones that have to be placed in the correct order (see the screenshot blow): An appropriate ending The dungeon crawler challenge version of the game ended rather abrupt. In order to give the game an appropriate ending, I felt that there should be an end boss. In a raycasting engine, there is a natural size limit for sprites (since the ceiling and floor heights are fixed here, and also because the sprites rotate with the camera). In order to create a boss that is adequately daunting, I decided to create a lindworm / a dragon-like snake that is assembled from multiple sprites. It moves very similar to the snake in the original snake-game. The screenshots below show a first impression. I also made a short video of the movement of the lindworm (see below). Ready for Beta-Testing? The puzzle and the boss-fight are not yet finished, but they are the last two features I will implement for this game. When those two tasks are done, I will start a short beta testing phase in order to collect player feedback and bringing this game towards a release. Thank you for reading, Carsten
  2. cpfr

    The Fire of Ardor

    The game takes place in a world which is infested by the curse of the daemon lord Ardor. Burning like a fire and spreading like a plague, the curse causes people to become greedy and grudging, some of them even turn into bloodthirsty monsters. By reaching out to reign supreme, the fire of Ardor burns its way into our world. The player is a nameless warrior who crested the silver mountain in order to enter Ardor's world and defeat him. To open the dimension gate, the player has to defeat a dungeon and obtain the soul stone that is hidden inside. During the game you won't confront the daemon himself, but obtain the soul stone from the dungeon and bring it to the wizard Randuras, the last resident of the doomed town at the top of the mountain. Update - Continuing Development Four months after the end of the dungeon crawler challenge, the game has changed a lot. Read more about it in the newest development blog post:
  3. cpfr

    Level editor

    I exactly know how you feel. I did the same for my dungeon crawler challenge game "The Fire of Ardor". After days of hex-editing multiple level files, I decided to implement an editor for the raycaster levels. Although my raycaster doesn't have different wall heights, I needed different information about block shapes and wall textures. Because I allow different textures for different sides of a block, I decided to use the game itself as an editor (i.e. painting the textures on the rendered walls instead of painting on a top-down map). Long story short; Good job! I'm excited to see the end result.
  4. While filling the new lower dungeon section with (undead) life, I thought that playing the game would take about twice the time, compared to the original version. I was glad that I finally got the opportunity to integrate the lantern that I had to cut from the gamedev challenge submission. Due to the increased length of the game, it came to my mind that it could be frustrating to start all over after dying. Further, I felt that the game might be too long to play it to the end in one turn. That's why I decided to implement loading and saving games. Implementation Loading a savegame is essentially the same as loading a level from file. The level files contain information about the level geometry and the entities within the level. The good news was that I already implemented loading levels from file. The bad news was that this was not enough for the player's savegames. First of all, only loading was implemented. Then, not everything could be loaded from the level file. The player entity for example was added to the world via code. ECS and savegames The good thing about the Entity-Component-System pattern is that loading and saving state is relatively easy -- as long as you adhere a very basic rule: Systems don't hold state. Every mutable information is stored inside the components of some entities (components = data; systems = logic; entities: containers for components). In my case, I had some data stored inside the systems. Some properties were added for convenience reasons. It was easier to store the data inside the system, rather than in a component. However, most of the properties in the systems were there for performance reasons; values that would have to be queried or computed every frame if not cached. The latter ones are no problem. These properties are fine, since they can be recomputed if needed. The former ones were a problem and I had to remove them. This means that I had to introduce a couple of new component types. For example I added a player component and put every player-related state into that component (although there is always only one player). Python and JSON serialization Fortunately, Python comes with an integrated module for JSON serialization and deserialization. This module is able to convert dictionaries to JSON strings and vice versa. Since I don't need dictionaries, but instances of certain classes (my component classes), this was not enough. In C# there is the Newtonsoft.Json library which converts between JSON and C# objects, which works really nice due to the static type system of the language and the way namespaces work in C#. However, in Python it is not that easy (I never thought I'd actually say that, but there's no reason to be dishonest). Since Python is dynamically typed, there is no fixed set of attributes for a class. Instead, attributes can be added after an object is instantiated and it can not be guaranteed that an attribute is present, except when it is assigned in the constructor. Further, namespaces in Python are not as explicit as in C#, which I would usually appreciate. In this case, however, the dynamic nature of the namespaces makes it difficult to locate a certain type by name. I don't want to discuss C# and Python features here, but this comparison came to my mind, since I use C# at work and Python / Cython at home. The solution I found uses Python decorators to register component types. The 'component' decorator registers a class under a certain name in the engine. This registration is then used when a level file is either serialized or deserialized. That way, the JSON file can use short, descriptive names for components while being independent from the actual class names. Here is the health component class for example: @chroniton.component("health") class HealthComponent(object): def __init__(self, currentHealth = 100, maxHealth = 100): self.currentHealth = currentHealth self.maxHealth = maxHealth By default, the engine will look for public attributes to serialize (i.e. attributes which names don't start with an underscore) and convert the object to a dictionary that only contains primitive types and thus can be converted to JSON very easily. For special cases, there is also the possibility to implement the special methods 'loadFromDict' and 'dumpToDict', which allow for a custom serialization. Finally, there must be a fallback solution for components that are not known to the engine. This can come in handy for a level editor that does not load all in-game dependencies. It enables the level designer to load a level, modify it and save it, without losing information about components that are not known to the editor. UI for loading savegames Last, but not least, the user has to be able to actually load and save games. I won't bother anyone with any more text and instead show a screenshot. A picture paints a thousand words: Bonus screenshot: Improved sky texture for the town Yay, okay. I like showing screenshots, even if this one is not savegame-related. I improved the sky texture of the town level section with some mountains (since we are at the peak of the silver mountain): Thank you so much for reading!
  5. Hi, it has been some time since the dungeon crawler challenge was over. There were many things left to do in my game submission, but I was relatively satisfied with the result and I was tempted to call this a game and move on to other projects. However, things never turn out as you expect. I was contacted by someone who offered me to write original music for the game. He asked me about the current status and about my plans for further development. His name is Neil O'Rourke and the portfolio on his Soundcloud page and Youtube channel impressed me. Somehow, his request motivated me to continue the work on this project. The version I handed in for the challenge was 0.1.0. The goal now is to make a stable 1.0.0 version with no major bugs and some of the features I cut due to the time restrictions of the challenge. I would like to briefly present the new features: Custom Music Of course, this was the fact that caused me to continue developing the game. I liked the CC0 music, I originally selected, but Neil did a great job on tailoring custom music for every section of the game (you can listen to some of the tracks on his Soundcloud profile). I think my favorite track is the wizard's house music. It combines a mysterious atmosphere with the cozy feeling of a warm fireplace within a hostile town. Bug Fixes Version 0.1.0 had some bugs. First of all, the collision handling code was bad. I already improved it, but it still needs some refinement. In some cases it is possible that the player glitches into a wall. In that glitch case, it was possible that being inside a wall caused a segmentation fault. This problem is fixed. Further, I improved the enemy AI and the enemy attack timing so that they behave less unfair if the player is running from them (they were biting way you too quickly). Another bug was the broken fullscreen mode on some systems, which has been fixed now. Further, the player can toggle between fullscreen and windowed mode at any time using ALT and ENTER. Also the framerate-dependent animation playback has been fixed. As well as the fact that dead enemy bodies prevented you from picking up the loot. Customizable Keyboard Settings I extended the main menu of the game (mainly because I like the new title music so much and I wanted the player to spend more time in the menu in order to listen to that music). There is now an "Options" button, which allows the player to customize keyboard and mouse button settings. More Enemies The original version had three enemy types: A rat, a black rat (which was stronger than a usual rat) and a ghost. Due to the fact that rats are not the kind of terrible monstrosities one would expect inside a demon's dungeon, I decided to add some more enemy types: Bats (they belong into a cave and are an alternative to rats) Depth Worms (mysterious creatures that appear though holes in the ground and spit acid slime on you if you come too close) Skeletons (the classic undead warriors, carrying a sword and a shield) A Skeleton Mage (an undead warlock, throwing lightning balls at you) The different enemy types are located in different sections of the dungeon. More detail on that in the next section. Lower Dungeon Section Again, inspired by Neil's music, I decided to add a lower section to the dungeon with the current dungeon being the upper section. The lower section is darker, colder and inhabited by undead creatures (see above). I even implemented ground-level fog in the engine, because I wanted the lower section to look more hostile. The lower section can be reached by using a ladder. The new section also introduces a new item: The toxic mushroom and another non-enemy NPC (but I won't spoil every detail here right now). Time Schedule and goals The goal is to extend the game so that it offers about twice the length of the original challenge submission by adding the lower dungeon section and the new NPCs, enemies and items. The world now contains more decorations and story-related elements to intensify the immersion (despite the stylized graphics). The idea is to create a playable beta version until the mid of August and provide it to a limited audience in order to test the game and release a stable version after implementing the feedback from the beta test. Finally, I want to thank Neil for his great work and his interest in my game. Further, I thank you all for reading and I would like to provide you some new screenshots as a foretaste to the 1.0.0 version. Best regards, Carsten Screenshots
  6. Hi there, more than a week passed since the dungeon crawler challenge was over and I used the time to take a deep breath. Now I finally managed to get a working Windows build done (thanks to Mingw64, VirtualBox and Stackoverflow 😁). I didn't have the time to fix any bugs, so this is the same code I released for the challenge submission, but hey - now it runs on Windows 😉 Best regards, Carsten
  7. This is the post-mortem for the dungeon crawler challenge submission The Fire of Ardor. You can find the project here: It is done. The last two months have been exciting, as well as exhausting. I took the challenge as an opportunity to push the development of the raycasting game engine I started years ago. I wanted to create a game in order to be forced to implement engine features as they are needed by the game. I always wanted to create an RPG-style game. In order to be realistic according to the time schedule, I cut many of my ideas: There should be three small dungeon levels with different enemy types per level and only few NPCs and items. However, finally, I had to further cut down my goals in order to hold the deadline. Engine Programming vs. Game Programming Using the game as a driver for engine development worked out well. The positive effect of the deadline is that I had to focus on important aspects and I didn't have the comfort to defer the implementation of inconvenient tasks. When I started the development of the game in the end of December, many of the engine features weren't finished. There was no collision detection, no animated sprites and no UI elements, just to name a few. In fact, I spent most of the time in developing engine features, fixing bugs and developing tools. I didn't have any level editor, so I had to edit the level in a hex editor. The level editor I have now is far from being complete. Since I only implemented UI elements that were necessary for the game, the editor contains almost no UI and is controlled by a bunch of keyboard shortcuts. Although I had to cut my expectations during development in order to ship a full game and to meet the requirements, I am very satisfied with the end result. There is only one dungeon level, only three different enemy types and only one non-enemy NPC. Nevertheless, I implemented sword fighting, fireball spells, a simple conversation system for talking to the NPC and reading books. I have a couple of items and a win and lose condition. All in all, I would say that the game is far from perfect, but a very well-rounded thing, also considering the fact that I only had time for development after work and after my little daughter was sleeping. What was bad I spent a lot of time on the collision detection code in the engine. In theory, collision detection in 2D space is relatively easy to implement - and in fact it was easy to detect collisions. The difficult part was to move the player without suddenly stopping on a collision (i.e. adjust the movement vector so that the player slides along a wall instead of getting stuck). The current code works, but it is not perfect, since it can glitch in some rare cases (no time to fix that though). The UI code also swallowed a lot of time, although it was only needed for the menu and the inventory screen. I came up with the idea of different automatic widget layout containers -- they are roughly implemented, but in some combinations (those which I don't use in the game) the layout is simply wrong. While the engine code is still pretty okay-ish, at some point the game code started to get messier and messier. Before continue developing this project (more levels, features), I will have to invest some weeks of refactoring. It felt a little bit like the effect that you have on a game jam (I also participated in the Global Game Jam this year and it was very hard to switch to another project for a weekend, knowing that so many things were undone). Building C - Python Extensions on Windows is a pain (Cython works really well for me on Linux). I didn't manage to create a Windows executable, yet. That means that the game is currently Linux only. Sorry Windows guys, I'll keep on digging into that (different compilers, different architectures, 32 and 64 bit libs) and deliver a Windows build as soon as possible. What was good Having a goal with a fixed deadline was motivating. I never worked that steadily on a hobby project. That effect was even enhanced when I decided to write blog posts about the development -- now I was not the only one who knew that I was developing something and I wanted to show that I would be able to complete the project. Having the deadline in mind, I also learned to cut features that would not contribute to the end product in an important manner. For example I cut an almost finished lantern that could be used to light a dark dungeon level, because other things were more important (for instance spending money for buying potions). While cutting down features, I still kept an eye on the features I implemented, like the sliding animations in the menu and health bar, the sounds in the inventory, etc. For the entities in the game I used an ECS approach. This one turned out to be very flexible. It was easy to add new items enemy types without or with only little coding. I also like the tools I used. I used Gimp for drawing sprites and textures, Blender for pre-rendering some of the sprites and audacity for editing sounds. The music tracks are CC0-licensed pieces from opengameart, the sounds are also CC0 licensed files from freesound and opengameart which I edited to fit to the game. All in all, I think that the game has a reasonably consistent art style (although the level of detail tends to differ from sprite to sprite). Conclusion I am satisfied with the end result, although I achieved less than I originally planned. I want to thank my wife who has been very patient with me the last couple of weeks. I am looking forward for you guys playing the game and giving feedback. Thank you for reading. Carsten
  8. Hi again, this time I'm posting a little status update video. First of all, there is a main menu (with only two options yet, I'll add options and load/save game if time will allow me). Further, there is an in-game menu which allows the player to go back to the main menu (challenge requirement). The interesting part is the new inventory UI. Items can now be collected and consumed. The UI shows some description texts of the items on mouse hover. The inventory layout is inspired by the Gothic RPG games. Finally, the video shows what will be the entrance to the dungeons and the gargoyles from different angles.
  9. Hi, here is a small update on the development status of The Fire of Ardor. The biggest change regards the engine. I introduced the Entity-Component-System (ECS) pattern for the renderers (UI and raycaster). This means that renderers (which were treated differently before) are now usual systems. There are several articles about the ECS pattern on Gamedev.net for further reading [1]. A visible change is that there are new sprites (see screenshots below): The meat will be dropped by defeated rats. The player is now able to collect items (currently health potions, mana potions and meat). After playing a sound, the item disappears from the level and it is stored inside the player's inventory (which doesn't have a UI yet and thus it's not visible). The gargoyle sprites are renderings from an old Blender model I created several years ago. I edited the Blender render output in Gimp so that it fits the overall pixelated style of the game, although some additional work might be necessary in order to reduce black pixel artifacts. The gargoyles look different from certain view angles. They consist of 16 single sprites. The correct sprite is determined by the relative position and rotation between the camera and the entity. The next steps will be implementing a conversation system (a text box is already shown in the first screenshot), as well as creating a UI for the inventory in order to view and use the collected items. Thank you for reading! --- [1] Articles about the ECS pattern (random order, more or less random selection) ↩︎
  10. Hi, this is my first blog entry here and also the first time that I actively participate in Gamedev.net. I am a software developer who develops application software at work. At home, I develop games in my spare time. I used to read Gamedev.net articles and blog posts for inspiration and motivation. Since I have the RSS feed subscribed on my phone, I read about the Gamedev.net Frogger challenge and I thought that I'm not interested in Frogger, but that I liked the idea of the community challenges. When the Frogger challenge was over, I read about the dungeon crawler challenge and I thought: "Okay guys, now you've got me!". I always wanted to create an old-school RPG in the style of Daggerfall or Ultima Underworld with modern controls (although I never really played them). More than 10 years ago, I started to write a small raycasting renderer in C++. Raycasting is the rendering technique that was used by the first person shooters of the early 90's (see also [1]). I never really finished that renderer and put the project ad acta, until, some years later, I stumbled across the old code and started porting it to Cython[2] in order to be able to use it with the Python programming language[3]. After some time, I was able to render level geometry (walls, floor, ceilings and sky), as well as sprites. After solving the biggest problems, I lost interest in the project again -- until now. I thought the dungeon crawler challange was a great opportunity for motivating myself to work on the engine. At the same time I would create a game to actually prove that the engine was ready to be used. I started to draw some textures in Gimp[4] in order to get myself in the right mood. Then I started to work on unfinished engine features. The following list shows features that were missing end of December 2018: Level editor Hit tests for mouse clicks Processing mouse scroll events Writing modified level files to disc (for the editor) UI Text Buttons Images Containers (layouting child widgets in particular) Scheduling tasks (async jobs that are run at every frame) Collision detection for sprite entities Collision detection for level geometry (walls) Music playback Fullscreen toggle Animated sprites Directional sprites (sprites look different depending on the view angle) Scaling sprites Refactorings / cleaning up code Documentation & tutorials Fixing tons of bugs Luckily, many of the above features are implemented right now (middle of January 2019) and I can start focusing on the game itself (see screenshots below; all sprites, textures and UI are hand-drawn using Gimp[4] and Inkscape[5]). The game takes place in a world which is infested by the curse of the daemon lord Ardor. Burning like a fire and spreading like a plague, the curse causes people to become greedy and grudging, some of them even turn into bloodthirsty monsters. By reaching out to reign supreme, the fire of Ardor burns its way into our world. The player is a nameless warrior who crested the silver mountain in order to enter Ardor's world and defeat him. To open the dimension gate, the player has to defeat tree dungeons and obtain three soul stones from the daemon's guardians. The following videos show some progress: First attempt: Rendering level geometry and sprites; testing textures; navigating through doors (fade-in and out effects) First update: Adding a lantern to light up the dungeon: Second update: Rendering directional sprites and animations Raycasting (Wikipedia): https://en.wikipedia.org/wiki/Ray_casting ↩︎ Cython: https://cython.org/ ↩︎ Python: https://www.python.org/ ↩︎ Gimp: https://www.gimp.org/ ↩︎ Inkscape: https://www.inkscape.org/ ↩︎
  11. cpfr

    The Fire of Ardor

    Album for The Fire of Ardor
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!