Omnimaga

Calculator Community => TI Calculators => ASM => Topic started by: chickendude on October 01, 2012, 12:38:24 pm

Title: Keeping track of events in RPGs
Post by: chickendude on October 01, 2012, 12:38:24 pm
I've been wondering how you can keep track of all the things you've done in a game, how you can advance while unlocking new places, opening treasure chests, NPCs coming and going, maps changing (for example, maybe a house gets built while you were out of town, or a rock gets moved). It's a lot of information to track and i don't think you want to make a second copy of every map in your game. Maybe my problem is that i have a lot of these things built into my maps when i need to somehow separate them?
Title: Re: Keeping track of events in RPGs
Post by: Yeong on October 01, 2012, 04:09:31 pm
arrays filled with "switches"(basically if it's on, 1. If it's off, 0) will help you a lot. Also, something dynamic, like chests, could be drawn over tilemap based on the "event switch" is 0 or 1.
Title: Re: Keeping track of events in RPGs
Post by: thepenguin77 on October 01, 2012, 06:34:27 pm
arrays filled with "switches"(basically if it's on, 1. If it's off, 0) will help you a lot. Also, something dynamic, like chests, could be drawn over tilemap based on the "event switch" is 0 or 1.

Building on this, here's by far the best way to actually do this. If you look at the list of memory addresses, you see this:
Code: [Select]
saveSScreen equ 86ECh
asm_prgm_size equ 89ECh
bstCounter equ 89EEh
flags equ 89F0h

Now, of course to you, this doesn't mean that much. But what's neat about this is that IY points to flags. Whenever you go to use a system flag, what you are doing is accessing $89F0 + [flag offset]. Now, this is what everyone is used to. But, look what comes before flags, 2 random addresses, and then saveSScreen! What makes this great is that IY can actually address backwards.

Ok, so to put some numbers on this.

IY is pointing to $89F0
The last byte of saveSScreen is at $89EB
The gap there is 4 garbage bytes
IY can go as far back as -128

So, put these numbers together and you can have 124 bytes of flag data. That's 992 flags.



Implementing this:
First of all, your flag data will be from $8970 to $89EB.

To access it, you would use "bit flag_bit, (iy - flag_offset)". Now, this works fine and dandy, but to be honest, remembering both the bit and the offset is rather annoying. This is in my opinion one of the pitfalls of TI's flags. So, a better solution is to create a macro.

This macro is for SPASM, if you use TASM then toggle won't work, and if you use Brass, I doubt any of it will work.
Code: [Select]
#define b_(bit) bit&7
#define f_(flag) -flag/$10 - 4

#define bit_(flag) bit b_(flag), (ix + f_(flag))
#define set_(flag) set b_(flag), (ix + f_(flag))
#define res_(flag) res b_(flag), (ix + f_(flag))

#macro toggle_(flag)
ld a, (ix + f_(flag)) 
xor 1 << b_(flag)
ld (ix + f_(flag)), a
#endmacro

That probably scares you, so let me explain.
- bit_(flag_name) is just like bit
- res_(flag_name) is just like res
- set_(flag_name) is just like set
- toggle_(flag_name) will toggle that bit

And to define flags, you do something like this:
Code: [Select]
flag0 equ $00
flag1 equ $01
blah equ $02
blahh equ $03
flag4 equ $04
flag5 equ $05
flag6 equ $06
flag7 equ $07
flag8 equ $10

The first number is the offset, and the second number is the bit. You can just keep this general pattern up for a while. I have to go now, but if you run out of flags using this method (the highest is $F7, let me know and I'll tell you how to continue).

And to invoke the flag commands:
Code: [Select]
set_(flag1)

Will set flag1


Edit:
   992 flags, not 496
Title: Re: Keeping track of events in RPGs
Post by: chickendude on October 01, 2012, 06:38:45 pm
Yeah, that's what i was thinking, just a huge list. It just seems like a very inefficient way to keep track of everything and not very flexible.

EDIT: I just saw thepenguin's post, thanks! I'm going to try a simple implementation and see how it works. This way i can give each of my objects that can be "used" (treasure chest, NPC's text, etc.) a flag id and when i open the chest flip the flag. This is pretty cool cause it would be very easy to implement things like changing sprites based on an event, since right now my data is organized like this:
Code: [Select]
Brushes:
.dw grass
.dw path
.dw door_bookshop
.dw sign_hanging

grass:
.db %00000000
.db 0
path:
.db %00000000
.db 1
door_bookshop:
.db %01000010
.db 24
.db 1 ;action#, 1 = change map
.db 5,7,1 ;starting x/y coords, map#
sign_hanging:
.db %10000110
.db 32
.db 14
.db 12
.db 0
.dw text1
...where the first byte is an action bit, the second byte is a sprite id, and the rest depends on what actions are set (passable nonpassable, if the tile has a variable height, actions when you walk into something, actions pressing 2nd, etc.) and i could easily change it to update both the sprite and whatever the action was. The only problem i can think of is that you really only have on/off so i can only assign one action to each object in the entire game. Sign_hanging, for example:
Code: [Select]
sign_hanging:
.db %10000110 ;action when hit with 2nd, variable height, nonpassable
.db 32 ;sprite id
.db 14 ;how far behind the sprite we can walk
.db 12 ;sprite mask
.db 0 ;action id, 0 = draw text, 1 = change map
.dw text1 ;action data, in this case text label
I could use maybe bit 3 (bits 3-5 are still unused) to change the event associated with it, and bit 4 to change the sprite associated with it:
Code: [Select]
sign_hanging:
.db %10011110 ;change sprite/event based on event id
.db 0 ;event id
.db 32 ;sprite id
.db 75 ;sprite id if event has run
.db 14 ;how far behind the sprite we can walk
.db 12 ;sprite mask
.db 0 ;action id, 0 = draw text, 1 = change map
.dw text1 ;action data, in this case text label
.db 1 ;action id if event has been run
.db 4,4,1 ;new action data
Another option would be to give each event 2 bits, allowing me four changes (i could maybe divide them into 1 bit and 2 bit events), i'll play with this a little and see what i can come up with. If it turns out i need more, i could always just change iy to another location (like 127 bytes into savesscreen, or wherever i've still got some free saferam left).

Thank you so much both of you for the ideas, i've got a bit to play with now, thanks :)

EDIT2: does anyone know of any good tutorials/articles on event programming/RPGs in general? I've been tackling things one by one as i come across them, kinda like hopping stone to stone across a river (and i don't want to get stuck in the middle of the river!).
Title: Re: Keeping track of events in RPGs
Post by: Yeong on October 02, 2012, 09:59:02 am
Well, I learned how rpg generally works by using rpg makers. It's really easy to use, and while using it, you'll know how rpg works generally. Also for hopping stone, make that tile has a movement bonus on character by 1?
Title: Re: Keeping track of events in RPGs
Post by: Eiyeron on October 02, 2012, 02:50:19 pm
Mmmh.. There should be more event theory here, could you please help me too? I thinking too about manage events.
Title: Re: Keeping track of events in RPGs
Post by: Yeong on October 02, 2012, 03:40:02 pm
What do you mean by managing events? You mean maintaining them or keeping track of them?
Title: Re: Keeping track of events in RPGs
Post by: Eiyeron on October 02, 2012, 03:53:53 pm
Both :-°/me is making his own rpg engine, so...
Title: Re: Keeping track of events in RPGs
Post by: Yeong on October 02, 2012, 08:48:37 pm
for tips on maintaining events, it's easy to "group" the similar events. Like, event #1~#100 is quest-related, #101~#150 is chest-related, etc.
For making one, see the posts above. :D
Title: Re: Keeping track of events in RPGs
Post by: chickendude on October 02, 2012, 09:00:31 pm
Eiyeron, what are you writing your engine in? I would be glad to help/talk about what i've done so far :)

And in theory, organizing things by number can be quite nice, but i've always found that without a nice tilemap editor to rearrange everything for you, adding new tiles/objects later on can be a pain, cause you have to change all your maps...

EDIT: You can see my source here if you're (or anyone else is) interested:
http://code.google.com/p/juego-rpg/ (http://code.google.com/p/juego-rpg/)