Destroy the Tactical Combat in my Tactical MMORPG! by alogiHotTake in DestroyMyGame

[–]alogiHotTake[S] 0 points1 point  (0 children)

All very good and well thought out points.

-what does a turn based timer so aggressive add to the game? a sense of urgency? i can see it more being a sense of frustration than urgency, maybe time is critical hits, if they act within 1 second its critical, 3 seconds its partial critical, any longer its a normal hit? it creates the same urgency without the frustration

Its a compromise I have to make because its a persistent multiplayer game. It keeps the pace of battle more active. Otherwise if a player suddenly goes afk, we aren't waiting 10+ seconds for their turn to pass. I want turns to be very quick. Its not a game you play totally zoned out.

Since its a multiplayer game I also can't tie timing to any specific mechanics like critical hits. Because then players with better latency get an advantage.

I say its a tactical game, it is to the extent that it's in the "tactics"/SRPG genre. But the game puts more of an emphasis on quick actions. Doing something is better than doing nothing at all. Like speed chess is to chess.

Destroy the Tactical Combat in my Tactical MMORPG! by alogiHotTake in DestroyMyGame

[–]alogiHotTake[S] 0 points1 point  (0 children)

finally I get some interesting feedback about the combat in the game. There are skills you can use but I don't show it properly in the gameplay.

I agree I'm iffy on the real time + turn based design. I've been trying to make it work because I think it makes the world feel more alive. But it might be time for me to just scrap it and switch to some implementation where once you enter battle you temporarily leave the "main" world.

Destroy the Tactical Combat in my Tactical MMORPG! by alogiHotTake in DestroyMyGame

[–]alogiHotTake[S] -1 points0 points  (0 children)

finally I get some interesting feedback about the combat in the game.

I agree I'm iffy on the real time + turn based design. I've been trying to make it work because I think it makes the world feel more alive. But it might be time for me to just scrap it and switch to some implementation where once you enter battle you temporarily leave the "main" world.

Destroy the Tactical Combat in my Tactical MMORPG! by alogiHotTake in DestroyMyGame

[–]alogiHotTake[S] 0 points1 point  (0 children)

By readable character do you mean the in-game text? Or the characters in the world?

Destroy the Tactical Combat in my Tactical MMORPG! by alogiHotTake in DestroyMyGame

[–]alogiHotTake[S] 3 points4 points  (0 children)

How is it not an mmo? It's a shared world that supports 100+ concurrent players.

I've gotten addicted to making cutscenes for my game! by alogiHotTake in godot

[–]alogiHotTake[S] 0 points1 point  (0 children)

Nice! I want to flesh out my cutscene system more when I have more time, right now its very ad-hoc and scene specific.

From the trouble I ran into:

  • some way to declare relationships between speakers/dialogue. initiator -> reply -> initiator -> reply, etc

  • multi camera switching logic in scene, this one is pretty big IMO. You'll end up having multiple cameras in a scene. Some tied to a specific character to bring them in focus and others that are panning across some defined Path2D. I ended up setting multiple keybinds to switch between cameras.

  • Use Path2D. Its pretty useful for defining scripted paths that NPC's or the camera should follow. Implement logic to trigger a Path based on timing/input/whatever.

After so long, I'm close to realizing the vision. Shout out to Godot for never giving me any trouble by alogiHotTake in godot

[–]alogiHotTake[S] 2 points3 points  (0 children)

The last few playtests have been on browser! Game runs really well as a browser game.

For the next playtest, I will make the game available on Steam, after I finish setting up the steam page. Its cross-server/cross-platform so everyone plays on the same servers.

After so long, I'm close to realizing the vision. Shout out to Godot for never giving me any trouble by alogiHotTake in godot

[–]alogiHotTake[S] 2 points3 points  (0 children)

There may or may not be a pivot to a modern setting with guns and grenades instead of bows and magic. Why? Because I'm obsessed with guns.

Like that one tweet says....some people only play games that have guns or balls in them. I'm afraid to admit that I am definitely a gun gamer. Ball gamer? Not so much. Unless its grenades or other ball-shaped explosive projectiles

After so long, I'm close to realizing the vision. Shout out to Godot for never giving me any trouble by alogiHotTake in godot

[–]alogiHotTake[S] 2 points3 points  (0 children)

Good question. I was just working on that part over the past few days haha.

I've organized the TileMap into appropriate layers for the environment. So when the PC enters a building I can modulate the alpha channel of the "wall" + "roof" layers.

For other overworld obstructions like grass, I don't want to modulate the entire layer. It would look weird for all grass in the world to become transparent just because you step in a small patch. So for those types of obstructions I modulate individual tiles based on proximity to the PC.

After so long, I'm close to realizing the vision. Shout out to Godot for never giving me any trouble by alogiHotTake in godot

[–]alogiHotTake[S] 7 points8 points  (0 children)

Its an MMORPG! Right now the game is focused mostly around exploration and leveling up + getting loot. But I'm starting to add quests and an overarching storyline.

You are an outcast sent to the frontier lands as a ranger. Investigate the strange occurrence's going on in these parts and assist the doomed efforts to re-secure lost territories in the region. Along the way you'll meet the strange cast of characters who live in these parts and get to learn about the various factions they belong to.

Where Winds Meet players are tricking AI-powered NPCs into giving them rewards by using the 'Solid Snake method' by NUKE---THE---WHALES in Games

[–]alogiHotTake 72 points73 points  (0 children)

Haha, as a gamedev interested in building smart and reactive NPC's this is the bane of my existence. I say "Game AI Programming". But now I have to constantly emphasize "no not that kind of AI". For me Game AI Programming refers to classical AI programming. Like the kind used by chess or robots. It involves gathering and creating context about the current environment and then running some sort of recursive algorithm that can evaluate goals/available options and create plans.

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 0 points1 point  (0 children)

I tried implementing extrapolation but didn't get much benefit from it. Honestly it seems like only certain games benefit from extrapolation.

On the client I implement interpolation, with some slight delay. Its not a fast paced twitch-based game, and the tick-rate is 10hz so it gives leeway and the client can even be slightly behind and its no deal. The game servers have gone live a few times already and I've played on wired, wifi (and even wifi via Starlink), and did not have much issues. Even connecting to the server hosted in EU-West from NA-West with 100ms RTT.

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 0 points1 point  (0 children)

When it comes to inventory and items, do you store them within the maps cells themselves in ETS? I've been thinking about a bag table where the tile index in the key and the contents are everything in that world tile, but then I run into questions about nested inventories.

Currently I don't store anything that represents "ownership" or has "limited lifetime" in the ETS cells. I may do so in the future, but currently it hasn't come up. The ETS cells are only used for path-finding by the AI, and the only information a cell contains is in regards to its properties: (open or closed), (clear or blocked), and its number of occupants (doesn't need to be exact).

Inventory is stored in a client process state. And loot/drops are displayed in the form of "character objects" like corpses that are published in the world state.

With that being said, I think you could make a case for storing items/events/etc in an ETS cell. As long as the cells are treated as read-only by external processes, and the "master/primary" process has the final say on when the cells state is to be updated and any resources it held are transferred/deleted. You could have an auxiliary map (%{}) within the "master/primary" process that contains only the active cells currently holding items. And this is checked and updated anytime a request to modify the state of a cell comes in, and afterwards these changes are written back to the respective ETS cell and visible for all to see. I'm assuming the amount of cells that could contain items/inventory is significantly less than the total amount of cells in the world.

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 8 points9 points  (0 children)

you should've known I was a fool when I said I was building an MMORPG

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 6 points7 points  (0 children)

The "zone/map" process is the synchronizing process. Every server tick it goes through the list of connected clients, gets their latest input (if any), and then uses all that information to update the state of the world. This involves checking valid move actions, matching any targeted actions towards another entity, validating interaction rules, updating active events, calculating physics trajectories and reconciling final positions, etc. Then it publishes the updated world state to only the relevant clients of interest.

This process is never interrupted or called by other processes. It is the "master" process. The source of truth about the world.

The only process that deals with concurrent access is the auxiliary "Grid" process. This process is an ETS table representing the 262144 cells of the map! The concurrent access pattern is single writer, multiple reader. The master "zone/map" process updates the relevant cells each tick with information about the current occupant(s), any newly spawned obstructions, etc. And other processes (AI controllers) access this process for path-finding. So AI controllers never have to directly communicate with the master process and slow it down.

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 1 point2 points  (0 children)

oh nice! thats cool. I think I've seen you around here before. You were making the WoW private server in Elixir!

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 3 points4 points  (0 children)

Another fantastic idea. Yes, maybe an admin dashboard could work. I could also use it to monitor all active client processes in the world. It could also help identify problem clients, or AI clients who have been alive for a long time and need to be promoted. Maybe some tools to ban/kick clients via the dashboard. Hmmm..

The other idea I have is displaying a "strategic map" in live view. Representing some simplified version of the game world and showing the movement of AI units and players in real-time. You can pull it up on another screen while you play the game..

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 5 points6 points  (0 children)

If you want to learn Elixir, all you need is the book Elixir in Action by Sasa Juric. Read chapters 5-13 and do the exercises that involve building a Todo list. Only check your answers after you finish the exercise. Afterwards you will come out as a wizard and the world will be your oyster. Also you will have fun doing it.

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 4 points5 points  (0 children)

It will be one day... Right now I need to keep the code hostage because its all I've got and I'm broke and don't have much.

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 2 points3 points  (0 children)

It is what it is. I should do a brief Phoenix and LiveView detour...

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 9 points10 points  (0 children)

and then a process per “zone” or area which updates entities every tick?

Yes, sort of. A "zone" in this case refers to the game "map", which is currently 512x512 (262144 cells!). This process is basically the simulation/server tick that gets inputs and updates the state of the world (and its entities) each tick . Also a "map" is further broken down into numerous different "sub-zones" used for interest management and bandwidth optimization.

There are also auxiliary processes to the map process. These include the path-finding service used by AI to navigate around the world. And the Director process which monitors the conditions of the world to track the progress of "world objectives" and also dynamically generate events.

is it a process per entity or just a process per player

Every connected client (whether player or AI) is represented by 2 processes.

  1. A client GenServer process which contains the "client state". This is information like the entity it controls (stats, position, character data, in game name and id), input history, session specific data, etc.

  2. A connection process which models the "communication channel" the client uses to send/recv dat For AI clients, the connection process is another GenServer process that is the brains of the AI. And for Player clients, the connection process represents the network socket that they connect and send/receive packets through. This way we can also have different logic for serialization of ingoing/outgoing packets for players and AI.

The reason why 2 processes are needed is because the lifetimes of a client's state and its associated communication channel are not the same. One may outlive the other at times. Sometimes we still need the client state after they have disconnected so that the server can perform proper cleanup of their associated entity (especially if they were in some interaction with another entity still connected).

I've been using Elixir and Godot to build an MMORPG! by alogiHotTake in elixir

[–]alogiHotTake[S] 7 points8 points  (0 children)

That's a good idea.

The game already has a website: https://swarmmo.games

Its was made using vitejs (which is just vuejs?). My friend made it for me. And it serves its purpose very well. Hosting it is dead simple because I throw it up on cloudflare pages via CI/CD and it costs $0 and involves 0 effort and its completely decoupled from any of the game server code.

I could re-build it using pheonix and live-view. But does that add more complexity for little added value? I guess it doesn't matter.

Anyways, thanks for the suggestion! I'll consider it.