VERGE-RPG
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login
    1. Home
    2. Overkill
    3. Best
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 32
    • Groups 0

    Posts

    Recent Best Controversial
    • Overkill's devlog

      There was talk of starting up “Gruedorf” again – a little competition made by McGrue and Kildorf, where all entrants would be required to work on something each week and post something about it. Once a post is made, you have 7 days (168 hours) to make your next post, or you “lose”. The goal is to keep a consistent stream of progress each week, and try to minimize “losing” by doing a little work and posting about it.

      As far as I know, there is no requirement that the project remain the same throughout all posts, which I’m thankful for. I accept that at this age that my attention span is all over, and I constantly cycle projects even on the best days. Although, finishing something is better than meandering between 3000 unfinished things that get abandoned for the next thing… Probably other rules I’m forgetting.

      Anyway, this sounds like fun. Like many regular routines in my chaotic day-to-day life, and like previous attempts when I had way more free time, I’m not sure I’ll be able to stick to any sort of consistent schedule, but going to give this a try in any case!

      With full-time work, and general lack of time organization, I have a few projects going on that I am cycling between depending on my general energy. Here are the ones I can remember off the top of my head, but it is not an exhaustive list:

      • Wiz, a high-level assembler. The compiler is a work-in-progress, but it’s already capable enough to write demos and games (and comes with working example programs included). It’s a strongly typed language, with C-like structured programming that compiles directly to machine instructions on different retro CPU systems (6502, 65c02, HuC620, Z80, GB, 65816, SPC700). It has gathered a small community on its Discord channel (linked in the project page). This helped stress-test the language, and uncover neat uses I didn’t expect were possible with the language, as well plenty of hair-pulling bugs. But it’s still nice that this tool has a userbase and came in useful to others, even if it was written as a hobby project for my personal use at first. Hopefully more iterations can be made to improve the syntax, the documentation, the compiler tooling, write more example programs and games, add more platform backends, etc.

        Dive into the “examples” folder included with the repo to see some examples of things you can do with it. I’ve included a Hello World for many systems, as well as a partial shmup demo for NES, a virtual pet sim on GB, a multiplayer VS game with ducks on Atari 2600, a few VFX tech demos, some libraries for some hardware register definitions and common utilities (GB and NES are most right now, but others are grown as examples and personal projects are made), and some other miscellaneous things.
      • nrpg, a turn-based RPG for the NES. This is written with Wiz, and is a real NES program. I’ve been wanting to design a game that has tile-based overworld puzzles such as Final Fantasy Mystic Quest, Lufia 2, Fairune, and others. It will have a battle system similar to classic FF games, with maybe a sprinkle of the SaGa series.

        So far I have a working MMC3 tech demo ROM that allows the player to walk around an top-down map with tile-based map. The map can scroll in all four directions without visible scrolling artifacts. The player is so far able to move across the map and jump (like FFMQ and FFL3/SaGa 3), but there is no support for interactive tile objects, zones or NPC system yet. There is also menu system with a working inventory subsystem. Still early, but the foundation needed to make an RPG is slowly coming together. I had to shelve it for a bit but I want to pick it up again soon.

        Here’s some screens and mockups (note some GIFs needed to crunched to 1x size to fit in imgur upload limits)

        tileset mockup (tileset / map mockup)

        item system (item system - capture from the NES ROM)

        overworld jumping mechanics (overworld jumping mechanics - capture from the NES ROM)

        mockup of combat scene (a mockup of a battle scene – not yet implemented in game, in typical Verge community style of not having a battle system yet)
         
      • Wandering Magic, an action RPG, which started as a PICO-8 demo title (released for the 3-color Jam in late 2017).

        Here is the original jam entry – you can play in your browser, and it’s about 30 minutes in length. It features simplified Ys-like bump mechanics for the combat, as well as simple leveling system that balances fast-paced grinding with finding/buying new items to enhance your combat abilities. Most areas are gated by your player’s stats (health, attack, defense), and equipment works as key items.

        I wanted to rewrite the game, so I ported the game to regular Lua + Love2D, as a cleanup exercise to make the PICO-8 source legible code again. But eventually, I wanted to rewrite the game again in C, as something that can compile out of the box with SDL, doesn’t require a dynamically-typed scripting language, and doesn’t depend on a heavyweight engine or content pipeline. I also wanted to double the game’s internal framerate to 60FPS (rather than PICO-8’s default 30FPS), increase the size of art assets (already redrawn but not integrated), write a coherent quest, and make the action more compelling. The bump combat mechanics were neat, but sometimes it felt like the enemy melee damage could be telegraphed better so the player could evade things more easily.

        dark mages shoot fireballs at you as slimes spawn in from the sides (dark mages teleport around and shoot fireballs at you, as slimes spawn in from the sides.)

        fighting a skeleton (fighting a skeleton that guards the entrance to the next area.)
         
      • vg - a virtual console system in C (working name, but might stick). This probably requires some elaboration – it simulates the experience of writing games for older consoles, but picks limitations that can be nicely fitted to a modern widescreen 16:9 desktop with gamepad support.

        It calls two user provided entry points, one for resetting the game, and one for updating the next frame. All data shared with the engine is global arrays, or through functions that act as ‘system calls’ that convert user-provided data into backend internal texture formats/sound formats/etc. Games are able to tileset graphics and palettes, and then draw them using either tilemap or sprite primitives, which are hardware accelerated. The user of the engine doesn’t need to know the nitty gritty about how the graphics get internally represented (it may be different depending on the platform), and can talk about things in terms of 2D tiles and sprites. Ideally, all games include all data directly as static global data in the source program, and work without solely using the exposed engine functionality. Programs can be written using no stdlib/stdio (except internally to the engine), so to allow extra portability, minimal load times, avoiding the runtime overhead of dynamic memory management by using the static data segment instead, and minimizing runtime issues relating to file I/O.

        The screen is resolution is 320x180 (very close to the 320x200 used in the Verge days, but it’s 16:9). Backgrounds can be made from 3 tilemaps of 64x64 each, which can either be comprised of 8x8 or 16x16 tiles. You also get 128 sprites which can be between any of the 3 layers. Tiles and sprites can have 16-step alpha blending applied, and palette remapping for hitflash effects and color swaps. Tilesets are capable of holding up to 512 16x16 tiles at once. The sprite layer and individual tilemaps can select which 256-tile window they are allowed to see of tileset (so one layer could point at a font, while another could be used for the main background graphics or sprites, the arrangement is up to you), Palettes are 256-color 24bpp RGB data. It’s possible to update the tileset graphics on the fly (to load another tileset or modify the current one), and upload new palettes. Input supports gamepads or keyboard input. Persistent saves of up to 16KB are possible (this limit might be expanded)

        For audio, it supports wavetable sound synthesis (similar to the PC Engine, SCC soundchip on MSX, Namco N163 expansion chip on the Famicom, GB wave channel, etc) with 6 channels. There is storage reserved for holding short 32-step wave samples and instrument envelopes. There is an MML-like SFX command data that can play different notes, change tracker speeds, apply pitch slides, note slides, vibrato, etc. Playing songs or sound effects works by playing different pieces of the sfx data memory, and is written so that multiple sfx issued on the same frame are played together (for allowing polyphonic music with synchronized channels). The audio thread can run on its own, in parallel with the main game logic, but receives updates from the main thread at roughly 60FPS during normal circumstances.

        There’s tools for importing tileset assets from PNG files, as well as converting text files containing an MML-like domain specific language into binary blobs that contain SFX commands.

        So far I’ve managed to get a working engine with an example program that I wrote at the same as the engine, need to write actual game with this next. There is a backend currently for SDL that so far compiles on Windows, Raspberry Pi 400, and Emscripten with minimal dependencies (user-installed SDL on non-Windows). It is intended to be easy enough to write other backends in the future, so that porting to non-desktop platforms is a possible option.

        Wandering Magic might be a good candidate to port to this engine, since it has enough features at this point.

        little background demo (a little demo mockup)
         

      …Wow that was a lot more rambly than I intended, lol. This initial post is a quite wordy summary of some projects I have going on and the state they’re in, but intending for future posts be more short and concise, unless something interesting warrants more elaboration. Let’s see if the habit of posting here will stick! Hopefully other folks will be posting on here too, to keep things interesting.

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Unfortunately, this week I didn’t get as much new work done as I had hoped, because my time was pretty divided.

      However, I did manage to contribute some changes to the v2wasm project, which is a project started by Andy Friesen / thespeedbump to emulate playback of Verge 2 games on the web. I made a few tweaks to improve its compatibility on certain verge2 games. These can hopefully be merged upstream soon.

      • Added more key[] bindings work in v2 games, by mapping more virtual key code into DOS/Win32-style physical key order that VC’s key[] array expect.

        Note that while this solution works on desktop devices, it may have issues with non-QWERTY physical key layouts.

        It also doesn’t address key[] usage from a mobile/tablet device which has no external keyboard – something that v2wasm will want to address later. Possibly we can handle this entirely in the web player that comes with Verge Archive, .
      • Added a compatibility option in user.cfg named recursive_render, that enables Render() to be called recursively with from a Hook Retrace callback. v2wasm is based on Verge 2.6 which disables recursive rendering by simply returning if you Render() while one was in-progress.

        However, this particular decision in 2.6 causes an compatibility issue with Beyond Babel, a game written for Verge 2.5 and winv2. It relies heavily on manual render loops that can be called inside of hook-retrace callbacks. During combat, it handles battle sub-menus by starting different menu loops within its retrace handler. To prevent infinite recursion, it calls HookRetrace(0) and manually Render() + ShowPage(). By unbinding the retrace function, it will do nothing when hitting the R layer while already in a retrace, and then restores the retrace hook after the menu is done.

        Since other games might rely on the 2.6 behaviour to not crash, this was made into a user.cfg setting that is off by default. Sort of unfortunate this settings needs to be added manually, but I think it’s the best way to support both versions without requiring VC code changes.

        The short version: a new compatibility switch fixes the screen not clearing correctly during battles in Beyond Babel, it might fix other games too.
      • Fixed the “manifest.txt” file listing for Beyond Babel so it’ll be possible to play in the Verge Archive player.
      • Added support for Fugue to the Verge Archive player. It seems to work pretty well!



      I also looked at Wiz, my high-level assembler, a little bit. I received some new bug reports I want to get around to soon, and I also thought a little bit about how to fix some things. No new commits, but planning is just as important when it comes to projects like this.

      • using pointer-to-struct to access nested struct members doesn’t work, when indexed addressing modes are available:
      struct Stats {
          hp : u8,
      }
      
      struct Monster {
          stats : Stats,
      }
      
      var monster : *Monster in ix;
      
      monster.stats.hp = a; // error.
      


      This is because currently, the compiler isn’t able to fold the index offset expression into a single constant. Converting the struct member access into indirected addition results in a reduced expression that looks like

      *(((ix + offset1) + offset2) as *u8) = a;
      

      to the pattern matcher, which isn’t a valid instruction on the Z80 CPU. However, *((ix + displacement) as *u8) = a exists on Z80! If the compiler could more aggressively fold constants together in this case, Then the issue would go away, and people will be able to use registers as general struct pointers.

      • Currently using a far function won’t validate that all call expressions are also far. When the calling convention doesn’t match on 65816, this results in runtime bugs. This is because a subroutine called with JSL must return with RTL, and a JSR must return with RTS, so the call and return convention must match.

        Wiz should make 1) far funcs imply far calls everywhere, or b) make it an error to call a far func without far. On platforms where far and near calls can be mixed without introducing problems, I might relax this restriction.
      • I also did a little planning for an eventual refactor I would like to do to Wiz’s C++ codebase. I’ve been trying to break out the compiler code into smaller parts in an incremental way.

        The compiler.cpp is a 7000+ line source file, and it is becoming a bit messy in its current state. Since passes of the compiler depend on each other, it’s not a super easy thing to just start splitting stuff up immediately. But there are definitely some subsystems and passes that don’t interact, as well as some common things that can be moved into their own file, with clearer data structures and code to operate on them. With a bit of cleanup, the project will be easier to read and maintain. Things would be more clearly separated, and it could eventually add test seams for unit testing.

        (Some candidates for clean-up: the scope stack + name resolution, the attribute stack, the inline stack, expression reduction (constant expression folding + typing + qualifying the expression trees), type-checking, type resolution, instruction operand creation, statement-to-IR compilation, IR passes)

        The code should have been written with unit tests in mind earlier on. However, I don’t know if Wiz would have ever made it to as far as it did, if it were encumbered by TDD when the basic language design was still being figured out and implemented.

        We do have some functional tests, but these run the compiler as a kind of black box, confirming the compiler will generate certain machine code or produce specific errors. Having more compiler-internal unit testing would improve things a lot. Not only would it aid in ensuring build stability, but it would also serve as documentation for some of the finer details in the compiler.

        Going to try to aim for some low-hanging fruit to start moving things out, and hopefully this will make it clear about other subsystems that can be split up next. Then once there are more. I know this order to write tests after-the-fact, especially after a refactor, is a little less conventional. But my thinking is that it probably won’t be possible to write good tests until the code is smaller organized chunks with easy tests to begin with. I need to dig things out of the hole they’re in first.

        Still not rushing this, but thinking about it.



      Aside from that, I drew a little bit. I made this little pixel sketch;

      56a99e1e-77ad-4294-b257-0c0add083420-image.png

      The background is a little bit too visually noisy, and needs a bit more variety in the wall tiles, but it was still fun to draw something. It could be cool to make the walls more crystalline and glossy/reflective (maybe some bright white speculars), and better hue + value-separate the background and foreground tiles.

      Anyway, that’s all for this week!

      posted in Gruedorf
      OverkillO
      Overkill
    • Hi! What's everyone up to these days?

      Heyyy! What’s new with everyone these days?

      I figured it would be nice to start a topic since the forum reboot and stuff and see what’s new.

      .

      Something lately has made me interested in looking at Verge again for fun. The other day I was feeling nostalgic, and started messing around with Maped2 in DOSBox and drawing tiles and maps. (It’s pretty fun! even if DOSBox crashes frequently!)

      I’ve also played around with PICO-8 a bunch and something about an environment where it’s easy to draw sprites to the screen and make little scripted stuff is fun. I think some of the appeal that PICO-8 has is similar to what Verge had going for it, quick and easy to throw together projects and make small games.

      (Part of me sorta wants to go back and revisit Verge 3 (and bring back VC from the 3.2 release into the master) and port it over to SDL2 for better portability, and add some sleep/vsync stuff to ShowPage so it runs with less CPU consumption for most games. It could be kinda neat as a small change to make the engine more usable/preserve older stuff and make it run more stable on new computers)

      .

      So yeah, other stuff. For a while I worked at Tribute Games in Montreal here. In April 2017, I released a game called Flinthook for PC/PS4/XB1/Switch, which is a roguelike action platformer with pirates in space and run-and-gun action. Since then, I did a few odds and ends and eventually left there. This year has been all over the place (part freelance, part new job) but been poking around with little projects here and there.

      What has everyone else been up to?

      posted in General Discussion
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This week I ended up expanding on that MSX mockup of Wandering Magic, and started planning a possible true MSX port of the game.

      Then I sat down and learned a bunch about coding for the MSX1.

      Along the way, I learned the MSX has a pretty extensive BIOS that provides many routines for common interactions with the hardware, so it took some learning to do things the “best practice” way. Some performance might be sacrificed, but it ensures compatibility between versions. And there are also faster methods for looking up I/O ports for some things, for stuff like graphics coding – where it probably matters most.

      I updated Wiz’s MSX “hello world” example to use these BIOS routines: https://github.com/wiz-lang/wiz/blob/master/examples/msx/hello/hello.wiz

      Previously I thought you had to write to I/O ports directly if you wanted any sort of speed, since I’m so used to that with other systems, and figured the BIOS was for BASIC programs only. But happy to be wrong here, and it’s easier to write code this way too.

      Now back to Wandering Magic. I also coded some sprite drawing code that handles scrolling the sprites off both sides of the screen, and an entity system (so far just spawning/updating/drawing – no collisions, no gameplay specifics yet). I also split the art work into bg and sprite tiles, and convert them using tools.

      31f9273b-ca25-48a4-b7a8-0af74ae9d07d-image.png
      713cc497-b29b-4d06-a06d-6565b21eca4a-image.png
      msx-wandering-magic-progress.gif

      Next up, I want to draw the background map, and see if I can get some player input and movement. The MSX has tons of RAM available, so it’s probably possible to unpack the entire room into individual 8x8 tiles in RAM, and transfer it to the MSX’s tilemap VRAM afterwards. I guess I’ll try this soon!

      See you next week!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Hello! This week, I made more progress on the MSX port of Wandering Magic in my spare time in the evenings.

      msx-wandering-magic-progress-movement-collisions.gif

      I managed to implement a few things that are pictured in this GIF.

      First off, I made a map loader, It loads an uncompressed tilemap from ROM into RAM, each part of the map is made up of 16x16px blocks called “metatiles” – 2x2 arrangements of 8x8px hardware tiles, along with some associated metadata like collision flags.

      In addition to loading the tilemap into RAM, the metatiles for each cell are then unpacked into the raw 8x8 tilemap format that the MSX VDP expects, and this will be copied to the screen between room switches.

      The upper area of the screen that contains playfield of the game is 16 tiles wide x 10 tiles tall. The lower part is reserved for HUD elements. The camera doesn’t scroll – the MSX1 is bad at hardware scrolling, and I designed the game around having individual screen-sized rooms.




      Next, I added player input and movement with the keyboard. That was pretty fast! One thing that was a little tricky is that the MSX returns a directional code from 0 - 8 (0 = no direction, 1 = up, 2 = up-right, 3 = right, 4 = down-right, etc. going around the circle clockwise), rather than having a separate input for each direction. This is at least if you use the standard “direction reading” routine from the MSX BIOS, so turning that into independent x and y axis takes a little bit of translation. But a nice feature of the BIOS, is that it standardizes reading both keyboard or joystick for directions and buttons.

      There’s also a way to read the keyboard matrix directly, which is necessary if you want to use other keyboard keys besides arrows + space bar. It seems pretty common to find MSX games that use arrow keys, space bar as a primary action, M as subaction, function keys for menus, and support 2 button gamepads. So I guess eventually I’ll need to look into all of that.




      After that, I added entity movement with tile collision support. The entity movement was pretty challenging to write but after some trial and error and lots of debugging to step through things, I managed to make something functional,

      The collision code even supports a neat feature – corner nudging! This will automatically slide the player around corners when it detects only one side of the collision test is obstructed. For example, if you’re walking up into a corner that is obstructed to the right but not the left, then the movement code will redirect your movement to the left, off the obstruction. As soon as the way is clear again, the movement code goes back to behaving as normal, proceeding in the direction the player inputted. Corner nudging makes it much nicer to do pixel-based movement through narrow spaces (especially single-tile wide ones), without needing to lessen the size of the player’s collision box too much.

      Collision still needs a lot of work to optimize things better, since it does slow down when there are several entities on screen. For testing this, I duplicated the player entity 32 times. I observed the framerate dip as soon as the movement began, with even more slowdown happening when moving on diagonals (since it needs to test on x and on y). When the entities are still, or there are less entities, no slowdown occurs, This slowdown problem also occurs at 16 of 32 entities, but only when moving in both directions at once. I’m not sure the exact tipping point where things spill out of the available frame time, but there’s a bunch of things that could be improved. I can live with some slowdown in heavy scenes, but I’d like to push things better than they stand right now.

      I need to measure things better, but there’s a quite a few steps involved:

      • converting values between 2’s complement fixed-point formats (4.4 -> 8.8 -> 16.8 with sign extension)
      • adding large numbers, using the carry flag to synthesize larger additions from smaller additions.
      • bounds-checking the entity position. This takes a fair amount of time, but is necessary since entities can move off the sides of the map.
      • converting pixel coordinates to tile coordinates
      • reading the actual data out of the tilemap
      • branching on the collision results
      • updating the position (if succcessful/unobstructed), or stopping the movement (if failed/obstructed)

      Here’s some code for anybody interested.

      The optimization steps to improve this could be messy, but hoping that my experience from writing programs for the Game Boy should help here. The Z80 is more powerful than the GB’s processor, so hopefully some of the more ugly tricks for performance aren’t needed, but I still have ideas for things to try.

      The performance issues are also not even accounting for the added processing required to do entity-vs-entity hitbox collisions, going to need to do that soon too!




      Lastly, I looked at adding a graphics loader for entities, so each room can have unique sprites depending on what is spawned there.

      Half the sprite tileset is reserved for the player + common sprites like treasure chests, item icons, explosions, enemy spawn indicators (like Zelda 1’s cloud puffs), etc.

      The other half is loaded between each room, allowing for entities to reserve their own sprite art, as well as the art for all their subobjects ahead of time. Then when the game is in action, no new graphics are required – simply spawn things that reference tile indexes based on what’s in the loader cache (cleared each room).

      This approach of loading ahead does mean that any particular room’s full contents (including subspawns) must be known ahead of time, but it also frees up more performance to gameplay, since graphical loading when the screen is in use means sacrificing vblank time, and potentially causing things to split across multiple frames. This quickly becomes messy, and I’d rather avoid any of that for this.




      There’s still a big list of stuff remaining! Not sure what I’ll do yet, but hoping I can continue to chip away at stuff on this.

      These are all features from the original Wandering Magic game that still need implementing:

      • entity-vs-entity collisions
        • support for obstructing other entities
        • hit-scanning for bump attacks (think Ys, Xanadu, Fairune, and similar games)
        • pushback on attack hits
      • entity movement/collision optimizations
      • hit flashes (temporarily colors the entity palette upon a hit)
      • HUD drawing
        • health bar + exp bar
        • health number + level number
        • attack + defense + gem icon and values
        • enemy health bar HUD (shows health bar and name + sprite when attacking an enemy)
        • modal full-size textboxes (hides HUD and displays text until player confirms)
        • short timed messages (uses same area as enemy health popup, disappears after time)
        • pause menu - lets you look at your equipment, and use healing items.
      • room switching
        • switching rooms when the player moves outside the screen.
        • doors that switch rooms when walked over
      • entity implementations
        • enemies (walk into to attack)
          • slime (weak, moves randomly, infrequently attacks unless the player hits them)
          • bat (alternates between flying around the room, resting, and flying at the player)
          • ghost (floats around the room slowly, occasionally moves toward the player)
          • dark mage (teleports around, shoots projectiles aimed at you)
          • snake (fast and aggressive, charges at the player a lot)
          • knight (slow and indestructible, you need a much stronger weapon)
          • skeleton (fast and runs around around, throws bones)
          • “red”/stronger versions of enemies (these have improved hp/atk/def/speed, and also grant more exp for defeating)
          • new enemy types
        • destructible trees/doors
        • chests (walk into to open)
        • dialog npcs (walk into npc to see their textbox)
        • player projectiles
        • enemy projectiles
        • shop items (stand over with sufficient gems, press action button to buy)
        • mini doors (if the player stands in front of them with a ring, transform them to a miniature form, and allow the player to proceed through the door)
      • save system
        • loading
        • saving
        • checkpoint tiles that trigger saving when the player presses the action button while standing on them.
      • game systems
        • level ups and experience
        • attack and defense stat gains on level up
        • healing HP to full on level up
        • equipment (automatic, each item belongs to exactly one slot, the next piece of equipment is always better than the last so it replaces it)
        • magic (an infinite use item that spawns a projectile when the player presses the action button)
        • healing items (consumable / limited use, restores player HP)
      • joystick input
      • support for more keyboard keys
      • title screen
      • game over

      The above list started as an immediate task list, but quickly grew to a larger list of stuff to do while I was writing this. Heh, whoops!

      Well, that’s all for this week! Hope to see you again soon!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This week was slower!

      I worked on Wandering Magic MSX some more. I’ve been porting the enemy logic from the original Lua code to Z80 Wiz code, So far, it’s going okay, but some things that are really easy arithmetic / comparison / math library calls in a high-level language, have to tediously be rewritten in assembly. Things like comparisons, while easy when comparing 8-bit values, quickly get messier when extended to 16 or 24 bits. Also, there’s a fair amount of counter variables that need to be split into multiple 8-bit pieces since (IX + dd) indexed addressing mode can only address a single byte at a time – so increments/decrements/adds/subs need to propagate intermediate results across the carry, zero, or negative status registers so that 16-bit math can be done. Eventually register pressure becomes important too, and book-keeping all of this can be tiring. I put it down for a moment, but I’m getting closer!

      The “patrol” AI for the slimes, snakes and knights is a bit complicated, but the good news it will make a few enemies in the game work at the same time, once supported. Going to keep pushing this porting effort, and see about phasing features in a bit at a time, until each can be tested and verified separately.

      Also, my MegaFlashROM SCC+ SD flash cart arrived in the mail:

      96b1b1fd-178d-4747-817d-07482a972710-image.png

      dec9084d-0cda-4d78-a78b-06a44351754c-image.png

      54efe653-195a-4450-9726-260ccf48e8f0-image.png

      Still awaiting my Panasonic FS-A1, but once I have that, I’ll be able to try things out on a real MSX system.




      Recently, I was also a bit bored, and decided to write some data structure code in C. It had been a while since I wrote a hashtable/dictionary type, and so I made a hashmap implementations.

      The hashmap does open-addressing / linear-probing and uses user-provided storage for tables with zero heap allocations during insertion. Instead the hashmap’s put operation simply fails when the table is too full. Like most hashmaps, it has best-case O(1) constant time, and worst-case O(n) linear time for lookup/insertion/removal, and it has O(capacity) iteration time.

      I also provided some helper functions to adapt this to a dynamically-allocated + resizable hashmap, by adding an insert operation that will swap the storage to a bigger area on the heap as the capacity is reached. I also made it so hybrid static/stack allocation + dynamic allocation could be used in the same hashmap, by keeping the user-provided storage and only allocating when capacity of the current user-provided storage is exceeded. This allows optimization akin to the SmallVector type in LLVM, but for a hashtable.

      In addition, I also did some library functions for a contiguous list data structure. Like the hashmap, they both serve as a simple wrapper over a plain array of data, or when wrapped with some dynamic-allocation, a resizable vector. And it’s possible to mix both pre-allocation + heap use again.

      Stuff that doesn’t need the heap though, will be able to cleanly avoid this and build lightweight lists and hashes, or statically-allocated ones that are loaded when the program begins.

      I also worked on a lightweight parser for a toy language. In some ways the scripting language could be thought of as similar to VergeC in some ways, where there are only a few built-in data types, no garbage collection. But unlike VC I was thinking to have automatic memory management through unique pointers to data + ownership/move semantics. Not going to allow refcounting, because the whole cyclic resource ownership problem it can cause.

      Within the compiler I had the idea for some kind of language that could target a fairly “robust” set of features with a single-pass parse, but no Abstract Syntax Tree, instead convert directly to Immediate Representation, and either interpret that in a VM as a “scripting language”, or translate into something like equivalent C code, WASM or LLVM IR.

      The idea being this language could be used to prototype stuff fast as a scripting language, and then build to C or IR when performance is desired.

      I was also thinking of potentially digging out an old register-based VM (that I think I called “lilvm” heh, not to be confused with llvm) I had started, and see if any ideas from that mesh.

      Anyway, I don’t really know what I’m doing yet, this idea is very much in the air, and so far I’m just building pieces that could potentially be used in a compiler. and coming up with ideas for a simplistic scripting language that uses strong typing, and compiles quickly.

      My hope is something as easy to embed as Lua, but with no GC, C-like + simple to learn, and have the ability to turn into native code later. I don’t know if I’ll finish this, but having fun trying stuff out.




      Also, outside that, I turned 33 and relaxed a bit. Happy Birthday me! Next weekend is easter so an extra day to relax again soon. Talk more next week!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This past week, despite being very busy, I managed to be a little more productive than previous weeks.

      I closed a few bugs in Wiz:

      • Fixed SNES debugger symbols to work again, so now you can get nice named labels and variable names in Mesen-S and bsnes-plus when debugging SNES programs.
      • Someone reported a Mac OS crash in the compiler! It was caused by C++ argument evaluation order being unspecified. This means that the order depends on the compiler vendor (usually dictated by the calling conventions of the target system).

        Usually this is easily avoidable, however std::move is a core feature as of C++11, which will transfer ownership of resources (eg. using unique pointers to enforce single ownership and prevent memory leaks, or for avoiding expensive copies of heap-allocated data structures). For unique pointers such as std::unique_ptr (or Wiz’s equivalent-but-better-inlined wiz::UniquePtr), moving is necessary, and the copy assignment and copy constructors are deleted to enforce move semantics.

        There is is a bit of a hidden “foot-gun” waiting to go off though: std::move has the side effect of moving its contents to the destination and nulling out the source afterwards, to preserve the single ownership of a piece of memory. This is how std::move is meant to work, so nothing unexpected here so far. But often, there is the need to move a value AND access some its members in the same call.

        Code like f(std::move(ptr), ptr->member); is easy to slip into the codebase by accident, especially as compilers don’t generate any warning for this. On x86-based Windows machines, where the argument evaluation order is right-to-left, this code will compile and run as expected. On Mac OS, this will compile too, but it will always crash at runtime, because it evaluates function arguments left-to-right – this means the std::move(ptr) is called before ptr->member is evalated.

        The fix to this crash is to store things into locals before a move occurs, so that you don’t use-after-move. But the nature of this being “unspecified” by the C++ standard means that the compiler never warns about this bug, and it may even appear to work if the vendor/platform-specific evaluation order just happens to works in the program’s favor. As a result, any change to the code could introduce this bug without notice. This reliance on the evaluation order is never desirable when wanting to write portable cross-platform programs in C++ that run reliably (and without crashing).

        Thankfully, clang-tidy is a useful static analysis tool that can detect these sorts of problems by running with the bugprone-use-after-move check enabled. It caught the crash and a number of others within the codebase.

        VS2019, for all of its bloat, even comes with clang-tidy. This would be great, but MS unfortunately messed this up somehow and shipped an update that breaks being able to do static analysis – I had to manually patch my VS2019 install’s version of intrin.h to get things working. Sigh. Anyway. A long journey later and things are working better.
         
      • Fixed the issue with nested struct access, Now you can declare an alias for register, and use as a pointer-to-struct by going var monster : *Monster in ix; and then use it like monster.stat.atk = 10;



      With that weight lifted, I started to get planning out the battle system and monster encounters for my NES RPG.

      I thought that it might be useful to design the encounters in a sort of “top-down” kind of way. having families/categories/taxonomies of monsters that all share common traits and behaviour. Within each family, the monsters would be divided into tiers, a sort of “evolutionary hierarchy” (for monsters) or “chain of command” (for humanoid types), where each tier is a higher difficulty and more powerful.

      Then, monsters families themselves belong to different environments. Things would be designed such that there’s a nice variety of different encounters spread across the environments – gradually increasing in difficulty, or introducing a new challenge or mechanic to the fights to keep things interesting.

      My hope is that this sort of approach will make it easier to get a general image of how the game should “look”, and allow me fill in boxes as I go. This should give a more coherent idea of the big picture of how things flow across the game area-to-area, something which usually gets lost when doing in a bottom-up method, one-map-at-time.

      Monsters themselves would have distinctive behaviour, and use a combination of some state-machine driven logic, turn-based countdowns, and reactions (counters). Each state would be capable of producing a list of actions that it wants to consider, as well as a preference score to each one. States could transition depending on specific conditions like HP %, being hit X many times, detecting the player doing something, etc. Monsters themselves could also track grudges, prioritize protecting other monsters and other stuff.

      But I am thinking of implementing monster AI in a way that it’s mostly driven by the monster’s state and a few other scratch variables. I think this method of monster design could be pretty versatile despite being fairly simplistic.

      I also had some thoughts about the battle system itself. I had originally made a mockup in FF6 style, but I was thinking it might be nice to use something a little different from ATB battles. I was thinking it could use initiative-based turn orders with a combination of randomness + character speed to help determine the order. Combatants would decide and act at the same time when their turn comes up. Some actions could potentially have a charge time (that resolves as its own turn between combatant turns). Actions could also have a cooldown that affects the timing of a combatant’s next turn.




      I also drew this little mockup of Wandering Magic if it were a game for the MSX 1:

      msx-wandering-magic-mock2-2x.png

      The mockup tries to follow MSX “Screen Mode 2” restrictions – 256x192 resolution, a fixed 16 color palette, backgrounds are composed of 8x8 tile patterns that can have 2 possible colors per 8x1 area, sprites are 1-color and 16x16 in size.

      That’s all for this week!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Another week passes.

      I didn’t get as much progress done as last week, but I did do a few useful things.

      I’ll start with the more interesting, which was to implement sprite flickering. This allows being able to see all the sprites on screen when there are too many on screen / too many per scanline, by alternating which ones are drawn each frame. This isn’t a built-in feature to the MSX sprite hardware, so games must manually cycle their rendering order to be able to flicker between the different sprites.

      My flickering system works by adding a prime number to the draw order each frame, and using another prime to walk through the array. Basically: index = (index + PRIME) % COUNT; at each loop iteration to shuffle the drawing order in a nice way, so that every sprite can be seen.

      Warning: Minor flashing Images (flickering sprite system):

      Flickering sprites

      So far I only implemented a sprites/scanline respecting flicker, but not something that will show everything if there was overdraw. But thankfully, I constructed the entity system to be 1:1 with sprites for now – it should be easy to do overdraw detection+cycling later if other things such as the HUD need it, or just reserve an entity for the HUD (sort of a hack but a cheap way to keep common sprite drawing structures).

      I also optimized the movement code for Wandering Magic a bunch. Now it is possible to move 16 copies of the player entity at once without lag. Beyond that it’s still not perfect though (the earlier GIF uses 24 sprites and slows down when moving, 32 is even slower). Not sure what the next steps would be to optimize performance, if we want to do all 32 entities, but I think I’m okay with slowdown after reaching 50% capacity of possible stuff to put on the screen. and 16 entities is enough to have room for the player, a few enemies, and a few projectiles. A little slowdown is okay as long as the control still feels responsive and works in the player’s favor. But I might try to do a deeper optimization pass later.

      Some optimizations I performed:

      • Reduce number of temp push/pop to the stack when not needed to preserve things.
      • Relieve register pressure by re-using more registers when their previous calculation is no longer needed. (This took a lot of careful reading of the code to figure out what registers were no longer live, something that liveness analysis in a compiler could probably do easily, heh.)
      • To multiply by 16, use repeated 16-bit self-addition (add hl, hl), instead of 8-bit shift left + rotate-left-with-carry. It takes less bytes and less cycles.
      • Comparison: Use inc/dec (which set the zero flag) to avoid overhead of comparing to 0 and 0xFF, when registers can be modified.
      • Sign extension: Use rotate/shift left by 1 (so the sign bit goes into the carry), then subtract a from itself with carry, to get 0 or 0xFF.
      • Use immediate load instructions when loading stuff into memory pointed at by index registers, rather than loading into a register first and then loading into memory

      Some possible (much later) optimization pass:

      • page-align the tilemap array + tileset array
        • possible because we load into RAM these can be easily located even if the source arrays aren’t aligned to the 256-byte boundaries
        • page-alignment speeds up all pointer math, since single 8-bit adds / bitwise or can be used, rather than 16-bit addition.
      • replace 4.4 with 8.8 fixed-point. Speed is passed as an argument through static RAM variables, so direct 16-bit stores can be accomplished.
      • page-align entity array + remove use of index registers (probably not worth the extra complexity)
        • indexed register usage is slower + takes more code space than indirected register pairs.
        • register pairs don’t have random access, but page-aligning kind of gives you this back.
      • use shadow registers more effectively.

      I also updated OpenMSX (and downloaded the debugger) and tweaked a few settings to have cleaner quality captures / better workflow. I fought with settings to get a nice clean integer scale render of the MSX screen. By default OpenMSX seems to like to use a bilinear filter over everything. Eventually after asking around, I figured out a some settings you need to open the F10 terminal in OpenMSX and set horizontal_stretch to 320, (which I couldn’t do from Catapult – OpenMSX’s GUI frontend) well as set scaler to simple, renderer to SDLGL-PP, disable all blur, glow, scanline noise, etc under video controls or from the OpenMSX F10 terminal. Anyway, way less friendly than most emulators in this regard, for getting a nice image without pixel blurring, when nearest neighbour is the standard in most emulators, but that problem aside it’s a useful tool. The earlier GIF was taken after fixing the scaling interpolation issues, making for less blurry screens than some of my earlier game captures.

      The OpenMSX Debugger seems nice too. But I’m not sure if I might still fall back to the less-accurate BlueMSX because I’m more used to its debugger by now, and I don’t do anything that requires too much hardware accuracy (I hope). But I’ll definitely test with both emulators, and eventually true MSX hardware, I hope.

      Other than that, I shopped around for a possible MSX to test development on. I found a Panasonic FS-A1, an MSX2 computer. It’s currently being recapped and then sent in the mail, if all goes to plan. There are probably cheaper ways to have gotten an MSX to test with, but not much to look for in North America, especially in Quebec.

      I also ordered a MegaFlashROM SCC+ SD, which is a flash cart that allows playing software, and includes a reproduction of the SCC+ soundchip (that Konami used in their games, such as Metal Gear 1 - 2, Space Manbow, Nemesis 1 - 3, Snatcher, SD Snatcher, and so on). The MSX is definitely a more expensive system (though I think cheaper than the PC Engine), so hopefully after these two purchases I’m set.

      I also bought a controller adapter to allow use of Atari/Genesis style controllers with the MSX, which is much, much cheaper than buying a nice Hudson Soft Joy Card or less comfy looking Panasonic 2-button controller. Controllers are weirdly expensive. So this adapter saves you about $100, heh. It’s not as essential since the MSX has a keyboard that can be used for games/programs too, but still nice this adapter makes it possible to get controllers.

      Anyway, buying all of this equipment with the partial intent of enjoying games, but also to test my creations on the real hardware, since I can copy my MSX test programs onto an SD Card that gets interacts with the flash cart. We’ll see how that goes, and hopefully be able to set it up and take captures of the game running on the real console.

      So yeah, that’s all for this week. Thanks and see you again soon!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Heyyy everybody, it’s egg here. Another week has flown by, and as usual things were very busy at work.

      But not-so-usual, on this weekend, I ended up participating with some friends in the Ludum Dare 48 game jam.

      We made a short game named “Frog”, which you can download here!

      frog-game-3da75.gif

      You’re a frog and you shoot bubbles! Descend the depths, find the treasure!

      Credits

      • 2bitcrook - art
      • cacciatc - programming
      • Kulor - programming
      • dustmop - programming
      • eggboycolor - programming

      Plays in an NES emulator, or on a Famicom/NES/Famiclone that supports VRC6 sound expansion.

      Try it out!




      The game is pretty short, but considering the timespan and that it’s a real NES game, I’m pretty happy with what we manged to accomplish.

      Thankfully, we picked the category of Ludum Dare that allowed not only team collaboration, but using existing code. Chris Cacciatore provided his NES-based game engine Veil to work with, and it was pretty fun learning how to write code with this toolchain. Chris, Dustin, and I collaborated on the coding side. 2bitcrook did the excellent pixel art for the backgrounds and frog + bubble sprites. The game supports VRC6 expansion chip audio, and kulor provided really cool music and sounds for that take advantage of this.

      It had been a while since doing any sort of game jam/compo, so it was great being able to team up with a few friends to make this. It was a bit tiring at time, as I forgot how stressful fitting things into single weekend can be, but once I found the right rhythm and got used to working in the tools, things started to snap in place. It was helpful to synchronize on tasks each night + morning during the jam, as it let us brainstorm and change plans/limit scope when we were getting a bit stuck.

      We originally had a few ambitious plans for the frog and the level layouts originally, with scrolling levels, multiple enemy types, and a tongue mechanic, but we quickly scaled it back. The final game has a bubble mechanic + static obstacles to navigate in order to reach the goal in each room. I’m happy the readjustment happened early enough that we could salvage the idea, and we managed to make some neat levels around it.

      Hopefully people get a chance to play and try it out! It’s a bit buggy, as with any jam game (especially a crash at the ending, some sprite and physics glitches), but for the time allotted I’m pretty happy with the little platformer creation we accomplished.

      Getting to jam was a nice way to recharge motivation for personal game projects. But on the other hand, it was also very exhausting to spend an entire weekend basically only working on that, with small breaks for food + walks. So that’s definitely not a regular thing I want to do. However, I’d potentially do another jam if circumstances were to work out again.

      That’s all for this week! Hopefully soon I can finally dust off my projects and talk about something new.

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Hi, sorry I missed last week’s post.

      Been pretty burnt out or something lately! To the point that, lately whenever I sit down to do something for a side project, my mind just sort of goes blank mid-way. I can manage for simple things, but as soon as more elaborate problem-solving or creativity is involved, it’s an uphill battle and a chore. I’m trying to get back to some sort of balance again, I’ve just felt mentally tired and creatively blocked on my existing side projects.

      I mean, otherwise I feel good! This doesn’t feel like depression or something. It’s just that, any time I’ve tried to do something, I just spin my wheels and stay in the same spot. Even if I cleared the time, psyched myself up to work on a thing, and wrote down steps of what I wanted to do, somehow there’s a mental block keeping me from doing the work, Sometimes, even the process of trying to write a plan down, I would just get distracted in the middle, and end up zoning out and doing something else.

      Work has been rather exhausting with its current place in production. Having two back-to-back holiday long weekends was nice, but an extra day or two still isn’t making up for a real vacation. Anyway, sometimes that’s how it goes.




      Putting that aside though, I somehow managed to do something over this weekend.

      I made a small platformer prototype, using PICO-8:

      wip gameplay screenshot

      You’re a quick-moving adventurer that can jump around and throw daggers.

      So far, it has basic character animations: idle, walk, jump, fall and shoot. There’s also some background tiles, and a repeating foreground layer with some simple oval-shaped clouds .

      The platforming code handles the basics of moving and jumping around, I recycled a lot of old code to get going on this. Dug up things from like 5 or 6 older unreleased projects of mine, and recycled various code to do with entities and collisions. Everything was adjusted to fit better after the fact, so it felt a bit more cohesive rather than just tossed together. Still, having some existing groundwork definitely helped with iterating quickly instead of spending all my energy on coding yet another entity system from scratch, heh.

      I implemented input buffering, so if you hit the jump button or attack slightly early, it will do the action if it becomes possible in a short moment after you press the input. This allows jumping slightly before landing, and hitting attack without needing to be as precise. I will probably add support for jumping for a short window into falling too, but in practice I think this this is not as vital to game feel as buffering – some newer games depend too heavily on “coyote time” for their jumps, in my opinion, and I’m okay with late input having a penalty.

      Another nice aspect of recycling old code, is that with only a few minor edits, room logic and enemy designs from the PICO-8 version of Wandering Magic can be dropped into this. While the enemies were designed for a top-down game, some work just as well in a platformer and can be used for prototyping. I need to implement a couple more things before the player and enemies can hurt each other, but the basic movement code for these could be carried over.




      So yeah. On the one hand, I started another project rather than trying to continue existing ones. But at the same time, given my current mental block, just being able to work on anything again was nice. I’m unsure where I’ll go with it, but it was fun to jam. I think it was possible because I could create without too much care, just whatever seems neat and letting my mind drift there.

      At this point I still have no idea what the game is about, or whether I will keep working on it, but at the very least it was neat to play around with something over the weekend. It’s also still at a stage where it’s relatively easy to iterate and adjust, even if I shelved it for a little.

      I’m trying to move the creative challenges into the level design instead of code, and stick to a format that fits easily within PICO-8’s confines. PICO-8 has a bunch of limitations, 128x128 screen, limited code, limited map + tile space, a 16-color palette, etc. If you don’t compress your maps, PICO-8 gives the choice of either 128 tiles + a 128x64 map (or 8x4 = 32 screens), or you can do 256 tiles but you only get a 128x32 map (8 x 2 = 16 screens). I’d rather have the extra map space since the art is quite small and I can make that work. But even then, only 32 screens for the whole world is a challenge.

      If you do compress your maps, then you can fit more data, but this comes at the expense of a much more complicated development process, since for anything that doesn’t stick to the basic format, you need to make your own tools and lose out on the built-in map editor tool. You also need to sacrifice code space to write a decompression routine. It can pay off for some kinds of games I guess if you’re willing to put in that sort of effort, but I would rather not go down that road! (this time)

      Too many past projects of mine tried to fight against these size limitations and ended up getting stuck mid-dev. So instead, attempting to embrace the limitations, and design stuff to extend the length of the game in the confined level space, and make it more interesting to navigate the space, it will probably have some non-linear elements, as well as gated challenges, puzzles, events, and reasons to revisit areas.

      The PICO-8 version of Wandering Magic stuck to the 32-screen format and managed to get a demo that was about 30 minutes long, with plenty of room to spare, so I think it’s possible to do something interesting in this limit design space. Might need to tweak the movement speeds slightly so the player can’t breeze through rooms, but hoping it can stay pretty fast-paced overall.

      Still trying to figure out how to build the maps for this, thinking of drawing an 8x4 grid of boxes on paper, and figuring out in the abstract what challenges and exotic elements each room have + as well as coming up with neat paths through this space. Fill in the blanks. Then actually craft the rooms, using those constraints. I have no idea if this a good approach to the design, but it’s what I had in mind to try for starters.




      Anyways, that will do it for this week. I’m still very much under the weather and this new project is if nothing else, a nice diversion from a mental and creative block. Hopefully can keep this momentum going and turn things around for the better.

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Hi, here’s another weekly update.

      I started blocking out some other rooms. I made this forest / plant zone underneath the “castle” zone:

      some new rooms

      Still super rough, and it will probably need to change as enemies and interactive objects are placed, and game progression is figured out. Anyway, having fun trying stuff out.

      Trying to keep to decorating things with a limited amount of tiles, conveying the general texture / theme of stuff with a couple small repeating patterns. The forest uses about 3 main tiles:

      • foreground “grass”/“bush”/“leaf” tiles
      • background tangled knot of roots/branches
      • background vines/branches

      Then there’s a couple blocks or bricks over that, but they’re less common in the central rooms of this area.

      In designing the rooms, I tried to make sure every area has multiple exits and distinct areas that can be reached. I’ve been trying to make branching paths that have you weave through multiple rooms, so you need to figure out how things connect. It’s pretty basic so far though. There’s no key items or collectable abilities yet, so it’s pretty easy to “solve the maze” heh.

      I still don’t know how I’ll fill in the rooms yet, but it’s a start.




      Also started mocking up this HUD, just tossing something very basic in:
      idevenk_1.png

      Since it’s a “fixed-screen” platformer, I thought a static full-width HUD probably makes the most sense. I was originally thinking of a HUD that repositions itself depending on your spot, but realized those are a bit annoying. And hiding the HUD isn’t really an option unless player health is communicated some other way, or you have a life bar over your player (ugly). And a fixed, floating HUD like Mega Man is more fitting for a game with a scrolling camera and fairly tall corridors, it doesn’t really work here. So static HUD it is!

      To compensate for the 8px of space used by the HUD, I scrolled the camera up a half-tile (4px) which seems to work ok. And it saves the need to edit all existing rooms to be 15 tiles tall instead of 16. I prototyped scrolling the camera slightly as you navigated but found it a bit annoying in practice to see it pan every time you go. So a fixed half-tile offset seems to be an ok compromise.




      Still seems like I’m in recovery mode, but every couple of nights, I poke at this prototype for an hour or so. Wish I could eventually figure out where this is headed, but it’s still nice to make minor progress somewhere.

      I also got my second shot on the weekend. Aside from a bit of a bruised/heavy feeling in my arm, and being a bit drowsy afterwards initially, there weren’t really a lot of other side-effects. After the 2 week recovery mark passes, this may mean more changes, as it will be possible to do a little more outside of the house. I’m still pretty hesitant about being too ambitious with that though, since lots of people still aren’t vaccinated yet, and the new delta variant, etc. Also it may mean working outside of my house a couple days a week, and I have mixed feelings about this. We’ll see.

      Anyway, catch you next time!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This week is very short to summarize. Other parts of my life have been competing for spare time lately. But in spite of that, I did manage to squeeze in a couple hours of work on Wiz.

      I improved integration with debugger integration with Wiz programs. I added some work to improve debug symbol sorting in wiz, so that fully-qualified / global names have precedence over anonymous / compiler-generated names. This means that it will be much easier to search for a particular symbol by name in the debugger and go to it – and its given name (since Mesen annoyingly only allows one alias for each address of memory) will prefer a deliberate user-chosen name over auto-generated stuff.




      I have wanted to also fix Wiz’s symbol exporting for the SNES.

      The problems are better explained by first explaining what a “debug symbol” is – basically, a label or identifier that gives a name to an address in memory, constant, or similar thing. This allows you to view these symbolic names rather than hex values inside of a debugger’s disassembly viewer. These give names to better indicate where functions, labels, variables, and constant data appear in the program.

      The problem is, currently the way addresses are mapped to the symbol file is incorrect. As soon as you have a program outside of bank 0 of ROM, the address calculation is wrong. Or rather, wrong depending on the ROM’s map mode that is used.

      The SNES is peculiar because the system allows several different ways to access the same memory areas. Firstly, on the CPU-side, the 65816:

      • you can access an 8-bit address, which is offset by the direct page register existing somewhere within bank 0 of the memory space.
      • you can access a value on the stack.
      • you can access a 16-bit absolute address, which has its upper byte of the effective 24-bit determined through the its data bank and program bank registers.
      • you can use 24-bit absolute long addressing. It allows you to access the full 24-bit address space of the SNES memory map. This is a similar concept to “far addresses” in 8086 parlance, but bit simpler. For familiarity, Wiz also names this far addressing.
      • you can index an 8-bit direct page address, 16-bit absolute address, or 24-bit absolute address.
      • you can use a variable within the direct page or stack as a pointer to a 16-bit or 24-bit address in memory.
      • Also, there’s two different sizes of stack-based call/return, which use different lengths of addresses:
        • 16-bit jumps with JSR (jump to subroutine) and RTS (return from subroutine).
        • 24-bit jumps with JSL (jump to subroutine long), and RTL (return from subroutine long).
      • and so on (there are more address modes)

      At the end, the operands to these addressing modes are decoded at some point into an effective address by the CPU. The way this is done is determined by the memory map of the SNES, which is configurable by the cartridge.

      There are LoRom, HiRom and FastRom SNES roms. (Going quick to not miss the Gruedorf post deadline hahah. But edited slightly for clarity and typos.)

      Here’s a small summary of the “map modes” on the SNES cartridges:

      • LoRom lets each bank of memory you access view of ROM in 32K blocks and the 32K of address space contains other stuff (RAM, the hardware registers, etc). These are located at banks $00 .. $3F / $80 .. $BF.
      • HiRom also lets you view your memory like LoRom (in banks $00 .. $3F) – but if you do this, each bank of memory is actually 64K, you only access the upper 32K in each view. But there’s another ranges of bank address that let use this as a full contiguous 64K block (in banks $40 .. $7D, or $C0 .. $FF). This potentially works better with games that have different data banks and program banks, so the program bank can point to a 64K area, but data bank if, or each can point at a different area.
      • HiRom allows more memory to be accessed at once, but requires using banks that contain only ROM space when they are selected, which means you will need to manage your data and program bank registers more, or use 24-bit far addressing more often. HiRom can still be used in LoRom fashion, but will be less efficient when used this way. It steps in 64K increments, but only sees each the upper 32K of a 64K block when viewed in the LoRom compatibility banks.
      • LoRom has less memory it can view at once and less maximum capacity, but its modes may be easier to work with because even if the ROM bank changes, the program can still access RAM and at the same time – which might be useful if you want to copy stuff within the same page using faster+smaller 16-bit instructions. It always steps in 32K increments.
      • FastRom mirrors the entire LoRom/HiRom address space in the upper area of the bank address space, but starts from $80, $81, ... instead of $00, $01, .... This high bit in the address line is used as a signal that fast access mode can be made (I think the cartridge hardware is responsible for checking this after a game software activates “high speed mode” on the SNES, but the exact details don’t matter for writing a program.)
      • The main takeaway from this is, the same memory area in the ROM can be accessed in many different “mirrored” banks of memory. (there’s more nuances if you get into expansion chips, or weird third-party cartridges which could have their own memory mapping schemes)

      Emulators such as bsnes-plus and Mesen have opted to, for whatever reason, import addresses from the symbol file as absolute addresses that are unmirrored (even though the addresses when fetched by the CPU are mirrored) As a result, this means a name can map to exactly one absolute address – no mirroring occurs.

      Maybe because that’s what WLA DX already used? Not sure! Anyway, so I need to adapt the debug code to use the absolute bank addresses exactly as they’re declared in the Wiz program, which are normally meant to relocate the program counter during assembling, but aren’t necessarily the true position in the ROM. Before this, Wiz was only using output-relative offsets: This is a better, relocatable concept, which refers to the exact address in the ROM, and the emulator could load this with mirroring in mind to resolve things. However, since not every emulator works like this, and we don’t want to fork existing emulators just to incorporate what we think would be better, a change is needed.

      I haven’t had a change to sit down and support this mode yet. I need some way to make these two addressing schemes be selectable by debug target:
      a) output-relative byte offset, or
      b) cpu memory map address space.

      This way, WLA DX-style .sym exports conform to CPU memory maps on all symbols. I’d like to make the default settings for auto-detected by debug symbol file format, to make it so that exporting doesn’t have to configure this. Need to think on this a little more.

      Anyway! Hopefully soon!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This week was once again pretty quiet, but I poked away a bit more at Wandering Magic MSX.

      I also had the last-minute idea to finally throw together a Twitch stream showing some MSX development. It was fun! There was also surprisingly a lot more viewers than I expected, and I was pleasantly surprised by that! Thanks to anyone who watched, I sort of announced the whole thing over the easter weekend, so not a lot of advance notice. I figured the long weekend was the right time to give something like this a try, anyways. But still, about 7 or 8 people were viewing, which was neat and unheard of for most stuff I tried on Twitch.

      It didn’t turn out to have any new code, and was instead a show-and-tell + hanging out and answering questions. It explains a little on the MSX, some of the pipeline I use to import graphics, some demonstration of the original PICO-8 game, some examples of some code I wrote for the MSX version. I had a bigger plan, but the script sort of got tossed out when there was more audience interaction than expected, so that made it sort of a more interactive Q&A + show-and-tell hahah, lesson learned for next time!

      Anyway, if you want to check it out, and you don’t mind watching me ramble on for a while, here’s a 3 hour archive of the stream: https://www.twitch.tv/videos/976933676

      (NOTE: some parts are loud due to some volume balancing issues near the beginning. So I recommend turning your volume down a bit lower around the Nemesis 2 gameplay. After this the stream gets better! There’s also a short dropout near the 2h30 mark or so I think, because my ISP. If I ever reupload this later, I might edit these out, but for now this version will have to do.)

      Setting up for this stream took away a fair amount of time from actually doing new development this week. But I’m going to count this is as progress, since I did get to relearn how to setup a stream + use Twitch, and it might open the door to newer, better organized streams in the future!

      Anyway, shorter update. Happy egg weekend!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This week was once again very busy for me. I thought a little bit about what would be a good next step for the Wandering Magic MSX port.

      In particular, I was thinking about trying to implement a subset of the enemy movement logic for starters, rather than trying to do a large line-for-line port of the entire behaviour at once. This way, progress is divisible into smaller, measurable chunks that can be tested and verified more easily. Trying to convert the entire function, although small and simple in Lua, is still a large undertaking to port all at once to assembly.

      This approach sort of stopped development dead in its tracks a bit, because trying to port things was done without an immediate goal in mind anymore. And when my time is so limited, any loss of clarity is translated into wasted time before warming up enough again and getting somewhere. A consequence of this is, I suddenly feel less inclined to work on something because I can estimate how long it will take to get started, and know that the overhead to pay just to get started again is too much.

      So, I need to come up with strategies so that it takes less time to resume the project. This ways it’s easier to shelve changes in the middle of something and come back. And I’ll still know what I’m doing, and I’ll know I have enough to make an attempt at the next piece.

      I was thinking of a better idea:

      • Start with just getting slimes that move in a random direction.
      • Then try having them change this movement direction when a collision is encountered.
      • Then add an expiring timer to the directional movement, so they re-evaluate their direction every couple of seconds.
      • Then worry about collision detection between the player and enemy.
      • Then add stuff to do with damage resolution, then experience+gold on death, then knockback forces. etc.

      The gist of this is, more itemized, short tasks with clear end goals. Rather than “here’s a function let’s rewrite the line-for-line equivalent”, without consideration for context and inevitably getting details wrong. This is easier to maintain things within my sparse free time/motivation on nights and weekends. And it might be easier to pick a specific task to show on a development stream, if I decide to do another stream on Twitch.

      Nothing is perfect, and some tasks do require deliberation and planning, but by focusing on low-hanging fruit, and incremental tasks toward a bigger picture goal, more work can hopefully be accomplished that will push things ahead. And the goals/tasks can evolve in response to the changes made, rather than speculating and planning in a vacuum.




      Anyway, so yeah would be worth giving this approach a try. Even just getting “pick a random direction and go in it” isn’t super simple, since it requires some code being already written, namely both movement code and a pseudo-random number generator.

      In this case, I already coded a Galois Linear Feedback Shift Register for doing randomness, in 6502 and GB assembly, so the translation to regular Z80 should be pretty straightforward. These randomizers are pretty short in terms of code, and have maximal periodicity for its bit depth, so they’re kind of a nice balance between “good randomness properties” and “low implementation cost”. Better randomizers exist, but these are some of the easier to write.

      To seed the randomizer, I plan to simply use a fixed seed on startup. But I will step the random sequence every frame, so over time the sequence diverges, depending on how many random values are sampled between gameplay choices. This means speedrunners can still get their frame perfect randomness (not that I anticipate any for my games, but…), and meanwhile normal players will still see enough random to feel that the game has some unpredictability/chance to its mechanics.

      On top of just pure random, I typically like when games do stuff internally that behaves like shuffling a deck of cards and dealing those out, only reshuffling when the list is exhausted. Also, counting duplicates and choosing another action if one is used too much. this will also mask any crumminess in the RNG since it’s much easier to shape the random to something more pleasing to players. It prevents hitting the degenerate cases as much, by encoding rules that ensure each event has a finite number of occurrences, or a decided-once order that is then consumed.

      Anyway, I got a little detoured here! adding randomness, and then adding a slime moving around that turns when a wall is hit, will already feel like a great start. Maybe by next week I can get this delivered. We’ll see!




      Even while being blocked on my project, the MSX was still on my mind however.

      I started playing around with taking some old art of mine, from a project called FROG EGG. I started imagining what it could look like in an MSX1 art style.

      Then I made a mockup with a water background. My goal was to see if I could make a scene that had 1-bit sprites over a somewhat colorful background (instead of black bg), and be mostly readable.

      msx-platformer-2-2x.png

      Here’s the original 1-bit game this was based from:

      frog egg 1-bit gif

      The original game was a game for the Arduboy, a small Arduino-based AVR handheld system with 2K of RAM, that has a 128x64 resolution and a dpad + 2 buttons.

      I ran into a snag though, in that, there is limited RAM + ROM space. Worse, if you go beyond a certain limit, the flash loader on the Arduboy gets bricked, and requires you to do the tedious work of factory resetting the device with a paperclip (easier said than done, from experience, even with the tools, because the reset button is inset pretty far and you need to hold it for a few seconds). Anyway, maybe one day I could make a small adventure out of the engine I did… it just got very precarious to make code changes which is not something I really wanted in a project in the prototype phase. (I eventually made an SDL wrapper of my engine for easier testing + sharing with non Arduboy users. That made things considerably easier, but still shelved things until I had a better plan formulated… And by then other projects came up on my radar lol… maybe one day)

      Anyway, at the moment, I have no plans to make a platformer with this art yet. However, I thought it could be fun to create more of these little mockup scenes like the above MSX one, with some background pieces + some different sprites. Stuff like forests, caves, cityscapes, ruins, etc. Possibly more in the MSX style as well. If enough areas were done, it could be neat to explore making a game out of it. But until then, happy to just explore making some more art and keeping my pixel art from getting too rusty.




      In addition to the above, I heard that Ludum Dare 48 is coming up soon! (the weekend of Friday, April 23 - Monday, April 26)

      I might enter the Jam with some friends, since it allows collaboration, and they allow bringing in existing code+art+assets. I’m always busy when LD comes around, but in this case, I planned ahead and tried to clear plans to ensure a greater chance of successfully working on something. Never tried the Ludum Dare team jam, so it will be fun! Last compo/jam I entered was a few years ago, and the last collab was even further back than that. I’m really bad at entering these, but giving this a shot, since 1) the timespan is short 2) I have the time available 3) I planned time a couple weeks in advance.

      Anyway, catch you later, hope everyone has a nice week! Next Gruedorf post will likely adhere to the later schedule I usually post in (Tuesday @ ~12:30 AM EST). This one was posted a bit sooner since I am busy tonight.

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      I’m late for my usual weekly update. It was a long weekend (Victoria Day weekend in Canada), so this threw off the normal schedule a bit. The weather in Montreal also warmed up, which was pretty nice outside. Indoors the humidity made things a bit less pleasant, and I had to get out a fan.

      I’ve been struggling to make much headway on anything programming-related outside of work in a little while. I’m not sure why, but I guess sometimes this happens. I was a bit tired with my current projects, so I decided to start on something a bit different.




      I had the idea to write a music engine for my homebrew NES games. I wanted to support FamiTracker, since it’s the most popular music tracking software for composing music for the NES.

      Before going down this road, it’s useful to evaluate what’s already there. A few other music popular NES engines exist that support importing from FamiTracker, such as FamiTone (or the older, original version here), GGSound and Pently. I’ve used Famitone and GGSound a bit, but they lack some features for making richer audio tracks in some regards. Never had a chance to try Pently.

      There’s also another tool FamiStudio, which is a separate piano-roll style desktop music editor. It has FamiTracker import, and supports targeting directly for its own improved engine fork of FamiTone. But from the page’s own description, it sounds a bit closed to outside contribution and it’s a larger codebase, so I’m bit unsure about it for this reason.

      Anyway, I looked at what was there but wanted to try writing my own thing. Hopefully something that has easy integration into my own projects, and has good support for some of the tracker effects that FT has available.

      I also wanted the potential for supporting expansion chips, to approximate the sound capabilities in other game consoles, such as the MSX, PC Engine, or Game Boy. It wouldn’t sound 100% the same, but it would give a way to test these things out at least.


      (MSX has on-hardware stuff like Trilotracker, and Game Boy has on-hardware LSDJ, and Nanoloop. But these are more strictly for writing and listening to music when nothing else is happening. Not meant as much for gameplay when the CPU is needed for other tasks too. There’s also Deflemask or XPMCK, which support a bunch of platforms but also don’t really have drivers that work great for a game. GB also has Paragon5 Tracker, but it’s ancient and clunky. So in light of all this, something like using FamiTracker to approximate ends up sounding like a good possible alternative.)


      I’ve previously worked on a a couple attempts on different music engines, but these always relied on notation similar to MML (Music Macro Language), or byte-code interpreters that used command opcodes for notes+effects. In these cases, I was writing the engine, but didn’t have easy integration to a usable music editor. They had sample data or text-based formats that they could convert, for the purposes of testing what sound engines were capable of, but nothing easy to actually make music with.

      There was also Bleep, an unfinished piano-roll music maker I was working on that ran on the GB hardware directly. While this was neat, and I want to continue with that someday, it’s less practical for game music making, and was more meant as a fun way to make songs on the go. For my current idea, I wanted something with easier integration with a desktop music editor that does chiptune music. Different goals.


      Alright. So this time, I wanted to make a project that took things in the other direction – rather than engine-first like usual, I decided to try doing an importer tool first, then a converter tool. This way, I could write a music player that can interpret the parts of FamiTracker song that I support so far. This would allow making music in FamiTracker from the beginning. I can incrementally add support for more things, while being able to compare the output from my engine vs the FamiTracker. I can also use my past sound engine work to fill in some of details later when I get to that point.

      FamiTracker’s normal file format is a binary and seems a bit annoying to handle. Not impossible but probably would take some extra time to get right. Thankfully, it also has a text-based file format that it can export that is (comparably) much easier to handle. Sadly, according to its own documentation, this export is not guaranteed to stay stable between versions… However, it turns out FamiTracker doesn’t change all that often anymore since it lacks active maintenance for the official version (last release in 2015). I also find it unlikely that they would abruptly throw it away fully, since lots of external music engines + converter tools depend on the format working a certain way now. So yeah, text format it is!

      The format documentation is included in the .chm help file that comes included with FamiTracker’s installation. I couldn’t seem to find a direct online version of the text format specification on their wiki or website.

      However, through a roundabout way (a github page that can link to .html files in github repos), I’m able to link to doc for those interested: https://htmlpreview.github.io/?https://github.com/HertzDevil/famitracker-all/blob/master/hlp/text_export.htm

      This format is a simple enough: text-based format with line-based commands consisting of space-delimited tokens. But there’s some slightly tricky business comes with how it handles strings, which need some escaping. Otherwise, not to much to say about the format itself. The commands of the format do stuff like define tracks, instruments, macros, etc, piece by piece, as each is read and interpreted. It’s kind of unfortunate that it’s a custom text format, rather than just using JSON or something, which would make it a bit easier to integrate without other tools needing to write a new parser. But what’s there is still pretty nice. Parts of it can be more easily be human-read, and the music patterns themselves essentially look very similar to how they’re written in the editor, so it’s easier to inspect.

      I originally wanted to write this tool in C++, but kinda regretting the decision to not just phone it in with a Python script or something instead. Writing anything that handles I/O and text handling with nice graceful error-handling always takes some work to get right. All in all, it’s pretty much the equivalent of split() with maybe a couple regexes, but I ended up settling on a simple character-by-character scanner instead since I could have finer control over the memory usage and more easily do input validation and errors with line info.

      Aside from the text input stuff, I made decent progress on some data structures representing the in-memory representation of a FamiTracker document. That part was kinda fun to work out, going backwards from the description of the various commands in the export spec. I’m sure if I need I can read the FT source later too, but I wanted to “clean room” things a bit for now.

      Anyway, I did manage to write most of a parser + a bunch of struct definitions for the FamiTracker’s document structure, individual tracks, patterns/rows/columns, instrument definitions, macro sequence definitions, etc. Didn’t quite get to the end, but close.

      If I can manage to get this parser done, I can start selectively outputting parts of FamiTracker songs from this tool. Or potentially toss it out, treating it as an exercise only, and maybe think about doing it as a Python script after all heh. We’ll see.




      I ended up returning a little bit to development plans for Wiz, too.

      I created a private Git branch of the source to allow me to try stuff. I like open development most of the time. However, for big changes, it can be annoying to make sure breakage doesn’t happen at every step of the way, once people are able to see. And I’d rather make intermediate commits that break things and fix it. I could make a separate public WIP branch, but for this, I don’t really feel there’s much value in people seeing my in-between meanderings and prototyping that I might toss away or never finish. So private repo it is.

      The project doesn’t yet have unit tests, so that’s one thing I want to fix. I also want to work on splitting the compiler into smaller modular pieces, which I’ve probably talked in another post before. Decided to just rip the entire compiler code out for starters, and phase it in piece by piece. This way, I can put more thought into where things should go this time around. I can potentially I clean up some inelegant things, and can review and make fresh notes about what to improve along the way.

      I’m still not sure about it, but I’ve long hoped to add features that can define platform backends directly in the .wiz language. Wiz already has it so that every platform provides definitions for register sets, addressing modes, instructions, and their encodings. Right now these are done directly in C++, but if these could be moved, that would make maintaining these bindings easier and allow new ones to get integrated too.

      With a little bit more work on top of that, it could even possible to allow mixing raw assembly with Wiz-style high-level code. This would allow interop with code written in other assemblers, allowing the inclusion of libraries that weren’t written in Wiz, without needing to port their sources.

      Another thing is that, Wiz currently targets binary opcode formats directly from its IR, and doesn’t have any text dump of the final program code. Having this feature would allow easier verification of the code generated for bug-checking the asm and potentially for writing some functional tests of the compiler.

      There’s also some language warts I’ve wanted to iron out, this gives a chance to potentially revisit that in the process.




      Lastly, I got a new laptop, an Asus Vivobook Flip 14.

      4613c4ed-68b2-4c08-8a87-d81e61d6286b-image.png

      It just arrived after the long weekend, and so far it seems pretty decent.

      The 2-in-1 laptop-and-tablet aspect wasn’t needed but it’s a nice extra. So far, I managed to uninstall the bloatware, disable a bunch of Windows 10 features + apply registry edits, and install a bunch of basic applications for getting development stuff done on it. And there’s Chrome, Steam, Spotify, etc.

      The half-size arrow keys are unfortunate, but unfortunately all Windows laptops I looked at had some drawback or another for my personal preference. Also, this laptop seemed to have some of the better specs for comparable things of its price. And didn’t do things like remove the headphone jack or only have one USB port.

      Overall, pretty happy to have a functioning laptop again. It’s been a long time since I’ve been able to do development away from desk.

      My previous laptop was from 2013. While still kicking somehow, it has a keyboard that’s barely longer usable. They don’t make it easy to clean the keys without breakage. It’s been like that for about 1.5 years now (basically keys died right after xmas break in 2019). So it’s made me do all development work exclusively at my desk. With the pandemic requiring my home desktop to become my full-time workspace, being able to do projects on a different computer, away from my desk is quite nice.

      I’ll probably keep my old machine as media box until it completely runs into the ground, since it’s still possible to type short parts of a url into a browser and then autocomplete and click on things.




      Okay, see you next week if I can remember this time! Now, to try to sleep again.

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Hi! Short update. Work has been busy, but holidays going on thankfully split things up a bit and give a couple extra days to unwind.

      I managed to squeeze in a little bit more sideproject time between other things. With Wiz, the initial rework to split everything into free functions is over with. The forked source is compiling again. The actual code organization is still a bit lackluster, and needs addressing. There’s also the matter of release mode code size increasing by about 30KB. It seems I only get a couple hours each week to poke at it.

      I can’t wait to move on from this work. It’s somewhat nice to see things getting there, but refactoring code and working on compilers isn’t always the most rewarding work. Especially between pretty dull and painful dayjob work that needs doing atm. I might just shelve what I did and start making projects again so I can give myself a little recovery from my dayjob.

      I keep pushing myself to do something each week on Wiz so I can finish this, but it’s also having the side-effect of sapping most of my enjoyment and energy for other projects. It’s unfortunate because finishing this work will open doors to allowing new bugfixes + feature work, and make homebrew projects nicer to do. Honestly, I could use a month or two long vacation to recharge and dedicate to solo work hahah, maybe eventually there’ll be a good moment for this.

      But yeah, that’s all for this week. Suddenly, most of North America is in a massive heatwave atm, Montreal being no exception here. The humidity is probably the worst part though, and makes it feel like a sauna. I have yet to install my A/C since it’s a two-person operation. Hoping I can survive through the week and maybe will finally get assistance installing it over Canada Day weekend.

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Overkill's devlog

      Another week passes. More tweaks and polish were made to last week’s untitled PICO-8 platformer prototype.

      attacking some bats

      I added some bat enemies, adapted from some old code but with slightly modified behaviour. Then I added the ability to hurt and defeat enemies, with small hitflash on damage and small sprite vfx when they dematerialize. I also drew a new player hurt animation and implemented the reaction in-game (no player HP at the moment though).

      I also adjusted the player art to have more readable poses, and some of the background tiles were slightly cleaned up. The art was edited even more since the above GIF was captured. I’ve tried different hair styles and color schemes for the player but couldn’t find anything satisfactory yet for mood / readability against background colors. So the self-insert miniature character remains for now.

      The player walk speed was slightly slowed, so that you can’t completely breeze through rooms, and it effectively makes it so there’s more area to cover within one screen. The collision code was improved to allow corner nudging when jumping into a ceiling corner, for better control while still allowing a full tile-wide collision box on the player.

      Progress has sort of slowed down from there. I struggled to put together other rooms that seem fun to navigate. I couldn’t figure out ideas for how the game should progress yet. And I couldn’t figure out many adjustments to the player character for the time being, but this is less crucial at this stage than the other elements.

      I’m still under the weather at the moment, and it’s become very easy right now to have small things completely stop me in my tracks. I was away from my computer this weekend, which helped a little bit for morale, even if it meant not doing creative work. But then, returning to the work week sort of deflated that, and drained my batteries once again. Hoping I can snap out of this and bounce back.

      It would be nice to continue things, if I can figure out where to go with it. The progress that’s there is early enough that there’s plenty of room to still change the game and expand on what’s there. And in the worst case, not too much time was lost, if for some reason it’s not continued. But I’d ideally like to keep going, rather than abandoning the project, if I can work back the energy to do more sideproject work.

      I’m getting my second vaccination this Saturday, Depending on how that goes, I’ll probably be recovering from that for a couple days. If I’m not completely out-of-commission, I might get a bit of time to focus on side-project things some more. We’ll see.

      Anyway, have a good week! Bye for now.

      posted in Gruedorf
      OverkillO
      Overkill
    • Running old Verge games

      Lately it’s come up a few times on the Discord chat about how to run older Verge games on modern PCs. So I thought it would be cool to share a few tips on how to run older Verge games in DOSBox. And eventually while writing this, I started thinking about Windows Verge as well.

      I won’t run down how to setup DOSBox and mount a drive and stuff like that, but the setup is pretty minimal mostly. If it makes things more convenient, I’ve used D-Fend Reloaded as a nice frontend on top of DOSBox to configure a lot of stuff up-front. Mainly you just need to mount the drive, and the rest of the presets can stay the same. There might be memory/mouse/CPU speed stuff to mess with too, but you probably don’t need to

      General Advice

      • Make a copy of your game, and do any changes on the copy rather than the original.
      • To be extra safe, don’t run the original either. Run a copy.
      • Why? Things could potentially modify files (eg. if you try to recompile scripts and compilation fails), or if you replace an executable (as some steps advise) it might not be compatible so it’s potentially good to keep the original

      Verge 1 games in DOSBox

      • Get a newer copy of cwsdpmi from here http://sandmann.dotster.com/cwsdpmi/ and paste it over the cwspdmi.exe included with the game.
      • Open DOSBox
      • Go to your game folder
      • Run cwsdpmi -x to disable its 1.0 extensions (which crash will Verge, and DOSBox itself)
      • Run main to launch the Verge game
      • For viewing maps, you can open maped or open the V1 map files in Maped 3. The map files will request something about creating a basic obstruction tileset when you import them.
      • For compiling scripts, you can use vcc, I believe the command is vcc all?
      • Configuration can be edited in setup.cfg
      • edit FILENAME can open text files in DOSBox, you could also inspect in a text-editor outside of DOSBox.

      Verge 2 - 2.5 games in DOSBox

      • Open DOSBox
      • Go to your game folder
      • You need to use DOS4GW to run the games, I think there’s a way to get this DOS4GW launch automatically for any executable that needs it, but I forget how to set this up. So I usually just prefix the executable with dos4gw instead.
      • Type dos4gw verge to run the game.
      • dos4gw vcc all to compile all scripts (be extra careful with this! you might want to do this only if you’re sure you have a backup first)
      • dos4gw maped to open maped2 and look at maps. For opening V2 maps on Windows. There’s also maped2w by aen written in allegro that could work for opening stuff, but it is a bit unstable.
      • edit FILENAME can open text files in DOSBox, you could also inspect in a text-editor outside of DOSBox.
      • user.cfg is the config file, and you can use the startmap FILENAME directive to change what map gets loaded

      Winverge Games (V1)

      • fullscreen mode will probably not work right on a modern display, and will force the display into an indexed color mode + hardware fullscreen at an very low resolution.
      • Maybe there’s an option to pass to setup.cfg that overrides fullscreen mode? (Does anyone know? I can’t find any mention of extra config options in the winverge.txt document)
      • This uses DirectDraw. On Windows Vista, 7 (and 8?) I think desktop composition / aero will be disabled.
      • Currently not sure how to run Winverge correctly. Is there a compatibility setting you can apply to winverge.exe to get it to run with the correct colors fullscreen mode? (trying 256 color mode crashes on startup) Otherwise, is there a way to run in windowed mode? I looked through the executable with the strings command and couldn’t seem to see the string setup.cfg referenced anywhere.

      WinV2 Games (Verge 2.5)

      • Should mostly work out of the box,
      • Might randomly run way too fast. In this case, it might be better run the DOS version of Verge 2.5 in DOSBox.
      • Sometimes DOS games written for V2.5 can work in WinV2, but not always. There are incompatibilities, and unlike DOS, Windows has memory protection, so any game that accidentally corrupt memory will likely crash instead of carrying along unnoticed.
      • fullscreen mode will probably not work right on a modern display, and will force the display into 256-color mode + hardware fullscreen at an unsupported resolution. It’s recommended to open user.cfg and add windowmode 1 to force windowed mode.
      • Add eagle 1 to double-size the window with a 2xSAI scaling filter applied.
      • You can resize the window manually (but unfortunately, if you the scaling doesn’t snap to integer factors or obey aspect so you’ll need to be careful)
      • This uses DirectDraw. On Windows Vista, 7 (and 8?) I think desktop composition / aero will be disabled. It works fine on Win10.

      Verge 3 Games

      • These should work out of the box on Windows 10
      • Older versions of Verge 3 use DirectDraw. On Windows Vista, 7 (and 8?) I think desktop composition / aero will be disabled. It works fine on Win10.
      • Verge 3.2 uses GDI, it’s mostly a drop-in replacement, but you might get some conflicts if you run a game that defines min, max, sgn, or other newer functions.
      • Some settings can be adjusted in verge.cfg - More documentation about the config options can be found here: https://archive.verge-rpg.com/docs/the-verge-3-manual/verge-cfg-options.html
      • system.xvc and precompiled scripts in .map files might not be compatible between Verge versions if you replace the executable. So any game that doesn’t have the original .vc scripts and is running with releasemode 1 in its verge.cfg will always have a harder time loading nowadays.

      Using the Archive

      For that matter, getting files from the Verge archive can be a bit tricky at the moment, because the mimetypes are a bit messed up. To navigate the archive, go to https://archive.verge-rpg.com/ - and click the Downloads link at the top. The search box won’t work anymore (since the site is a snapshot), so you need to use Downloads tools > File directory in the left-side bar of the page.

      Oh!! Or you can just click here to go directly to the Directory, hahah: https://archive.verge-rpg.com/downloads/directory/index.html

      If you try to click the download button directly, it will present you with page of indecipherable binary garbage because the webserver currently tries to serve downloads as HTML pages. Once you find the file, right click the download button and click “Save Link As”. Manually save as a .zip file. (Hopefully most files are .zip and not .rar or something else!) If all goes well, you should be able to extract the zip and get it working.

      Request for Archives

      I think it’d be great to pool together the resources to make a bigger archive of Verge-related zip files. If you have your own webserver, or someone else can host, it’d be nice to make publically browseable lists of the stuff people managed to save from the older Verge days. The verge-rpg site archive has a lot of stuff, but it’s incomplete and it’s currently difficult to navigate

      Especially:

      • source code for various Verge versions, as well as source code for old tools. Not immediately useful but could help anyone who wants to further any archival efforts down the road.
      • earlier variants on released games (such as different versions of Sully, etc)
      • games that were released or shared but aren’t in the site archive.
      • unreleased games

      Other

      It’d be very cool if there were was a “Verge emulator” that could support V1 and V2 games of various versions out of the box. Even if it’s extremely niche and limited appeal, it’d be great for archival purposes to not have to rely DOSBox exclusively. As much as something like on-the-web would be cool, Verge has a few features that depend on a physical filesystem, so I would recommend it be done in C++ for making the effort of porting existing source more possible. Use SDL 2 since it’s cross-platform, support conventional keyboard controls but also allow the SDL game controller APIs for support that out of-the-box. Could always be tied to emscripten to allow compile-to-the-web.

      But this is just tossing the idea in the air, it’s a pretty huge undertaking to support in general. Honestly, just reimplementing V1 on its own would be extremely neat. DOSBox is ok in the meantime though

      –

      Anyway that’s all I have for now! Hopefully other people can chime in some tips, and throw out advice, etc. It’d be cool to get advise for Verge 2.6, ika, and other Verge-adjacent engines in here too.

      I’d love to see more recordings to help show off older Verge games. Hatcher has been talking about this a little bit on the Discord channel lately. I also remember a few videos posted online by rainwarrior that showed off some older DOS games, including a playthrough of Sully Chronicles.

      posted in General Discussion
      OverkillO
      Overkill
    • RE: Overkill's devlog

      This week was super busy again!

      I overbooked myself to an extent, and had lots of things going on outside of work. It was nice to be moderately more sociable again, but came at the sacrifice of free time for projects work, and a need to recharge afterwards. I guess the weather was nice, so I wanted to enjoy this a little bit. (but done with respect to safety, social distancing, etc.)

      Curfew also was rolled back to 8pm here, and that’s a source of stress and annoyance too, sometimes requiring me to rework my schedule to fit things in the hours we’re allowed to go outside. But yeah, still not a pretty situation here and case numbers continue to climb, and vaccination is still catching up to more groups. Waiting and watching the government updates, and staying close to home a lot, as usual heh.

      I also got to work on my taxes… I had started a while ago, but didn’t make it too far, and with the Canada tax deadline approaching, the urgency and stress to finish that and make sure it’s done correctly is a weight on my mind lately. …But I didn’t finish that either! Some stuff about federal work-from-home benefits that I got stuck on, and I had to wait to ask questions to some friends/coworkers on that and a couple other things… But then I didn’t have a free night yet to resume where I left off. Taxes aren’t fun/passion project by any means, but they’re “work on something” that I needed to do outside of the hours of my dayjob! So it counts for “weekly progress”, maybe?




      Speaking of dayjob, currently I work as a programmer for Tribute Games, and we’ve been working on Teenage Mutant Ninja Turtles: Shredder’s Revenge, a 2D beat-em-up with pixel-art sprites, and a spiritual successor to TMNT games like those for the Arcade/NES/SNES/Genesis. The game was recently in the April 14th Nintendo Direct, so that was exciting to see! Featured at 11:07 in this Nintendo Direct video – https://www.youtube.com/watch?v=2RNkRaNfCp4&t=667s

      There’s this gameplay trailer if you’d prefer something more compact format:
      https://www.youtube.com/watch?v=GemOAwU-9fo

      Some of the things I did programming on are captured in these trailers! However, as the game isn’t released, I probably am not allowed to say anything much beyond that. But still, it’s been very cool to work on. I’m happy and fortunate to be able to collaborate with great people on projects like this for my full-time job, and here’s hoping development continues to go smoothly for us. I still plan to keep my posts to primarily about personal things, but made a rare exception for this! (Also if you’ve never tried, Panzer Paladin are Flinthook are two other games that I worked on with Tribute, if you want to check them out! Plugging over.)




      Aside from that stuff, I also had the idea to study some visual effects + animation captures, especially from SNES and GBA games, for research and analysis. I was thinking it could be cool to record some GIFs that first show a cool animated sequence or effect, and then do an analysis that decomposes the effect into its different elements + timings. If done well, this learning could even come in handy for creating new VFX creations for myself, and I could also share the notes made with others.

      I was hoping to capture footage, in particular, from Super Robot Wars: Original Generations. This game series by Banpresto has excellent combat animations, and cool visual effects that are comprised of many parts. The Super Robot Wars games are are series of cool mecha strategy games that fuse elements of many popular mech animes, some original characters and even some cameos of Gundam/Neon Genesis Evangelion/etc in certain games.

      The series has been around a long time, and characters from the older titles occasionally appear in newer games too. It continues to get new titles to this day, such as Super Robot Wars T (import-only but does have English version through EastAsiaSoft). They don’t seem to be released outside Japan and Asian markets very much anymore, but the few games we got in North America are a lot of fun to check out. We got the Original Generation series, and there’s also some weird DS spinoff RPGs like Endless Frontier: Super Robot Wars OG Saga too, not sure what outside of that we had.

      One game we never got here, for the Super Famicom, was Super Robot Wars Gaiden: Masoukishin – The Lord Of Elemental which looks super cool, and has a fan translation by AGTP. I want to play this someday, but I’m getting sidetracked somewhat heh.

      Anyway, here’s some SRW:OG GIFs of Kyosuke piloting his slow-but-powerful red mech Alteisen, performing Heavy Claymore + Revolver Stake attacks:

      Heavy Claymore
      Revolver Stake

      I was hoping to dissect these into timelines, figuring out how much time they spend on each “state”, and also figure out what elements comprise these captured segments. I don’t have an animation or film background, so it would be explained more from the context of a game programmer who enjoys coding VFX. I would trying to think of things in terms of “systems” they use, their compositions, a possible flow between different distinct states of animation. I could see how different sprite particle effects, screen shakes, sprite shakes, palette changes, blinks, hit flashes, transitions, scrolling backgrounds, character movements, etc are done, and what they contribute to the overall effect.

      I also wanted to capture a few attacks from FF6 for ideas from there too. I was hoping I could also compare it against earlier battle FF systems and show the smaller, less-obvious ways in which the battle animations were improved between game revisions.

      Anyway, still gathering captures + playing enough of each game to be in a spot that can be captured nicely. Then next comes actually taking notes. Then making still diagrams / text explanations / or smaller explanatory GIFs. I don’t have time to do any of this yet, but maybe one day, if I keep pushing it along.




      Well, this still isn’t what I hoped to have done this week, but this is how it goes sometimes. While I didn’t have the energy to do my game projects, I at least did other stuff that. And I wrote a lot of words here again! Maybe someday the stars will realign and I can continue where I left with things on Wandering Magic MSX, it’s still regularly on my mind even if it’s not moving at present.

      And besides that, getting excited for Ludum Dare jam this upcoming weekend! Hoping to participate with friends. I was recently sent a doc by my teammate, that contained a tentative schedule + a guide to setting up with the tools that they’re planning to use.

      Looking forward to be able to talk about how it went next update! Crossing fingers!

      posted in Gruedorf
      OverkillO
      Overkill
    • RE: Running old Verge games

      I think most of the source is now backed up, thanks to the archives that people sent me! Check the page here (as linked before): https://github.com/verge-rpg

      Now we have source for Verge 1’s June 1998 release, WinVerge, v2chr (distributed as zip-only, per request), Verge 2.01a, Verge 2.5, Winv2, Verge 2.5j / v2k+j, and a few revisions of 2.6. Also the Verge 3 source code was moved to the verge-rpg Github organization – I kept a fork at my github account to preserve any existing outgoing links, however.

      However, we’re still missing source code to official Verge 2.5’s VCC, and the source we currently have of WinV2 appears to be from unstable build, not a release version. It seems like Verge 2.6 revision 9 might be able to do a lot of the same things that 2.5 could do + some extensions added later.

      If you have any copies of these missing source files, let me know and I can put them on the github repo. Also, if you made any tools for Verge-related stuff and want us to host it, let me know and please let me know any licensing/terms for distribution! For now the GH is for preserving the engine source code, we still need to figure out a different solution for demos and games.

      If someone has a good idea for hosting our own organized file directory, maybe we can figure something out! For now we have the vrpg archives, but they’re incomplete, and it would be nice to recover and preserve what we can in a collective effort.

      Also, Andy (implicit_cast / thespeedbump) has been working on a WASM web player port of V1, and it’s open to bug reports and contributions: https://github.com/andyfriesen/v1wasm – it can sort of run parts of Sully so far, so that’s exciting news!

      posted in General Discussion
      OverkillO
      Overkill