Live data from Hacker News

A Pokémon battle simulation engine

github.com

41–49 of 49 posts

Re: A Pokémon battle simulation engine

#41

This is strange - this post is on the front page right now. It says that I submitted it eight hours ago. I was asleep eight hours ago. I submitted this last week and it did not get any points hardly but now it is on the front page with an incorrect timestamp but still attributed to my user account.

Second Chance Pool: https://news.ycombinator.com/pool Many submissions get overlooked the first time and then get nominated for a second chance.

I think the second chance pool is great but why rewrite the metadata with false info? It just confuses everyone. This isn't the first, and it won't be the last.

Re: A Pokémon battle simulation engine

#42
post #8

Earlier quoted context omitted.

I get that permissive licenses are popular now, but “freedom to make sure other people don’t have freedom” still doesn’t feel like a compelling argument. In specific cases, they make sense purely practically; but generally? It feels like a huge error for the whole world to leave copyleft and the GPL behind. The reason we can run Linux on everything is because Torvalds chose the GPL, and so vendors are forced to share…

GPL makes sense in a context where that sort of vendor compatibility creates existential conflicts for the product. For an operating system and associated toolset, it is clearly an excellent license and does great work encouraging the necessary cooperation from otherwise unwilling partners. Games are a different beast. For one, the dominant revenue model for videogames continues to be to sell copies of the software,…

If I make a game with SDL then I am not the user of SDL, I am an intermediary between the people who develop SDL and the player who eventually uses SDL in interacting with the game. Calling people who distribute libraries with their programs users instead of reserving that term for the people who actually use the programs with the included libraries is just wrong. If a farmer sells oranges to a supermarket and the supermarket then puts those oranges in baskets together with other fruits and then sells those fruit baskets you wouldn't call the supermarket the consumer of those oranges.

Re: A Pokémon battle simulation engine

#43
I would love an ncurses battle simulator where you would choose the monsters with perfect EV and IV's (maxed stats) with any attack the monster supports (either by level or TM's) and you would just fight against a series of trainers a la Battle Tower or similar.

You would get the actual fun of Pokémon battles without grinding. And, yes, I know emulators with fast forward and so on, but even Pokémon Radical Red has mechanics on purpose to send grinding to /dev/null with dumb battles against Audinos in order to get EXP like craze.

BTW, Pokémon Unbound might be the best hackrom ever because of the environment and features, but when you just want to fight, an straight offline simulator would be much better.

Re: A Pokémon battle simulation engine

#44

As an avid Pokemon Showdown player, this caught my eye: > In the case of Pokémon Showdown, only bugs which stem from a misimplementation of specific effects are reproduced in the engine, bugs which are the result of a misunderstanding of the fundamental mechanics of Pokémon or which simply arise due to specific Pokémon Showdown implementation details that aren't replicable without making the same (incorrect) architec…

Pokémon Showdown was written to simulate interactions that occur in Generation V (which was modern at the time) based on the (very rough) understanding of mechanics that we had 15 years ago. Every other generation was then shoehorned to fit into this architecture (which isn't actually even correct for Generation V). While this kind of works for modern generations, Generations I and II were quite a bit simpler. e.g., what Pokémon Showdown deems as the "residual phase" does not exist in Generation I & II, and this results in an incorrect ordering of events compared to the cartridge implementations. https://github.com/pkmn/engine/blob/main/src/lib/gen1/README... goes into detail about what Pokémon Showdown-specific behavior is currently unimplementable in Generation I (though binding moves like Wrap have actually been fixed on Pokémon Showdown and there's a branch that should update this section to account for that).

Re: A Pokémon battle simulation engine

#45

Combining Zig and TypeScript sure seems like a funky way of developing software, but on the other hand it does expose the API to a wide variety of FFIs (with browsers being a major one here). I wonder if the performance numbers stay up like that as the project matures and actual game logic gets implemented. I'm a bit surprised to see a patch for the Zig compiler itself in the source tree, though. I thought manually p…

Most existing Pokémon projects are written in JS/TS, Python, or C#. This engine is targeted primarily towards AI projects (https://pkmn.ai/projects/) where speed is of the utmost importance, hence a low level language like Zig shines (C/C++/Rust were also considered, Zig was actually the last choice here, it just ended up being the best one). TypeScript is convenient because its a decent scripting/glue language and plays well with the existing Pokémon Showdown codebase for easy integration testing.

The performance numbers for Generation I will not change as other generations get implemented (by design), and Pokémon Showdown will likely fare better as the game logic gets more complex but I would still expect at least a 1000x difference in performance even for modern generations - the things that make Pokémon Showdown slow do not go away as the generations increase, there is just perhaps less irrelevant stuff happening in later generations to slow things down.

The Zig patch in the source tree is optional and for performance reasons... but a ~20% performance boost is hard to pass up. This is not a general purpose patch, it is only relevant to this project which makes heavy use of sub-byte integers and has a very very comprehensive testing suite to ensure that the undefined behavior that could occur if this patch were applied and used to compile arbitrary Zig problems are not an issue.

Re: A Pokémon battle simulation engine

#46

I like that it has a C API (although it uses opaque data without any real way to initialize it other than just storing it in the program, which doesn't seems like very good to me), and had wanted that before, although I would have preferred one that is written fully in C rather than Zig. (Actually, I did start to write some ideas (including some parts of a .h file) about the structures and functions that the C API sh…

The C API provided here is unquestionably anemic, though perhaps makes more sense when understood to exist more to facilitate bindings written in other languages (Python, C++, Rust, etc) and not as an API intended to be used by developers setting out to write an application in C. The two main reasons the C API kind of sucks is that (1) C does not support namespaces/modularization (2) C does not have convenient standardized bitfield support that works cross platform. Finally, I can't really imagine someone wanting to leverage this engine from C and balking at spending an afternoon writing a friendlier wrapper API specific to their use case. That being said, if you have suggestions for improvements please open an issue on GitHub to discuss it.

Team validation is an an orthogonal problem, and is almost completely solved by PKHeX (https://github.com/kwsch/PKHeX) which already does a better job at it than the original game developers. Pokémon Showdown's custom rules are almost all enforced at team validation time, and the standard clauses/rules which require modifications to the engine (e.g., EBC, Sleep/Freeze Mod, Desync Mod) are all supported already by this engine when -Dshowdown compatibility mode is enabled. Your other requests (Unown/Spinda/PP UPs) are all client concerns and thus would be implemented at a higher level than the engine shared here. Your switching scenario will also be handled whenever the generations it is relevant to get implemented. Pokémon Showdown already supports the concept of "maybe trapped" so presumably handles the scenario you're detailing, though if not I'm sure they would appreciate being made aware of any bugs that might exist.

Re: A Pokémon battle simulation engine

#47
post #46

I like that it has a C API (although it uses opaque data without any real way to initialize it other than just storing it in the program, which doesn't seems like very good to me), and had wanted that before, although I would have preferred one that is written fully in C rather than Zig. (Actually, I did start to write some ideas (including some parts of a .h file) about the structures and functions that the C API sh…

The C API provided here is unquestionably anemic, though perhaps makes more sense when understood to exist more to facilitate bindings written in other languages (Python, C++, Rust, etc) and not as an API intended to be used by developers setting out to write an application in C. The two main reasons the C API kind of sucks is that (1) C does not support namespaces/modularization (2) C does not have convenient standa…

While there are problems with the C programming language, in my opinion the other programming languages that they tried to make it better, often has their own problems instead, so I still find C to be better anyways.

I probably would not expect to use your program, although I had these suggestions anyways, since it would make sense to be improved even if other implementations also exist. However, I do think that your program does many things better than Pokemon Showdown does (I dislike much of the design of Pokemon Showdown), and the stuff you have written may be helpful when making a different one, if as you say, there are problems with the implementation in Pokemon Showdown.

Having a separate structure for active and inactive pokemons is good that what you have, and is what I had thought should be done also and, reading your documentation, I found out that Pokemon Showdown doesn't do that.

If I write one, I also would want to be more targeted in scope than the official games and Pokemon Showdown, although my scope would be a bit more than you have. What you did may be OK for your uses, although not quite what I wanted to make. I also intended to be more flexible in some ways; this might be slower than yours but would probably be faster than Pokemon Showdown.

> Team validation is an an orthogonal problem, and is almost completely solved by PKHeX

OK, although PKHeX is now another different programming language (C#), and the programs have their own dependencies (in that case, C# 13 and .NET 9.0), while your program also has the dependencies (a Zig compiler, which must be older than a specific version, and also JavaScript code).

> Your other requests (Unown/Spinda/PP UPs) are all client concerns

PP Up does affect the team definition and the game behaviour (it affects such things as e.g. whether or not Struggle is a legal selection). However, at least in the case of generation I, this might not be relevant if you allow starting the battle without being fully healed (if, as you mention, your library does not do team validation). For some later generations, it might be significant if PP can be recovered during battle in some circumstances.

If your program expects the client to decide whether or not teams are revealed, then you could say that my things about Unown and Spinda are client concerns, although I would have the battle engine to specify by the API that some things are exposed, in order that the caller does not have to know what is supposed to be exposed according to the specified rules.

> our switching scenario will also be handled whenever the generations it is relevant to get implemented. Pokémon Showdown already supports the concept of "maybe trapped" so presumably handles the scenario you're detailing

This is OK, then.

Re: A Pokémon battle simulation engine

#48
post #46

Earlier quoted context omitted.

The C API provided here is unquestionably anemic, though perhaps makes more sense when understood to exist more to facilitate bindings written in other languages (Python, C++, Rust, etc) and not as an API intended to be used by developers setting out to write an application in C. The two main reasons the C API kind of sucks is that (1) C does not support namespaces/modularization (2) C does not have convenient standa…

While there are problems with the C programming language, in my opinion the other programming languages that they tried to make it better, often has their own problems instead, so I still find C to be better anyways. I probably would not expect to use your program, although I had these suggestions anyways, since it would make sense to be improved even if other implementations also exist. However, I do think that your…

> I still find C to be better anyways.

Whatever floats your boat, programming language wise. People tend to focus too hard on languages and forget they're really they're just a tool to build cool things.

> What you did may be OK for your uses, although not quite what I wanted to make

Totally understandable - engines are hard to be perfectly general because of the various tradeoffs and constraints involved. If my work and documentation helps make it easier for future developers to write their own engines that better suit their needs that's still a plus in my books.

> OK, although PKHeX is now another different programming language

You'd probably just stick it behind a simple API and run it on a server if you wanted to host a full blown simulator in the spirit of Pokémon Showdown. Or if you want it client side you can just write your client in C# (pretty common for games) and then link in the engine separately (you don't need a Zig compiler, just grab the release).

> while your program also has the dependencies (a Zig compiler, which must be older than a specific version, and also JavaScript code).

This is a misconception, hopefully careful reading of the documentation would reveal this to not be the case? The engine itself does not require JS (it is a development dependency - you don't need to be able to run the integration tests to use the engine) and works perfectly on every version of Zig since 0.11.0 (which is no small feat), it just is faster on older versions, thus those are recommended.

> PP Up does affect the team definition and the game behaviour (it affects such things as e.g. whether or not Struggle is a legal selection).

Pedantically, PP, not the number of PP Ups impacts whether or not Struggle is a legal selection (or even more pedantically, PP plus things like whether a move is Disabled/Imprisoned etc impact whether or not the Pokémon will Struggle).

> For some later generations, it might be significant if PP can be recovered during battle in some circumstances.

Yeah, in Generation III and onward I believe it will become relevant to store the number of PP Ups applied (due to the introduction of the Leppa Berry) whereas in Generation I and II only the total PP is required (MysteryBerry exists in Generation II but since it always restores 5 PP when PP reaches 0 and no move that can have its PP restored has less than 5 PP this is still safe).

> although I would have the battle engine to specify by the API that some things are exposed

This additional bookkeeping slows down the engine. A design principle of the engine is that if something can be pushed to the client it will be. This makes using the engine much more tedious, but means the engine will be as fast as possible which ultimately makes it viable for a wider array of use cases.

Re: A Pokémon battle simulation engine

#49
post #44

As an avid Pokemon Showdown player, this caught my eye: > In the case of Pokémon Showdown, only bugs which stem from a misimplementation of specific effects are reproduced in the engine, bugs which are the result of a misunderstanding of the fundamental mechanics of Pokémon or which simply arise due to specific Pokémon Showdown implementation details that aren't replicable without making the same (incorrect) architec…

Pokémon Showdown was written to simulate interactions that occur in Generation V (which was modern at the time) based on the (very rough) understanding of mechanics that we had 15 years ago. Every other generation was then shoehorned to fit into this architecture (which isn't actually even correct for Generation V). While this kind of works for modern generations, Generations I and II were quite a bit simpler. e.g.,…

Oh damn, as a deep gen 1 player, this was unknown to me. I now understand what startup clients feel when a startup is built exactly around them.

", Wrap does 0 damage against Ghost-type Pokémon instead of properly respecting immunity, "

This was the only significant effect I could find, it would change dragonite and wrap.

I think it would be a nerf, but it may be a buff. Wrap is also used as a kind of u turn, but it works both ways, currently you can use gengar to pivot vs wrap.

I think this would nerf dragonite as he wants to pivot away from gengar, and buff arbok, as it would allow glare-EQ vs gengar, even if they have psychic.

Not massive, but you never know what butterfly effects bugs like these can have, or even unknown interactions, we learned from the Body Slam 2015 revolution that for metagames so advanced small changes can have profound implications.

Finally, while the project is cool, selectively patching the most key feature (which in competitive games and in Smogon is decided by prioritizing high elo votes) would make for an interesting concession

Post reply on HN