views:

278

answers:

3

First, some backstory:

I'm making what may amount to be a "roguelike" game so i can exersize some interesting ideas i've got floating around in my head. The gameplay isn't going to be a dungeon crawl, but in any case, the display is going to be done in a similar fasion, with simple ascii characters.

Being that this is a self exercise, I endeavor to code most of it myself.

Eventually I'd like to have the game runnable on arbitrarily large game worlds. (to the point where i envision havening the game networked and span over many monitors in a computer lab).

Right now, I've got some code that can read and write to arbitrary sections of a text console, and a simple partitioning system set up so that i can path-find efficiently.


And now the question:

I've ran some benchmarks, and the biggest bottleneck is the re-drawing of text consoles.

Having a game world that large will require an intelligent update of the display. I don't want to have to re-push my entire game buffer every frame... I need some pointers on how to set it up so that it only draws sections of the game have have been updated. (and not just individual characters as I've got now)

I've been manipulating the windows console via windows.h, but I would also be interested in getting it to run on linux machines over a puTTY client connected to the server.

I've tried adapting some video-processing routines, as there is nearly a 1:1 ratio between pixel and character, but I had no luck.

Really I want a simple explanation of some of the principles behind it. But some example (psudo)code would be nice too.

+4  A: 

I am not going to claim to understand this, but I believe this is close to the issue behind James Gosling's legendary Gosling Emacs redrawing code. See his paper, titled appropriately, "A Redisplay Algorithm", and also the general string-to-string correction problem.

Matthew Flaschen
"that section of the source was headed by a skull and crossbones in ASCII art," - oh dear god. I'll have to look that up, it sounds like fun.
Ape-inago
I'm going to aaccept this as my answer, the string-to-string correection problem lead me to this paper: http://www.xmailserver.org/diff2.pdf , it explained things enough for me to possibly make a rudimentary one on my own.
Ape-inago
+6  A: 

Use Curses, or if you need to be doing it yourself, read about the VTnnn control codes. Both of these should work on windows and on *nix terms and consoles (and Windows). You can also consult the nethack source code for hints. This will let you change characters on the screen wherever changes have happened.

MkV
Right, i can update a specific character, i guess I more need to figure out a good way to keep track of what characters I need to update, and how to transmit/store that information . good resources though. +1
Ape-inago
"VTnnn control codes"... the first link on Google is this question! did you typo, or am I missing something?
Ape-inago
Update: VTnnn means like: VT100, VT451 etc. I found it through looking up xterm documentation.
Ape-inago
A: 

Having a game world that large will require an intelligent update of the display. I don't want to have to re-push my entire game buffer every frame... I need some pointers on how to set it up so that it only draws sections of the game have have been updated. (and not just individual characters as I've got now)

The size of the game world isn't really relevant, as all you need to do is work out the visible area for each client and send that data. If you have a typical 80x25 console display then you're going to be sending just 2 or 3 kilobytes of data each time, even if you add in colour codes and the like. This is typical of most online games of this nature: update what the person can see, not everything in the world.

If you want to experiment with trying to find a way to cut down what you send, then feel free to do that for learning purposes, but we're about 10 years past the point where it is inefficient to update a console display in something approaching real time and it would be a shame to waste time fixing a problem that doesn't need fixing. Note that the PDF linked above gives an O(ND) solution whereas simply sending the entire console is half of O(N), where N is defined as the sum of the lengths of A and B and D.

Kylotan
sending 80x25 at 30fps does add up... if I only had to send 5-10 characters per update, there wouldn't be a bottleneck. This is my bottleneck, I've bench marked it. The more charactes I send, the lower the fps gets. ANd this is in a gigabit lab with p4's
Ape-inago
- I think it may have something to do with ssh overhead and perhaps to do with how console data is sent with putty (it may not be buffering). If I subverted that entirly and wrote my own tcp protocol, then it might be as you've put it.
Ape-inago
Ok, most people with games like this won't be attempting to send 30 updates a second - screen refreshes rarely match network updates 1 to 1. Deltas could help if you want to do this, but sending 5-10 characters per update is a very inefficient use of TCP anyway. (Up to 75% overhead plus no guarantees the data won't get batched up and delayed in transit.)80x25x30 = 60KB/second. Even the worst network cards these days handle 100KB/second. So you have inefficiencies elsewhere in the process - this isn't a bandwidth issue.
Kylotan