dMZX Forums: red postmortem - dMZX Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

red postmortem

#1 User is offline   Dr Lancer-X 

  • 電波、届いた?
  • Group: DigiStaff
  • Posts: 8,944
  • Joined: 20-March 02
  • Location:ur mom nmiaow

Posted 08 October 2013 - 12:27 PM

This is sort of a partial development postmortem / retrospective design guide of red. It's going to contain some spoilers, although probably not that many; but still, be warned if you're especially bothered by that idea. I'm basically trying to assemble some of the things I learned while making this game, both so that by writing it down I can help myself understand it and so I have a record of it for the next time I want to create an RPG. I don't think all of this is specific to MZX, although certainly some of it is. It's also not necessarily all specific to RPGs. Game design tends to share a lot of constants irrespective of what genre you're working in.

Data-Driven Design

For an RPG that you want to scale alongside your development, data-driven design really is pretty essential. I attribute much of the ease in which 'red' was developed to data-driven design and most of my design regrets are only that I didn't make more use of it. Basically, this is referring to the fact that the game maps, the sprites, the data and functionality of the items, equipment and spells, the data behind the enemies, the effects used for attacks etc., the scripts for pretty much every character you talk to, every cutscene, most of the puzzles etc. exist outside of MZX and can be modified independently of the game. You could probably take this stuff and make a completely different RPG with different characters, story, items, enemies etc. to 'red' without touching the MZX file (except to replace the title screen).

The benefits to this approach are difficult to overstate; much of it comes from the fact that you can describe the things you are putting into the game in a domain-specific way- you don't need to throw in all sorts of extra stuff that could be needed if you were writing things directly into Robotic. Even if you can ameliorate this somewhat with subroutines and/or handler robots (which can pose their own problems) it's still far messier. Compare:
:npc
{Townsperson} "Hi, how are you doing?"
@end

: "npc"
set "$textbox" "{Townsperson} \"Hi, how are you doing?\""
goto "#textbox"
end

Over the course of writing a long game with many characters and more complicated handling, this sort of thing will add up and at the very least reduces maintainability. The goal is to be able to work basically at the same level of logic as the stuff you're doing requires. This may involve having multiple ways of expressing things, multiple mini-"languages" to cover different aspects of the game. 'red' basically had two main ones:

vdata. 'variable data', what an inspired name. This is the stuff found in the vdata_ files in the game's directory. These are text files that consist of lines, a field and value on each line. The main structure of these vdata files was typically 'name: {the name of the thing}' followed by lines that cover the stats of said thing. At startup 'red' goes through the directory and reads every file starting with vdata_ into counters and strings. Some fields are counters, in which case the value is either the number or the name of another counter to read the value from, while some fields are strings, in which the value is text used directly. Which fields are counters and which fields are strings is actually hardcoded into the MZX, which in hindsight was probably a mistake, but at the time made sense as I was only going to have 1-2 string fields. A better way would probably be just to use the standard string prefix, $, and use '$name: blah' instead. Some fields were also handled in other special ways, again hardcoded into the MZX. 'name', for example, would advance a counter for the particular kind of object we are reading data for as well as store the index of this object in the counter {object type}[{object name}] (this object type comes from the filename; e.g. files starting with 'vdata_art' read in objects that are given the prefix 'art' and advance an 'arts' counter with each name) while other fields were set to work with mini-lists; for example:
eff: ART_CURE_EFFECT
eff_a: EFFECT_POISON
eff: ART_CURE_EFFECT
eff_a: EFFECT_SLEEP
eff: ART_CURE_EFFECT
eff_a: EFFECT_LOCK


Here, 'eff:' is a field that maintains its own advancing counter (art#eff) and writes the values that are associated with these fields into art#eff#, art#eff_a# etc. to allow giving multiple effects to an art (in this case, the curing of poison, sleep and locking) without needing to maintain a list. I don't even make use of this consistently; for example, the battle arts associated with weapons are actually stored like this:
art0i: art[Battle Cry]
art0req: 4
art1i: art[Defensive Pose]
art1req: 8
art2i: art[Bisect]
art2req: 25
arts: 3

Here I basically do the same thing, except I have to manually keep track of the lists. This is another thing related to expressing your design as close to the logic as you can- don't keep track of things that you can write code to keep track of. Your work will be less error-prone and it will save you time in the long run. The only reason I didn't do this was because storing battle arts with weapons is one of the earlier things I did in 'red' and I hadn't implemented the auto-advance fields at that point. Implementing them then would have required rewriting code and rewriting the weapons I had already added so I didn't bother. Other than the specifically-named auto-advance fields, string fields and name:, the other aspects of the vdata_ file pack all the necessary logic required into the files themselves rather than into the .mzx. For example, given a typical filename:
vdata_item[2]weapons.txt

the 'vdata_' portion marks the file as a vdata file so that the game sees it when scanning the directory and knows to read it in. The text following vdata_ but preceding the opening square bracket is the object name. In this case, item, so each object that appears in this file will increment the 'items' counter and those objects will fill the counters item#{field name} and strings $item#{field name}. The text after the closing square bracket is just a comment- it tells me that there are weapons in this file. This part isn't actually used by the game at all. The number inside the parentheses is read order- I read vdata files with lower numbers first. This is necessary as I need to be able to reference counters that are written in other vdata files, which means I need to be able to depend on those counters being written first. For instance, the enemy Shell Wisp casts the spells 'drain life' and 'unwound', as represented here:
name: Shell Wisp
...
art: art[Drain Life]
art: art[Unwound]

Now, the 'art:' fields refer to counters, not strings, and because the value field contains text it is read as a counter, so a counter called "art[Drain Life]" must already be set. However, we also store arts in vdata files.
name: Drain Life
desc: Drain life from one foe
type: ART_TYPE_SPIRIT
….

Unless we see this file first, art[Drain Life] will not be set. So we store Drain Life in vdata_art[1]spirit.txt and we store the Shell Wisp in vdata_enemy[3].txt. Why not vdata_enemy[2].txt? This is because I use [2] for items, and enemies need to be able to refer to items (as some enemies drop items), while items also need to be able to refer to arts (because some items cast arts as part of their use- in fact, most of them do because that's a straightforward way of implementing the behaviour of most items in the game. Arts that are only cast by items and aren't actually available for use as spells are in vdata_art[1]potions.txt and vdata_art[1]items_2.txt).

There are some cases where this solution is not perfect. For example, while enemies need to be able to see spells, some spells need to be able to see enemies; the enemy spell 'Batckup' spawns the enemy 'Cave Bat' but because spells are loaded before enemies 'Cave Bat' doesn't exist at this point. One solution could be to give 'Batckup' specifically a higher load order so it appears later; but this means every enemy that uses 'Batckup' needs to be have an even higher load order itself, hence things spread over even more files and it becomes harder to organise things. My solution in these cases was to store the string 'Cave Bat' instead and look the enemy up dynamically. It would be possible to use this solution for everything and remove the need for dependencies, but it would require more coding as I'd need to basically dereference all these strings when looking everything up and that can be a bit of a pain in MZX since you can only use && brackets for interpolating strings and those can't be nested.

The other language used in 'red' is the 'npc' language, the scripts of which are all located in the 'npc' directory. As the name suggests, this was originally intended to be used just for NPCs but gradually grew in scope until it was a general-purpose scripting language used for almost all event scripting in the game. While I do regret somewhat that I didn't design it as a cleaner language to begin with (the code for NPCs is pretty clean, but instances where I was basically coding puzzles in it look really messy. One good example of this is npc/dungeon2.txt, which has the code for all the puzzles in that dungeon, including the light road puzzle. Things like the pushable blocks and boulders were also written in this language.) I think it really helped the design of the game overall and I don't regret using it so much one bit. If anything, I regret that the language wasn't more powerful so I could use it for every bit of event coding- there were still some bits that either had to be done in MZX or were only done in MZX because I hadn't decided to use the npc language to implement them at that stage. Having a specialised language that can work at the domain level of the events is important; everything is so much more consistent and so much less error-prone. To make Sophia walk one tile west, with animation and everything, all I need to do is @plr_w(1, 3, 3). This made those little cutscenes so easy to write. If there was anything I found I was doing a lot, I could just write another method to handle it.

Working in the domain isn't the only benefit to data-driven design. You can also modify pretty large sections of the game while you're in the middle of playing it, and for something like an RPG being able to edit things as you play really is a necessity because you need the game to scale to the player's party throughout and getting this drastically wrong can ruin your game. I'm just going to say that I have no idea how djtiesto made Kikan because it's also a long RPG and is pretty much the diametric opposite of data-driven design – and yet it still manages to maintain balanced throughout. I can only imagine it was a lot of work. It also means that when you fix bugs related to low-level implementations of certain things, the fixes tend to propagate well and you don't need to rewrite a heap of code. Imagine trying to transition from a subroutine-based textbox model to a call-another-robot-based textbox model after you've created five locations, thirty NPCs and three cutscenes, all containing goto "#textbox" and a textbox implementation across a dozen robots.

Graphical Limitations

I've tried different ways in the past to try and make as much use of the limited charset and palette MZX gives you as possible.
In Ultima IV: Quest for the Avatar[ I basically didn't have much of a choice. I settled on tile sizes early on that made it possible to visually approximate the original game screen and the game data contains the graphics of the tiles and the designs of the maps and I simply had to make do with the chars I had to display. I dynamically allocated the entire charset- I needed to be able to write text into the console on the right and draw tiles into the display on the left and I would only store the font characters and the tile graphics I specifically needed into the charset. I dynamically allocated the palette as well, but this was less important as I was never in danger of running out of colours. Now, most of the game was fine with this- the game has 256 different graphical tiles and while every tile on the screen could be different (and impossible to store in the charset at once since these tiles required 6 chars each) in practice this just wasn't the case. However, at some points it was possible for the charset to fill up and there would simply be no way of displaying that screen in MZX. I tried a few tricks to deal with this- some tiles I modified so that I could display them with fewer chars, like the water tiles and other heavily repeating tiles. I also modifed some really tile-intensive parts of the game, just changing them visually (parts with a lot of those nasty text tiles, usually) but it's not perfect and occasionally this collapses, if only momentarily.

A number of years ago I worked on a solo DoZ.. can't remember the title, it was something to do with 'memory'. The game was very incomplete and a pretty big failure, but it was my first SMZX game and I attempted to deal with the same issue there; the issue was that each enemy and other graphical effects would take up their own space in the charset and palette (so I could do fancy things with colour, transparency etc.) hence I needed some way of handling the instance in which they fill up the screen. I opted to deal with this in the NES way by flickering some of them off on alternating frames when I went over the limit. This isn't too bad a solution but it's pretty obvious when it happens (whereas I hope that the few cases in Ultima 4 where the graphical model breaks go unnoticed by players- you kind of have to be looking for them.)

In a non-SMZX case, Thanatos Insignia 2 also allocates a unique portion of the charset to every enemy so each enemy can have any number of animations, including fancy death fades etc. The enemies were allocated their own portion of the charset, so the entire charset wasn't dynamically allocated; only the enemy portion, but there was still a chance that the enemies could fill up the charset and this would cause problems. My solution for Thanatos Insignia 2 was to only 'remember' a relatively small number of enemies (so enemies would rapidly spawn 'offscreen' and die just as quickly when you wander away from them) and to only keep enemies around when there is space in the charset for them. If there isn't enough space for an enemy, I don't spawn that enemy. This approach had all sorts of interesting side effects, like the fact that you could 'clear' a boss arena so the boss can appear just by wandering around it until you've offscreened all the enemies enough to vanish them.

Anyway, I gave these examples basically to show how much of a colossal pain the dynamic management of char and palette resources is. They compromise gameplay (TI2), they compromise graphics (Ultima 4), they compromise the solidity of the experience (that DoZ game I mentioned) or all three. Basically, it's a huge pain and if you can avoid it it's best to avoid it. With 'red' I avoided it entirely; there is no dynamic allocation of any graphical resources whatsoever. I designed the graphical style of the game to entirely use the charset and palette.

For the field, this meant creating a charset for each location, although it was essentially an SMZX charset- I worked on it in low resolution and had a conversion utility find the most efficient way of packing the colours used into the palette. To create the tileset for a location I would draw directly on this charset and if it failed because the converter couldn't pack the colours I used into the 256-colour palette I would modify it and run it until it could.

For the battle engine, this meant partitioning up my character set and palette and dedicating specific roles to them to create the desired graphical results. These limitations were then built into the conversion utilities used for creating backgrounds, enemy sprites and graphical effects and these utilities forced the limitations. The result is that content was created in a fairly restrictive way – I only had 24 tiles to create areas from (compare with Ultima 4's 256!) and was always battling the colour limitations – but the game had a consistent look and I never had to worry about running out of chars and colours in the middle of the game where I would have to programmatically make tradeoffs instead of being able to decide at the point of content creation which tradeoffs to make. This means I couldn't do a few things, like have a particularly plain background and use the space chars and colours to make a fancier enemy, but in the end this all worked out quite well. Thanks again to Otto Germain and Lachesis for drawing enemy sprites for me – battling char/colour limits to draw something nice is incredibly tedious and they managed to draw great stuff.

RPG Mechanics and Balancing

Mechanics in an RPG are pretty easy to get sorta right and very hard to get exactly right. There's a reason a lot of games like to lift mechanics directly from established pen and paper RPGs – because those games have been tested over a long period of time and have probably gotten a lot of things right.

I didn't do that here, but I tried to design mechanics that were simple and reasonably intuitive and I managed that with some success, given some definition of the word 'success'. The numbers that appear when you hit enemies at the start of the game are pretty good and the numbers that appear when you hit enemies at the end of the game are pretty good, so that's what ultimately matters. You're designing systems that have to scale across a game people are playing for 15-20 hours, providing a steady advancement so players always feel they are making progress, so the random battles they have to fight hundreds of don't feel entirely pointless etc. and so players are always finding cool stuff that makes the battles easier and the game more enjoyable. I think a good RPG can be the crack cocaine of video games; I find it scary how I can dump 100 hours into Sengoku Rance, 100 hours into Yumina or 100 hours into Skyrim and still want to keep playing. While I think 'red' is a long way from that, I made my attempt here.

In the game thread, I listed some things I'd change if I were to make the game again:

Quote

- The multipliers for 'jewel' and 'greater' arts would disappear. Neither are useful to rely on and most of the spells from those people actually use have relatively little to do with the multipliers. I would make the remaining effects reasonably constant- hence you would specialise in basic, battle or spirit arts (or potentially a combination of them)
- Art multipliers would no longer go below 1.00
- For battle arts, when you master a weapon (unlock all arts) you permanently learn one of the arts and can use it with any weapon. Dunno if I'd let you pick the art or just have a predefined one with every weapon (and hopefully different for each weapon!)
- Battle arts would be further multiplied by your damage multiplier (and the more powerful battle arts probably nerfed a bit to accommodate this).


The first two are basically designed to reduce one of the penalties associated with using arts, particularly the powerful ones. Basically, if you use those jewel arts or greater arts too much, your multipliers for the other kinds of arts (that are more 'general use' and where having a good multiplier is more important) will drop. This is not an inadvertent or unforeseen side-effect; I designed the multiplier system with these penalties in mind. However, I'm convinced now that it's the wrong way of doing things.

Greater arts should be powerful no matter what. If you were using other kind of arts throughout the game before getting your first greater art, the greater art multiplier for your main spellcaster is probably along the lines of 0.01. Now, I designed most of the greater arts to not be particularly damage-focused (Blaze Moment is one of the exceptions) so it ended up not mattering too much in that respect. Unfortunately, it was a different story with jewel arts. Jewel arts are expensive throughout considering gems are a limited and valuable commodity. You can't just buy them and they take ages to 'farm' from gem hoarders, the only renewable source of them. This means you don't use them very much; only for emergencies, which means your jewel art multiplier probably goes towards 0.01x just like the greater art multiplier. This is fine for stuff like Prismatic, Grand Mirror and Timecross which will work fine no matter what your multiplier, but it meant the attacking spells weren't all that great, especially for the cost. The problem the multiplier system was intended to solve here (overuse of those powerful arts) was never really an issue – jewel arts are expensive by nature and the high energy costs and long cooldowns of greater arts means you're not using them in every battle anyway.

Battle arts were another thing; they were associated with the weapon (you never actually 'learn' battle arts- I just keep track of the number of battles each character has used each weapon in and dynamically fill spell lists with the available arts based on what arts are associated with the currently-equipped weapon; elegant design, but possibly a mistake) but couldn't be carried across and to be honest I didn't really know what to do with this balance-wise. As a result, there were like 3 battle arts in the game and nearly all weapons had none at all until I got to the end of the game, realised I had really neglected this particular aspect and went in adding a ridiculous number of them and assigning them fairly haphazardly to the weapons. I never balanced these and in some cases these had pretty horrible bugs that I didn't know about because I never tested them. These arts didn't carry across between weapons and each time you switched weapons you had to learn a new set of battle arts (you may have learned how to bisect enemies with your scimitar, but you need to learn it again for the broadsword!) - as a result, I made them quite powerful to compensate but trying to specialise in battle arts was still a really limiting role. The latter two changes were designed to redress this somewhat. The last change in particular, since there were certain cases (particularly if your battle art multiplier wasn't great) where you could use a particular battle art corresponding to some fancy sword technique and have it do less damage than just attacking normally with the same weapon, which is all kinds of wrong. Siphon was a good example in its original form- it cost 10 energy to use and would regularly draw in 4-5 points of energy from enemies. really useful!!

Story

Actually, I don't have much to say about story, except I'd recommend having a better idea of your story (and I mean the whole thing- how it starts, how it ends and how you plan on getting there) before starting real development on things like characters, events and locations. Perhaps you can tell, but I didn't do this. This can manifest in a story that is weaker than it could have otherwise been due to needing to work around the architecture you've already built.

Suffice to stay, I'm still trying to work out how to write and more importantly TELL a good story. I don't have it yet, but I think story is damn important so I'm going to keep at it.
Posted Image
<Malwyn> Yes, yes. Don't worry I'd rather masturbate with broken glass than ask you for help again. :(
3

#2 User is offline   Lachesis 

  • the pinnacle of human emotion
  • Group: DigiStaff
  • Posts: 3,949
  • Joined: 17-July 04
  • Gender:Female
  • Location:Sealand

Posted 08 October 2013 - 01:51 PM

Data-Driven design:
I CAN NOT STRESS THIS ENOUGH: USE IT WHEREVER POSSIBLE IN MEDIUM TO LARGE SCALE GAMES. This will save you literally 70% of your game development headaches if you can get over the initial hurdle of writing interpretters for your data files in MZX.

Graphical limitations:
Dynamic allocation of MZX chars is a horrible balancing act but I wouldn't necessarily say to avoid it always, especially if you're planning on having a lot of variation in enemy types, having a lot of different animations for enemies, having enemies bigger than 2x2, or having enemies where the graphical dimensions can highly vary (Pandora's Gate). Static enemy allocations really impede the amount of the char set you can put towards the level graphics, too--while this wasn't a problem with red due to the BG graphics being squeezed into an insanely low char-space, in a typical MZX use case, you could be utilizing between 64 to 96 chars for your level to get it to really look the way you want it to.

Example:
Thanatos Insignia and Pandora's Gate used 96 chars for the levels (but I wasted them in several cases).

Example:
Thanatos Insignia 2 used a 96 char section of the charset with 48 chars for each area (it was originally planned to dynamically swap these in and out; when I ended up with only two charsets, I decided to not bother).
"Let's just say I'm a GOOD hacker, AND virus maker. I'm sure you wouldn't like to pay for another PC would you?"

xx̊y (OST) - HELLQUEST (OST) - Zeux I: Labyrinth of Zeux (OST) (DOS OST)
w/ Lancer-X and/or asgromo: Pandora's Gate - Thanatos Insignia - no True(n) - For Elise OST
MegaZeux: Online Help File - Keycode Guide - Joystick Guide - Official GIT Repository
1

#3 User is offline   A-Guymzx 

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 225
  • Joined: 19-June 09
  • Gender:Other

Posted 08 October 2013 - 04:23 PM

I myself only recently started creating data interpreters, though the input for them still comes mainly from the game itself.


Up until about half a year ago I had no idea how Eternal Eclipse Taoyarin's textbox worked, for example. Up until that point I had the entity you interacted with write all the text that had to be displayed off-screen as overlay, made one robot open the textbox with overlay copy-pasting (from somewhere else on the board), and then made another robot to copy the off-screen overlay text letter by letter into the visible textbox. Around that time I started to understand what the Vlayer really was and how it would be used, and as such started using it for sprites for the first time. a few months ago I finally managed to build a string-based textbox system (which also supports codes for playing sounds, changing text color, slowing down writing etc. directly from the input string :() for the first time, which I am really happy with.

About a month ago I started to experiment with storing data in files outside of mzx for massive amounts of near-similar counters, and I really do see how much it helps. I'm pretty sure some of you remember how I was excited when I got to write "over 50 counters!" in a text file back in the days I was working on that LoZ thing. Well, I now also understand why you were making fun of me because of it.

Right now I am making an RPG for school for a project, and I'm really starting to see the usefulness of storing data outside of megazeux and the sheer amount of counters needed to make more complex systems (like a typical RPG battle system) work properly. Right now I have 14 different counters for only 1 player containing basic stats, and this number is very likely to increase as the game is still in it's very early stages.

In terms of graphical limitations, I have very little experience in either dynamic character allocating or any of the SMZX modes, so I'll probably just make the best of what I have and start experimenting with some minor dynamic character allocating, as in reserving a set area in the charset for enemy and player textures.
0

#4 User is offline   Dr Lancer-X 

  • 電波、届いた?
  • Group: DigiStaff
  • Posts: 8,944
  • Joined: 20-March 02
  • Location:ur mom nmiaow

Posted 09 October 2013 - 12:30 AM

Enemy Behaviour / AI

With turn-based RPGs you generally don't have to do a lot for implementing enemy behaviours. Just throwing in a list of actions for each enemy and letting them pick one at random usually works pretty well for a lot of things and that's precisely what 'red' did. I don't have any problems with this approach, but I think there is some value to increasing the amount of variety in enemy behaviours- and this is where 'red' sort of fell over.

So, enemies in 'red' pick a move (each enemy can have both a set of attacks and a set of arts) at random and attempt to use it. If they can't use it (not enough energy, no viable targets) they try again and eventually give up. This works pretty well. I also provide enemies with certain 'hint' attributes for specifying targets, but these are implemented in a very simple fashion; for example, one specifies the percentage of the time that the enemy will cast beneficial arts on itself (e.g. Skullslugs and enemies like that will only use Regenerate on themselves) while another specifies a percentage of the time the enemy should target beneficial arts on the ally with the least % health. There was another hint that I use on a couple of enemies but never actually saw occur (I may have managed to break it at some point); that is, a 'bounce' % which indicates that the enemy should attempt to cast a harmful art that can be reflected on an ally with a mirror to get around any mirrors the player's party might have up. These hints were designed to minimise enemies making outright stupid decisions, but they were very limited and I would have preferred to do more in that area – no healing allies with full health, no unpoisoning allies that aren't poisoned etc. I would prefer to do something that makes putting status cure arts on enemies actually useful.

Another area that, design-wise, I completely dropped the ball on was counters/interrupts. Now, counters/interrupts are basically any enemy behaviour that depends on the player doing something; an enemy that uses a powerful move if you hit it with magic, for example. I thought I was creating a fairly general system for this but what I created was so annoying to use I ended up using it for a grand total of 2 enemies in the entire game (the first boss and the final boss). Given the versatility of the system and complexities involved in creating it in the first place this was a huge mistake.

Basically, I set up a system where I'd record actions taken by characters and then check between rounds if a response is possibly applicable; then discard records that have been processed. I set up the system to work just by sending a label to a robot so I could code anything I wanted just by implementing that code. This is a good example in which data-driven design would have helped. When I create enemies by editing a text file, I don't want to have to write some code in a robot that's probably going to end up being a nightmare to work with since I would have to implement all the other checks that are normally done by the enemy's main behaviour code (making sure to pick a valid target for a counterattack, stuff like that.) As a result I basically never used it, meaning it was a waste of time since I could have just hardcoded those two checks into the robot that controls move execution in battles.

A better approach would be another scripting language for enemies; one that very naturally creates the 'pick a random attack and use it' default behaviour, but can easily extend to more complicated behaviours, incorporating counters and stuff like that. The final boss of 'red' is entirely sequenced in robotic and for the simple behaviour involved ended up requiring quite a lot of code. Ideally I would be able to code that same final boss just using the same scripting language. It would also be able to incorporate stuff like the 'hints' far more naturally. This would encourage the creation of more varied enemy behaviour patterns, like certain enemies that just attack normally but hit you with spells if you happen to perform a particular action it doesn't like.

Non-Linear Design

Something I probably can't stress enough- if you're going to create a game where you can accomplish objectives in more than one order you'd better plan for this by the start and think through all the implications, everything that will be affected, all the areas where things characters say may need to change for things to make sense.

I had vague ideas of things I wanted the player to be able to do in any order but I didn't think through this and this proved to be a mistake, in which I had to do all this extra work to account for the player doing stuff in a particularly obtuse order. This can also lead to subtle bugs if you leave stuff out.

Non-linear design is great, but you'd better plan for it and know exactly what it entails with respect to your game.
Posted Image
<Malwyn> Yes, yes. Don't worry I'd rather masturbate with broken glass than ask you for help again. :(
3

#5 User is offline   Dr Lancer-X 

  • 電波、届いた?
  • Group: DigiStaff
  • Posts: 8,944
  • Joined: 20-March 02
  • Location:ur mom nmiaow

Posted 11 October 2013 - 12:58 PM

Level editing

'red' used a custom map editor, mostly because I wanted to work with tiles. It was pretty simple and just supported plotting tiles and block copies; limited, but quick enough for the work I needed to do. I wouldn't recommend this as a general approach, for MZX and other things as the MZX editor is already pretty good and there are a lot of general-purpose tile editors available already you can plug into a non-MZX project. It might be helpful if you need to be able to do something specific for your kind of project.

The cave tileset was the main exception; in my view it's easily the nicest tileset in 'red'; it's pretty seamless and the flickery torches add some nice variety, so I'm pretty happy with the results given the limited tilecount, but creating levels for it was a huge pain. I ended up actually creating a random map generator for the cave tileset after I had made the first few cave maps and I used that for the rest of them, touching up the end results as necessary. I think I got away with it here but it's probably better to work out some way of just using automation to improve the efficiency of manual map creation rather than relying on it to produce entire layouts for you.

I had solidity (whether you can walk on a given tile or not) set per-tile rather than something you can control separately (i.e. like customblocks/customfloors); I think this was a good decision to make as you rarely need to use the same tile for both floor and wall and those exceptions are easy enough to handle when they come up. The chance of screwing up and making entire sections wall when they should be floor (or vice-versa) is just too great; I've done that in MZX several times and it's always annoying to fix.

As well as laying out tiles, the map editor was also used to lay out tags, which were associated with a particular position on the map and resulted in some function being called; for example, there was a 'chest' tag used for indicating a treasure chest's contents, various exit tags used to mark passages to other maps and an 'npc' tag which called a label in an npc script. I'd probably make this more general and have them all call scripts, and let the script responsible determine how to deal with the tag in question. For example, chests would still be specified with chest(X, Y, item, quantity) but I'd have code actually show the opening of the chest, the message and give the player the item(s). This would also make it less effort to add new types of tags and I'd be able to use them in more sensible ways (by far the most commonly used tag was 'npc', with 3691 'npc' tags used in the game compared to 734 'chest' tags).
Posted Image
<Malwyn> Yes, yes. Don't worry I'd rather masturbate with broken glass than ask you for help again. :(
3

#6 User is offline   nooodl 

  • Senior Member
  • PipPipPipPip
  • Group: Members
  • Posts: 735
  • Joined: 28-October 06
  • Gender:Not Telling
  • Location:Belgium

Posted 12 October 2013 - 10:54 AM

View PostLancer-X, on 08 October 2013 - 02:27 PM, said:

A number of years ago I worked on a solo DoZ.. can't remember the title, it was something to do with 'memory'. The game was very incomplete and a pretty big failure,


It was 'Irreplacable Memory', 12984.zip.
0

#7 User is offline   djtiesto 

  • SHOPPING PLEASE
  • PipPipPipPipPip
  • Group: Members
  • Posts: 2,660
  • Joined: 01-June 04
  • Gender:Male
  • Location:Long Island

Posted 28 October 2013 - 12:44 AM

For balancing Kikan, a lot of it was actually data-driven. I ran a bunch of simulations in Excel with different statistics and tweaked the algorithms to get a pretty smooth difficulty curve in there... I worked for years doing modeling and simulation so it was second nature by that point :(

The rest of the game was programmed on a board-by-board basis. The battle engine was probably the hardest to do, probably the biggest thing I've ever programmed in MZX. Kikan was my first MZX game in a long while so going back to coding in it (especially after a lot of features like sprites and per-pixel movement were added, stuff I never fully grasped back in the day) was tough!
Posted Image

Posted Image
0

#8 User is offline   Dr Lancer-X 

  • 電波、届いた?
  • Group: DigiStaff
  • Posts: 8,944
  • Joined: 20-March 02
  • Location:ur mom nmiaow

Posted 28 October 2013 - 02:43 AM

That's interesting. My approach was very ad-hoc-- for creating enemies I'd just grab another enemy that's similar to the new thing I'm creating, pump up its stats a bit, change its attacks around a bit and throw it in. I'd then play the area in question and if things felt off I'd adjust as necessary. A more methodical approach to this would definitely be the way to go and probably produce a much smoother experience.
Posted Image
<Malwyn> Yes, yes. Don't worry I'd rather masturbate with broken glass than ask you for help again. :(
0

#9 User is offline   KKairos 

  • not an actual chipmunk
  • PipPipPipPipPip
  • Group: Members
  • Posts: 2,245
  • Joined: 05-August 00
  • Gender:Male

Posted 02 March 2014 - 11:04 AM

I'm a bit late to the party on this one, but I'm just reading this thread for the first time and it's so full of win.
darganflayer.net kaikairos.dev itch.io
0

#10 User is offline   Dr Lancer-X 

  • 電波、届いた?
  • Group: DigiStaff
  • Posts: 8,944
  • Joined: 20-March 02
  • Location:ur mom nmiaow

Posted 12 July 2015 - 01:39 AM

So I went and replayed red, and I had a pretty good time, which was nice. It's honestly quite hard to accurately judge your own creations during or soon after developing them, so I wanted to come back and play it again after a year or two, but I think I can see its merits and flaws a bit more clearly now.

CJA has commented in the past how he thinks RPGs should start with the player insta-killing enemies, and a bunch of things along those lines, and I think he's probably right. This specifically came to mind because he mentioned it with respect to how red starts out - when you grab the first weapon, you start insta-killing everything in that starting cave, and when you grab the first set of armour, the damage those enemies do to you is reduced to almost nothing.

The problem red has is that this state very quickly changes. While the game is pretty fun after you've gotten past the first part, the worst part of the game is early on, when you initially have access to the world map and have a number of places you can visit, none of which you're a high enough level for. The XP values of enemies are also too low and the enemies hit too hard so you need constant healing at a stage in the game where healing is very expensive (items are too expensive and are used up too quickly, inn visits cost too much, using energy on healing art will waste that very quickly and you definitely can't afford items that replenish energy) - I think it's because I had been playing a couple of games that would probably count as 'hardcore JRPGs' of the 'you need to sell your starting equipment to buy healing items' class, and I wanted to create something sort of similar here - but the rest of the game is not like that, and early on there is not enough variety and strategy to the combat to really let you do much other than grind in that first part.

As a result, the first part of red is a pretty boring, grindy slog. When I think of other JRPGs, they were not like that at all - typically the reduced combat variety in the early game was balanced with the game being relatively easy and existing to teach you mechanics and let you experience the story, and they got hard later. FF5, for example, was never an easy RPG (the first time I played I basically only survived in World 2 onward thanks to Coin Toss) but the beginning of the game was not hard at all, and I think this is the correct approach. You should absolutely never make the player grind or need to save/load a lot before they've gotten reasonably invested in your game.

The next problem that red has: puzzles. I kind of like puzzles in RPGs and red certainly had plenty of them. I'm also pretty happy with red's puzzles on the whole, so I don't think they were too hard or too easy. The problem here is the way the puzzles were used to bulk out gameplay. red has small dungeons, so I included puzzles to make them longer. I reasoned that this would also be more enjoyable than just wandering around a large dungeon with nothing in it. red also has an enemy encounter rate to match the size of the locations, so it is fairly high, but given the size of the dungeons you don't encounter too many enemies anyway, so it's not too bad. Unfortunately these design decisions collide, making the puzzles quite a bit less fun. Lufia 2 had tons of puzzles and it's something people really liked about that game, but what it didn't have were random encounters while you were doing them. In addition, the quantity of puzzles was simply too high. A couple of levels like the towers (short but packed with puzzles, optional items and tough monsters) would be fine, but in red every dungeon was like this. Many of the puzzles also weren't so much difficult as fiddly, involving pushing things on a path towards an objective that is obvious from the beginning, and this combined with random encounters is pretty awful. A better design for the towers would have been to make them large with a lot to explore, with dangerous enemies and lots of good items but far fewer puzzles.

Apart from those two things, I'm pretty happy with red - there were a couple of things that I noticed on my playthrough that could be touched up, and I've mentioned balance issues with the different classes of arts earlier, but it works.
Posted Image
<Malwyn> Yes, yes. Don't worry I'd rather masturbate with broken glass than ask you for help again. :(
0

#11 User is offline   CJA 

  • «≡larch bucket≡»
  • PipPipPipPipPipPip
  • Group: Members
  • Posts: 3,263
  • Joined: 23-June 05
  • Gender:Male
  • Location:......@.c....

Posted 12 July 2015 - 03:07 AM

View PostLancer-X, on 11 July 2015 - 09:39 PM, said:

The problem red has is that this state very quickly changes. While the game is pretty fun after you've gotten past the first part, the worst part of the game is early on, when you initially have access to the world map and have a number of places you can visit, none of which you're a high enough level for. The XP values of enemies are also too low and the enemies hit too hard so you need constant healing at a stage in the game where healing is very expensive (items are too expensive and are used up too quickly, inn visits cost too much, using energy on healing art will waste that very quickly and you definitely can't afford items that replenish energy) - I think it's because I had been playing a couple of games that would probably count as 'hardcore JRPGs' of the 'you need to sell your starting equipment to buy healing items' class, and I wanted to create something sort of similar here - but the rest of the game is not like that, and early on there is not enough variety and strategy to the combat to really let you do much other than grind in that first part.

I see where you're coming from 100% in regard to red having an early grind phase and a lack of reliable healing. Even inns felt very expensive early on, and I felt like I was treading water just trying to survive. That sort of synergizes in a negative way with the necessity to grind: because restoring your characters took a significant chunk of resources, the game seems to tell you to just keep going before you die, rather than sticking around to get used to the battle system and enjoy learning the mechanics of the game at your own pace. In other words, I felt rushed by the inability to maintain homeostasis while building gold and XP early on. And, of course, rushing forward = getting into even more shit.

I feel like just nerfing the starting enemies in red isn't a satisfactory solution on its own. I think something that could have worked well would be a designated challenge dungeon near the beginning of the game. You'd tell the player that the fights will be hard, and let them get used to the fact that they'll have to run away a bit. Alternatively, you could do something like Paper Mario TTYD's Pit of 100 Trials, which is accessible in the first chapter of the game, but very hard to beat reliably, even in the post-story game. Letting the player have a free inn or source of healing would have made me slow down a lot and feel comfy getting more XP. The difficulty level also made me very reluctant to use any healing items.

Here's something you nailed--lots of really interesting bosses and mini-bosses in the first part of the game! I liked how many there were and how they just felt like JRPG bosses--quite hard, but not impossible for a first playthrough, moderately levelled party. They served as checkpoints to make sure you WERE doing okay with XP levels. It really gave me motivation to keep getting those chunks of experience.

I feel even now that designing an RPG is so very hard because you want your players to do everything, be in every situation, and play with every archetype your game has to offer. You give players decisions, and these decisions create different playstyles, psuedo-classes, and stories. One that I learned from Fallout 3 was to make cross-class jumps possible. For example, Nerd Rage! allowed you to really get into the melee weapons; it's an INT perk, but it maxes out your STR when active, giving you a chance to do other things. This is something I'm struggling with, as I know that most players will only do one playthrough, and perhaps they themselves will angst over what class to choose and what path to go down. Letting players know that there are distinct ways to go about them, and allowing them the chance to jump in from time to time is great. You did this with that mission early on where you had to teleport to the mainland, and provided several ways to do so. You gave the player a set of choices, but still allowed them to explore multiple options just to see what was up. I liked that.
Need a dispenser here.
0

#12 User is offline   Terryn 

  • ******
  • Group: DigiStaff
  • Posts: 2,966
  • Joined: 12-October 00
  • Gender:Male

Posted 12 July 2015 - 04:08 PM

(Keep in mind that I haven't played this game in a long time, so my recollections might be off.)

Honestly, I didn't have any issues with the early game. If Unwound wasn't such a cheap and effective skill, though (or if it was battle-only), there would have definitely been problems, since that skill was vital for keeping HP up between fights. Those who didn't think to acquire it probably suffered.

If you want to know what the real slog was, it was going through the RED area and fighting loads of the same enemies you'd seen for ages, since it acted as a hub of sorts. Differentiating the enemies based on the subsection you're in, or simply removing encounters in that section after the main plot jump, would have helped immensely.

As for balancing, can I just say that item combining can get absolutely absurd? Sure, it ends up costing a fuckton of money; however, due to the world's shops essentially becoming worthless outside of buying the odd consumable in the last 40% or so of the game (since most of the high-end equips are strictly loot-only), you don't have much else to spend cash on anyway. Want to make a god weapon that fills your energy and HP every attack? SURE Want to make earrings that pretty much resist everything and make casting cost half as much? WHY NOT Want to attack everything at once seven times in one action? WHAT KIND OF QUESTION IS THAT

The contrasting area in the game puts some tension back into things, thankfully. It becomes a nice shift, having to rely on items for healing and the normal-strength equipment you can find/buy to take out or simply endure fairly powerful enemies (and you can't know just how powerful unless you put in some chaos labyrinth time beforehand, either). Sufficed to say, running became a fairly common tactic in that area.
angelic stream - shed sanguine - ill-adapt - avis - para/lyser - renaissance - dead tangent - phosphene blur - birth breeds death - ________ - painted glass - lagniappe

<Exophase> HES STEALING MAH AIRSHIP!!!!!!11111111
0

#13 User is offline   Dr Lancer-X 

  • 電波、届いた?
  • Group: DigiStaff
  • Posts: 8,944
  • Joined: 20-March 02
  • Location:ur mom nmiaow

Posted 12 July 2015 - 10:39 PM

Quote

Honestly, I didn't have any issues with the early game. If Unwound wasn't such a cheap and effective skill, though (or if it was battle-only), there would have definitely been problems, since that skill was vital for keeping HP up between fights. Those who didn't think to acquire it probably suffered.


Even with unwound it definitely felt slower than I would have liked. I am specifically referring to the first two missions from mystics here - both the cave with the writings and the mimic chest are too dangerous for the player at that stage and there's a bit of a gap with nothing else to do but grind. If you managed to beat the fire goblin to escape the first area you'd be fine, but if you got Spirit Travel instead there's a good chance you'd be quite a bit underlevelled and I don't think that's the right stage of the game for grinding.

Quote

If you want to know what the real slog was, it was going through the RED area and fighting loads of the same enemies you'd seen for ages, since it acted as a hub of sorts. Differentiating the enemies based on the subsection you're in, or simply removing encounters in that section after the main plot jump, would have helped immensely.


Yeah, that's true - another potential solution would be to wind the encounter rate way down and wind the difficulty of the enemies way up. Then the enemies are a legitimate threat and will contribute to the feeling of danger you should get from that location when you first visit it, but will be a lot less annoying when you come back and they aren't a threat to you any more.

The thing that.. didn't so much bother me, but made me think that perhaps it could be a potential bother, is the fact that you need to go through a tower to visit the maze each time. In my latest playthrough I was in a situation where I had already cleared the star, sword and crescent towers, but I had managed to miss the key to the spiral tower in the maze, and on realising that I needed to take a tower to get back in but the spiral and gemini towers were locked to me (and I didn't want to repeat a tower) - ended up taking the heart tower instead, which is a little out of order but oh well. While it was always intended that the towers should be the only link to the red maze from the start and that they should be a challenge, it seemed like making it annoying to get back in shouldn't be the thing to do. I figure a good solution would be to put each floor of a tower in a 'solved' state after you pass it so when you revisit a tower you can very quickly get back up to the top without having to redo the puzzles. They wouldn't be entirely solved, just enough so that there is a direct path to the staircase.

Quote

As for balancing, can I just say that item combining can get absolutely absurd? Sure, it ends up costing a fuckton of money; however, due to the world's shops essentially becoming worthless outside of buying the odd consumable in the last 40% or so of the game (since most of the high-end equips are strictly loot-only), you don't have much else to spend cash on anyway. Want to make a god weapon that fills your energy and HP every attack? SURE Want to make earrings that pretty much resist everything and make casting cost half as much? WHY NOT Want to attack everything at once seven times in one action? WHAT KIND OF QUESTION IS THAT


Absurd, yes, but not quite broken - I feel it might be worth a bit of a rebalance, particularly on the "combining cheap bullshit into something overpowered" side of things, but most of the time it definitely works to fill a gap in the equipment that's available (as well as extending the life of both the money you collect from enemies and the spare equipment you pick up). The only problem is that the game lacks ridiculously powerful foes to use it on, meaning that the really ridiculous equipment is only necessary for the Chaos Labyrinth (which I used extensively to level my party, get money and get more equipment to combine) - enemies continue to present a good challenge, as there are still foes that can hit you even when you have all elemental resistances, all status resistances, 100% block and 100% dodge. (I never got 100% permanent barrier - dunno if it's possible. EDIT: looks like it is, but you need to get a lot of Shields of Fate from the Chaos Labyrinth, which probably requires exploring more than anyone could be expected to endure. Only one other item grants it, and that item is not combinable)

Sadly, I was never able to get enough Nexus equipment in the Chaos Labyrinth to create a really powerful gun - I picked up shotguns and AR-15s, but never anything else to combine them with.
Posted Image
<Malwyn> Yes, yes. Don't worry I'd rather masturbate with broken glass than ask you for help again. :(
0

#14 User is offline   CJA 

  • «≡larch bucket≡»
  • PipPipPipPipPipPip
  • Group: Members
  • Posts: 3,263
  • Joined: 23-June 05
  • Gender:Male
  • Location:......@.c....

Posted 05 April 2016 - 11:52 PM

I forget exactly where you mentioned this, Lancer, but I recall that you said that the less spare time you have to make games, the better stuff you do during that range of time. That wasn't in this thread, but it makes me think of this thread, and whatever, it's worth reviving.

Anyway, I just noticed that I ALWAYS begin an actual, sincere, hopeful MZX project during the weeks leading right up to finals. Bombin' Dude 2 was what I made last finals period (and gee, I ought to release that). I think that this has something to do with the fact that MZX is a process very prone to procrastination, and the way to defeat that temptation is to ALREADY BE PROCRASTINATING. At least, it seems that way.

Also, I have to say, there is a lot of merits to moving to data-driven design, but there is also a lot to say about post-data-driven design, which I'm doing for this project. Going back to keeping enemy stats right next to sprites on the board, written out as Text blocks with terminators... programming players' stats via lines of Robotic in the global robot... it's all super refreshing and reminds me of engine design that's really fun. It also helps me focus more on making dialogue and battles event-based, rather than throwing all the burden onto the engine to be able to emulate every scenario that happens to the game. Decentralizing the code and continuing to use Robotic to script--directly invoking the "OOP" of Robotic--is a mainstay of MZX that I sort of forgot about for a bit.
Need a dispenser here.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users