I have started to develop a simple MUD (text based multiplayer dungeon) where client uses only terminal to connect and play.
However i approached it the different way, i want the player to be able to move around the rooms (x,y) and see the map of a room like in the screenshot below
The whole screen as it is seen is being sent out by the server to the client on updates like:
somebody moved, something has changed in the current location, somebody dropped something, etc ...
At the bottom of the screen, there is a place where clients can put commands like:
look, east, west, pick up, drop, inventory, ...
Problem
The problem with the design however is, that when user is in the middle of putting a command and in meantime server has updated it's screen (somebody moved, or some event was generated ) he will loose the command he was typing because the whole screen got refreshed.
How do i send the screen to the player?
I build the view on the server side, and when sending to the client i use ANSI characters to:
Question
Is it possible, that clients don't loose their input when i send a view to them?
In other words, is it possible (maybe some ANSI code required?) that when i type something in the terminal and meantime if i receive something, my input is not broken by the newly received message?
To visualize the problem:
Good:
from server: aaa
from server: bbb
> input
Current:
from server: aaa
> in
from server: bbb
put
It's probably a better idea to construct the view on the Client side - then the server only needs to send the "raw information" and the client can display it. In this case, you've said the server sends a new view on events like someone moving - so just send a message to the client saying "Bob has moved", rather than an entirely new rendered screen, and let the client handle the update.
This has multiple advantages - to solve your problem, you can just buffer any server input until the user's finished typing, or redraw any bits of the screen that the client user's not actively changing.
It also allows for more customisation on the client side - if the server sends the view over, how does the client display it on a terminal that's a different resolution to the server's view? With client-side rendering, you can deal with this sort of issue on a per-client basis. You can also open up the door to massively more customisation by letting client users customise their personal views.
If you are fixed on having the server construct the views, then on the client you might be able to read single-character inputs at a time (on windows _getch
, on linux ncurses
provides this functionality), then if a server update occurs just render the new view and then re-render what the user's entered beforehand.
ANSI codes are... messy. Using a library like curses
can make console-based-guis much nicer and more maintainable. On linux there's ncurses
, and on windows there's an open-source variant called pdcurses
(apparently has the same API, just exposed in an independent library. You'd need to change linker settings when compiling on Windows, but hopefully not any code). Thanks to Bartek for mentioning this.