[Utility] Card Hunter Battle Replayer

Discussion in 'Card Hunter General Chat' started by ParodyKnaveBob, Nov 8, 2017.

  1. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge


    For the past couple years, I've enjoyed playing and spectating Card Hunter, but a missing feature for which I've pined nearly ever since I found it had actually fun online PvP (gasp!) was the ability to record battles for watching later. Y'know, without video recording software that takes more RAM than my computer has in the first place. $F^ ,

    All righty then. I'm on it.

    The other day, I set up a Trello board. (It's public. Poke around all you like.) If you have requests (or bug reports once I get that far), just post here, and I'll add it to the board. I've now posted this on the GameMaker Community, too, but its required "screenshot" is practically a technicality, lol. (See my first reply to this thread down below.)

    Meanwhile, I'd like a better name. I don't really want "Card Hunter: ______" because that sounds too much like it's trying to pose as some official spin-off / sequel / etc. program. I do like "Card Hunter Spectator's ____" or some such, but I haven't been satisfied with any blank-filler yet. Something with at least a touch of flavor, y'know? $E^ b
    • Card Hunter Spectator's Table
    • Card Hunter Spectator's Chair
    • Card Hunter Spectator's Tome
    • Card Hunter Spectator's Cauldron
    • Card Hunter Spectator's Kit
    • ...
    If you have any questions or other comments, do tell. $:^ ]

    Last edited: Nov 12, 2017
  2. Flaxative

    Flaxative Party Leader Staff Member

    Interested to see how you manage this ! :)
    winner, Sir Veza and ParodyKnaveBob like this.
  3. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Thank you for the encouragement/curiosity, Flak! -- and of course likewise the encouraging Likes, everyone else, heheh.

    Since I'm using Trello for all my centralized immediate tracking, I'll just post weekly updates here (unless specifically answering somebody or something probably). I just posted this on Twitter a few minutes ago:


    I wanted to tighten the text lines to show more of the console log, just for kicks, but then it got into the blocked list, lol... I know I could've just c/p'ed from a later spot in the log, but I'll save that for when my parser can do that on its own. $}^ J

    Don't worry, I intend to give you all access to a working(-in-progress (lol)) demo. I just first want some core HTML5 functionality finished, plus I feel obligated to know what in the world is the deal with this IDE's EULA before I publish anything, even an barely scraped together alpha.

    Fwiw, this week, my lovely Done list reads (in chronological order)...
    • perform metamancy on Trello ($:^ P ...just, y'know, getting the board set up and all)
    • basic window properties
    • design user's basic playthrough/workflow
    • basic custom error catcher-tracker
    • core log ingester
    • a touch more metamancy on Trello (because my first run at organizing my thoughts needed improvement)
    ...and In Progress (in loosely prioritized order)...
    • bring in CH button graphics (I kind of reverse-engineered the text button to work with any text label I wanted .. pretty nice, methinks!)
    • credits/legal info

    All righty, I'm tired, and this is not my most organized post ever. $F^ ,
    I believe I'll quit now while I can still pretend I'm ahead.

    Brandon W. Horton
    winner likes this.
  4. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    My plan was to get a couple very particular GUI things done this week so that I could show off an awesome GIF and let you folks play with the bare-bones interface while I gradually built it. $:^ b However, no, sorry, that small task completely defeated me. Fwiw, here's the post I wrote in the game dev community:


    Frustrating. Spent all week working toward a very specific goal -- researching, working out preliminary and similarly prototypical functions, researching more, beating back a preventative SVN issue for a day or two, etc. -- only to find in the end, I seriously absolutely cannot accomplish that goal. Cross-browser limitation by design -- not technical impotence. ~sigh~ Therefore, my day-late-dollar-short update (minus screenshot even) says...

    ...Done (in chronological order)...
    • bring in CH button graphics (fixed an edge case that broke text buttons)
    • fix SVN issue not allowing the latest commit! (BUG)
    ...and In Progress for the upcoming week (in loosely prioritized order)...
    • HTML5 fullscreen toggle (I finished all of its primary stuff this week (especially to prep the framework for getting the aforementioned functionality-which-failed) *except* for keyboard shortcuts, thus I might as well start with that to have something nice and easy to get my juices flowing again heheh)
    • accept logs in different ways (the good(?) news is the failed function just shortened my checklist by some four items (out of thirteen)...)
    • credits/legal info (still have to spend the time to recover my help desk account in order to then to ask the IDE's company if the EULA changed, if something's bugged, if I'm missing something, etc.)
    Let's see if next week can be a happy update again, despite Thanksgiving and other time-consuming (albeit fun) events. $F^ J
  5. Sir Veza

    Sir Veza Farming Deity

    If it works, it will be great! If it doesn't, don't beat yourself up. You appear to be learning, and learning is good. Good fortune to you.
    winner, ParodyKnaveBob and Flaxative like this.
  6. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Thank you, Sir Veza, for the encouragement. For sure, I'm learning. I just wish I weren't learning so much of what I can't do every time I turn around, lol.

    Update this week: My day job siphons a lot of my free time away. Thanksgiving was a blur. I spent one day on a designed-to-be-short game for a 3-day-jam and still dropped it (because busy the rest of the weekend), meh. All that to say, I got very little done on the tool this week -- but I did get stuff done. (I was hoping to be a lot further along and feel comfortable about preparing for BVD's tournament. Instead, I haven't even logged on in a couple weeks. Hm.)

    • HTML5 fullscreen toggle -- as it turns out, the medium limits expected keyboard shortcuts -- spent a lot of time learning that I couldn't do anything with it (besides make unexpected shortcuts like "press F key" ha) -- therefore, nevermind HTML5 fullscreen keyboard shortcuts. The mouse'll just have to suffice.
    • Accept pasted logs in HTML5! ...in Edge only for some reason, witw.
    In Progress:
    • I'd like to list "refactor" and "still gotta learn some legal stuff re: the IDE," but I might have to spend all week just trying to figure out why in the world Chrome, Firefox, and Internet Exploder (I haven't yet bothered with Opera nor Safari) fall apart at the seams at my log ingestion... (Is it the prompt hackery? Is it the value passing? Is it the value ingesting? ~exhale~ Not like the IDE's HTML5 debugger does me much good in this situation (where the browser just silently crashes the game to a black screen).) ... I just can't feel comfortable working on other things until I bypass the one hurdle of making sure it can accept logs from a browser in the first place.
    I spent 4-ish more hours than expected tonight trying to beat a bug into submission. (Absolutely undocumented issue, ugh, where going through an extension (which I'm developing for this) changed the game's scope, silently pointing variables to the wrong object.) My point of pushing through tonight was to ensure I had a #screenshotsaturday to show for the hard work squeezed into this week -- and then ShareX would only crash on me while trying to record a 15 second GIF however many times I tried. Baaaah.

    Anyway, progress, yay. ~nodnod~
    winner, BlackVoidDeath and Sir Veza like this.
  7. It is as if I could hear your swearing while debugging with different browsers and checking the browser's documentary for feature completeness ... ah, wait, it's just me swearing every time I try to add something new to the utils I'm maintaining now. Just a small hint how this can get easier: Work with exactly ONE browser (and try to stick with code that doesn't rely on the newest features) and let the community report back if something is broken in other browsers. Atm I'm struggling with a bug report for the utils that shouldn't be there according to the available documentation, so ... (don't rely on documentary either)

    Btw: are league matches and match spectation in your scope? I'm not really into ranked MP but would definitely participate in the testing process if those variants are supported.

    And another small tip from developer to developer: Fixed-interval iterations are always a good way to motivate yourself but - as you've already experienced - also a great way to demotivate yourself. Perhaps it would be a bit more relaxing if you define (small) tasks and just work on them until they are done. Just my 5 cents.
    Last edited: Nov 26, 2017
  8. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge


    Goal 1: ranked
    • My design plan should automatically take care of constructed leagues and -- I hadn't thought about it until you asked, but -- even Quick Draw! $:^ ]
    • I expect a spectator's log to work out-of-the-box exactly the same as a player's log, only the information will be more limited. ( from Wish List: https://trello.com/c/b6jJIXuI )
    Goal 2: fixed leagues, casuals
    • This should be able to use some information like I intend with ranked. The complications: monster tokens/designations and minion presentation.
    Goal 3: campaign
    • The big problem I foresee is that the API only returns MP battle info, thereby making SP replaying rely on other sources of info...
    Yeah, you definitely didn't hear me swearing any. Lol. $E^ b
    (I'm glad to say I can't even remember how many years it's been since I did. Hm. ~nodnod~)
    I hear ya, though. $:^ b

    I appreciate, but accessibility is a big thing for me. My IDE of choice (GameMaker Studio) handles most of the browser compatibility stuff for me anyway, which is great, thus I mostly can just build and debug in native Windows, then run quick confirmations in a browser or two and move on. However, for certain functionality, I'm having to write my own extension, and Javascript is a cruel, hateful beast. (Lol.) My process there is to learn what I need, confirming with multiple sources, (especially when it comes to potential incompatibilities -- which I'm keeping everything as standardized as possible,) and primarily building using Edge. Then, I try in Chrome, Firefox, and IE11. (IE11 is a special case. I can't even really try WebGL in it and will instead rely on the W3C <canvas> JS recommendations. Again, mostly auto-handled for me, which is nice. Mostly. Lol.)

    Fwiw, I nailed down the reason that no browser but Edge was ingesting properly. Lo and behold, DOM nuances. Next, I have to solve why my latest fix hangs and creates a startup loop on IE11, though...

    Thank you very kindly there. I can organize all kinds of things super-efficiently, but time has eluded me from early childhood! ~sigh~
    I hate leaving things undone -- but then that can cause me to leave other things unstarted. $:^ [
    I still haven't been able to crack my anti-system all these years...
    I'll certainly give your advice more thought. ~nodnod~


    Pleasant update this time! $:^ ]

    Between day job, life errands, and reviewing games in a game jam last weekend (which I barely entered ha ha), I managed to get some nice things done.

    I kind of messed up saving my screenshots, but they're on Twitter, yay. According to my Trello list, Done (chrono order):
    • refactored some things, partly just better maintenance, but some crucial encapsulation for the Javascript extension I'm building for the project
    • reported some IDE issues - as I note on Trello, although it's satisfying seeing accomplishments sitting on a shelf together, in the future I'll use Habitica to track my progress reporting those (and indeed I reported more just the other day)
    • "slightly improve the title graphic, lol" $:^ P
    • improve HTML5 standards (speeding up final MSIE load time, supplying more informative fallback when no JS)
    • the big one! now exporting to EXE or HTML5 accepts pasting the battle log!
    In Progress for next week:
    • BUG: unfortunately, Internet Exploder lives up to its epithet (or epitaph...) and crashes the tool on the new paste code
    • legal/credit stuff - I began the process to ask about something, (i.e. confirming my Help Desk account in some secondary browser,) thus I'll likely do that simple task this week
    After that, (mainly the point of ensuring IE can use this, too,) I'll get back to the log parser itself. That's the meat and potatoes after all; I just want to make sure the user has a fork first! $:^ b

    But all right! BVD's tournament is this month, too. Considering I'm unprepared for having instead so far focused on Jam stuff and this project, I might not last long and therefore might have more time for Jam stuff and this project after all. Lol. $;^ b We'll see what happens.
    winner likes this.
  9. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Addendum @PhoenixTheHunter: Nevermind, I give up on MSIE (at least for now). I worked around the strange error it gave me, only to find IE11 wouldn't go along with my text input at all. $:^ [ Now I just have the app warn IE users it won't work (and remove the paste button) -- but to let me know if they prefer IE. ~shrug~ For this tool, it'll likely be fine. (I do, however, want to eventually solve this for my Javascript extension's sake -- not to mention for IE's sake.)
    winner likes this.
  10. I just had a little chat in-game with @Sasoo8 , @QuickJon and others about some kind of mentoring in the CH community in a way that you spectate or play a game and get advices from some advanced player. My next thought was that your Replayer may be a awesome tool for this. Please decide yourself, if this is worth the additional work (as your basic idea - if I got it right - was just to get rid of a recording tool when making game play vids):

    What if I could import someone's log (either my own or the log of an un-experienced player I'm mentoring) and replay it and while doing so, marking remarkable situations by time-code and perhaps with an additional comment text-box (like the Gary-boxes in campaign) telling you things like "Oh, see there (pointer to opponents hand), you knew he had a remaining block. Don't waste your powerful attack first just to trigger the block!". After this I can export it in any format (exporting will probably already be part of your basic concept) that I then can either send to players I'm in some way mentoring or upload it here for the whole community.

    If the technical aspects were already in scope, see this post just as a pointer to how this project can be a great benefit for the community.

    And finally: You'll still be testing with all other browsers a lot, because they're always differing in exactly those points that are important for you. That is their vendor's way to (not) appreciate you working with their product.
    winner and ParodyKnaveBob like this.
  11. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Hmmm, hadn't considered adding custom annotations. I know about how/where it would fit into the grand scheme of things. I'll add it to the Wish List, thank you! $:^ b

    Btw, since I'm here, sneak peek: with the above pasting issue no longer In Progress, today I spent about an hour reviewing my code and adding new functionality. Progress. $:^ ]


    (The comparison to the older screenshots is that this shows a log tech demo starting at a battle being entered instead of logging onto the game -- yet it's still using the same raw log.)

    Re: basic idea
    I've had multiple reasons for wanting to do this for years, but the final motivation to start this project was my hardware simply not being able to video-record games, yeah.
    winner, Flaxative and Sir Veza like this.
  12. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    I've had Internet issues for some days now, hence the late update. Also, if my hardware could handle GIF-recording the screen, (and I intend to try another program soon,) I could show you the simple window with a paste button receiving the click to paste, then (instead of showing the whole log in the background like I've been doing,) displaying some parsed info (scenario, room name, etc.) and a new "Replay Battle!" button which, upon appearing and being pressed, brings you to the new (albeit blank atm) battle screen. $:^ ]

    Done (in chrono order) this past week:
    • refactor Javascript extension (encapsulated more, sped up input some, cleaned a little memory, etc.)
    • find a battle's start and end (as mentioned in the above preview post)
    • parse a battle's core static data for further parsing (of more polish-y data and more moment-to-moment data)
    • quick Card Hunter API test (which unfortunately succeeded in telling me what I can't do, meh)
    In Progress (in loose priority order) this coming week:
    • credits/legal info - I received my main info on this, added a simple button for it on the GUI, and scratched off a lot of legalese-writing-to-do since the IDE requires less of me these days (surprising!) and unfortunately I don't need to fulfill BM's API TOS/EULA requirements after all
    • move from title screen to battle - as I mentioned in my intro paragraph, this is going all right so far - I mainly just need to confirm what data I need to move, and confirm what data I already do move - the core of this task might be done already $:^ P
    Not sure how much I'll accomplish here this week. Internet problems might persist -- I'm surprised it's doing all right tonight even -- and I have some weighty offline stuff to handle this week, plus an online obligation or two... (And no telling what's going on with BVD's tourney atm...) Anyway, we'll see. $:^ J

    P.S. It's getting frustrating to come to the forum lately since not only has my 'Net connection been acting up (further driving me away from firing up CH the game, too), but the forum's been doing that weird log-me-out-every-few-minutes thing again. Been months since it did that last. Weird.
    winner and Sir Veza like this.
  13. Just another quick idea (and this one should be quite easy as soon as the Replayer works roughly): Most of the time someone posts quotes (or screenshots) from Battle Log or Chat these posts are partially anonymized. In general the right way should be to ask your opponent if creating a replay of this match is OK for him/her. But if the Replayer (and in case you don't find another name for it, I like it) allows anonymization for one or both players you can create replays without exposing the opponent's identity to the ones viewing the created replay. This would be an advantage compared to every screen-capturing software (even if the software allows to gray-out certain areas it is hardly possible to cover all relevant sections without hiding interesting details, every mouse hover over an opponent's character displays his/her name).

    Just rename the anonymized players to some generic "Player 1" and "Player 2" and the characters accordingly "Char 1" etc. Or allow custom replacement names. And if you can identify text-characters that are forbidden in player names ("[" and "]" might be forbidden to prevent players to name themselves "XY [Mod]" but the devs probably will tell you if you ask them) you can use those characters to express that the names are artificial ones (like in "[Player 1]").

    And as some kind of follow-up question to my question about leagues and spectation mode: Are you aware of the additional complexity when replaying co-oped casual games? In those matches are up to six players in up to two teams controlling up to ten minion groups. And even if you only focus on matches with MP team characters you still have up to six players in two teams with one char each.
    winner likes this.
  14. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    re: anonymous
    I don't believe this is necessary. Does anyone else reading really super want this kind of feature? After all, I see some screenshots posted for logs' sake with names blotted out, but usually the blotting is just done for malcontents and such so as to not "name and shame," or sometimes "funny moments" posts for ..habit? ..overextending cautious courtesy? ..I don't know why, lol. However, I don't remember a single time seeing a console battle log modified for anonymity before posting (since that's generally been about proving mechanics and not about player behavior); point me to some posts if I'm wrong. Yeah, it'd be super simple to replace names once they're properly ingested in the first place, but ~shrug~ I don't see it being useful.

    (Although your edge case of a player modifying a log to show an impossible name in order to try to trick someone sounds interesting. But .. eh. The adamant player could just "create" an artificial win log anyway. Once again, too bad we don't have any usable battle/room ID to connect the logs to the API to prove certain things that happened! ~ At some point awhile back, I decided I would clean up very little because GIGO: if a user feeds modified data, don't be surprised if something breaks -- or not. (I mean, I could give neoncat's/your tool fake data and have a 100% badge, but what good does that do me? Lol.))

    re: leagues, casuals
    Yep, I'm aware.
    I forgot to write about team battles in that blurb -- sorry 'bout that -- but I did account for it in a Wish List card ( https://trello.com/c/6mQoOauc ) over a month ago.
    winner likes this.
  15. I mean, you're the one that has to implement this, so decide yourself. Just as an example: @Frostguard has tried to anonymize a screenshot in the Funniest Moments here although he missed two occurrences of his opponent's name (in case he changes this, this might not be true anymore the time you follow the link). And this wasn't done because he was saying anything bad/mean about anyone, but to show us his own situation in a match without risking to give any information about other players.
    winner and ParodyKnaveBob like this.
  16. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Yepyep, like I said, if I hear various people clamoring for it, then it shouldn't be too hard to add in, but I don't see it as "worth it" enough until then.

    In other news, now that I have stable Internet again and caught up in various places (yet not all, bah), I got back into this this week. Didn't do much, but all progress is progress. I'm currently adding code to strip out invalid-starting lines (like for logs interrupted by user commands -- and for now, verbose mode info). Oh great! Good news, while typing this, I cleared out the last bug on the core of this, and now it only ingests timer info -- next, to whitelist battle commands, but another day. Outta here! $:^ J
    winner likes this.
  17. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Well, this is unfortunate.

    I did get code into place to sift the battle log for a whitelist of valid battle commands, throwing away anything else (such as user commands, verbose mode stuff at least for now, etc.). Very nice. $:^ ]

    This week, however, while trying to design a fully reliable method to extract from the log even 2 players' names (let alone variable 2-6), knowing this would affect extracting characters' names and linking them to their correct players (with campaign minions in the back of my mind, too), I found it's going to be much harder than expected because 1. I utterly cannot connect the game's API to the game's log (~sigh~) and 2. to get this info, the log can't be very incomplete (defeating the idea of using to view moments, such as for bug reports or "highlight reels" ha), and it'll have to check the whole log in multiple ways to piece just this basic info together. $:^ [

    You can read my technical design details on the "determine everyone's names" Trello card.

    I expect I'll keep working on this, but all these limitations (especially imposed on the end user) are killing my motivation, and that was highly unexpected. $:^ \ Meanwhile, if anyone who has control over the log output and/or API (@Jon? @Farbs? @Flaxative?) could somehow bridge these two islands, that would solve the core problem on its own -- although I admittedly have not tested yet to see if/how the API handles team battles (listing all the players on which teams using which REST calls).

    Meanwhile, in the next couple days, I hope to slap together a super-quick tabletop game tool for an RPG I'm GMing. It's not directly related, but I already know I can use at least some of its features for the table view in CH Battle Replayer.
    Last edited: Jan 20, 2018
    winner and Sir Veza like this.
  18. Farbs

    Farbs Blue Manchu Staff Member

    It's been a long time since I've looked at any of this, but honestly I'd be a little surprised if you could build a decent battle replayer out of the default console output. It's just debug guff, and isn't intended to be comprehensive. Verbose mode on the other hand shows the contents of every network message, so theoretically could be used to piece a battle back together, but even then I doubt we're sending current health values etc, so the replayer would need to know what each card does and simulate that locally. Sounds like a _lot_ of work.
    winner, Sir Veza and ParodyKnaveBob like this.
  19. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Yep, a lot of work. $E^ J
    However, no, it does detail damage taken and health received. $:^ ]
    (Still, yes, it'd be nice to do this from the inside out, like Tess said on Twitter you all wanted to do in the first place, ha ha, instead of re-creating from the console.)

    I surprised myself and cracked this back out tonight. Break, lunch, after day job. Boom, it now reliably extracts the two primary players (team leaders). Although it doesn't yet recognize other team members' names, the framework is in place, and that task might be next -- either that or move on for now to character extraction. The player order is currently a bit arbitrary, but I already have designed a rudimentary way to make it less arbitrary -- reliable for a full log, natural-looking for an incomplete one.
  20. ParodyKnaveBob

    ParodyKnaveBob Thaumaturge

    Ironed stuff out this week more than adding per se; I also played some ranked for the first time in two months methinks. $E^ J

    I researched Campaign logs finally.* It shouldn't be any problem to distinguish from other battles, and I already have basic ideas how to add them in the future, which will be more time-consuming than difficult, methinks (once MP is in), although it still might not be pretty...

    *Last night, I saw I'd missed the latest Mauve Manticore. Crazy talk. Beat all battles first try. That was nice. Then, to test a regular adventure log, I took Myx'd Mess'zh, solo elf wizard, through The Wizard's Workshop. Good times, good times. Beat the first battle without any equipment, lol. Suited up on Flame Spits and Reflexive Teleports for the second, which worked surprisingly well. Figured I could be the last in plainclothes, but that it'd take too long -- Fey Silversmith and Unstable Bolts to the rescue! heheh

    I also researched, designed, and programmed re: custom matches against Gary. Last but not least, I fixed a silly bug I hadn't noticed yet (forgot to clean up a memory map -- not just a benign leak, but an overflow crash, ha ha ha). I also started some frameworking for parsing characters -- and researched and designed a surprisingly reliable way to extract races (but not classes, unfortunately) in most MP matches -- but I'll get onto that next week.

    Perhaps since it's past the point of "crash when you look at it" I'll put the alpha online for any curious lookyloos this week, too. We'll see!
    winner and Sir Veza like this.

Share This Page