Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - xee

Pages: [1]
1
Programming / Re: Basic game programming concepts
« on: October 10, 2013, 06:42:03 PM »
I'm up to a few thousand lines of code already into my project and so far using tables to keep track of everything seems to be working out: 

;pWorldTable    coords from (0,0) to (4 Billion,4 Billion)
;     DWORD,DWORD == # entries,ID# of active area (used to calculate which WX,WY to -> to)
;     DWORD,DWORD == WorldX,WorldY   our first area starts at (2 Billion, 2 Billion)
;     DWORD,DWORD == pLocalTable,RESERVED
;     DWORD,DWORD == WorldX,WorldY   
;     DWORD,DWORD == pLocalTable,RESERVED
;               etc.
;
;   pLocalTable    coords start from (0,0) to (width of window,height of window)
;        DWORD == <RESERVED>
;        DWORD == MobsTable
;        DWORD == StructsTable
;               etc.
;
;      pMobsTable
;        DWORD,DWORD == # mobs,<RESERVED>
;        DWORD,DWORD == X|Y,pChar pointer to char/mob/item detail sheet
;        DWORD,DWORD == X|Y,pChar pointer to char/mob/item detail sheet
;               etc.
;
;      pStructsTable
;        DWORD  ==  RESERVED
;        DWORD  ==  pStructure
;        DWORD  ==  pStructure
;        ...
;        ...
;        0     
;
;         pStructure
;           DWORD,DWORD == RESERVED, RESERVED
;           DWORD,DWORD == RoomX|RoomY,RoomW|RoomH
;           DWORD,DWORD == WallX|WallY,pChar pointer to char/mob/item detail sheet
;           DWORD,DWORD == WallX|WallY,pChar pointer to char/mob/item detail sheet
;                  etc.

I use nested tables, so for instance my WorldTable contains a bunch of LocalTables and each LocalTable contains a MobTable, StructsTable and soon an ItemsTable.  And each MobsTable would list an X,Y and it's corresponding pointer to a Character Sheet of the mob/item at that location.

And everything, you, the mobs and even a piece of the wall in a structure has their own Character Sheet:

;Char sheet offsets
OFFSET_MOB_OBJ_ID   equ 0
OFFSET_MOBSPEED     equ 4
OFFSET_NAME         equ 8
OFFSET_SYMB         equ 12
OFFSET_COLOR        equ 16
OFFSET_ALTCOLOR     equ 20
OFFSET_VISIBLE      equ 24
OFFSET_MOBMEM       equ 28
    OFFSET_MOBMEM_COMBATANT equ 0
    OFFSET_MOBMEM_NUMSTEPS  equ 4
    OFFSET_MOBMEM_ENCCS     equ 8
    OFFSET_MOBMEM_ORIGPATH  equ 12
    OFFSET_MOBMEM_ALTPATH1  equ 16
    OFFSET_MOBMEM_ALTPATH2  equ 20
    OFFSET_MOBMEM_DMGMSG    equ 24
OFFSET_FONTWH       equ 32
OFFSET_STATS        equ 36
OFFSET_HPCURRHP     equ 40
OFFSET_ALLEGIANCE   equ 44
OFFSET_WEAPON       equ 48
OFFSET_DOORWAY      equ 52
OFFSET_BgXY         equ 56
OFFSET_STATUS       equ 60
OFFSET_STATUSMSG    equ 64


To keep it simple I'm just using a single character sheet for everything so not all the fields would be used by some things so I'm wasting quite a few bytes for sure but OTOH if I decide later on to implement destructible environments, the HP field is already in place for me to use for the walls for instance.

I'm using Assembly btw so I don't know if any of this would apply at all in an OOP language.

2
Programming / Github, bitbucket etc.
« on: July 11, 2012, 02:18:31 PM »
Does anyone use such sites?  From what I gather they're basically sites you post your code to and allow others to view, make changes, suggestions etc. to your code?  Are there downsides to using such sites or is it better to just slap your stuff onto your own blog site and call it a day?  ;D  Thanks for any info!

3
Programming / Re: Newbie programming Q's
« on: June 20, 2012, 06:25:06 AM »
Why did you pack data about initial stats in such a strange way ("01100011011000110110001101100011b")? The machine code necessary to unpack it probably takes more bytes than you save.

It looked like an easy and convenient way to store dice rolls for the initial stats.  So say I have an Ogre race, with brute STR, but dumb as a rock, so-so DEX and decent HP, I'd maybe use the following dice rolls for STR INT DEX CON:

8d3 3d4 4d4 7d3

I can make each die a nibble:

1000 0011 0011 0100 0100 0100 0111 0011

which all conveniently crams into 1 register, which I can then run once through my dice roller function for each Ogre I create:

Code: [Select]
DiceRoll4 PROC USES ebx ecx edx edi Dices:DWORD
        mov ecx,32
        .REPEAT
            mov ebx,Dices           ;contains (4) individual #d# dice rolls in binary form for stats
            sub ecx,8
            shl ebx,cl
            shr ebx,20              ;bh==1st die
            shr bl,4                ;bl==2nd die
            cmp bl,0
            jz @F               
            movzx edi,bl
            mov bl,bh               ;final stat min==1st die since nrandom can generate a 0
            push ecx
            push eax
            .REPEAT
                invoke nrandom,edi
                add bl,al
                dec bh
            .UNTIL (bh==0)
            pop eax
            pop ecx
         @@:mov al,bl
            ror eax,8
        .UNTIL (ecx==0)
        ret                         ;eax==(4) completed dice rolls
DiceRoll4 ENDP       

and now have 4 randomly rolled stats in one register :)

4
Programming / Re: Newbie programming Q's
« on: June 19, 2012, 06:14:35 PM »
Er, to be honest, w->type is just as OO irrelevant as internally referencing variables...w->type() (with the inference of inheritence) would be the only way to actually imply OO-ness.

Also, reduce() is acting like a factory call for some reason?  Hello over-complicated memory management -- you're just begging for memory leaks.  Why can't a weapon reduce itself?  And if you need both copies, clone() it first and then reduce one?  

Also, why does your class type look like a variable name?  And even when you have 1 line conditionals, it's still recommended to put {} around them.  And to only have one return path from a function.

OMG I have no idea what you just wrote :)

Here's the first few lines of my code that populates the fields of your character '@':
Code: [Select]

STATS STRUCT
    raceidptr   DWORD ?    
    symb        DWORD ?
    color       DWORD ?
    attribs     DWORD ?     ;STR INT DEX CON
    weaponptr   DWORD ?
STATS ENDS  

human STATS <MOBTYPE_text1,'@',COLOR_SNOWWHITE,01100011011000110110001101100011b,dagger1>    ;6d3 all stats
goblin STATS <MOBTYPE_text2,'g',COLOR_CHARTREUSE,01000100010001000100010001000100b,barehanded1>  ;4d4 all stats

barehanded1 DWORD WEAPONTYPE_text1a,'|',COLOR_SNOWWHITE,00010011b,WEAPONTYPE_text1b    ;1d3
dagger1 DWORD WEAPONTYPE_text2a,'|',COLOR_SNOWWHITE,00010100b,WEAPONTYPE_text2b        ;1d4

MOBTYPE_text1 db "a human",0
MOBTYPE_text2 db "a goblin",0

WEAPONTYPE_text1a db "barehanded",0
WEAPONTYPE_text1b db "punch",0
WEAPONTYPE_text2a db "a dagger",0
WEAPONTYPE_text2b db "pierce",0
WEAPONTYPE_text3a db "a longsword",0
WEAPONTYPE_text3b db "slash",0
...
...
    invoke HeapAlloc,hTable,NULL,128
    mov [esi+16],eax                        ;Setup first LocalTable
    mov esi,eax

    invoke HeapAlloc,hTable,NULL,64         ;Setup Character Sheet
    mov pChar,eax
    mov [esi+12],eax
    push esi
    mov esi,[esi+12]                        ;load Char sheet
    mov eax,[human.raceidptr]
    mov [esi],eax                           ;->"human"
    mov eax,[human.symb]
    mov [esi+OFFSET_CHARSYMB],eax           ;'@'
    mov eax,[human.color]
    mov [esi+OFFSET_CHARCOLOR],eax          ;SNOW 3
    mov eax,[human.weaponptr]
    mov [esi+OFFSET_WEAPON],eax
    mov DWORD ptr [esi+OFFSET_ALLEGIANCE],1
    mov DWORD ptr [esi+OFFSET_STATUS],1
    mov eax,1
    shl eax,16
    mov ax,1
    mov [esi+OFFSET_CHARMOBID],eax          ; area 1|id# 1
    invoke HeapAlloc,hTable,HEAP_ZERO_MEMORY,96 ;create space for personal memories
    mov [esi+OFFSET_MOBMEM],eax
    lea ebx,[eax+12]
    mov [eax+OFFSET_MOBMEM_DMGMSG],ebx    
    invoke DiceRoll4,human.attribs
    mov [esi+OFFSET_CHARSTATS],eax          ;STR|INT|DEX|CON
    movzx eax,al                            ;isolate CON stat
    push ax
    shl eax,16
    pop ax                                  ;Normally HP==CON*LVL
    mov [esi+OFFSET_HPCURRHP],eax           ;HP|Current HP
    
    pop esi                                 ;->LocalTable
     
Here I'm just filling in the fields of a memory block with appropriate values of my character and it's basically the template used for all the monsters in the game. How would this look in proper C++ syntax out of curiosity?  Just wondering if it's more or less code and if it's truly more self explanatory.

5
Programming / Re: Newbie programming Q's
« on: June 19, 2012, 02:11:56 AM »
May I ask, why you started with it and not something a little bit more high level like Java or C++?

For some reason or another I've found C++ to have a much higher learning curve than assembly. Moving bits around registers can be tedious, but it's pretty straightforward and no-nonsense,  but OO concepts I just find difficult to grasp and it just makes my head spin.

You probably don't have to worry about memory when it comes to the stats of enemies. How many enemies are going to be spawned at once?

Right now I'm playing with the idea of have invading hordes of enemies you eventually have to deal with.  And so far I have their data structure mirror your own, they have their own stats, weapons, armor, etc.  I like to have lots of in-fighting as well with the different races, so they'll probably have their own XP and character levels as well.

Quote
I don't think that you need to worry about whatever your collision detection is or how you're doing it (unless you're looping through all of the tiles in the area or something, since you really only need to check the tile you're going to).

I didn't know about tiles until I started reading this forum, I might consider implementing that.  For now I actually have my mobs just plotted at random X,Y coords in the area and they pretty much have the freedom to walk onto any X,Y on the screen.  Mobs are often misaligned when standing next to each other and next to doorways which is more problematic.  My collision detection routine does loop through all the X,Y's in the area, and using their font width and height, tries to calculate if an X,Y is safe to venture onto. 

As far as using too much memory I don't think it will be an issue, not with a Roguelike. I could be wrong. You only really need to track instances on that level, right? Things on other levels can just be saved and reloaded if you go back to that level.

You're probably right, if anything memory leaks are probably going to be my bigger concern than running out of memory :)

Quote
OR you can google the Nethack and Crawl wikis and be blown away by the number of items and monsters. At some point you want to figure out if you want a game with tons and tons of stuff or a game with a few things done very very well (like in Brogue).

Wow, lots of good stuff on the wiki, thanks for the heads up!

Greetings and welcome to the RogueTemple!

Thanks!

Quote
My guess is you use MASM and it is not your first programming language. You choose it because you want some challenge and a roguelike game seems like a neat thing to do in it.

Yes, I've played with asm before back in the days of DOS using Borland's TASM, more so than any other language so it didn't take long to pick up from where I left off.  Coding with the windows API and with the boatload of macros available in MASM it almost feels like a high level language at this point!

Quote
Before I respond with my comments on data structures: my assembler of choice is Netwide Assembler (NASM). I view MASM as insufficient because it is limited to Microsoft. Most of my experience is with NASM. It should apply but be wary of subtle differences cropping up here and there.

I've heard NASM and FASM are good alternatives to MASM, could they all assemble from the same source code with little or no modification?

status code - 0:dead, 1:normal, 2:in_combat, 3:fatality

Quote
First two are sufficient. At least I haven't seen a roguelike using more than those two.

I have it coded this way for now, because normally my mob would just move in random directions.  But that changes if the status code is in_combat, and if the target is not in range, he will try to move in your general direction to track you down.

Is this a good approach to have every mob and item in the game to have their own personal record/character sheet?

Quote
Probably not. PRIME has this. Every monster has its stats rolled and has skills. Most of that depth is neither used nor shown to the player so it is a potential complexity that is close to useless in the end. I would not bother with it unless you have specific plans how to take advantage of it.

I was thinking it may be more realistic if monsters had some individuality to them, ie their own stats, some would be stronger/faster than others, using their own variety of armor pieces and weapons and inventory.

Also after a lot of head banging and hair pulling I finally have my collision detection an pursuit code up and running somewhat, just wondering though are there standard algorithms for such things?

Quote
Ha, it is not going to get any easier in future. Respect for undertaking up such a difficult language to learn. Someone made a roguelike game in Prolog so maybe just maybe there will be one in assembly too thanks to you.

Assembly programming really seems have fallen by the wayside but there's lots of fun stuff that can still be done with it!

I think there is a place for assembly language even today, but it's not in game programming. Higher level language is better. You need to know a lot about programming to use assembly, otherwise you'll probably just waste your time.

For large scale projects, you're probably right on the money.  But since I'm already somewhat familiar with asm, I decided to stick with that instead of trying to learn another language from scratch.  Actually programming for Windows was almost like starting all over again but the windows api really took out a lot of the grunt work to get something up and running coding in asm.

6
Programming / Newbie programming Q's
« on: June 17, 2012, 02:23:32 PM »
Hey guys, I'm excited to have stumbled upon these forums!  I decided a couple months ago to take up a programming language (windows assembly) and to keep things interesting I started working on a rogue variant from the very beginning to help me learn.  I have a couple questions though:

How do you keep track of everything in the game, do you keep everything in seperate tables?  For instance my tables looks like this right now:

2 columns, each field DWORD in size:

Main table:
# mobs, pStruct (pointer to a table of existing structures)
X|Y, pChar (pointer to a char sheet of X,Y)
X|Y, pChar (pointer to a char sheet of X,Y)
X|Y, pChar (pointer to a char sheet of X,Y)
...
...
etc.

pStruct:
# structures, Reserved
RoomX|RoomY,RoomW|RoomH  (each are WORD size)
Wall_X|Wall_Y,pChar pointer (pointer to char sheet of wall)
Wall_X|Wall_Y,pChar pointer (pointer to char sheet of wall)
Wall_X|Wall_Y,pChar pointer (pointer to char sheet of wall)
...
etc.

pChar: 1 column, DWORD in size
pointer to name/race id
symbol
color
MobID - unique id# for this mob (word size each: # area it belongs to|# obtained from a loop counter)
STR|INT|DEX|CON  (1 byte each)
HP|CURRHP  (word size each)
status code - 0:dead, 1:normal, 2:in_combat, 3:fatality
weapon/armor/item codes
pointer to personal memory->
  DWORD == # steps to an encounter/item/etc
  DWORD == pointer to char sheet of encounter/item/etc.


(if pChar was for an item/structure instead of a mob, fields other than nameptr, symbol and color would have different meanings)

Is this a good approach to have every mob and item in the game to have their own personal record/character sheet?  Should I be concerned how much memory I'll be taking up?

Also after a lot of head banging and hair pulling I finally have my collision detection an pursuit code up and running somewhat, just wondering though are there standard algorithms for such things?

Also is there a standard database of monsters/items for roguelikes I could use as well?

Thanks for any info!

Pages: [1]