The second approach is nicer for writing borgs and things. It's the one I am more interested in, although it does require more work.
pyAngband's thread
Collapse
X
-
I think the second is likely better as well. You encapsulate the game state and then pass it off to a visualizer -- which might be headless in the case of the borg, or could be an OpenGL renderer for First-Person Angband, or a curses display for Angband-Over-SSH, etc. Basically you get a lot more flexibility in how the game is handled.Comment
-
I agree, I was partly hoping for a cop-out response so I would have an excuse to not work as hard, but alas, doing it now will take longer; but will be better in the long run.
At least some things won't change the state of Angband itself (and if you don't know, I refer to the game core as Angband, and the display/input as the Client). Things like checking character stats, looking around, looking at inventory, basically informational stuff do not change the game state, so those are not so difficult to implement.
Things like moving, shops, and such are a bit more tricky, but not too bad I'd wager.
I was thinking each element on the game map has it's on ID, therefore the client can decide how to display that (prefs, etc) with a "default" pref that can be sent from Angband itself.
Text and such would require special formatting inside to show what words are important or not. That or using an intelligent parser on the client side. Personally I like special formatting better... at least the thought of it, but a parser would probably be better, because at least for testing you won't get a bunch of text like:
Code:"The (k:m t:'Yeek') hits you for (k:d t:'4') damage" k = kind (m = monster, d = damage), t = text
Comment
-
Quick question, I have Angband running as a FSM right now. The client pushes keys onto Angband's internal key queue, and when the client calls Angband's run function, those keys are used up, and so on.
What I'm trying to decide now is if I should continue this pattern (passing keys into Angband), or should I put some kind of link to the external inkey() function from the client so that Angband itself can get keys when it needs them?
Angband getting its own keys would make some code a little easier, and wouldn't really cause too much coupling with the client, but it would add some. What do you all think?Comment
-
Quick question, I have Angband running as a FSM right now. The client pushes keys onto Angband's internal key queue, and when the client calls Angband's run function, those keys are used up, and so on.
What I'm trying to decide now is if I should continue this pattern (passing keys into Angband), or should I put some kind of link to the external inkey() function from the client so that Angband itself can get keys when it needs them?
Angband getting its own keys would make some code a little easier, and wouldn't really cause too much coupling with the client, but it would add some. What do you all think?
Command could be:
"Cast Spell - No arguments", and the game engine prompts for book, etc.
or
"Cast Spell - Heal Self". Game just casts the spell implied by the command arguments.Comment
-
How about using a Command queue instead? Keys can be bound to commands arbitrarily (think Roguelike versus Standard, and also think Macros). This could offer richer scripting options too. Macros could be more than just sequences of keystrokes, but could become richer.
Command could be:
"Cast Spell - No arguments", and the game engine prompts for book, etc.
or
"Cast Spell - Heal Self". Game just casts the spell implied by the command arguments.Comment
-
I guess maybe you were asking how the game prompts for a spellbook. My comment was intended to express dislike for the giant switch statement that dispatches off the user's keystroke, where case 'm' means cast a spell, etc.
But some actions will need to prompt the user, and the issue is how to do that. In some respects, this should be the game client's task to implement, as it might be nice for the game engine to say: Here are a list of choices, go get a response from the user. Some clients might pop up a menu. Others might do significant work to emulate menus on a console. Others might allow rich hot keys. Some might be maintaining a buffer of keystrokes and first try to read the next key in the buffer ... whatever. But it would be nice for the game engine to have an abstraction barrier separating UI from logic.
Game Engine:
Ask the client for the next Command.
Ask the command to Execute.
Spell Command -> Command:
Do I have arguments that indicate what spell to cast? If so, just cast it. If not, build a list of spell books and ask the game client to have the user pick one. Then ask the book to enumerate its spells, and again ask the client to have the user pick one. Then lookup the spell object and invoke it. (Aside: It would be nice if spellbooks where dynamic containers of spell objects, as this opens up the opportunity for customization, or scribe classes that copy scrolls into their spellbooks, etc.)
Get Command -> Command:
Pick up the object currently under the player and put it into inventory.
etc.
Sorry, I'm jumping into this thread a bit late ... I'll shut up nowComment
-
Well that giant switch statement exists at some point, somewhere. BUT I can keep it out of the main game code, and stick it somewhere else.
Here's a rundown of what happens:
key comes in -> key passed to Angband -> Angband build's a command and puts that on the queue -> commands are processed as long as the player has the energy to do so
but yeah, I'll probably do something like this for the prompt:
Code:def prompt(self, choices): #if choices is an empty list, then it's a directional prompt, otherwise its a list of things if(len(choices) > 0): return self._client.select_prompt(choices) else: return self._client.direction_prompt() return None
Comment
-
At some level you're going to have to map input to actions, but I do agree that this should be at the interface level, not the engine level. Not just roguelike vs. "standard" keysets, but also mouse input (clicking on buttons that the client shows the user), touchscreens, gestures, etc. are all things that the client would have to interpret for the engine anyway, and having the client have to say "Okay, the user just made the "cast spell" gesture, so I should map that to 'm' for the engine so it can map 'm' to "cast spell"" is just silly.
How's about this for interaction?
* Client passes Cast Spell action to Engine.
* Engine passes ObjectPrompt object back to Client. ObjectPrompt contains a list of valid targets for Cast Spell action (including spellbooks in inventory and on floor, in this case)
* Client shows selection to user, gets the user's choice, returns that choice to Engine.
* Engine passes ChoicePrompt to Client, asking Client to choose which spell is cast; Client prompts user, sends to Engine.
* Engine passes AimPrompt to Client, asking Client to choose where the spell is cast (or an ItemPrompt for casting on an item, etc.); Client prompts user for tile/direction, sends to Engine.
Prescripted responses to Prompts could be passed to the Engine; in that case, the Engine would match up Prompts to entries in the pregenerated response queue. For example, if the Client sends the Engine "cast spell, object target spellbook 1, choice target 1", then the Engine would skip the first two prompts as it already has responses, but would still send the AimPrompt to the Client.Comment
-
Sounds like a good idea.
Although I loathe to let the client know about the inner workings of the game, I do believe now that the client should generate the commands. This is especially important for the possible use of different devices, which may manage input in different ways. Ports then become much easier.
Edit: And it's not like changing commands is a difficult port to make...Comment
-
Comment
-
That's what I was trying to do at first, but yeah, it was getting to be a PITA quite quick.Comment
-
The current strict disconnect between I/O events and commands (via util.c`inkey_ex) is extremely valuable.
* currently implemented in dungeon.c`process_commandComment
-
Woot! 500th post!
Right now pyAngband has gone though some changes. I basically threw out a bunch of my object code and such, and have decided to move on with that in a simpler, ground-up approach.
Anyway, commands are generated client-side and sent to the game so that the core logic doesn't give half a crap about keypresses.
Core logic can tell the client to prompt, and can check for instant-inkey for interrupts, not that repeated commands are implemented yet...
Door's can be opened and closed. I need to fix prompts, but besides that it works pretty well.
I will upload to Github a little later, going out now. Will also post a .zip of code here since it is still quite small.
EDIT: Posted source as .zip, only WindowsClient.py works for now, so just run that. I'll fix and upload the CursesClient after a bit.Attached FilesLast edited by Sirridan; November 15, 2010, 21:29.Comment
Comment