Infinity 2 is a Free (GPL'ed<) procedurally-generated infinite rogue-like game written entirely in Python.
I told my girlfriend, excitedly, that "I think I'm writing the first ever Free procedurally-generated infinite rogue-like game in the Entire World". She looked at me, and said, very casually, "You know, I wonder how many people there are that have this many red fruit loops at the bottom of a white bowl, sort of like this one..?" Pleased that Amber had taken such an interest in statistical analysis, I immediately replied with, "That's a very good question; I too, wonder..." 250 million people in the United States, x many colors of bowls, r % of breakfast serials are fruit loops...
Hehe heh. I looked up at Amber. "That was good Amber, that was read good; We laughed for some time.
Last night, I worked on the creature code. For some reason, it was just really long in the doing; I think that, since it's been a week since I touched the code, there was some sort of psychological difference between me and the code. I don't know.
Anyways, I've made images for several of the easier monsters, and the human player. There is new code for terrain types and their capabilities, segment activation and deactivation code, and code to see if a monster of a given type can exist in a given terrain or not. Procedural generation of spawner points is written but not tested, the same goes for spawner patches.
Coming up next, code to make it so that the spawner points appear in the UI, and then a debug cycle. Then I need to make it so that the God/Kami mode allows you to add and remove spawner patches. Finally, creature instantiation upon segment activation, and creature motion.
Then I'm done with the basics for creatures..! (Combat/XP remains to be written in another stage of implementation.)
No major screen shots this time; Just the player is now moved as if it were a creature, and the creature motion framework is all in place. Commands are properly relayed to that framework. This is advantageous, since it will isolate all collision code and combat resolution to th creature section of code. I can also make the fairy player gain poison capabilities upon reaching level 4... (if I recall from my notes correctly...)
Alright; I'm about done with the basic terrain world editing features. Everything's working like I want it to, and it's rather pleasant.
I could do with an undo feature, and there's a few things that I like. I've got many ideas on how to implement them, but it's time to move on; These things are non-essential and can wait for future versions. I'll have better ability to implement reversible commands and what not then.
Here's the shot:
You can't see it in the screen shot, but under the "Edit" menu, you can set an entire segment's type to forest, cave, or mine in one fell swoop. You can also pick the density (0%, 10%, 20%, ..., 90%, 100%), as well as the hostility (0%-100%, once again.) You have to be careful when modifying densities, since a density modification tosses out all patches on the neighbors, since neighbors have to recalculate their densities as well.
Next, ... creatures, including the player, and then having them walk around..! Woo Hoo! The beginnings of a game!
Whew! That was easier than I thought it would be; I now have persistant edits of the procedural world! Woo hoo! It's surprisingly fun to just edit the world willy nilly, when there is already something there to work with.
Here's a screenshot:
Here's a quick to do list:
I'd like to make sure that all segment patches aren't loaded into memory at once. I may slap a bunch of accessors on the gamedb module to do this, but, unfortunately, it's not really a priority. It's probably fine to guzzle the memory; I'm more concerned about writing a complete game. Put it on the list of things to add for the next game.
It's been 18 days since I worked on Infinity 2 last; My attention was suddenly and completely captivated by a book on Category theory, which I'm almost halfway through now...
I've solidified the main loop, and the initial pre-inventory, pre-godmode GUI interface is complete. (I'll need to work out a crude inventory system soon...) You can now walk about, even though you don't appear. It's fun to see the procedural world generation in action.
Here's another screenshot, not too different than the last:
Coming up next: God mode edits. After that, segment activation/deactivation, creatures, and spawners. And then after that, items, inventory, and inventory ui... We'll almost be up to 0.9, a playable game... Woo Hoo!
I'd write about the cool stuff that's in here, but it's too late, and I have work to go to tomorrow, and class to give as well...
Here's a screenshot:
Quick rundown of what I've added:
Next, I'll make it so that in the UI, you can move around and explore the world. Currently, exploring the world consists of dumping huge quantities of map to the console like this:
######## ###########...........T........%....T....T..%....T. ## # #####
######## ###########....%.%.T.T.T....%.....T........%T..TT.. ### ## ##### ##
######### ##########...T...%T..%...T%.....T...T..T.....T.... ## # ### #####
########## #########.%......TT..T............T.%.T.....T..%.###### ### ## #
########### ########........T............T........T.T......T#### # ##### ### #
############ #######..TT........T...T.T.......%..T%.......%.### ### #######
############# ######T..T.%.TT%..T..T..TT.....%.........T.T..##### # # # # # #
############## #####.....%...T..%....T........%...T..%...%T.### ##### ##### ##
############### ####...T........T%T.........%.......T..TT...##### ## #### ##
################ ###T...T.TT..T.T...T..%..T..%.TT.T...T..T..## # ## # ## ### #
############ ####..%....%T%..%....TTTT...T..T...%.%.%T...### ## # # #### #
### ######### ####%..T%T....T.....T.T........T....T...T... ## #### # ##
###### ###### ## .%TTT.....................T.T..T.T.....T# ### ### ### ## #
######### ### ##.......%T....%T.%.............%.........## # #### # # # #
############ # ####..T%T.T.T...T.......T....TT.%%T...T.T.T. ###### # # # ## #
############## ####.T.T...T.T...TTT..%...%.TT.T...T........ # ##### #### ##
############### ####.....%..........%.T%T...%...T...T.T%....# ######## #
############### ####T..T%..T.....TTT.T.....%...%....T..T....### ##### # ## #
############### ####.T........T........T.T.%......%.......T. ## # ## # # # # #
############### ####....%.T..%T......TT.T..T..........TT....# # ##### # ####
############### ###### ################################# # ## #### # ##
############## ######### ############################ ### ### ## ## # #
############ ########## ############# ########## ####### ### # ## ## ###
## ########## ########### ########### # ####### ########### # #### ## ######
#### ######## ############# ######### ## ### ############# #### ##### # ###
##### ###### #### ####### ####### #### ## ############### ## #### ## ######
####### ##### ## ## ######## ##### ##### ## ################ # ## # ## ## ##
######## ## ##### ######## ### ####### ## ############## ## ## ## # # ###
########## # ######## ######## # ######## ## ############### # ### ## ##
########### ########### ######## ######### ## ################ ## ### ## # ##
########## ############# ####### ######## ### ############ ## ### #### #####
######### ############## ###### ## ######### ## ############ # ### # # # ####
######## ################ #### ### ######### ### ############ # #### # # # ##
####### ################## ## #### ########## ### ########## ## #### # ### ###
###### #################### ##### ########## ### ###### ## # # # #
##### ##################### ##### ########### ### # ######### # # # ##### #
#### ############################# ########### # ############### ## # #
### ############################## ############ ### ########### # ###### # #
## ############################### ################# ######## # # # ## ### #
## ############################### ################# ########### # ## ### ## #
Um... That's about it; I'm really tight on time, what with teaching classes Monday and Saturday, and raising Sakura... I'm really happy to be getting as much as I have done so far.
On the slate so far for Infinity 3:
Sure, I could do those in Infinity 2, but by the time I finished, would I have the emotional money to complete the rest of the already ambitious project? I don't know, and I don't want to find out. I'll leave it for Infinity 3. I just want a playable game with a neat plot and an editable infinite map... {:)}=
As long as I'm looking into the future, I should note that I really want to make a summary of the key techniques and design decisions that went into Infinity 2. It was a major drain trying to figure out how I was going to activate/wake/sleep/reap enemies, and what my data structures needed to look like. When I'm done, I'll write them down, so people can see how it works without having to dig through miles of source code.
I've just started programming, after about a week of hashing out details in my notebook while waiting for the bus, while on the bus, between bites of dinner, etc., etc.,.
The actual game design was easy; That I did Sunday night, in a fit of inspiration. I set down to program late that night, and then realized: "Good God, this isn't going to work..." So I've been meditating on the technical design to support the game design, and I believe I've got it all worked out, with the exception of a few elements that I believe are easy, since I've implemented them before.
The hard part has been an editable procedural world system. Procedural worlds are relatively easy enough to write; Just pack an X and Y into a uint32, and start cranking out numbers. But an editable procedural world system? Editable at run-time?
More things than I had thought about came up: What if the player enters God mode, and decides to nuke some creature; what happens? (Answer: Introspect the creature for the spawn segment and point, and tell the segment to remove the creature spawn point. The creature spawn point will tell the creature list to dump all entries created by it. The creature has to detach itself from the spawn point before it's traced back, and the spawn point needs to detach itself from it's creatures before it destroys them; otherwise you get circular destruction loops. There are other ways of handling this that I am considering- One way is a mark of death- you mark creatures for removal, and then remove them at the end of the turn. Easy. May as well do it, though I suspect there may be some atomicity issues there...) Do creatures get saved? (Answer: Yes, the whole creature list gets saved. Python's shelves make this easy.) When do creatures get reaped? (Answer: Outside of a sleep range. When the creature is within a certain range, it is active. Outside of a further range, and they get reaped.) When will segments that are activated spawn a monster, and when do they just stay quiet? (Answer: They spawn a monster when the player activates them after having been a certain distance away. That is, when they enter the activation set, they spawn. The activation ring is either 2 or 3 segments away, which gives you some back and forth walking space, and a fair number of monsters.)
So, it's been quite a week for design. Nice to be finally writing some code.
Tonight I extended the RandomSequencer. The RandomSequencer makes it so that random numbers are procedurally generated in a given context, even if you switch to a different context for a while. For example, if you are pulling out data for segment 0,0, and then need a piece from segment 1,0, you can go generate it, safe in the knowledge that the RandomSequencer has kept your context in mind when you return to 0,0.
More importantly, I wrote the segment cache and segment class. As another aside, I also started the Game Database. It's a Python shelve, so that last part was easy.
The cache is properly building, retrieving, aging, and tossing segments. WooHoo! Also, the segments are properly alloying their density and hostility levels. Woo Hoo!
Segments load in 3 phases: Blank, Simple, and Complex. Simple information includes type, x & y hookup points (so that neighbors can aesthetically link up to the segment), and unalloyed density and hostility information. Complex information is where the density and hostility is alloyed with the help of neighboring data (the RandomSequencer becomes a godsend here),
There's no way I could have done this without planning; There's just too many interddependencies, no matter how you cut this sucker up. The Segments, Segment Cache, and Game Database are just too interdependent; It's a coding 3-some. Maybe I'll see the light some day, but it seems pretty tight to me right now.
I have repeated more than once in my mind tonight: "Premature Optimization is the Root of All Evil." -- Donald Knuth
That said, there is plenty of room for optimization in here, if it later comes to that. I don't see many stumbling blocks with porting to C either, if I ever get to that stage/need. Sure, I'm using the shelve, but the data is standard enough; It should be a straightforward conversion process.
It's 4:31am, time to sleep. =^_^=
Code from tonight; remove the ".v1" to play with it.