Doom RPG-like game and questions about it

Hi there,

I’m trying to make this kind of game, and I have a lot of questions.

  1. At first I thought of moving like this (yeah, I know that Q and E buttons not work the way they are supposed to)

    but I realized that I would have to match the step size to the scale of the map.

So here is test map


I think, that it is necessary to make a “grid” so that both the player and the enemies (and objects) move exactly at the given coordinates. But how to do it?

  1. I make a sprite sheet through the editor, loading 256x256 sprites into it. And in the scene this object looks like a very big one

    based on what this size is taken?

Hello there!

I must say I’m not 100% sure about the first statement. If you’re making Doom-like RPG (that is rather TES: Arena / Daggerfall :D) then you don’t need grid-based movement and let the player roam freely. You can just use TCastleWalkNavigation and it will do everything for you. Just use 3D FPS game template from Castle Editor and it’ll get you started.

If you want something more like Anvil of Dawn / Eye of the Beholder, with grid based movement, then you’ll need to control the input by yourself. Imho it’s much more convenient to do so through a custom navigation class that will take care of the movement between grid tiles. Maybe not the best example of the code, this is a very old project, but a working example can be found here EugeneLoza / Duungeeon · GitLab

1 Like

No, Doom RPG-like exactly, not Doom-like RPG, because Doom RPG - Wikipedia
But yes, you’re right with Eye of the Beholder, I know about it, but I never play this.

wow, excellent and suits me perfectly, but project does not compile, so I brought back Scene.Spatial := [ssRendering, ssDynamicCollisions] in WorldUnit instead Scene.PreciseCollisions := true.

Thanks very much for the tip, and I’ll be thinking about shooting and objects

1 Like

Ah, it could make sense to update Castle Game Engine for you, because PreciseCollisions was one of the few fixes I’ve had to make it to work with latest version - and it’s how it’ll be working in the future.

And yes, I didn’t know about Doom RPG. Makes perfect sense!

offtop: why you licensed under the GNU GPL? I think, MIT or BSD suits better

No specific reason. In complex projects I keep the idea of “viral license” that requires derivatives to be opensource too. CGE also uses LGPL license (with linking exception).

Duungeeon was planned to be a full and complete game, not just a small abandoned demo :slight_smile: But in its current state indeed a more permissive license would work better. Should I alter it? I don’t have anything against MIT if you may find reusing chunks of code useful :slight_smile: However, I’d rather encourage you to write those better - that code does what it is supposed to, but it’s not good. If I’ll return to the idea of making this kind of game (maybe next week? Unlikely but still) I’ll be rewriting a lot of stuff from the scratch, just copying ideas, not actual code.

@sthox

  1. Although @eugeneloza already provided an exhaustive answer and complete example, I also wanted to take a stab at this, as I love “Eye of the Beholder” :slight_smile:

    So I added a cool new example to Castle Game Engine: examples/eye_of_beholder ( castle-engine/examples/eye_of_beholder at master · castle-engine/castle-engine · GitHub ).

    It shows how to do “Eye of the Beholder” navigation using the simplest code.

    Can you guess which one is the original “Eye of the Beholder” game? :slight_smile:


  1. If you don’t have PreciseCollisions defined, then indeed the first thing you should do is update – take latest CGE from Download | Castle Game Engine .

  2. As for camera movement: to be clear (as I don’t know Doom RPG), you want camera like in “Eye of Beholder” or @eugeneloza 's Dungeeon? So

    • view from first person
    • movement by 1 grid tile back / forward
    • rotation by 90 degrees

    To do such movement in an “instant” way, your code is along the lines I would do. Just change MainViewport.Camera.Translation or MainViewport.Camera.Rotation in response to key.

    If you want to move/rotate smoothly (not instantly), using TCastleCamera.AnimateTo is the simplest option. My example examples/eye_of_beholder shows this.

  3. As for the sprite sheet size: the size just follows the sprite sheet frame size in pixels. It makes sense in 2D games, it is indeed unnaturally large for typical 3D games – simply scale it down, i.e. set Scale to something like 0.01 0.01 0.01 (scale 100x smaller in all 3 dimensions).

2 Likes

I attach the “Eye of the Beholder” CGE demo as a separate zip download here, to get it easily. But in a few hours it should also be available in snapshot on Download | Castle Game Engine .

eye_of_beholder-0.1-src.zip (10.9 MB)

2 Likes

Two questions more - how I can make a weapon sprite in the viewport?


And I created a crosshair, how to make it illuminate in a different color when pointing at something, and that enemies die when you press the left button and if the sight is pointed at them?

Attach a TCastleScene with a sprite sheet of your weapon as a child of the camera. See pointers from Camera | Manual | Castle Game Engine . So place a weapon just as we do in examples/fps_game, however in your case the weapon will be just a sprite sheet, properly scaled and rotated.

There are other ways of doing this (e.g. additional TCastleViewport with Transparent = true, only to display the weapon), but for start I would recommend the simplest approach above.

See “3D FPS game” template for an example how to shoot at enemies.

To change the crosshair color when your cursor is over an enemy, you would implement in Update method of your view (see Designing user interface and handling events (press, update) within the view | Manual | Castle Game Engine about views and their methods) a check “does the current MainViewport.TransformUnderMouse indicate an enemy” and based on this, you can change crosshair color.

How to implement a pathfinding algorithm in this project (to enemies), I think it should be A*. I know this is a complicated subject, but can you explain in a nutshell? And for the enemies to walk the same way on the cells - you have to stretch their collision, like the player’s camera, right?

You might be surprised, but simple dungeon crawlers don’t really use pathfinding at all. If the enemy can see the player character/party directly - moves towards it (strictly along X or Y axis). If not - just makes a step in random direction (Eye of the Beholder) or stands in place without moving (Dark Side of Xeen). Sometimes the enemies aren’t even seen at all (Wizardry 6,7) - or rather they don’t exist before initiating combat with Player party.

In order to “see” the enemy you can just do a raycast (see Castle Game Engine: CastleTransform: Class TCastleAbstractRootTransform) - the trick is to do raycast from player’s position, not from the enemy.

No, I’m not surprised, because it depends on what you consider a pathfinding. I consider this situation: the enemy stands around the corner, the player shoots, the enemy goes to the player.
изображение
Here, without pathfinding, there is no way for the enemy to find the player.
Again, if you ask why go to all that trouble, you’d be right in the first place. But I’m considering all options.
All in all, you didn’t surprise me, but rather opened my eyes.

something like P.S.: Last Thursday I downloaded and played Eye of the Beholder. As far as I understand, it’s not a turn-based game like Doom RPG. Generally what I want to do: Eye of the Beholder, but turn-based. I would also like to implement procedural level generation, as far as michalis said it could be done. You showed me your project - but it was only implemented in the code, and the generation was only by cells, while I would like to insert scenes through the editor and connect them in the code. And the two difficulties I have are the implementation of enemies and generation. The implementation of the inventory, interface, and such was shown in the examples, so I can do that, and thus learning Pascal.

I rewatched a Doom RPG video again and I don’t see an ability to shoot around the corner there. But of course you may want to have obstacles like “can see and shoot but not walk” (fence/grating, table, lava, etc.) and you may not want to give the player “strategical advantage” of shooting the enemies from a safe place.

Sometimes you of course may want a more complex behavior. Then implementing A* or Dijkstra could be the way to go. It’s almost trivial on a grid, however, note that you need the level layout in a more “convenient” way to work with (like an array). If your level is small and/or you don’t want to pathfind on large distances you may forget about optimizations. If your map grows to 512x512 or larger then you’ll need to make it more optimal.

Eye of the Beholder, but turn-based

Yes, Eye of the Beholder (like Dungeon Master and many other games of the era) are more or less real-time, while Might and Magic 1-5, Wizardry 6-7 and a myriad of others are truly turn-based.

while I would like to insert scenes through the editor and connect them in the code

Note that “partial generation” is harder than manual level design and fully-procedural generation. In the latter case you can also have as much additional information on the level as you need (especially efficient for pathfinding). So I’d highly recommend you going for a fully-procedurally-generated level (as in logic of generation) which can be composed of “blocks” made up in Castle Editor as castle-transform files (or simply as gltf models made in Blender like I’ve made in that Duungeeon example above). Also making all generation blocks 1x1 is much easier (and still versatile enough) than making them of variable size; I’ve been playing with NxM generation blocks and it works - but it’ll take much more effort.

In the context of pathfinding, or in general? I thought partial generation was easier, and it’s implemented in many games. And even if pathfinding - you can only do pathfinding in that part of the scene, isn’t it?

In context of generation.

When you have procedural map - it’s one thing.

When you have a manually designed map - it’s another thing.

And you need to “blend” them together. Both in terms of “looking good” and logic (pathfinding included).

Partial generation can be ok when you just fill in placeholders on a premade map. But when you need to blend human-designed thing without a logic layer with something generated by a logical algorithm - it’s a very different thing.


How do I remove the overlapping of sprites?
изображение
And how remove that white “frame” from the sprite?

Actually, I guess I should post the code, I’ll do it soon

eye_of_beholder.zip (45.5 MB)
Yes, I make this project on top of the example, and using parts of the other examples
I’ll post it on GitHub as soon as it’s done

This may be either alpha bleeding (Alpha Bleeding | Manual | Castle Game Engine - see there for a solution) - this is most likely the case; or texture bleeding (couldn’t find a good link, but it happens when your UV unwrap - make sure that UV borders make sense).

How do I remove the overlapping of sprites?

Unfortunately it has been (very) long ago when I did something like that, but try changing “Blending sort” to bs3D.

2023-05-09 23_17_34-Greenshot

It didn’t help

I don’t know how UV can be used here, but I use sprites
And I have no idea how sprites work in the engine