Thursday, July 25, 2024

Enchantasy: Never Tell Me the Odds

 
Chicken dinner.
        
At the end of my first session, my mage PC was joined by his fighter friend, Jared. This session joins the two characters on the road to Macino, in the north-central part of the game world, where their friend Rodell is supposed to be waiting. We win one combat on the way but get killed in the second and are forced to reload. Moments later, we face the exact same combat that killed us, in the exact same place, and get the exact same attack and damage rolls--which means it had the same outcome.
   
It turns out that the game must generate a bunch of seed numbers and store them in a file. Even entering a city, or quitting and reloading, doesn't break the pattern. Casting a spell like "Minor Heal" does, fortunately. Between pre-generating a list of seeds and simply generating random numbers when you need them, what programming advantage does the former offer?
        
Move over, Warren Buffet.
      
More on combat below, but for now we manage to make our way to Macino with only one more battle against a single warrior-bear. It gets us 4 gold pieces; the rewards for combat so far have been relatively pathetic. We spot a dock with a ship's captain just to the east of the city as we enter.
        
Macino's the first city so far to have its dock outside the city, on the main game map.
      
Rodell is waiting near the entrance and joins the party, telling us that we should find our fourth companion, Shyra, in the city of Tiernan. He's a Level 2 ranger. He comes with a bow and a few arrows but no armor. Jared doesn't have any armor, either. I find an armory in the city, but I can't really afford anything because of the need to constantly replenish food.
   
The game does something pretty cool with a beggar, Suffield, that we meet near the entrance. He asks for gold pieces and despite being relatively poor ourselves, we give him 4. He happily says that's enough to get a room at the inn for the night (the bastards charge us 10 gold pieces!). Then--and here's something I've never seen in an RPG before--he actually goes and gets a room at the inn. We encounter him there later, where he says that the innkeeper also gave him a job. I'm always complaining that beggars in RPGs never seem to improve their lives no matter how much gold I give them. What an awesome counter-example. 
      
I do wish the author had put keywords in bold or CAPS. It feels like NPCs are constantly using air quotes or making puns.
      
The city has a dungeon that we accidentally stumble into. We're driven back by a tough battle that leaves us all nearly dead. Rodell and his bow are the only reasons there's a "nearly" in that sentence. We find that paying to rest at the inn fully restores health and magic points. Oddly, the healer does nothing for regular wounds. When we try to pay her (while injured), she just says we don't need her services. She must be for poison or death or something.
       
A dungeon battle that left us in rough shape.
     
In the tavern, we meet a lumberjack named Worrell who says his job has become deadly with monsters now everywhere. We also meet a man named Corey who says that he repairs slot machines for the Slots of Fun casino. There's also a piano player who plays one of the game's tunes for a gold piece.
   
Because the game's economy has been so tight, I decide to analyze odds at the slot machine. Each roll costs 1 gold piece. There are three reels. Various combinations of five symbols pay off different amounts shown on the screen. The highest is three smiley faces at 50 gold pieces; the lowest is a heart with any two other symbols (except other hearts, which pay more) at 3 gold pieces. My first attempt at figuring the expected payout goes awry because I fail to realize that the first reel actually has six symbols. The sixth is a sort of hollow smiley face that figures in no winning combination.
   
Accounting for that extra symbol on Reel 1, and assuming that each symbol has an equal probability of appearing, there's a 0.16667*0.2*0.2 = 0.6667% chance of any of the first eight combinations appearing. Number 9 has a 2.6667% chance, and number 10 has a 13.333% chance. The cumulative probability of any winning combination is 21.333% Multiplied by their payouts, I come up with an average payout of 1.4933 for every gold piece spent. I track around 300 rolls, and my results roughly jibe with these calculations: I win 21% of the time and get an average payout of 1.38. 
     
I only get 3 on this one.
     
In other words, good odds. By the time my experiment is over, I have over 300 gold pieces from a starting point of about 40. But the favorable gambling odds don't break the economy as much as you might think because the game forces you to watch the reels spin and pauses for a couple of seconds after each outcome. It takes me almost an hour to earn my 260 gold (artificially prolonged by the fact that I'm recording the results, but still). Sure, I could cheese it by putting the emulator into warp mode or writing a macro, but the point is that the author tried to limit the amount of gambling a player would do by making it boring. There's a modern analogue, I suppose, in games like Red Dead Redemption, where you can reliably make money at a lot of gambling games, but you actually have to play the full game, including watching the players' moves, taking time to shuffle and deal, and so forth--and even then, there's a maximum to what you can win. This is gambling done mostly right. No one would take the time to save and reload to win these slots.
   
With my newfound wealth, I go back to the armory and buy a short bow for Jared, a sling for Chester, cloth armor and wood shields for Jared and Rodell, and more arrows and food. There are a few things about the purchasing and inventory process that I like. First, when you buy something, even though equipment all goes into a common pool until you equip it, the merchant asks who you're buying it for. He alerts you if that character can't equip the item because of strength or class. Second, I like that the game uses a common pool for unequipped items, arrows, food, keys, and so forth, so that you don't have to micromanage each character's unique inventory.
       
Thanks for letting me know!
      
It turns out that the maximum number of common items, including food and arrows, is 99. We'll see how I feel about that later. The number feels small; a single combat can easily take 10 or 15 arrows. Food depletes somewhat slowly, but I still think that maximum might put an artificial limit on, say, dungeon exploration. Maybe it's meant to add to the challenge in some way.
 
I also buy a pick-axe, because it seems like something you should have, and something called a "telegem." I assume it's going to be an auto-mapping tool, like the gems of Ultima, but when I use it, it seems to be looking for a portal nearby. I really need a place to buy keys and picks, as I'm constantly encountering locked doors.
         
Sigh. You were not "robbed." You were "burgled."
       
Upstairs, I find a house belonging to a married couple, Grace and Bo, who used to run a jewelry store. It is now closed, as their stock was stolen in a burglary. They suspect a notorious thief named Blaze, and they're offering a substantial reward for the recovery of their property. Everyone in town has an opinion about Blaze. Corey and Suffield think that he's hiding in the dungeon.Worrell heard that he died and was buried on an island by fellow thieves.
   
Rather than search the dungeon right now, I decide to head to Tiernan and pick up our fourth party member, who I assume is going to be a thief. Tiernan is in the far southeast of the game world, and we're in the far north, so I try to reach it with ships, even though my funds are somewhat low again. I pay the captain outside Macino to take us to Keldar. From Keldar, the only other place to travel is Hazlett, which gets us about two-thirds of the way to Tiernan.
    
Between ports.
      
Hazlett is a floating city, full of wooden docks, and not much else to do. Odolf is the retired captain of the SS Minnow, whose ship went down after it was torched by flames from the sky (I suspect a dragon). Lester is an aspiring scientist who wants to become as great as Leo, the greatest scientist in Savallia. Leo lives in Riisa Village. Edwin is a small boy who lives in a house with his mother, Silvia, a healer's assistant. Edwin has recently learned in school about the knights who used to guard the king's castle. The greatest of them was Sir Kenway (who I also heard about in Macino), who wore a powerful set of silver armor. It was lost when Kenway was trapped in an underwater cavern.
    
I've been exploring the cities somewhat cursorily, as I know I'm going to have to do it again when I have a proper supply of picks and keys; every city has a lot of locked doors. For now, there are no ships heading to Tiernan or any destination to the south, so I leave Hazlett to finish the trip overland.
      
Finding our way across the land. The signs really do help.
          
Predictably, we face several battles along the way. The game uses a relatively simple turn-based combat system on a tactical grid. It echoes both of Enchantasy's major influences--Ultima V and The Magic Candle--while not being quite as complex as either. Enemies start some distance from the party, and some (magicians and archers in this example) can attack at range. If the party is surprised, enemies go first; if not, the party goes first. Each character gets one action (though that may change as we level up): move, attack in melee range, shoot a missile weapon, cast a spell, or apply first aid to another character. Assessing monsters and equipping items can be done freely and don't count against the character's turn. Movement can be done in eight directions instead of just the four that you can use in the exploration window.
     
Again, there are some neat touches here. I like that you can quickly see the status of the enemy party in the upper-right corner; you can also use the A)ssess command to get more specific statistics about each of them. If you try to equip a bow when you have a shield equipped, the game warns you that you can't do that--and then asks if you want to unequip the shield. That's something I've never seen. It's almost as if the author of this game wanted to make the interface as helpful as possible rather than to punish the player for every mistake.
   
Missile weapons really improved our survivability, and we get through the battles without much trouble. As our hit points start to drop a bit, we find a delightful surprise on the way to Tiernan: a little inn on the side of the road. I like that the game doesn't make it too easy to restore all your health and magic but occasionally provides conveniences like this.
     
Nailing a bat from a distance.
      
While fiddling with the controls looking for some way to turn off the music, I find that there's a "combat frequency" setting that you can use to increase or decrease the number of random battles. It's already set pretty low, though.
   
If I'm getting attacked this much at 3, I'd hate to see what 10 looks like.
     
The game mixes good and bad sound. I like some of the effects, like the creaks of the doors opening and the smash that accompanies hitting enemies in combat. Some of you might like the opening theme, which seems to pay homage to The Terminator, but I find it a bit too emphatic. The dramatic tune that introduces each combat is too bombastic. The game doesn't give you any options to turn off sound that I can find, let alone turn off music independently of sound. I've thus been mostly playing with my headphones hanging on their hook next to my window. This caused a bit of farce the other night when I heard some clanging and thought that the raccoons were tearing apart my bird feeder again. I went charging outside in the middle of the night to find that Irene had brought the feeder indoors. 
        
We grab the last party member.
      
Shyra is waiting as soon as we enter Tiernan. She's in the city looking for someone named Boris, who supposedly has a treasure map. She joins the party at Level 3 and, as I expected, she's a thief. She also joins with no armor. There's an armory in town that sells leather suits, but none of my characters are strong enough to wear them; I hope strength goes up with leveling, then. 
    
The full party.
       
With the team together, I have a couple of options. I can head back to some of the earlier cities and try to start solving some of their side quests, or I can pretend that I'm starting anew and just begin exploring systematically. I decide to play by to-do list in order of priority. This is what I have now, organized by importance and urgency:
       
  • Kelder: Re-explore. Explore dungeon, looking for Joey (missing child).
  • King's Castle: Re-explore, explore the dungeon, looking for king's tiara.
  • Macino: Re-explore. Search dungeon for Blaze and the missing jewelry.
  • Tiernan: Fully explore, looking for Boris and his treasure map.
  • Udim/Forest of No Return: Explore, looking for the magic horn.
  • Aramon: Explore. Try to find Wade, who was researching the legend of a Mystic Bow.

The above task came from a diary entry in Macino that I forgot to mention.
     

  • Keldar: Bring healing ointment to sick NPC.
  • Dalia: Explore and buy a Locator, then explore Jack's Cave and the cave near Tiernan for gold.
  • Mountains???: Search for Jamal/missing prince.
  • Kadaar: Explore
  • Shaaran: Explore
  • Hawthorne Land: Explore city and castle, talk to Duke Hawthorne.
  • Portsmith: Explore
  • Sonora: Explore
  • Haskett: Re-explore.
      
"Explore" and "re-explore" includes searching just about all stumps, shrubs, and pieces of furniture for items. Almost every time I do, I find food, a key, a pick, or something else. Gods know what I missed in the early cities. 
      
I need to do this more often.
     
I am really liking this one. Although it looks at first glance like a bog standard Ultima clone, it offers a delightful surprise almost everywhere you look. This is the second time in the last year or so that I've been surprised, in a good way, by an Ultima clone, the first being Antepenult (1989). It feels like I've been happily surprised a lot lately. Fifteen years into this project, it's finally serving its purpose.

Time so far: 5 hours
 
****
 
I know this is going to upset some people, but I'm going to kick Betrayal at Krondor a couple of notches down the list, so as to give me time to finish reading the novels on which the game is based before my first entry. I expect Quest for the Holy Grail and Syndicate will be quick, so it won't be that long.
 

51 comments:

  1. Some nice touches indeed. Maybe Abel wanted to address what he felt were certain shortcomings in or at least potential useful additions to the games he had played himself - to the extent possible as sole developer in such a format. Guess we'll never know now, though.

    I wonder if the city name 'Tiernan' was inspired by the director of some popular movies in the late 80s and 90s.

    ReplyDelete
  2. "What programming advantage does the former offer?" - in theory, it prevents players from save-scumming by giving the same results after you restore. In practice, as you noticed, that usually has workarounds.

    This game was written in BASIC, which has a standard random number function (like most programming languages). I'd say it's somewhat unusual for a programmer to write his own, although it isn't that complex either.

    A common trick is to have the next generated number depend on the current, e.g. N = (N + 4723) % 10000. When using this, you only need to store one number in the saved game.

    ReplyDelete
    Replies
    1. Another thing is that sometimes it's the emulator doing this. Though rare, I've seen people complain that it didn't do this in the original.

      Although I don't think so in your case, because as I understand you don't usually use save states, those could also cause this, since you restore to that exact moment and some algorithms only change with a hard reset, not time.

      Basically it's just lazy programming or the programmer didn't know how to change it though. Final Fantasy Legend 2 for the Gameboy uses the same exact patterns (entering combat and everything else being two different patterns) from the same exact point every time you turn on the Gameboy, as an example of a big company doing this, so it's not just new programmers.

      Delete
    2. It all depends on the method used for the random seed. For instance, if a console game uses values in unitialized memory, then on an emulator those are probably zero, and on a real console they can be basically anything (hence, a good random seed).

      Conversely, if a console game uses time since power on, then on an emulator those depend on accuracy and on speed of the host computer, and on a real console they will be the same every time (hence, not a good random seed), as older consoles, such as the Gameboy, don't have a real-time clock.

      Tool-assisted speedruns require that a game's randomness is predictable, one way or the other.

      Delete
    3. Built-in random number generators tend to produce "good" randomness only when considered over a certain range (that is, the output is very random if you ask for a number between 1 and 65,536, but not especially random if you ask for a number between 1 and 10), so people wanting high-quality randomness generally did have to roll their own, though perhaps using the system RNG to seed the initial conditions.
      @Radiant While consoles like the gameboy don't have a real-time clock, they have something very similar in that the video hardware runs at a fixed rate, so basically every system up through the 16-bit era can, whether on hardware or emulation, accurately calculate time-since-power-on as a function of the number of times the screen has been drawn. A typical way to write a "good" RNG in that era would be to set the initial value to the number of frames at the time the player pressed the "start" button and then update it with a linear function each time a new random number is required. A typical way to write a "bad" RNG would be to just take the required number of bits from the current frame counter.

      Delete
    4. @Ross, I assure you, there are tons of ways of mapping a good random number between 1 and 65536 to get a good random number between 1 and 10.

      Delete
    5. @Radiant, a standard way of getting a random behaving seed is to use CPU clock value as a seed. Using any memory content as a seed is asking for trouble.

      Delete
    6. You're right, but the man page for the standard C rand() function used to explicitly warn against using the low-order bits, so I presume it was common practice to just use the simplest thing, possibly even moreso on old systems where every cycle mattered.

      Delete
    7. @Ross what I mean is that the Gameboy doesn't know the real-world time (like a PC does). It only knows how much time has passed since it was powered on.

      Delete
    8. @Ross, you describe essentially a bug specific to old C implementation, and not a feature of pseudo-random number generators specifically. What's more, since random numbers occur in control logic, which is rarely called, there is little reason to conserve anything there.

      @Radiant, it doesn't matter - any variable with changing value would do.

      Delete
  3. It looks like an interesting game indeed, with love and as much fluff as the engine allows.

    Sad to see the "moods" at the end of the articles went and left already.

    ReplyDelete
    Replies
    1. I think it's probably just as well; it struck me as amounting to a constant "not having fun" reminder for himself if he started out on a down note for whatever reason.

      Delete
  4. AlphabeticalAnonymousJuly 25, 2024 at 3:34 PM

    Your to-do list on this one is already impressively long, and I'm glad to see it's surprisingly enjoyable. A diamond in the rough, indeed.

    I had also wondered whether you were going to try any of the Feist books (I presume you're reading the "Magician" books which give the backstory of some of the characters...?). As I recall, the books aren't too much of a slog. Good luck!

    ReplyDelete
    Replies
    1. Feist has written a _lot_ of books, so I'm curious which one(s) you're reading for BAK!

      Delete
    2. My understanding is that the four books that make up the "Riftwar Saga," beginning with Magician: Apprentice, occur before BAK. That's what I've been reading. I'm just finishing the second one.

      Delete
    3. Yeah, that should give you all the relevant 'previously on' info for BAK.

      Delete
    4. I think they're enjoyable enough. Standard fantasy if it wouldn't contain the interdemensional clash of two very different fantasy settings.

      Delete
    5. Yup, those are the ones to read, as the game takes place in the aftermath of the events in A Darkness at Sethanon. There were a few other books in the series that were out by the time the game was released, but they’re side-stories featuring people and locations that IIRC are at most tangentially included in the game.

      Delete
    6. I liked Magician: Apprentice/Master a lot in high school or whenever I read it. Peasant boy becomes badass, what's not to like? The next two books, not nearly as much...

      Delete
    7. I too have read the first four books (Magician: Apprentice, Magician: Master, Silverthorn, A Darkness at Sethanon) a over the previous years. I liked them quite a lot. In my opinion, they don't break a lot of new ground in the fantasy genre, but otherwise feel well-written and very well thought-out, with high amount of details, world-building and character-building.

      Delete
  5. How do you find time for all these games AND reading? If I attempt either, I generally fall asleep. By default I blame having kids, but I feel like I could still do better. Anyways, props!

    ReplyDelete
    Replies
    1. Fortunately, I've yet to find an effective way to play RPGs while on a plane or while falling asleep at night.

      Delete
    2. Apple Vision Pro for both scenarios! Jack in, mannnn!

      Delete
  6. These old games are somewhat entertaining, but I just wish I will live long enough to see your review of Red Dead Redemption.

    ReplyDelete
    Replies
    1. RDR doesn't really count as a CRPG.

      Delete
    2. AlphabeticalAnonymousJuly 26, 2024 at 3:59 AM

      The writeup could just be a BRIEF, then ;)

      Delete
    3. He covered some games that were probably less of an RPG than RDR

      Delete
    4. "Those antiquated games are cute, but I can't wait for you to review a real game like Helldivers 2" :)

      Delete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Since no one has commented on the entry title so far: You don't have to do this gambling to impress us. Those odds definitely sound better than 3720:1, though.

    ReplyDelete
  9. "While fiddling with the controls looking for some way to turn off the music..."

    A-ha! That must've been after more than ten minutes :)

    ReplyDelete
    Replies
    1. "The dramatic tune that introduces each combat is too bombastic."

      As long as it wasn't boombastic, amirite?

      Delete
  10. Reading the first four books of the Riftwar Saga is something I've been wanting to do for some time, and I think I saw them at one of our thrift book stores. I'm going to check those out, get ready for a read-along...

    ReplyDelete
    Replies
    1. Isn't there a blog somewhere for the Fantasy Novels Addict? :)

      Delete
  11. so as to give me time to finish reading the novels on which the game is based before my first entry.
    ------

    I'm not sure that's a good idea, by the way. The problem is that one of the main advantages (or disadvantages, depends on your point of view) of the BaK is that it's not so much a game as a book disguised as a game. So if judged by the literary standards of CRPGs, especially of that era, the game does indeed outclass all of its contemporaries. But by the standards of literature... it's a pretty mediocre book. Much like the Feist's own books.

    ReplyDelete
    Replies
    1. Personally I found the writing in the game superior to that in the books. Kudos to Feist for the world building, though.
      The game also has solid and varied game play, so the story doesn't get in the way.

      Delete
  12. > The sixth is a sort of hollow smiley face

    The slot machine is using the IBM PC “emojis” (https://www.ascii-codes.com/). I don't know why IBM, which designed a computer meant exclusively for serious purposes (sound and graphics were totally unfit for games) decided to offer a character set with some funny symbols. But they were useful to add a tiny amount of niceness to programs working in text mode. This game seems to use a hybrid graphics mode with both text and bitmaps.

    ReplyDelete
    Replies
    1. While the PC was a business machine first, it wasn't made exclusively for business. IBM did publish games for it, and when one of the main output methods is a dedicated text mode with no user definable characters it helps to try and cover as many bases as possible

      Delete
    2. That's a cool bit of trivia, and it makes sense. If you're designing an in-games lot machine for which the graphics are going to be tiny anyway, why not just use a symbol font that comes with the machine.

      Delete
  13. Odolf is the retired captain of the SS Minnow, whose ship went down after it was torched by flames from the sky.

    Did he blame his incompetemt first mate for the flame? Also since you found the scientist, you should find a rich guy and his wife, a fatm girl and a movie star nearby.

    ReplyDelete
  14. I wonder, do the gambling games access whatever random number table the game is using, and thus would affect the encounters and combat results?

    ReplyDelete
    Replies
    1. I'll have to check that out, but I imagine it would.

      Delete
  15. Sigh. You were not "robbed." You were "burgled."

    It depends when the theft happened and if the shopkeeper was threatened during the crime. It's possible it was neither a burglary nor a robbery!

    ReplyDelete
    Replies
    1. He makes it clear in the dialogue that it happened when the store was closed.

      Delete
    2. And the owners weren't there, I meant to add.

      Delete
    3. In which case, agreed, and carry on!

      Delete
  16. I wonder if Portsmith is a callout to Might & Magic 1. (It's got the same name as the town that drains males.)

    ReplyDelete
    Replies
    1. Ah, almost certainly. I had forgotten that was how it was spelled.

      Delete
  17. 1) When writing code, I can "seed" the random number generator and then just generate numbers from there, so I only need the 1 seed. If I seed it and generate 100 numbers, it will always be those 100 if starting from the same seed, so you don't have to store much.

    2) Why store a seed ?
    A)
    Can prevent save-scumming (though as you say, doesn't necessarily do that). XCom: Enemy Unknown famously did this, and people griped because they wanted to save-scum, but you can sometimes reorder your actions to fix it.

    B) Debugging. I have sometimes logged the initial seed out and then re-seeded with the same seed when loading to test the exact same game state and look at why a bug occurred.

    C) If you're doing world procedural generation, this can allow people to "share" their worlds with each other by giving the initial random seed.

    ReplyDelete

I welcome all comments about the material in this blog, and I generally do not censor them. However, please follow these rules:

1. DO NOT COMMENT ANONYMOUSLY. If you do not want to log in or cannot log in with a Google Account, choose the "Name/URL" option and type a name (you can leave the URL blank). If that doesn't work, use the "Anonymous" option but put your name of choice at the top of the entry.

2. Do not link to any commercial entities, including Kickstarter campaigns, unless they're directly relevant to the material in the associated blog posting. (For instance, that GOG is selling the particular game I'm playing is relevant; that Steam is having a sale this week on other games is not.) This also includes user names that link to advertising.

3. Please avoid profanity and vulgar language. I don't want my blog flagged by too many filters. I will delete comments containing profanity on a case-by-case basis.

4. I appreciate if you use ROT13 for explicit spoilers for the current game and upcoming games. Please at least mention "ROT13" in the comment so we don't get a lot of replies saying "what is that gibberish?"

5. Comments on my blog are not a place for slurs against any race, sex, sexual orientation, nationality, religion, or mental or physical disability. I will delete these on a case-by-case basis depending on my interpretation of what constitutes a "slur."

Blogger has a way of "eating" comments, so I highly recommend that you copy your words to the clipboard before submitting, just in case.

I read all comments, no matter how old the entry. So do many of my subscribers. Reader comments on "old" games continue to supplement our understanding of them. As such, all comment threads on this blog are live and active unless I specifically turn them off. There is no such thing as "necro-posting" on this blog, and thus no need to use that term.

I will delete any comments that simply point out typos. If you want to use the commenting system to alert me to them, great, I appreciate it, but there's no reason to leave such comments preserved for posterity.

I'm sorry for any difficulty commenting. I turn moderation on and off and "word verification" on and off frequently depending on the volume of spam I'm receiving. I only use either when spam gets out of control, so I appreciate your patience with both moderation tools.