Architecting a collectable card game - javascript

I'm trying to learn how to program a (virtual) Trading Card Game game (similar to Magic the Gathering) in Javascript. I've read a little about MVC architecture and controllers, but it's all over my head (I don't have any formal CS education) and I'm wondering if anyone has any good links or tips about how I might learn more about code architecture at a beginner's level.
Would each "card" be represented as an object, and all the logic of the cards' rules be wrapped inside one large game engine function, or many small functions that are connected to each other?
Here's an example question:
Imagine there's a card which says, "When this card comes into play, draw a card." How should I architect the game to prepare for this situation, and how is it triggered (most efficiently)? Does the card trigger the game engine, or does the game engine parse each card that's played?
Here's another example:
Imagine there's a card which says, "All your cards cost 1 less to play." and it stays in play permanently. How does the game understand that it needs to alter its rules in this case? Is this a function which listens for card to be played and interrupts the cost? As each turn resolves, where is this rule stored? Are there variables which store the base rules of the game (global card cost modifier: 0; your card cost modifier: 0) and other variables which store those new rules which cards introduce (your card cost modifier: -1), or are these variables dynamically created by the game engine as cards alter the rules (your elf cost modifier: -2)? And how do the rules know to change when a card has been destroyed, thus removing the card's rule modification?
Is what I need a primer on listeners and events? (I don't really know anything about them, but I've seen references to them from time to time.) Could you point me in the direction of a good resource?
To be clear, I'm not trying to make a long-winded request for folks to manually Google for me; I'm blindly fumbling in the dark and asking if someone would point me to the right words or phrases to search. Thank you!

There is a very nice blog about recreating a similar card game: Hearthstone from Blizzard. Allthough it is written in C# and uses Unity as a view layer, you get a pretty good understanding of how one goes about creating a suitable architecture for such a game. A fair warning though, recreating Magic the Gathering in Javascript can prove incredibly complicated and mess with your head a lot (I have first hand experience).
Blog: http://theliquidfire.com/2017/08/21/make-a-ccg-intro/

You need to go a level deeper here and think about the "game" itself. The game you're describing will actually be built around a "state machine" which is a core CS concept you should dive into and understand before you start building.
The rules of your game are going to be a state machine and the events (cards) triggered (by being played) during your game can modify those rules. You'll want some kind of interpreter to "read" the card and to modify either the rules or the game state. And then you'll need something to iterate the game through turns and phases, reading the state and taking appropriate action.
You'll also want to learn about stacks. If your game lets players interrupt each other you'll need a way to keep track of which event should happen first because events will want to be able to affect, block, redirect other events. A stack will help you keep track of that ordering.

Related

Does CLS penalize websites using animated HTML elements?

A lot of online games use animations of HTML elements as a core gameplay mechanics. For example, a solitaire game may have a DIV element or an IMG element for every card on the gameboard. Players drag and drop these cards across the board, and the game often shows animations that last a few seconds. An example of such animation is dealing cards, i.e. distributing them from the deck to their proper places on the gameboard at the beginning of the game. This is usually done 1) without user interaction, upon entering the website, and then 2) after user interaction, upon finishing one game and starting another.
These animations are longer than 500 ms, and so (as I understand) the elements, which finish their movement after that time, count towards CLS regardless of whether the user initiated the animation or not. Moreover, the card-dealing animation that greets the user on the website is entirely counted towards CLS. This might be solved by forcing the user to interact with the website before the initial animation, but it is a bad UX, as this is an extra unnecessary and potentially annoying click for the user. There is a lot to write about it, but for now, I’ll just state that showing a (not user-initiated) greeting animation is the best UX practice in this context and it is employed by the most popular games (also those using canvas).
The websites with games based on HTML elements are quite popular, and include Solitaire, Mahjong, Minesweeper etc. Some are at the top spots in the Google search results and have hundreds of thousands of users every month. I suspect that other, non-game-related sites may also employ useful movement animations of HTML elements which are appreciated by the users. Hence, I’ll ask in general:
Do I understand correctly that such animations of HTML elements, despite being expected by the user, are misclassified by contemporary CLS measures as unexpected?
Is the intention of the designers of the CLS measures to penalize this type of website behavior? I am especially asking in terms of SEO as I suspect CLS may be used as a factor by some ranking algorithms.
It's hard to say exactly what's causing your issue without knowing how you've implemented your animations, but if you are animating or transitioning using the CSS transform property, then it shouldn't contribute to CLS because it doesn't trigger a re-layout of the page.
In general, this is a best practice for smooth animations, so I'd recommend it even if your CLS was fine.
See more details here: https://web.dev/optimize-cls/#animations

Is there a way to prevent click input from bots?

I have a javascript canvas game with pixi.js that requires a player to press a certain combination of buttons to complete a level. They basically have to press the button that matches a certain color.
It turns out that players are writing bots in python to do this task and they are getting the maxium score each time. The game is already live and users enjoy playing it so I can't really change anything gameplay wise.
So I thought about a few possible solutions but I have some concerns
Captcha between each level
Check the speed of the input
Check how consistent the input is
The captcha will hurt user experience, and there are tons of video's how to bypass it. 2 and 3 will fail after the creators of the bots understand what is happening. So I am really stuck on what I could do.
I would consider a random grace period before allowing the buttons to be clicked. this may stump some bots, but is circumventable.
Besides that, I would profile the timing of the clicks/interactions. Every time next level is requested, compare to the profile, and if they are consistently the same introduce a randomized button id, button shape (circle, oval, square, etc.), button placement (swap buttons) to avoid easy scripting. Also the font and the actual text could be varied.
I would also change the input element to <input type="image"> since it will give you the exact coordinates (if possible - I'm not familiar with pixi.js) and this will aid in the profiling.
You could also implement some sort of mouse position tracker, but people on touchscreens will not produce data for this. You could supplement with additional check if the user input is touch, but a bot would easily be able to circumvent it.
EDIT
I don't know if some library to detect other JavaScript imports and thereby detecting potential bots would be applicable. Might be one avenue to consider.
Doing something like this: Check whether user has a Chrome extension installed to verify that you are running in a browser and not in a python environment could be another avenue. It would mean that you restrict your users to certain browsers, and as a lot of other code, could be circumvented. Cost/benefit should be kept in mind here.
If everything is being run though the actual browser with some sort of headless interface it is not going to be useful at all.
EDIT 2
A quick googling of python automate browser game brings up a tutorial of how to automate browser games with python. based on a cursory glance, making your buttons move around and changing font would be effective, and even resizing the playing area "randomly" (even if you have a full screen function) may be a viable defense. Again, following the tutorial and trying to automate it using that, and seeing how to block it would be a good exercise.
You could also consider asking some students for help. This could be a good project idea for many computer studies courses that offer project based courses. It could also be a student job type deal - if you want to ensure that you get a result and a "report".
I think your approach is valid. It seems a bit excessive to add Capcha between each level, perhaps add it before the game starts.
It might be a good idea to check interval between individual clicks, and define some threshold when you can safely assume that it was a bot who clicked the button.
Another approach you could take is to make it more complicated to look up the correct buttons. Approaches like randomizing the element IDs, not rendering the label inside the buttons but as separate elements (I assume it is a game with some fixed window size and you don't care about mobile that much).
I am not familiar with Pixi.js, but that could be an approach to consider.
----------------------- Edit -----------------------
What if you run your game in an iframe ?

Creating Instances of a Parent Class with a Variable Number of Subclasses which Modify the Parent Class

As a beginning note, I'm writing a discord bot with Discord.js. And sorry for the potentially confusing title.
The basic functionality of the bot is that it helps multiple users play card games together, say for example Go Fish.
I'd like to eventually add the functionality for server admin to write and add their own "mods," (modifications) to spice up whatever game they'd like. In this case, someone could make it so that the game would require either 4 or 2 cards to complete a set in Go Fish, depending on if the mod is enabled for a specific instance of the game, or perhaps modify the drawCard() method to continue drawing cards until the player gets a card they already have at least one of. (or honestly do whatever with the original game, doesn't matter.)
As of my current code, I have a few basic classes, with a specific class coreGame, and then different "base games" which extend coreGame, providing basic functionality for all types of card games. When a user wants to play a game, I won't know which mods are available, since they're server-specific. The best I think can do is create a new instance of baseGoFish (My original, unmodified implementation of the base game which isn't server-specific)
I'm thinking that mods would extend the base game, like class modExample extends baseGoFish {...}, but I'm not sure how I would create an instance of the modded game, and even less sure if there were multiple mods.
As another note, I think have to call mods' methods twice, once before the base game's actual code, (so that it can choose to cancel the base game's methods, as if it were an event, or do its own thing unrelated to the base game), and once after, so that mods could edit what the base game just did. This specific part seems pretty jank and likely to break, so what would be a better solution here as well?
I've looked briefly into mixins, and those seem like they'll help here, but I'm unsure of how to properly implement them, as I've never used them before (much less used javascript with classes.)

Gameloop wont match css animation

(I'm trying to make a basic space invaders game)I'm very new to coding so this might be a total mess, however, I'm using gameloop(s). One of them is moving the hero, one is moving the missiles, and drawing them. However, I can't seem to split them. I want to split them up so I can change the setTimeout, but it doesn't want to split up.
Tried to split them up by making a gameloop_1();, but that wouldn't move the missiles... sooo... I'm lost
var missiles = [];
function drawMissiles() {
document.getElementById('missiles').innerHTML = ""
for (var i = 0; i < missiles.length; i++) {
document.getElementById('missiles').innerHTML += `<div
class='missile1' style='left:${missiles[i].left}px;
top:${missiles[i].top}px'></div>`;
}
}
function moveMissiles() {
for (var i = 0; i < missiles.length; i++) {
missiles[i].top = missiles[i].top - 15
}
}
function gameLoop() {
setTimeout(gameLoop, 950)
moveMissiles();
drawMissiles();
moveFiende();
drawFiende();
collisionDetection();
}
function gameLoop_1() {
setInterval(gameLoop_1, 100)
moveMissiles();
drawMissiles();
}
gameLoop();
gameLoop_1();
What happens when I split them up, is as I said; The missiles won't then shoot.
Disclaimer:
If you expect an answer for your specific code here, you'll be disappointed, so if you do not intend to start from scratch or something like that, I'm sorry for the whole text.
I think you're misundertanding the purpose of a Game Loop.
There are some things wrong with your code, but I'll stick with the basis of your question, which also happen to be the basis of every game, the Game Loop.
Frames
Let's start with Frames. You probably know what a Frame is. It is like a drawing on the screen of a single moment in time. For example, when you watch a movie, you're actually watching a lot of pictures (frames) being drawn very fast, one after another, which gives the illusion of movement (usually 30 "pictures" per second).
The Game Loop
The Game Loop is the responsible for drawing the frames of the game, one after another, it executes functions, methods, changes variables and based on the results, it finally draws on the screen what is happening on the game.
The Game loop is basically what makes everything in the game possible to happen, it's like what time is for us in real life: without time passing, there would be no past, present or future, we would be stuck in a single frame forever.
The same happens on a game, withou a Game Loop, there would be no iterations, nor changes or frame updates.
Extremely basic game structure
Knowing that, the first thing you must do is always having a "central" game loop, and never split it. Always name other methods as "updates" and call them from the master game loop.
So a most correct structure for your code would be (this is just pseudocode similar to js, not any language in particular):
SpaceInvaders = {
GameLoop(){
UpdatePlayer();
UpdateProjectile();
UpdateEnemies();
setTimeout(GameLoop, 16) // to call the loop each 16ms, thus giving you 60fps
}
UpdatePlayer(){
// do stuff like move the player and fire
}
UpdateProjectile(){
// do stuff like move the projectile and check if it hitted something
}
UpdateEnemies(){
// do stuff like move the enemies
}
}
SpaceInvaders.GameLoop();
If you want to have a more in depth look on Game Loops, please check this amazing article, it helped me a lot when I was starting my first HTML5 canvas game:
https://isaacsukin.com/news/2015/01/detailed-explanation-javascript-game-loops-and-timing
You'll be presented with the hardware compensation problem that comes as consequence of the Game Loop and some other interesting stuff.
Your situation
Now that the Game Loop principle is better explained, let's talk about your specific situation a little more. There are 3 main things that pop into my eye:
First of all, I don't think that it is going to be a good experience to try making a game using only HTML concatenation and CSS, if you really want to do it from scratch all by yourself, I hardly encourage you to try making a game using HTML5 canvas. For me it was a great experience to learn the very basics of game development. As I look back now, tho, I see how my code sucks (used vanilla js, and compensated the hardware by hand on each frame in all moving entities). If you want to see this project done:
https://github.com/diguifi/littlejsworld
Second, you're not working with objects, that's going to make the code very messy in later stages of development and very hard to work with (even if it's just space invaders). What I mean by objectifying your game is, for example: instead of loose methods for "drawMissiles" and "moveMissiles" you should have an object called "Missile" and another called "Player".
The Missiles would have such methods ("draw" and "move", accesible via "Missile.draw()") and the Player would have a list of Missiles (this is just an example, you must use objects for everything in your game, in order to have a well designed project).
And third, seems to me that concatenating divs on innerHtml of an element from the DOM is not a good thing to do, it's very costly, ugly and time consuming.
My suggestions
If you want to make this game as an exercice for learning the basis of game development, I think you should start from scratch using only a canvas element and center your code efforts on the javascript, not messing with html elements to create the game. There are many articles and docs to help you in this task, such as the one I mentioned that talks about game loop.
If your goal is just to make a game, without having to understand basic problems, you should try a game engine, such as:
Godot: a free, easy and lightweight engine to create games, no need to worry about game loop here.
Phaser: code with js, without worrying about game loop management and many other basic stuff.
Unity: code in C# but not so much code is needed
Game Maker Studio: no coding needed, only basic programming logic
Construct 3: same as Game Maker, maybe easier

Advice on specific Web Based 3D Game Development

I'm relatively new to HTML and Javascript, but I'm knee deep in the Udacity interactive 3D course and have gotten my hands dirty with some three.js + WebGL. And I've been able to make and somewhat understand this:
http://goo.gl/UPWKKL
So far.(having a hard time understanding the API and getting cannon.js and really any interesting mechanics to work, any advice for learning APIs like threejs?)
I was wondering if anyone could provide any input for someone whose end goal is to make a game that is somewhat like a demi-version of: REZ, Exteel, Armored Core or Zone of The Enders versus mode.
My goal is implementing: rail shooting(w/ cannon.js?), health bars, NPC boss battles with different stages, animated movements, a cross-hair, level bounds, concepts of upgrades to a character.
To be really specific, a 5 level game with PointerLockControl + shooting interface, where each level pass requires bringing a boss' health bar down to zero. The enemy would have a vulnerable mesh area where if bullet objects hit it, it'd trigger a collision event where its health decreased. If health<= 25 it speeds up and becomes harder to kill. After its death the screen blacks out and restarts with a new boss and so on. I'd want to put in victory screens, failure screens and if possible, cut scenes where I guess I'd disable user control and enable some kind of path cinematic camera. And preferrably for this to all be in the browser like Quake, BUT if something like this isn't possible, I'd try something else.
Sorry if this question is too broad or weird, I want to work on video games for a living, I will appreciate any feedback I get, I just want to know if someone more experienced can look at what kind of game I want to make and recommend some up to date material or helpful sites.
Currently I'm working with webGL and threejs, I've looked into Unity3D but I can't develop that on my Linux machine. Far FARR down the line I'd like make full blown games in C++.
Design as specifically as possible, because then you will have lots of small tasks whose role in the greater whole is known. Then if you don't know what to do on any given day, just look at your design, your map, and pick a piece that you can do that day.
Sorry if this answer is not specific to WebGL but you have asked broadly.

Categories