## My Adventure Game Engine - Making Way For Adventure Engine 2

Jasoco
Inner party member
Posts: 3650
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

### My Adventure Game Engine - Making Way For Adventure Engine 2

NEW DEMO AVAILABLE ON PAGE 27
viewtopic.php?f=5&t=888&start=260

THE INSIDE STORY OF THE ROAD TO DEVELOPMENT:

While it is not ready for public consumption, I thought it was ready enough to show off. OMG SO MUCH TEXT! Read it all, it's good stuff.

First a little history. I have dreamed of creating a Zelda style game since high school when I took a graph paper pad and would draw tile based worlds and plan out scripts and how it would play. But I didn't have the means. None of the languages I knew were fast enough and I didn't know enough about programming to create a working engine, so I put the idea on hold for a decade.

Last year I discovered DOSBox, an app for OS X that emulates DOS at full speed or faster on my Intel Mac. I promptly found an old copy of QuickBASIC 4.5 and started work on an RPG engine designed to mimic games like the old Dragon Warrior or Final Fantasy games with battles mimicking Earthbound. While it was fast as long as I upped the cycles I quickly ran out of RAM since QuickBASIC was designed for old computers who never had more than 1MB of RAM so the program had an artificial memory ceiling. Boo! I had to find a replacement language quick!

The day before I found out I was losing my job I started work on a version of my engine that ran in Safari using its superfast JavaScript engine and took advantage of CSS and HTML5 features like the Canvas element that allowed drawing of shapes and images onto a "canvas" in an HTML page much the same way LÖVE does it. I quickly discovered that the JS engine was so fast, I could switch to live-action Zelda style encounters instead of turn-based. At first I also had scrolling maps but quickly went back to screen based maps when it turned out to be way too slow on large maps. (Moving a giant canvas, actually multiple giant canvases, every frame was taxing)

One day, a few months ago, I was cruising iDevGames' blog when I stumbled upon an article for Löve. What a crazy random happenstance! Had I not decided to look at that blog I would have missed this amazing engine. As soon as I downloaded it and examined all the wonderful examples and discovered how easy it was to create in Lua, I was hooked. I promptly started work on a Lua version of my engine I had written and rewritten twice already.

Right now it is a game engine without a direction. But that will develop in time. The final game WILL NOT be a Zelda fangame. And it probably won't even resemble Zelda. Hell, there is no roadmap for the game development. Right now all work is being concentrated on the engine stability and features so I can do things if I choose to. The player uses a sword and has a boomerang and bombs and arrows, but that could become a gun or rocks or a bat at some point. Who knows what I will create? I'm no Pixel, I could never come up with a compelling Cave Story. And I didn't create Knytt Stories, nor am I going to try to. I really don't know what this will be when it is all done say 5-10 years from now. Remember, Cave Story took 5 years and one person. Bob's Game also took 5 years and one crazy-ass person who completely went about it all wrong. I am also one man, and I also plan on taking 5 years on and off to create a game. Probably.

Do I have an idea for a setting? Well, I was always thinking of modern times. Not many games like this take place in modern times. With modern technologies. I want to create a world with modern settings, cities with buildings, not villages with huts. I hope to create a huge sprawling world with many sections. Even though I want to make the game free as in Cave Story free, I want it to be good enough that some publisher sees it and says "Hey, that could work well on the Wii/360/PS3". But you don't get to that point by being cocky or rushing things. Braid took a few years before someone said it was Xbox 360 material. Cave Story came out years ago and is just now being ported to the Wii. There are tons of indie games out there, but only a handful are good enough to be remembered as "Yeah, I loved that game."

I will not provide the code at this time, but would be happy to answer any questions about how I do things I do. Without further do and adieu and ado and all that, here is a list of features...

FEATURES THUS FAR:

Rolling Health Display
What does this mean? Well, think the Mother/Earthbound series. Not many games use this system, which is terrible because it's such a cool idea. Basically think of it this way. Say you have 50HP and an enemy hits you for 51HP. Obviously you now have -1HP, i.e. you're dead.. right? Not necessarily. In EarthBound, the rolling HP counter was used so if you are in a battle, you still have time to heal yourself (or your companions) before you die. The slower your counter, the more time you have. Your character does not actually die until the counter reaches the new HP. So you can get hit and have -1HP (Well, let's just say 0), but your counter is still slowly (or quickly) counting down to 0. And with special items or armor that slow the counter, you can live for a while before having to quickly heal yourself. I am thinking of taking advantage of this by having health recovering special moves or items you can cary and use before you are down to 0.

Mapping System
Smoothly scrolling maps can be virtually any size and up to 5 layers (One main layer and four object detail layers.) at any time. Also in place is support for animated tiles like water.

Dialog System
Text dialogs pop up onto screen animated, then text types itself out onto the screen. You can press the action button to speed it up if you are impatient. Future plans call for "talk bubble callouts" where it will look like the character is saying it, like in the Mario & Luigi games, rather than just a plain box with text. (My JS game engine had this feature)

Scripting System
Currently in place is a rudimentary scripting system. This is my current focus. Without a good scripting system, a game is useless. So the Script system must be perfect. Currently there are three commands; Dialog, Warp (For changing to another map) and Give Money.

Enemies
Currently in place are enemies shamelessly copied from Zelda. Octorocks (Three kinds) spit rocks, Moblin's run around shooting arrows, and goddamned bats bounce around the playfield occasionally stopping and getting in your way. The enemies are categorized into two groups, simple and advanced. Simple enemies have minimal frames of animation, like bats who don't have left, right and back profiles, just a front. While advanced enemies have wide ranges of attacks and animation frames. Not in place yet is a Boss system. Bosses will be a project for the future and due to their complexity and scripting I will be working on them for a while. To start I plan on once again duplicating Zelda enemies (Like the dragon in level 1 who has a simple walk up and down and shoot three fireballs occasionally style attack pattern.) until I get the hang of it and create my own bosses.

Droppable Items
Enemies will drop items ranging from money to arrows and bombs and health and other things. What more can I say?

Live Action Battle
This ain't no turn-based RPG. It's a real-time Zelda style adventure engine with on-screen battles using a wide array of weapons. (All currently shamelessly ripped from Zelda)

Explosions
I call them that, but they're really a fancy name for temporary animations that can be spawned at any time. For instance, destroy an enemy and it explodes in a puff of smoke.

Projectiles
Projectiles are anything that is created, thrown across the screen, then destroyed when it's run its course. Like weapons from both the player and enemies.

Weapons
What kind of weapons are currently in the engine? First off a sword. Or if you want, a close range melee weapon. Secondly, arrows. For long range attacks. A boomerang is next for stunning the enemy. It has two modes, one stuns and returns, another goes twice as far and keeps going through enemies to hurt them all in a row. And lastly so far, bombs. Bombs are a projectile with a 0 movement speed and a timer. When they "go off" they hurt all enemies in their range. When an enemy is hit, it flies back. Same happens if an enemy hits your player.

Weather
Currently rain with lightning. You can also set fog instead. The ferocity of the rain can ge adjusted if need be. Lightning looks really cool. Set the darkness of the sky as well. This might be used if I decide to create a time-based game where night and day comes and goes and different things happen at different times.

Simple Lighting Effects
Lighting effects like a lantern the player carries. (Think Link to the Past with the lantern in the dark basement of the castle.) In its simplest form it consists of a mask that has a cutout of a transparent area, with blackness surrounding it, which is drawn centered on the player, then the empty space is filled in by transparent black rectangles totalling maybe 5 different objects being drawn at once at the very least. This is how Zelda does it. This is done with no hit to the framerate at all.

Strafing
You know what strafing is. It lets you face one direction while moving around dodging enemy fire while keeping your character facing toward the target. Hold the left Shift key to move around while facing in one direction. Great for boss fights. 3D Zeldas have this, but 2D ones do not. Why? Seems they could benefit from this feature.

An Inventory Screen
Well, a useless inventory screen with no purpose right now. But it has neat floating rotating icon placeholders for whatever I decide to put there though I will probably rip the whole damn thing out and start over eventually.

Multiple Resolution Choices
Okay, right now there's two. Switchable by pressing M. You can play in 4:3 640x480 or 16:10 800x500. I prefer the widescreen view. It looks much nicer and gives more room to see. Plus when I press F to go fullscreen it takes up the whole screen if stretched. Very nice features. In the final product these will be placed in an Options screen at startup.

MAP EDITOR:

Yes, a working Map Editor in LÖVE both loads and saves maps. Currently does not deal with animations yet. I will implement that soon once I figure out how animated tiles are going to be finalized. I worked all last night on a map editor in JavaScript and CSS that ran in Safari because I thought it would be easier to code for. But it wasn't. The JavaScript version is buggier than hell. So today I decided to throw it all out and create an editor in Lua/Löve. Man, it was so much easier. And less buggy. And FASTER. Sheesh. So I have a working map creation system.

FUTURE DEVELOPMENT:

Enemy/Object Lock-on
Zelda, anyone? This would allow me to press a key (Probably Z) to lock onto the closest enemy. (Or switch to the next enemy in range) And while locked on, all weapons would fire in their direction and the player can move around the enemy in a circle. Cannot do this yet because the player currently only has four directions to face and only fires in four directions. Eventually I will allow full 360º turning. If all goes well.

More Script Commands
Plans include enemy, NPC and player movement, creation of enemies and/or bosses, items, whatever wherever, weather control, time control (If I go that route), pretty much anything that can be done will be able to be automated. Also control the camera, panning, locking to player or another character, all that will be done.

Levels
No, not like RPG levels, more like floors. For example, in Zelda: Link to the Past and Awakening and all other 2D Zeldas since, Link is able to traverse from one floor to another on the same screen allowing for neat things such as bridges Link can walk under or over. The use of stairs or a cliff you jump off of provides a transition from one level to the next. This could be easy to implement, but will not be until I have finalized some things first.

AND NOW SOME SCREENSHOTS:

This is what you really want, right? Screenshots of what I have so far. Note that all graphics are PLACEHOLDERS for development and will change. I am borrowing sprites from various games such as Zelda, Final Fantasy 4 and Earthbound, Dragon Warrior, whatever, I forget, it doesn't matter. These shots are just to show the concept of the engine.

1) The original QuickBASIC engine:

This version used special palette swaps to be able to use colors DOS didn't normally show in 16-color CGA screen mode 7 which was required for the ability to do flicker-free animation. This version led the way to the next version...

2) The previous JavaScript/CSS/HTML5 engine:

Utilizing 640x480 pixels of screen space and the graphics from the previous version bumped up (The trees and grass use the same color values as the trees and grass in Link to the Past.) this version ran pretty spiffy fast, but was still limited by your processor and Safari's will to go fast. This wouldn't do, but it looked like it would have to, until Löve came along...

3) General gameplay:

You see the Debug text on the left, and under enemies and projectiles. You also get to see NPC's and enemies in action.

4) Lighting and Weather:

In this shot, the player has a lantern and it is raining. (And lightning at random intervals) The lantern will be different when it is done, but for now this is awesome.

5) Scripts and Dialogs

A sample script I created shows a dialog box, gives the player 1000 monies, transports him to another map, spawns in enemies and shows another dialog. In this shot you see the beginning of the script displaying a dialog.

6) The Editor:

The last shot shows the editor as it stands right now. Point and click in your face interface. Saves and loads maps. As you can see, since animations aren't supported yet, it just shows black in the water area.

Not shown: The inventory menu and weapons. Sorry. Forgot. Maybe later.

Eventually I will post a video. When it is ready enough to show off.
Last edited by Jasoco on Sat Jun 11, 2011 7:03 pm, edited 12 times in total.

bmelts
Party member
Posts: 380
Joined: Fri Jan 30, 2009 3:16 am
Location: Wiscönsin
Contact:

Hey, this looks pretty neat! I'm looking forward to future updates.

Also, that looks a lot like the EarthBound font in that first screenshot, where'd you get that?

It sounds like, in addition to the obvious influence of Zelda, you're taking a lot of influence from the Mother series. I fully support this, those are probably my favorite video games ever I'd be very interested in seeing how the rolling HP meter integrates with a real-time battle system, too, since only EarthBound and Mother 3 have ever used it, and those were turn-based battle systems. The rolling meter made the turn-based a little more real-time... I wonder what it will do to combat already in realtime?!

Jasoco
Inner party member
Posts: 3650
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

I made it. It was a simple string of text that the DRAW command used. For instance, the capital letter A (I think) was represented by "D5BD2U0BM+2,-7". Put plainly, D meant draw down. D5 meant draw down 5 pixels. M meant move the amount of pixels, or to the pixel specified. The +2,-7 would mean move from this spot 2 pixels to the left and 7 pixels up. The B before the M and the D before it meant move but don't draw. Now that I look at it... That's not an A. It's an exclamation point. Move down 5 pixels, then down two to make the dot. Haha, silly me. You get the idea.

The game loaded a text file with character definitions in it at start and just drew them as the letters were called. I got the idea from another QB RPG called "Mini RPG" that did the same thing with its fonts. I modelled them after the Earthbound font because it looked much nicer than the monospaced font most other RPG's on the NES and SNES used.

When the player is hit, a "RollingHealth" variable is adjusted. For instance, when the player gets hit, his Health is subtracted. And if the Health is different from the RollingHealth variable, it slowly goes down to meet the Health variable. If the health goes up though the RollingHealth is just set to the Health since there's no reason to roll upwards. The RollingHealth is displayed by way of a red area behind the green area in the health bar. And the RollingHealth is decreased by the "RollingHealthValue" which could be set to whatever you want. .1 or 1. Every frame would subtract whatever the value is. If the RollingHealth gets down to 0, you would die. But if you pick up health before that, you can save yourself from death. It's the same basic concept as EarthBound except in real time. i.e. you can just run from the battle to grab some health instead of waiting your turn which in EarthBound usually resulted in quickly running through all your characters turns just to heal yourself in time.

If I can think of good ways to do it, I might implement special moves that might recover health. Not sure yet.

Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

That was... quite a story.

Good luck with the game.

napco
Party member
Posts: 129
Joined: Fri Jun 12, 2009 9:28 pm
Location: Ital... ehm...

Very nice! Debug messages have made me curious about your programming technique... VERY CURIOUS!!! Will you upload only the .exe or also the .love? Don't worry! I'll never ever steal other's code but only look at it to discover new techniques (I haven't used OOP script for lua cause it has been written from others). By the way i noticed that you aren't using pure Zelda graphics (I see a bit of FF4 here and there)... Interesting.

Jasoco
Inner party member
Posts: 3650
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Eventually I will provide Löve to you forum members. But not yet. It is 1MB+ right now also, so it's not like I can upload it as an attachment. Eventually I'll put it on MediaFire or something.

I changed the color of a standard Link sprite for the prototype because I always thought a blue tunic would look neat. This is NOT a Zelda clone. The graphics are placeholders and proof of concept.

The best part is that it runs at 60FPS even with all this stuff running.

An explanation of the Debug info:

The top area has the game Timer and the session Timer (Game Timer - Start Time) formatted using a function I created to turn the output into hour:min:sec format. As well as the "Game Mode" which means simply where in the game you are. 0 for main menu, 1 for game, 5 for inventory screen, etc. The numbers can be whatever, they just tell the Update and Draw functions what to update and draw.

Next you have Counts which counts how many different tables are currently filled. Enemies, Projectiles, Explosions, Droppables are all in tables, but when there are none, the tables are empty and the count is 0. Simple stuff. You can see how this is done in the example "kkav" which is a scrolling SHMUP.

Player data follos. His X and Y both coordinate wise and what tile he is currently stepping on. His invincibility time, i.e. when he gets hit, how long he remains invincible before he can get hurt again. (He blinks while invincible like Link and Mario and every other character in the history of games) The Attack Timer is also used to specify how long to keep the sword out when you press the attack key.

Push is an interesting part. It detects when the player is walking into a wall and counts how many frames he is pushing. This will be used for things like blocks that can be moved or activating scripts like doors in EarthBound work. (The player would push against a door tile on a building and it would activate the script to go inside or outside.) When it is -1, there is nothing being pushed against.

Map size shows how big the map in memory is. How many tiles it is wide and tall and how many pixels that comes out to. The Bounds part is my favorite though, it calculates what tiles are actually on screen so the for loops that draw the map only run through the visible tiles rather than starting at 0 and ending at 33 it starts at 7 and draws until 33 or starts at 11 and ends at 29. Calculate Bounds will find out the appropriate lower and upper bounds of the maps horizontal and vertical dimensions and return them for use in the Draw functions:

Code: Select all

for x=xBounds[0],xBounds[1]-1 do
for y=yBounds[0],yBounds[1]-1 do
--Draw the stuff
end
end
Works much better than:

Code: Select all

for x=0,mapWidth-1 do
for y=0,mapHeight-1 do
if x is on screen then
if y is on screen then
--Draw the stuff
end
end
end
end
Since with larger maps it had to still run through every horizontal and vertical tile even if it wasn't on screen which took a few FPS off my speed. So instead of doing say 32x32 (1024) checks per frame it only does 27*18 (442) draws. On big maps this is a lifesaver. It means the map could potentially be 1000 tiles wide and still go as fast as a 20 tile wide map. (Though right now I have the limit set to 500, but I can do 1000 or more if I want, but something to note is if I set the max to a large number it takes a few milliseconds longer to setup because it has to create a multidimensional array for the tiles at the beginning, and 1000x1000 is a lot more than 500x500 or 100x100. Of course this number will be changeable depending on how big I actually make my maps in the final product. Right now my main map is only 32 tiles wide. No where near even 100. And far from 1000. But if I can eventually make a 1000x1000 main map... holy jeebus that's a big game. So really 1000 is overkill. Hell, the Dragon Warrior overworld map was only 130x130 give or take. And that was the OVERWORLD! And back then it seemed huge! (Dragon Warrior II was 256x256 as was Final Fantasy 6 and Link to the Past And Dragon Quest 6 was slightly smaller tile-wise. Seems 256x256 was a popular choice, probably because of RAM banks back then. Each tile had to store a byte at least that defined a tile to use. For me though my maps use 4 characters per tile layer. Though I'm working on a way to get that down to 2.) To think of a map being 1000 tiles or even 500 is just huge even now.

Oh, and that last section in the Debug info just shows the timing for lightning. When it goes off next and its timer. Nothing big.

On the right side you see debug info for the Script. It appears when a script is running. Right now it's simple barebones. Is a script opened? What line are you currently on? What is the current command? Is it currently paused? (This is true when a script command takes time, like a dialog waits until you dismiss it before unpausing the script to run the next command) And below you see the commands listed out, and whether they have been run yet or not. They're all False because the Dialog is the first command, and it hasn't been dismissed yet. I will explain scripts in detail sometime later when I have them working better and figure out a better way of implementing them.

I'm off to try and create a 1000x1000 map just to see if it works, and how big it would be travel-wise. (How long it takes my main character to walk across it.)

zugamifk
Prole
Posts: 28
Joined: Sun Jul 26, 2009 4:01 pm

I'm wondering, is there an efficient way to manage huge maps, memory-wise? Like I said in a previous thread, my current tile based game uses roughly 700Mb of memory on a 1000x1000 tile map as compared to 20 on a 100x100 map. It's storing a fair amount of data for each tile, but that difference seems to be a lot higher than it needs to be.

The other question I have is how do you plan on switching between maps? Are you going to use loading screens or just load sections as you get close to them?

What about AI? Are you planning anything big for that?

I'm very interested in hearing more since I'm making a similar sort of game

Jasoco
Inner party member
Posts: 3650
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

700MB? Is that Real memory or Virtual memory?

The maps take like a millisecond to load. In fact, to put in a fade down and up would actually make it take longer. But I do want to put in some sort of fad down, load, fade up quick just to give the player visual feedback that the map has changed.

I haven't made a 1000x1000 map yet. Wow. What are you actually covering the map with? Because as I mentioned, even the biggest games in the NES/SNES days only used maps of at most 256x256. I do plan on creating one with my map creator to do some tests. Maybe I'll do that tonight and report my findings memory-wise.

Maps are stored in text files (I could do Lua, but I'm working with what I know) and are loaded as needed. The variables are simply replaced in the same memory space. I define the array at launch at the maximum a map will be rather than redefining the array every time a map is loaded because let's face it, defining a multi-dimentional array of 500x500 or 1000x1000 takes too long to be redefined every time. So it's better to just set the memory aside at the beginning so it's there to change than worry about redefining it bigger and smaller and wasting loading time.

I do plan on some sort of AI, but it might just be simple AI in that enemies will walk around randomly until the player walks into their field of view, then they will go into pursue mode like Link to the Past had. Bosses have patterns, and it would just choose different patterns depending on the stage of the battle if I want to have complex bosses. I haven't thought that far yet. I need to get a solid engine and scripting system in place first before I start worrying about how enemies move around.

I noticed you use a different method for storing each "layer" of the map. Using one single three dimensional array with X, Y and Layer arrays whereas I use 7 different 2 dimensional arrays, one for each layer. I wonder which method uses less memory. I would assume it uses the same amount since X Max * Y Max * Layer Count would be the same either way, right? But it is pretty smart, I might have to convert my system to that method instead. It might load faster and save a lot of code.

map[x][y][layer 1-7] = ?

vs.

mapTile[x][y] = ?
mapDeco1[x][y] = ?
mapDeco2[x][y] = ?
mapDeco3[x][y] = ?
mapDeco4[x][y] = ?
mapHit[x][y] = ?
mapHitN[x][y] = ?

Looks like I got some testing to do. I'll see what I can do and report my findings.

In the meantime, this is my newer style health bar:

zugamifk
Prole
Posts: 28
Joined: Sun Jul 26, 2009 4:01 pm

To be honest, I don't actually know the difference between 'real' and 'virtual' memory. I was checking memory usage through my task manager, just quickly. I know when I upped it to 10000x10000 it would freeze on loading, and I have 4Gb or RAM, so there must be an exponential increase in usage for some reason. As it currently stands I've got a "world map" array that stores where each map lies on a grid, and each index is a different map file. So as you get near the border of one, it gets loaded quickly and the old maps get saved and dumped off memory.

At least, that's how it should work, theoretically. I haven't tried it on that sort of scale yet so I'm not sure if it's that simple. I originally had what you've got going right now, with multiple 2 dimensional arrays, but I got to the point where I need too much information for each tile. Right now each tile holds 20 different variables, for each drawn layer as well as things like keeping track of how old the plants growing on that tile are. And I'm still at very basic stages, so I know I'm going to need to manage memory usage carefully.

I was reading around a bit and there's some pretty cool things people have been doing with dynamic pathing and such. I don't know how hard it would be to implement in LOVE, but now that today's computers can process information so much faster, the idea of surprising a player with guards that try to flank you or push you into those endless pits sounds like awesome fun to me.

Also, your graphics are prettier than mine. I really ought to touch mine up. Kudos on that.

Oh, and there's the other thing I wanted to ask. Regarding collisions. For now I've got my collisions based on tiles, but I'd really like to have objects inside of tiles with bounding boxes, I just don't know how to do it. How do you manage it right now? How do you scan for collidable objects? Do you just keep them all in memory and check if you're about to move into one at any given time?

TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Denver, CO
Contact:

zugamifk wrote:I know when I upped it to 10000x10000 it would freeze on loading, and I have 4Gb or RAM, so there must be an exponential increase in usage for some reason.
I would assume it is quadratic.
1x1=1
2x2=4
3x3=9
4x4=16
100=10x10
10,000=100x100
1,000,000=1000x1000
100,000,000=10000x10000
x^2=memory needed

### Who is online

Users browsing this forum: No registered users and 17 guests