As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/

[Game Dev] I don't have a publisher. What I do have are a very particular set of skills.

1777879808183»

Posts

  • CornucopiistCornucopiist Registered User regular
    Handkor wrote: »
    I wonder if there would be a market for audio only games where the input is limited to tapping/jostling your phone while it's essentially in your pocket or hand. Audio games for the bus there all you need is to put on earbuds and close you eyes while you just tap on your phone in you hands without needing to look.

    Easy to do for choose your own adventure audio books but something more involved where the accelerometers pick up the direction of your tap.

    Don't underestimate the appeal of blinkenlights. There's a lot of juicyness in just having bright colorful light coming from a screen.

    Elvenshae
  • KupiKupi Registered User regular
    Kupi's Weekly Friday Game Dev Status Report

    You know how they say "never change a working system"? This whole project to convert to System.Text.Json from the Newtonsoft library has been a real lesson in why that adage came about (whatever legitimate reasons I may have for wanting to change to the new library as documented in my previous post). For context, I'm stuck with .NET Core 3.1, as that's the only version that Monogame supports on consoles (granted that I'm about a decade out from being able to produce anything worth publishing to the console audience, but I'm working on not declaring myself incapable of success). Well, I discovered that the initial version of System.Text.Json that shipped with .NET Core 3.1 has a pretty incredible bug-- if you have an object with a property that is a custom collection type (that is, it implements ICollection) with an auto-initialized value, i.e.
    public class CustomList<T> : IList<T> {
        // IList<T> implementation details
    }
    
    public class BugCauser {
        public CustomList<int> DeserializesBadly { get; set; } = new CustomList<int>();
    }
    

    ... then what happens is System.Text.Json first detects that you're using a custom ICollection, reads all the objects stored in the JSON list into a temporary list instance, and then (incorrectly) says "Oh, this property already has a value assigned. I'll just call ICollection.Add() passing in my temporary list". You can't add a list of ints as a member of a list of ints!

    I can see how this bug happened, because there is also a branch much earlier on when it's detecting the type of object it's writing into where all the built-in types are given special treatment, and I'd say a solid 99.9% of people are using the built-in collection types instead of their own.

    Now, I did learn a lot through this exercise. I learned how to make the debugger download the source code from Microsoft (though the step-through experience is a bit janky because you're stepping through optimized binaries), got some exercise with tracking down the commit in the public GitHub repo where the problem was introduced and subsequently fixed, and nevertheless discovered to my immense disappointment that the fix was published in .NET 5 and is unlikely to be backported. Fortunately it's possible to work around the problem (it's actually never really necessary to auto-initialize a property of my custom collection types, and in a very extreme case you could implement your ICollection.Add() method to detect when it's been passed an enumerable of its collection type and add all the elements to itself), but it's something that needs to be fixed as part of this change-over project that actually doesn't need to be.

    My Pokemon knockoff, meanwhile, proceeds apace; I'm still in the process of sorting out the format for the various content files, but I've just reached the threshold of starting work on the battle engine, which is the fun part. So look forward to that aspect of the report being a lot more fun next week.

    My favorite musical instrument is the air-raid siren.
    PeewiCornucopiistexisDisruptedCapitalist
  • ScooterScooter Registered User regular
    halkun wrote: »
    Blind game

    There's a forum you might want to check out if you're interested in feedback from blind devs/gamers: https://forum.audiogames.net/

    I'm not a regular there or anything, but I did get some attention there a ways back from having Text-to-Speech in my game. In my case it wasn't even something I put in for accessibility reasons, just a quick implementation after a user said they preferred to listen to text games rather than read, but they do seem hungry for that kind of stuff. Unfortunately I was never able to make my game fully blind-accessible, as I added more stuff it would have taken more and more time to get everything functioning with audio cues. In my next game it's probably going to be even less practical.

    HandkorCornucopiistElvenshae
  • CornucopiistCornucopiist Registered User regular
    So, still a bit annoyed that all of the animations, scheduled texts etc. which point to my Serializable Enum 'Gamestate'
    So I switched over to Enum gamestates.
    Full disclosure; the gamemanager script was passed on from two earlier game, and I had a 'knocked out' enum gamestate all ready to go.
    The one issue is that I've serialised a class to set up animations, triggered by the gamestate.
    This way I can easily set these up in the editor.
    ziwk03xa1zlk.png
    HOWEVER!

    If I add an enum, the animations I have already set up change their enum value, because they're stored as the index rather than the string.
    So after adding an enum I need to look at all my animations and reset them.
    Would be useful to have a fix for that...

    So, I've circled back to this problem. Enums work, they are *just* available to select in my 'animation' class and some others that work the same way. However, what it's really pointing to is the position in the declared enums list, and when I add an enum all the instances of the 'animation' class have to be checked and corrected, as they now point one enum earlier.

    I don't really need the enum functionality. What I truly desire is the following:

    1) attach my gamemanager script in the scene / create a scriptable object in my project
    2) list strings in a 'gameState' list in either.
    3) attach my animator script in the scene and fill in a list of 'animation' class where I can select strings from the gameState list.

    What it really comes down to is the ability to declare in my 'animation' class a gamemanager.gamestate.string or something like that.

    But I can't get this to work...

  • ScooterScooter Registered User regular
  • exisexis Registered User regular
    Kupi wrote: »
    Kupi's Weekly Friday Game Dev Status Report

    You know how they say "never change a working system"? This whole project to convert to System.Text.Json from the Newtonsoft library has been a real lesson in why that adage came about (whatever legitimate reasons I may have for wanting to change to the new library as documented in my previous post). For context, I'm stuck with .NET Core 3.1, as that's the only version that Monogame supports on consoles (granted that I'm about a decade out from being able to produce anything worth publishing to the console audience, but I'm working on not declaring myself incapable of success). Well, I discovered that the initial version of System.Text.Json that shipped with .NET Core 3.1 has a pretty incredible bug-- if you have an object with a property that is a custom collection type (that is, it implements ICollection) with an auto-initialized value, i.e.
    public class CustomList<T> : IList<T> {
        // IList<T> implementation details
    }
    
    public class BugCauser {
        public CustomList<int> DeserializesBadly { get; set; } = new CustomList<int>();
    }
    

    ... then what happens is System.Text.Json first detects that you're using a custom ICollection, reads all the objects stored in the JSON list into a temporary list instance, and then (incorrectly) says "Oh, this property already has a value assigned. I'll just call ICollection.Add() passing in my temporary list". You can't add a list of ints as a member of a list of ints!

    I can see how this bug happened, because there is also a branch much earlier on when it's detecting the type of object it's writing into where all the built-in types are given special treatment, and I'd say a solid 99.9% of people are using the built-in collection types instead of their own.

    Now, I did learn a lot through this exercise. I learned how to make the debugger download the source code from Microsoft (though the step-through experience is a bit janky because you're stepping through optimized binaries), got some exercise with tracking down the commit in the public GitHub repo where the problem was introduced and subsequently fixed, and nevertheless discovered to my immense disappointment that the fix was published in .NET 5 and is unlikely to be backported. Fortunately it's possible to work around the problem (it's actually never really necessary to auto-initialize a property of my custom collection types, and in a very extreme case you could implement your ICollection.Add() method to detect when it's been passed an enumerable of its collection type and add all the elements to itself), but it's something that needs to be fixed as part of this change-over project that actually doesn't need to be.

    My Pokemon knockoff, meanwhile, proceeds apace; I'm still in the process of sorting out the format for the various content files, but I've just reached the threshold of starting work on the battle engine, which is the fun part. So look forward to that aspect of the report being a lot more fun next week.

    Interesting find. No criticism, but given your reasons for migrating, do you feel it was worth the effort? Seems it was a good opportunity to learn some stuff but also seems like it was pretty far into nice-to-have territory to start with?

  • CornucopiistCornucopiist Registered User regular
    Scooter wrote: »

    I thought saw that reply, but I saw a different similar question (more recent). Both OPs seem to have exactly the same problem I have...
    It's a bit clunky to my mind. I've been using lists of ints like this for tiles types in some of my other projects. It's always a shuffle between logically (human-readable) grouping ints (1000s are ground, 2000s are buildings) and adding types on the fly. You end up scrolling down long lists of values to figure out what you have to add the new tile as.
    For gamestates, there's two considerations. One is predicting granularity. I started with a few gamestates to represent the game's major set pieces. Then I added camera stations. Next, it's ending types (out of fuel/out of nodes/crash/win). Feature creep galore!
    So I might think that I only need 3 digits to cover all game states, but maybe later I'll end up having to squeeze more extra gamestates in than foreseen. At which point that defeats the whole exercise.

    The other is logic. Sure, enums give me 'craft_hovers < ignition'. I'd like to at one point do more with my game logic. The smart thing to do would probably be using Unity's animation system which does exactly that, but I like to work in code. So I'd love to be able to have a custom class, which I can make a list of, where each state includes things like a list of state names and conditions that the state could move to.


    For the moment what I've done is created scriptableobjects with only a string inside. Also clunky.

    Writing all this I realised that another workaround would be to have an GameStateName enum with all the strings I need. Then have all my animation and cameracontroller classes etc. set up in the editor using the enum (out of order). Then to have a custom GameState class that contains the same enum for the object name and for pointing to the next class.

    Thanks, duck!

  • HandkorHandkor Registered User regular
    The project I am currently working on involves roller skating. I've quickly done some programmer art level animation using UE5's FullBody IK with a simple rig which is serviceable for now to allow me to move forward and setup my animation blueprints and so on.

    Eventually I will want something that looks good without necessarily be motion capture. The UE4 marketplace gave me a lot of skateboarding but no roller derby style roller skating.

    Do any of you know of a good way to find people willing to do commissions?

    I looked at Fiver as an option but are there better or other ways of finding animators that do freelance?

    I don't need a character artist but just animations using the default unreal skeleton. Maybe I could reach out to some of the animators already on the marketplace to see if they do commissions.

    Endless_SerpentsMadpoetElvenshae
  • Endless_SerpentsEndless_Serpents Registered User regular
    Handkor wrote: »
    The project I am currently working on involves roller skating. I've quickly done some programmer art level animation using UE5's FullBody IK with a simple rig which is serviceable for now to allow me to move forward and setup my animation blueprints and so on.

    Eventually I will want something that looks good without necessarily be motion capture. The UE4 marketplace gave me a lot of skateboarding but no roller derby style roller skating.

    Do any of you know of a good way to find people willing to do commissions?

    I looked at Fiver as an option but are there better or other ways of finding animators that do freelance?

    I don't need a character artist but just animations using the default unreal skeleton. Maybe I could reach out to some of the animators already on the marketplace to see if they do commissions.

    I’ve no answer, but I wonder if the animations for Jet Set Radio are out there somewhere, and you could retrofit and alter them to suit…

  • HandkorHandkor Registered User regular
    Handkor wrote: »
    The project I am currently working on involves roller skating. I've quickly done some programmer art level animation using UE5's FullBody IK with a simple rig which is serviceable for now to allow me to move forward and setup my animation blueprints and so on.

    Eventually I will want something that looks good without necessarily be motion capture. The UE4 marketplace gave me a lot of skateboarding but no roller derby style roller skating.

    Do any of you know of a good way to find people willing to do commissions?

    I looked at Fiver as an option but are there better or other ways of finding animators that do freelance?

    I don't need a character artist but just animations using the default unreal skeleton. Maybe I could reach out to some of the animators already on the marketplace to see if they do commissions.

    I’ve no answer, but I wonder if the animations for Jet Set Radio are out there somewhere, and you could retrofit and alter them to suit…

    Even if they are, I don't want to take from a copyrighted work. Also making them work on the unreal skeleton would probably take me as much time as finding good footage and doing it myself.

  • MadpoetMadpoet Registered User regular
    Handkor wrote: »
    The project I am currently working on involves roller skating. I've quickly done some programmer art level animation using UE5's FullBody IK with a simple rig which is serviceable for now to allow me to move forward and setup my animation blueprints and so on.

    Eventually I will want something that looks good without necessarily be motion capture. The UE4 marketplace gave me a lot of skateboarding but no roller derby style roller skating.

    Do any of you know of a good way to find people willing to do commissions?

    I looked at Fiver as an option but are there better or other ways of finding animators that do freelance?

    I don't need a character artist but just animations using the default unreal skeleton. Maybe I could reach out to some of the animators already on the marketplace to see if they do commissions.
    Ooh, can you talk about the project? One of my BFFs was a coach on the (four time WFTDA champion) Rose City Rollers, and I might be able to help if you need footage, information, or contacts.

    HandkorElvenshae
  • HandkorHandkor Registered User regular
    edited November 26
    Madpoet wrote: »
    Handkor wrote: »
    The project I am currently working on involves roller skating. I've quickly done some programmer art level animation using UE5's FullBody IK with a simple rig which is serviceable for now to allow me to move forward and setup my animation blueprints and so on.

    Eventually I will want something that looks good without necessarily be motion capture. The UE4 marketplace gave me a lot of skateboarding but no roller derby style roller skating.

    Do any of you know of a good way to find people willing to do commissions?

    I looked at Fiver as an option but are there better or other ways of finding animators that do freelance?

    I don't need a character artist but just animations using the default unreal skeleton. Maybe I could reach out to some of the animators already on the marketplace to see if they do commissions.
    Ooh, can you talk about the project? One of my BFFs was a coach on the (four time WFTDA champion) Rose City Rollers, and I might be able to help if you need footage, information, or contacts.

    That's really cool but for now youtube is quite good with training videos actually. Not going to be following any roller derby rule sets or anything as it is not going to be fought on track and against other teams.

    The setup is five members of a team are driving back from a regional tournament only to be caught in a flash of light => crash car => wake up in a post apocalyptic world. Car is trashed so they put on their gear and head out and navigate multiple roads only to fight multiple mad max style local warlords to get to the macguffin that allows them to go home. B movie shlock essentially.

    The bad guys are not going to be on roller skates but other forms of travel, I don't want to make this a world that for some reason everybody settles their differences with roller derby.

    The gameplay is going to be similar to Road Rash and Death Skid Marks with the whole team carrying weapons. The idea is that you not only control your own character but you set formations and launch teammates at targets to attack or get launched yourself to take out targets. The idea would be to equip blockers with defensive gear and shields and attack with the jammer or pivots. So controlling when to attack and regroup will be important to prevent getting injured.

    The enemies are going to vary from guys standing in the road or running to some on horseback. Later as the difficulty increases you'll be facing off with enemies in cars and truck.

    I'm still in early prototyping right now and work is keeping me very busy so this project may end up getting nowhere.

    Handkor on
    IanatorElvenshaeMadpoet
  • CornucopiistCornucopiist Registered User regular
    edited November 26
    Handkor wrote: »
    The bad guys are not going to be on roller skates but other forms of travel, I don't want to make this a world that for some reason everybody settles their differences with roller derby.
    But whyyyyyy?

    I mean, you're already investing your own dev efforts into rollerskating as a mechanic. Then, your environment is already set up for that rollerskating. Then, your player is going to get onto the rollerskating learning curve.
    It sounds to me that if there's a value to your game it'll be strongly linked to rollerskating.
    So the logical thing to me would be to make it all-skating and see if that works before adding more mechanics?

    As a worldbuilder of sorts, to me the 'everybody rollerskates' is catnip.
    Primo, it stands out. You want to have a 90ies approach to worldbuilding; it has to be extreme to the max. Going solo means you don't have anyone at the table who doesn't like rollerskating and makes it all vanilla.
    Segundo, design choices should have meaning. They rollerskate because they happen to have skates along is weaksauce. They roller skate because they were actualised as the atavistic gods of destruction in this roller-derby world, now you have meaning.
    Tertio, no plotholes or fridge logic. In any world where violence is a valid option, you need to explain why swords beat guns and skates beat monster trucks. That might be handwaved away (Dune Holtzman shields) , but it could end up with stacked piles of reasons... ex: swords beat guns because swordwielders can move faster. Fast swordwielders can't themselves carry guns because guns are too heavy to move fast. Swords are lighter than guns because they are made of unobtainium. You can't make guns from unobtainium because... it has a low melting point?

    There are of course counterarguments.
    -You can explore the sweet spot of rollerskate/monstertruck interaction and make that the strong point of your game. But the more vehicles you add, the more interaction types you get, and the less likely it is that you hit the sweet spot for all of them.
    -And, sadly, realistic games do better in today's market. But that also means you're up against every other realistic game, rather than nailing the postapocalyptic roller derby niche.

    Cornucopiist on
  • KupiKupi Registered User regular
    Kupi's Weekly Friday Game Dev Status Report
    exis wrote: »
    Interesting find. No criticism, but given your reasons for migrating, do you feel it was worth the effort? Seems it was a good opportunity to learn some stuff but also seems like it was pretty far into nice-to-have territory to start with?

    Your criticism has nonetheless been graciously accepted. :wink:

    Being honest with myself, I don't think there's actually a metric for success that I can use on this project. The primary measurable advantage that I can think of-- reducing garbage collections that occur during gameplay as a consequence of doing content loading in parallel-- hasn't manifested yet and is unlikely to for quite some time. The philosophical comfort of using only the built-in tools is really only valuable to me. So, with the benefit of hindsight: this probably wouldn't have passed muster in a professional setting. (Fortunately, I'm not a professional right now. :lol:)

    Setting aside the necessity of the thing, I completed the conversion to System.Text.Json as my JSON handler this week, and after finally getting past all the compiler errors and "oh right that needs to use properties instead of public fields" cases, I loaded up my test project and oh lord it was only rendering every fifth frame. Which shouldn't have been a thing that changing the loading logic should have been able to affect! As it turned out, the "configuration" logic that I use to set engine settings, such as the internal resolution (what the pixel-art is rendered to before being stretched to fit the device resolution), the size of the tile placement grid, collision layer interactions, and so on, wasn't reading from the settings file correctly. For safety's sake, I had set that up so that if a configuration value failed to parse, it just stayed with the default value. (So if you set the tile placement size to "dfahjdf", it'll just stay at 32.) Well, in moving over to the new JSON parser, I'd accidentally removed the logic that makes sure it never loads the configuration setting more than once, and since my old configuration settings file had some invalid JSON (which Newtonsoft was happy to parse, but System.Text.Json is stricter about), it was throwing and swallowing an exception every time you tried to use that configured value.

    When you throw and catch thirty exceptions a frame, bad things happen.

    After getting my test project (the Sonic demo) to work, I decided to make sure that my stress test project was working as well. It took a few format fixes, but I got the ants bouncing around in their maze again... and discovered that the frame time for my most-used test case had gone from 5.2 ms/frame to 6 ms/frame. Somehow, switching from public fields to properties had raised my frame time by a little under 20%. As the first StackOverflow question to come up on the subject itself states, that's a serious "wait, what?" because if you actually got that much perf out of using fields, Microsoft would tell you. And then I had a forehead-slapper: I was running my stress test in debug mode. Properties are just a syntactic sugar for methods, and while they're aggressively inlined by the JIT compiler, debug mode doesn't perform those optimizations to let you set breakpoints on them. When I ran the stress test in the Release configuration, not only did the difference between the new and old timings disappear, the base test case went to 3.3 ms/frame-- in other words I think I'm in the clear to stop worrying about perf.

    That said, I did one more thing on the subject of object serialization, which is that I wrote a custom loader for my pooled object type that allocates an instance from the object pool rather than creating a new instance when loading that object, so objects loaded from files can also be repeatedly created (and disposed) without doing garbage-producing allocations.

    Unfortunately, I'm going to have to delay the talk of my Pokemon knock-off by another week, because trying to schedule a repairman for my refrigerator took a toll in time and anxiety for several mornings this week and pushed my retraining exercise time out of the way. However, I will share the name of an ice-type move that occurred to me and struck me funny enough that I knew I'd have to use it somewhere: Snow Flak

    The next thing I have on my list is fixing a few nuisances in my content editors. Which is standing in the way of my actually using them to make content which can be used to make games which is what I'm supposed to be doing.

    My favorite musical instrument is the air-raid siren.
  • HandkorHandkor Registered User regular
    Handkor wrote: »
    The bad guys are not going to be on roller skates but other forms of travel, I don't want to make this a world that for some reason everybody settles their differences with roller derby.
    But whyyyyyy?

    I mean, you're already investing your own dev efforts into rollerskating as a mechanic. Then, your environment is already set up for that rollerskating. Then, your player is going to get onto the rollerskating learning curve.
    It sounds to me that if there's a value to your game it'll be strongly linked to rollerskating.
    So the logical thing to me would be to make it all-skating and see if that works before adding more mechanics?

    As a worldbuilder of sorts, to me the 'everybody rollerskates' is catnip.
    Primo, it stands out. You want to have a 90ies approach to worldbuilding; it has to be extreme to the max. Going solo means you don't have anyone at the table who doesn't like rollerskating and makes it all vanilla.
    Segundo, design choices should have meaning. They rollerskate because they happen to have skates along is weaksauce. They roller skate because they were actualised as the atavistic gods of destruction in this roller-derby world, now you have meaning.
    Tertio, no plotholes or fridge logic. In any world where violence is a valid option, you need to explain why swords beat guns and skates beat monster trucks. That might be handwaved away (Dune Holtzman shields) , but it could end up with stacked piles of reasons... ex: swords beat guns because swordwielders can move faster. Fast swordwielders can't themselves carry guns because guns are too heavy to move fast. Swords are lighter than guns because they are made of unobtainium. You can't make guns from unobtainium because... it has a low melting point?

    There are of course counterarguments.
    -You can explore the sweet spot of rollerskate/monstertruck interaction and make that the strong point of your game. But the more vehicles you add, the more interaction types you get, and the less likely it is that you hit the sweet spot for all of them.
    -And, sadly, realistic games do better in today's market. But that also means you're up against every other realistic game, rather than nailing the postapocalyptic roller derby niche.

    I get what your saying but I've just started working on this idea and derisking the tech hurdles first. Gameplay mechanics comes next and then fleshing out the story and content. One of my goals is to have variety between the enemy factions to not just be palette swaps. This can lead to a section of the game where you go against a rollerskating faction but I really don't want this to be a 90s style extreme everything is focused on this one thing. Heck eScooters are more common than rollerskates today so they'd be more likely to be found in large quantities. I'd rather have the protagonists succeed because they are using a novel approach that all the enemies were not ready for.

    You've already put more thought into the world building and design than I have. I'm still just exploring some mechanics so I'm not investing much energy yet into the story, that can come later when I have all the parts that I want to be working with.

    The game is not going to be that realistic, I'm already using stylized/cartoonish looking main characters already. Realistic is too much work for a one person team and esthetics and art style come much later in my process.

    Sword beats gun is easy, guns are rare and so is ammo so only bosses/end game enemies have guns. Car and truck win against rollerskates but when the roller skater can grab onto the vehicle, suddenly the vehicle is vulnerable, especially to sticky bombs or slashed tires. Again working cars and fuel will be rare so moslty bosses or near endgame. Frankly somebody on horseback seems harder to handle than a car.

    The team is not rollerskating just because they have them, it's what they are best at.

    As for marketability, I am doing this for me and do not care about target audiences and such, this is a hobby not a source of income. But as the project progresses if it does turn out to be more fun to make it a rollerskate-a-palooza-extravaganza then it'll be easy to pivot towards that.

    Cornucopiist
  • CornucopiistCornucopiist Registered User regular
    Handkor wrote: »

    You had me at escooters.

    Handkor
  • PhyphorPhyphor Building Planet Busters Tasting FruitRegistered User regular
    "16k ought to be enough for anybody"

    So I was wondering why my compiler instance was just up and dying, so I went back and rebuilt the debug version, only to find that it had been exiting normally, and that it couldn't accept any message bigger than 16k and I was trying to send 36k of code... Although to be fair to myself I was initially planning on IPCing handles and not file contents but uh it's easier to just stuff a bunch of text in a pipe so that's what I did

    I have been doing many things in the past few months but mostly in the backend stuff

    I rewrote how I was handling all input to get the click model I wanted and reduce spurious clicks, which broke many things
    Then I decided to bite the bullet and rewrite my serialization from ad-hoc to flatbuffers and that broke many different things too
    Then I pondered how I was going to do things properly. I started writing a C++ version of the CPU & PPU as a sanity check, then I realized that I'm writing them as if I was running a normal emulator engine where you tick the CPU and that triggers bus activity and that won't work

    Because CPUs back then ran at the speed of RAM, and because they had no pipelines, RAM access was asynchronous-read, synchronous-write. This provides a very peculiar dynamic, that if you read data it is available immediately (well after some gate delays anyway) but if you write data it only has to be available at the clock edge, in other words read data depends on the address bus or specifically that an input port depends on an output port and I can't handle combinatorial cycles at all

    My testing protocol is "set inputs, evaluate, read outputs" but this is incorrect in this instance. Someone could create a design that actually passes testing because I would just provide all values anyway but if the read data is somewhere in the dependency of the address bus then the actual simulation of the whole system would fail mysteriously

    So I have to make this a component that the player connects stuff to directly, then I can pop up an error in the editor if a combinatorial loop exists. However, this isn't how hardware design languages work, so they still need to be ports when saving/loading but I have to sneakily elide them from the usual display and pretend they are ports on this entirely different component instead

    And so I rewrote my sample CPU implementation in the proper way, which turned out to be quite easy. I have a giant file with microcode entries, but to make my life easier most of those entries are either constant 0 for unreachable states (which converts nicely to a pointer) or a reference to a named local parameter that sets up all the bits in a defined way, so to create my C++ version I just make an array of function pointers, implement each of my constants as a function that looks like so
    void ADDR_ZP(NMOS6502 *cpu)
    {
    	cpu->addr = cpu->readpc();
    }
    void ADDR_ZPX(NMOS6502 *cpu)
    {
    	cpu->al += cpu->x;
    	cpu->readpcninc();
    }
    void OP_STA(NMOS6502 *cpu)
    {
    	cpu->write(cpu->addr, cpu->a);
    }
    
    and reformat the list like this
    	// 95 STA d,x
    	ADDR_ZP,
    	ADDR_ZPX,
    	OP_STA,
    	INSTRUCTION_FETCH,
    	0,
    	0,
    	0,
    	0,
    
    and boom instant cycle-precise bus-agnostic CPU

    With any luck I can probably use that to automagically generate the million test cases I'm going to need for a thorough test. Although even for that I've been thinking about how precise and picky I want/need to be. There's the first level where the instruction is implemented logically. Next level, it's implemented with the correct cycle count. Then, because it has no concept of "idle bus cycle" (yet, the 16-bit version added that) it matches the correct sequence of operations, eg RMW instructions always read the address, then write the original data back, then write the new data back. "Page crossing" instructions have a cycle that reads from an address 256 bytes away from the real address, etc. Then finally, undefined instructions are implemented (which I don't even do yet). I'd like to accept and recognize all of these as increasingly precise implementations, and probably score them amongst only peers when I get around to that

    I also created a little circuit that will let me draw text (and it flips the color each frame)! Uses features not available in the editor yet though. It's actually quite heavyweight, with 2 8-bit adders per character. It's adding constants so maybe my optimization passes are eliminating some gates but still, 23 MHz is a pretty nice result, I only need 5.4 to run it realtime and this might be roughly comparable to how big the sprite engine is
    lik0tlkmlxrv.png

    ElvenshaeIanatorHandkorCornucopiistKupi
  • KupiKupi Registered User regular
    Kupi's Weekly Friday Game Dev Status Report

    Circumstances conspired to leave me emotionally and physically drained this week (either dealing with a refrigerator that the repairman ensured me was working correctly the day before it actually died and left a puddle in my kitchen, or feeling the effects of my COVID booster shot for most of the last 24-hour period). Therefore, not much was accomplished. To make up the deficit, I'm going to make this post itself part of my game dev work by describing the premise of the game I'm working on as retraining for the job market.

    A while back in a previous game dev thread, I discussed a game prototype I'd made that used the game of Nim as a basis for a JRPG battle engine. The game of Nim goes by many names; for instance, there was a Flash game called Pearls Before Swine that made the rounds in the Internet of the late 90s/early 2000s. It's an exercise that shows up in programming interview questions and any time some video game needs a puzzle to wall the player for a little bit. The short version is that Nim is that game where you have one or more piles of tokens, and on each turn you have to pick up some restricted number of the tokens. Your goal is not to be the one who takes the last token. I felt that Nim could contribute an interesting element to a JRPG battle engine by providing a "board state" separate from character HP, MP, and status effects. In most JRPGs, what happened last turn has very little effect on your decision-making; you choose the same options round after round in an attempt to bring the enemy's HP to zero, stopping only to heal or work around a bad status effect.

    In my original prototype, events that would normally be influenced by the randomizer-- like critical hits and misses-- were instead put on a timeline of events. Every time a character (or team) took their turn, the timeline would advance by a particular amount based on what move they were using, and whatever node on the timeline they landed on would affect the outcome. If you landed on a critical hit node, then the attack would be a critical hit. If you landed on a miss node, the attack would miss. There were also things like half-damage or bonus-damage nodes, MP cost reduction nodes, and certain moves would directly influence the timeline, like turning nodes into land mines that caused the character who stepped on them to take damage. I wrote a minimax AI to play as the enemy, and it was able to reason through the battles quite well-- too well, in fact.

    See, the timeline was generated on a fixed schedule, depending on the battle. That meant the AI was able to reason about the consequences of its decisions fifty turns out. Meanwhile, I discovered that humans (at least, the one human exposed to the game, myself) really struggle to see more than two or three turns out, especially once the timeline started to fill up with triggered effects and extra negative nodes. It worked, but it wasn't fun. So I put it into storage and moved on to other projects.

    So, lately, I decided to revisit this design with the knowledge I'd gained from the first attempt. Between the arrangement of the combat parties (in the original prototype, there was a Darkest Dungeon-style marching order) and the constantly-mutating timeline, there was actually too much "board state" for a human to handle. On the first point, a Pokemon knockoff makes a great fit for a game with one-on-one duels, so that's the direction I'm going for the framing device. And as for the timeline itself, the timeline no longer has an extensible node type, but represents a simpler, reusable state. Now, the timeline is just a randomly-generated stream of digits from 0 to 9, plus two special symbols. That is, at any given time during a battle, you see something like this:
    > 1 * 5 8 1 6 2 1 8 X 3 5 5 6 0 4 5 6 0 0 8
    

    Where the ">" represents the current head of the timeline, and the numbers thereafter approach from the right. On any given turn, you first choose to advance the timeline by 1, 2, or 3 spaces, and what the number you land on determines is which of your moves you're allowed to use. Every move has a range of numbers it's allowed to be used on; in my head, it feels appropriate for weaker moves to be available on a larger range of smaller numbers, while stronger moves are available on a narrower range of higher numbers. Or, to borrow some terms from Pokemon, you can use Thundershock on 0-4, Thunderbolt on 5-7, and Thunder on 8-9. (And the move actually has to be one of the limited number of moves you're allotted per monster to begin with.) (You are allowed to land on a space you have no moves for-- you just can't actually do anything on that space.) Therefore, your choice of how much to move the timeline ahead not only influences what moves you have available on your turn, but what moves your opponent will be able to choose from on theirs.

    There are two special symbols on the timeline, the * and the X. The * is a wildcard and always lets you use any move. The X is a penalty space; not only will you lose your turn for landing on it, you'll lose your turn just for crossing it. This produces the dynamic of the original game of Nim, with both players trying to avoid being the one to cross the X and lose a precious turn. (There's actually a third special symbol, the "taming" symbol, but that's used to add wild monsters to your team and doesn't bear elaboration at this point.)

    Because only 21 numbers exist on the timeline at once, there is a hard cap to how much the computer can think ahead of the human player. It's subject to similar uncertainty regarding the next values to come down the pike.

    So, that's the premise I'm working off of. I feel like this design avoids the excessive complication that plagued the first one, giving a human a much better shot at keeping up with the AI.

    On an unrelated note, I am making a point to be more deliberate in the use of my time. Time management has been a weakness of mine of late (and was rather involved in why I lost my last job), so I'm taking up a strategy of forward-declaring my intent for how I'm going to spend the next hour, every hour. Hopefully this will produce better results than just going wherever my heart takes me. We'll see.

    My favorite musical instrument is the air-raid siren.
    Ianator
  • PhyphorPhyphor Building Planet Busters Tasting FruitRegistered User regular
    That's an interesting turn system but who loses their turn is always "fixed"

    > 0 1 2 3 4 5 6 7 8 9 X

    (6,7,8) -> 9 because your opponent is always forced to skip
    Therefore, 5 -> (6, 7, 8) always leads to losing your turn
    (2,3,4) -> 5 because your opponent is always forced to skip
    Therefore, 1 -> (2, 3, 4) always leads to losing your turn
    Player 1 should advance 0 -> 1 and player 2 always loses their turn. Player 2 will in fact always lose their turn unless there is already a multiple of 3 numbers until the next X. Now it's possible individual move power levels can override this as the player who is losing their turn anyway has more freedom to choose and maybe the forced numbers suck but there is almost certainly a "correct" answer at any point

Sign In or Register to comment.