Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Shalinor posted:

I wish it at least allowed baking SH in a room, then saving that off as a prefab to spawn elsewhere later, but nupe.
You could theoretically do this with a pile of editor or runtime hacks, since you CAN manually modify the SH coefficients. You can rotate the SH vector if you need to as well, but the coefficients have weird weightings applied to them. Oh and if you modify a SphericalHarmonicsL2 off of the main thread, it throws an exception, even though it's just a blob of floats. :iiam:

Adbot
ADBOT LOVES YOU

Ranzear
Jul 25, 2013

I still think Dishonored has the worst art direction of any modern era game.

Every guard looks exactly the same, and not even to really benefit game mechanics. Everybody wears exactly the same clothes, which all look bolted on because of absolutely no cloth physics (notice all the women wear pants or less because of this, even the hookers and maids). Everybody has the same gaunt cheeks and flat dark hair except maybe Samuel, and they're either clean-shaven or chinstrapped. I get that it's a parallel to industrial age London, but that still gives more options than navy blue wool and/or off-white linen. Oh wait, that guy in the brothel had a red vest, because he was important I guess. That's about where I stopped paying attention.

The lore, story, and gameplay is great. The art is loving bland and actually ruined the game for me, because it's like half their art team quit or were fired six months into development. Normally art is a non-factor to me, but holy poo poo the characters are about as differentiated as chess pieces, except those at least come in two different colors.

I set aside the thought of Dishonored actually being a Thief homage far before it actually came out, so my expectations were low. You don't have to tell me my opinions are poo poo, because all I've seen of this game since playing it at release has been speedruns and I didn't touch the follow-on DLCs and whatever. It's the only game I have this problem with.

I could take screenshots of most of the characters in the game, blur them a bit and cut out the background, and you could not possibly tell me which was which with any consistency...

Ranzear fucked around with this message at 23:58 on Oct 14, 2016

Yodzilla
Apr 29, 2005

Now who looks even dumber?

Beef Witch
That's honestly the saltiest I've ever heard someone speak about Dishonored. Not saying your opinion is wrong but drat that's some strong hyperbole, especially in a world where Battleborn exists. :v:

I think Dishonored's NPCs are incredibly similar and samey looking in the face. I didn't notice the lack of cloth physics (for some reason I thought D1 was built in Source but I was wrong apparently!) but I absolutely love the costume and environmental design.


e: and I doubt you'll play them but I just played through Dishonored's story DLC and it might be some of the best additional content I've ever experienced in a game

Ranzear
Jul 25, 2013

Yeah, I know the DLC is really good. It's an opinion built long after actually playing the game and while watching my brother play it or speedruns. It's much harder to ignore when you're just a spectator. It's the crazy disconnect between intent and result that gets me in one particular instance: The maids. They're in black with white frills like the intent was 110% French Maid, but they're wearing loving breeches and working in a bar.

That the gameplay is good enough to distract from that is nothing but praise.

Unrelated:

I just chased the dumbest thing in circles for about an hour. Let's see if anyone else can spot the issue:

A player entering a room is put in a queue stored in the room object for whichever door they're coming through with a 500ms countdown.
The room simulation step subtracts the 'last run' timestamp stored on the room object from the current time for a delta and steps the room that far, which also counts down the room entry queue.
When their entry queue reaches zero, they're placed in the room at the door they entered via.
Rooms can be unloaded from the worker back to the head when all players leave, and dispatched back to a worker when a player reenters that room.

Why was the entry queue getting skipped on room reload, breaking my nice zelda-slide transitions?

Ranzear fucked around with this message at 02:33 on Oct 16, 2016

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Ranzear posted:

A player entering a room is put in a queue stored in the room object for whichever door they're coming through with a 500ms countdown.
The room simulation step subtracts the 'last run' timestamp stored on the room object from the current time for a delta and steps the room that far, which also counts down the room entry queue.
When their entry queue reaches zero, they're placed in the room at the door they entered via.
Rooms can be unloaded from the worker back to the head when all players leave, and dispatched back to a worker when a player reenters that room.

Why was the entry queue getting skipped on room reload, breaking my nice zelda-slide transitions?
A few possible problems from the description:
"Reaches zero" might exclude "already passed zero".
If the only player in a room leaves and enters simultaneously (as "reload" might describe), unloading might occur after dispatching to a worker.
It's unclear whether "all players leave" includes players in the entry queue, or just players actually in the room. (Similarly unclear, whether "reenters" refers to the post-queue entry or the pre-queue entry.)

Ranzear
Jul 25, 2013

You hit everything I thought of at first.

roomforthetuna posted:

"Reaches zero" might exclude "already passed zero".
Most of my decrements use a Min(value,decrement) pattern, but I was checking <= anyway.

roomforthetuna posted:

If the only player in a room leaves and enters simultaneously (as "reload" might describe), unloading might occur after dispatching to a worker.
Rooms stay active, simulating frames, for ~1.25 seconds when the worker has zero players assigned to that room, the issue only happens at least 500ms after this timeout.

roomforthetuna posted:

It's unclear whether "all players leave" includes players in the entry queue, or just players actually in the room. (Similarly unclear, whether "reenters" refers to the post-queue entry or the pre-queue entry.)
That's actually something I'll have to look into, if a room can get unloaded while someone is in an entry queue, but each player object stored in the worker has a room assignment and it counts these room assignments rather than anything in the room, so I'm pretty sure it's safe.

It wasn't a problem with the entry queues (though I came to discover it when I shuffled the order of room sim and entry queue) More clarity: When a room is active, the main thread only tracks what worker it's assigned to. When a room gets unloaded back to the main thread, it gets put in an inactive set that stores the entire room object for dispatching to any worker later. The main thread doesn't run any room simulation on inactive rooms...


Edit: I won't drag this out - When a room was reloaded from inactive, it's last timestamp was from way back when it was first unloaded, so the room was getting simulated for the entire time since, including the entry queue timeout. I'm just surprised there weren't huge lag spikes as it did hundreds of frames at once. The solution was to set the last run timestamp to 'now' on reload.

Ranzear fucked around with this message at 22:19 on Oct 16, 2016

22 Eargesplitten
Oct 10, 2010



Is there a way to set up pathfinding for a 2d game? The built in navigation won't accept sprite renderers, just mesh renderers. I've been trying to write my own pathfinding, but I feel like there should be something simpler.

E: It looks like A* wouldn't be right. It's not really pathfinding so much as it is choosing a random direction to go once it hits a node. I'd also need to be able to handle collision with other non-statics, but I would think that was a pretty standard part of pathfinding.

22 Eargesplitten fucked around with this message at 22:54 on Oct 16, 2016

Yodzilla
Apr 29, 2005

Now who looks even dumber?

Beef Witch
Are you talking about top-down/isometric 2D or side scrolling?

22 Eargesplitten
Oct 10, 2010



Top-down 2d. I'm remaking this.

E: If someone wants to take a look at what I've done by hand, I can show it, but it's kind of a mess of poo poo that I tried, didn't work, and then kept throwing stuff at the wall to see if it stuck. It's really not working well, so I want to scrap it and start over rather than just plastering over the holes.

22 Eargesplitten fucked around with this message at 02:44 on Oct 17, 2016

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

22 Eargesplitten posted:

Is there a way to set up pathfinding for a 2d game? The built in navigation won't accept sprite renderers, just mesh renderers. I've been trying to write my own pathfinding, but I feel like there should be something simpler.

E: It looks like A* wouldn't be right. It's not really pathfinding so much as it is choosing a random direction to go once it hits a node. I'd also need to be able to handle collision with other non-statics, but I would think that was a pretty standard part of pathfinding.

Just use A*..? It most certainly is pathfinding.

I don't know what rendering has to do with search.

22 Eargesplitten
Oct 10, 2010



Sorry, bad phrasing. I just want the enemy to pick a random adjacent node and go to it. Should I just do A* for each time, despite it always simply being move in a random direction? Just pick the target at random? That actually makes some sense now.

Unity has a built in navigation tool, but unless I missed something it doesn't work with objects that have a sprite rather than a mesh. So it won't work with a lot of 2D assets.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
If the node is adjacent any kind of pathfinding sounds excessive. Why can't you just, you know, pick the node and move?

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

22 Eargesplitten posted:

Sorry, bad phrasing. I just want the enemy to pick a random adjacent node and go to it. Should I just do A* for each time, despite it always simply being move in a random direction? Just pick the target at random? That actually makes some sense now.

Unity has a built in navigation tool, but unless I missed something it doesn't work with objects that have a sprite rather than a mesh. So it won't work with a lot of 2D assets.

A* will not return a random result. You need to a-priori have some utility function to feed into it. If the conditions of the path could change, yes you would want to run it again. If you're looking for a random result, just use rand().

Linear Zoetrope
Nov 28, 2011

A hero must cook
For 3D modelling for characters in games is it more common to sculp a high poly model and then retopo the finished product into a saner lower-poly version, or model from the ground up into your poly count with, e.g., box modelling or whatever?

leper khan posted:

A* will not return a random result. You need to a-priori have some utility function to feed into it. If the conditions of the path could change, yes you would want to run it again. If you're looking for a random result, just use rand().

If the conditions of the path could change, use D*-Lite, which is relatively straightforward to implement and is basically A* with the ability to do cheaper recomputation of paths. There is a caveat that it gets a bit more expensive if the change is closer to the goal node, but it should still do better than A* in the general case in these scenarios.

The other solution is two-tiered pathfinding, where you use A* to select a general path, and steering behaviors or potential fields or whatever to move between the nodes while avoiding obstacles, but that's a bit more involved. (The idea is basically to create invisible waypoints with a "pulling" force and obstacles with a "pushing" force, and delete the waypoints when you reach them or at least get close, it takes some massaging to look natural).

Linear Zoetrope fucked around with this message at 08:31 on Oct 17, 2016

Surprise T Rex
Apr 9, 2008

Dinosaur Gum

Jsor posted:

For 3D modelling for characters in games is it more common to sculp a high poly model and then retopo the finished product into a saner lower-poly version, or model from the ground up into your poly count with, e.g., box modelling or whatever?

The general idea last time I did any 3D (3 years ago or so?) is that you build a low-poly version, and then after that you build all of the extra detail in on a high-poly version. You bake the higher insane-poly version to a normal map, usually, and apply that to the low poly model.

floofyscorp
Feb 12, 2007

Jsor posted:

For 3D modelling for characters in games is it more common to sculp a high poly model and then retopo the finished product into a saner lower-poly version, or model from the ground up into your poly count with, e.g., box modelling or whatever?

It varies, but generally we start with the high-poly sculpt - basing it off poly-modelled basemeshes where needed - and retopo afterwards.

HaB
Jan 5, 2001

What are the odds?

22 Eargesplitten posted:

Top-down 2d. I'm remaking this.

E: If someone wants to take a look at what I've done by hand, I can show it, but it's kind of a mess of poo poo that I tried, didn't work, and then kept throwing stuff at the wall to see if it stuck. It's really not working well, so I want to scrap it and start over rather than just plastering over the holes.

I wouldn't call anything the enemies in that game are doing "pathfinding". It's pretty much just: "at each junction, randomly turn right or left. If you hit a wall directly, add reversing as an option"

Pathfinding would be if they were actively seeking the player, but it's clear they aren't from the video.

But as already stated, A* isn't random at all. The nodes are weighted, so that higher weighted ones have a better chance of being picked. You would do something like: write a function that determines the general direction the player is in, and weight the adjacent nodes more in that direction. Recompute that function every X player moves. That would make your enemies seek out the player, but again - if you are shooting for a remake of what's in that video, that is definitely not going on.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I need to think out loud here about integrating a GUI into my actual game. My control code is tightly-coupled to player control, and I want to separate it now that I have a GUI to go with it. The defect that is forcing this the game unpausing if the player hits the back button to escape a submenu off the main menu. It should wait until the player backs out of the main menu, not just any menu. I did see it coming though.

I was thinking of doing something like a stack system where control is given to the top of the stack, and the stuff lower on the stack sees nothing. I suspect Unity's GUI system handles this already with the new GUI system. I'll be finding out if it can do a basic blocking dialog box soon. I just need a similar system to transition between in-game and paused GUI interaction.

Even without having a button to bring up my main menu, I have to deal with the player wanting to look at their inventory. The game is paused, but the player would still say they're actively playing the game there. The code to manage that also looks like poo poo since it's crammed into player control. So I figured I'd have the inventory push onto the stack, steal player control, and then relinquish it when it pops off the stack.

Each element that wants to receive player control has to take events to be notified when they are gaining and losing control. So in-game, the player may chose to pause, but the player control code doesn't actually do the pausing. Something else receiving for notification that it has lost control on the stack will manage it. It might be in the same source file--it might even be a method in the player control--but it won't be an if-else condition in Update().

I'm assuming I'm on the right track here and will work off of this, but I wanted to air it out for any suggestions before I paint myself into a worse corner.

22 Eargesplitten
Oct 10, 2010



HaB posted:

I wouldn't call anything the enemies in that game are doing "pathfinding". It's pretty much just: "at each junction, randomly turn right or left. If you hit a wall directly, add reversing as an option"

Yeah. I just wasn't sure what else to call the logic telling the enemies where to go Turn left, right, or go straight is pretty much what I have, but when they hit each other, if a third ship gets involved in the collision they just all get jammed up. When I'm at a computer I'll either edit in the relevant code or reply with it. I feel like the colliders might be hitting each other quicker than the game can handle for some reason.

Explosive Tampons
Jul 9, 2014

Your days are gone!!!
Does the original game has ships passing through each other when they collide (aka they don't)? You might want to do that to simplify your life. You might not even need to handle background\object collisions depending on how you're remaking the game, actually... it feels like you can just run simple grid based logic for that.

Also, semi-random enemy movement can be pretty convincing, esp. on the type of game you're making... take a look on how Pac-Man did it, it might interest you if you want to do a tweaked AI mode without adding too much complexity to your project. Check out this article, it might give you good ideas for both collision and AI.
http://gameinternals.com/post/2072558330/understanding-pac-man-ghost-behavior

Explosive Tampons fucked around with this message at 03:08 on Oct 18, 2016

Triarii
Jun 14, 2003

22 Eargesplitten posted:

Yeah. I just wasn't sure what else to call the logic telling the enemies where to go Turn left, right, or go straight is pretty much what I have, but when they hit each other, if a third ship gets involved in the collision they just all get jammed up. When I'm at a computer I'll either edit in the relevant code or reply with it. I feel like the colliders might be hitting each other quicker than the game can handle for some reason.

Looking at that video, I don't think they're colliding, exactly. Rather, it looks like each ship checks whether there's another ship directly in front of them, and if so it reverses direction before the collision happens. You could disable collision between the ships entirely and just do that with a short-distance raycast or spherecast (I guess that's a CircleCast in 2D).

Chernabog
Apr 16, 2007



I have a cannon sprite that is working mostly fine, except that if I activate it twice before the "cannonActive" animation is over it won't reset to the "cannonStatic" (idle) and will stay on the "cannonReady" state as default.

code:
void Update()
{
	if (Input.GetKeyDown(KeyCode.A))
		{
			anim.SetTrigger ("cannonActive");
		}

	if (Input.GetKeyUp(KeyCode.A) && CDFlag == false)
		{
			StartCoroutine (Cooldown ());
		}
}

IEnumerator Cooldown()
{
	CDFlag = true;
	Instantiate (CD, transform.position,transform.rotation);
	anim.SetTrigger ("cannonInactive");
	Instantiate (macroF, transform.position,transform.rotation);

	yield return new WaitForSeconds (1);
	CDFlag = false;

}

Here's the animator flowchart:


Any ideas?

Edit: Couldn't figure out how to fix the animation so the cannon is now inactive while the cooldown is going on.

Chernabog fucked around with this message at 17:34 on Oct 18, 2016

Lork
Oct 15, 2007
Sticks to clorf
Are you sure your transition between cannonReady and cannonStatic doesn't have an exit time? If it does, it won't happen unless your condition is met at the specified point in the animation.

Chernabog
Apr 16, 2007



Yeah, they are both unchecked.

Lork
Oct 15, 2007
Sticks to clorf
Can you post a screenshot of the transition editor for that transition?

Chernabog
Apr 16, 2007



Yeah, I'll take it tomorrow.

Luigi Thirty
Apr 30, 2006

Emergency confection port.

I'm working on a new Atari ST challenge!



Does anyone know anything about board game AI? Cause I sure don't! I know that Othello AI is simple but I've never done any AI programming, especially not on something as limited as a 68K...

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Luigi Thirty posted:

I'm working on a new Atari ST challenge!



Does anyone know anything about board game AI? Cause I sure don't! I know that Othello AI is simple but I've never done any AI programming, especially not on something as limited as a 68K...

MCTS is all the rage these days. The result improves iteratively, too; you can probably get good results on low powered hardware.

Luigi Thirty
Apr 30, 2006

Emergency confection port.

leper khan posted:

MCTS is all the rage these days. The result improves iteratively, too; you can probably get good results on low powered hardware.

It's as simple as performing as many random games as you can and keeping track of which move led to the most victories? That's easy enough even on a 16-bit computer and even lets me implement difficulty levels easily by cutting down the time to think.

Linear Zoetrope
Nov 28, 2011

A hero must cook

Luigi Thirty posted:

It's as simple as performing as many random games as you can and keeping track of which move led to the most victories? That's easy enough even on a 16-bit computer and even lets me implement difficulty levels easily by cutting down the time to think.

Not quite, that's known as rollout. MCTS is a bit more involved, but not by much. It's still running random games, but the key is that it tries to focus on running promising looking random games. Rollout works quite well, but it takes a long time and takes a lot more samples per move to return a good action.

The general idea is that you start with an empty tree, and at each node You try each potential action at least once, and create a subnode for the resulting state (note that state is important, a single action yields multiple possible states since your opponent isn't taking the same move every time, this is the key thing that makes it better than minimax, which assumes the opponent will pick the "best" action). After creating a subnode, you run a completely random game and bubble up the reward, adding it to the total reward you've seen for that action so far (in your case it can just be 0/1 for loss/win). Now, for every node at which each action has been tried at least once, you use a heuristic you can look up based on the number of times an action has been tried in that state and the reward to select which action to pick. The heuristic essentially balances exploring promising actions and not neglecting actions you simply haven't gotten enough information for.

It may be a little bit involved, but should be doable in a really low level language. It'll probably be a bit problematic keeping track of the Action->Substate Nodes without having a library function to hash the state, though.

I know that's a bit dense, I can write it in pseudocode if it'd be more helpful.

E: You can probably get poor-man's MCTS by never expanding the tree past the root and just using rollout with the heuristic. I have no idea how well it'd work. It's much easier to implement in a low level language, but also limits the recognition and exploitation of "promising" moves to depth 1. It'll be better than straight random rollout, but I don't know by how much. Limiting the max depth before you stop creating subnodes and auto-rollout is another way to control difficulty/computation time, but of course requires you to implement the full algorithm.

Linear Zoetrope fucked around with this message at 22:40 on Oct 19, 2016

Luigi Thirty
Apr 30, 2006

Emergency confection port.

I'm doing it in 68k ASM but I do have a C compiler and most of a C stdlib in case I need it in my tools package. Currently the "game" isn't much more than drawing 16x16 blocks on a blank board anyway so I've got a ways to go before writing an opponent. Sure cool to do it on an Atari though!

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
I'm playing around a bit with Box2D and am wondering why I'm getting pixel-wide gaps between everything? It looks like this:



My body generation code:

C++ code:
void Box2DManager::addBody(glm::vec2 pos,glm::vec2 dims, bool isStatic) {
    bodyDefs[numBodies].position.Set(pos.x,pos.y);

    if(isStatic) {
        bodies[numBodies] = world.CreateBody(&(bodyDefs[numBodies]));
        shapes[numBodies].SetAsBox(dims.x*0.5f,dims.y*0.5f);
        bodies[numBodies]->CreateFixture(&(shapes[numBodies]),0.0f);
    } else {
        bodyDefs[numBodies].type = b2_dynamicBody;
        bodies[numBodies] = world.CreateBody(&(bodyDefs[numBodies]));
        shapes[numBodies].SetAsBox(dims.x*0.5f,dims.y*0.5f);

        fixtureDefs[numBodies].shape = &(shapes[numBodies]);
        fixtureDefs[numBodies].density = 1.0f;
        fixtureDefs[numBodies].friction = 0.3f;
        bodies[numBodies]->CreateFixture(&(fixtureDefs[numBodies]));
    }

    numBodies++;
}
And my vertex definition code (OpenGL 3.3)

C++ code:
void sprite_manager::addSprite(const glm::vec2& pos, const glm::vec2& size, const glm::vec3& color) {
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    float interleavedData[] = {
            -0.5f*size.x , -0.5f*size.y ,  color.r,        color.g,        color.b, (float) spriteIndex,
            0.5f*size.x  , -0.5f*size.y ,  color.r,        color.g,        color.b, (float) spriteIndex,
            -0.5f*size.x , 0.5f*size.y  ,  color.r,        color.g,        color.b, (float) spriteIndex,
            0.5f*size.x  , 0.5f*size.y  ,  color.r,        color.g,        color.b, (float) spriteIndex,
            -0.5f*size.x , 0.5f*size.y  ,  color.r,        color.g,        color.b, (float) spriteIndex,
            0.5f*size.x  , -0.5f*size.y ,  color.r,        color.g,        color.b, (float) spriteIndex
    };
    glBufferSubData(GL_ARRAY_BUFFER,spriteIndex*6*(sizeof(glm::vec3) + sizeof(glm::vec2) + sizeof(float))
                    ,6*(sizeof(glm::vec3) + sizeof(glm::vec2) + sizeof(float)),interleavedData);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    setVM(glm::translate(glm::mat4(),glm::vec3(pos.x,pos.y,0.0f)),spriteIndex);

    spriteIndex++;
}
I'm using an orthographic projection that runs [0;6.4] in X and [0;4.8] in Y with a 640*480 viewport.

E: It's fixed if I add a .015 bias to the dimensions of the quad for rendering, but I feel like I shouldn't have to do that?

Joda fucked around with this message at 19:19 on Oct 21, 2016

Jewel
May 2, 2009

Jsor posted:

Not quite, that's known as rollout. MCTS is a bit more involved, but not by much. It's still running random games, but the key is that it tries to focus on running promising looking random games. Rollout works quite well, but it takes a long time and takes a lot more samples per move to return a good action.

The general idea is that you start with an empty tree, and at each node You try each potential action at least once, and create a subnode for the resulting state (note that state is important, a single action yields multiple possible states since your opponent isn't taking the same move every time, this is the key thing that makes it better than minimax, which assumes the opponent will pick the "best" action). After creating a subnode, you run a completely random game and bubble up the reward, adding it to the total reward you've seen for that action so far (in your case it can just be 0/1 for loss/win). Now, for every node at which each action has been tried at least once, you use a heuristic you can look up based on the number of times an action has been tried in that state and the reward to select which action to pick. The heuristic essentially balances exploring promising actions and not neglecting actions you simply haven't gotten enough information for.

It may be a little bit involved, but should be doable in a really low level language. It'll probably be a bit problematic keeping track of the Action->Substate Nodes without having a library function to hash the state, though.

I know that's a bit dense, I can write it in pseudocode if it'd be more helpful.

E: You can probably get poor-man's MCTS by never expanding the tree past the root and just using rollout with the heuristic. I have no idea how well it'd work. It's much easier to implement in a low level language, but also limits the recognition and exploitation of "promising" moves to depth 1. It'll be better than straight random rollout, but I don't know by how much. Limiting the max depth before you stop creating subnodes and auto-rollout is another way to control difficulty/computation time, but of course requires you to implement the full algorithm.

You can probably also run this on your own powerful computer and save the heuristics in some kind of map that the game just indexes into. Kind of like old games storing trig tables.

Mastigophoran
Oct 1, 2016

Not exactly immortal...
but close enough

Chernabog posted:

I have a cannon sprite that is working mostly fine, except that if I activate it twice before the "cannonActive" animation is over it won't reset to the "cannonStatic" (idle) and will stay on the "cannonReady" state as default.

code:
void Update()
{
	if (Input.GetKeyDown(KeyCode.A))
		{
			anim.SetTrigger ("cannonActive");
		}

	if (Input.GetKeyUp(KeyCode.A) && CDFlag == false)
		{
			StartCoroutine (Cooldown ());
		}
}

IEnumerator Cooldown()
{
	CDFlag = true;
	Instantiate (CD, transform.position,transform.rotation);
	anim.SetTrigger ("cannonInactive");
	Instantiate (macroF, transform.position,transform.rotation);

	yield return new WaitForSeconds (1);
	CDFlag = false;

}

Here's the animator flowchart:


Any ideas?

Edit: Couldn't figure out how to fix the animation so the cannon is now inactive while the cooldown is going on.

Hi, sorry for not seeing this and responding sooner, I think the solution to your problem is probably pretty simple.

You're probably better off, for this purpose, not using an animation tree like this, with animator triggers etc; you might be better served by using eg anim.Play("cannonShoot", -1, 0f); - this would have the animator jump to the correct animation when you want it to, and then just have that animation fall through states with an exit time into your idle state. One of your problems is (probably) that triggers are 'sticky', and will stay on triggered on until that trigger is read (or reset) for some reason, and you don't prevent the trigger from being reactivated if you push the A key again while it is cooling down, but you do prevent the coroutine from restarting if it as active, which is likely why your animation states are getting jiggered. I'd probably declare a Coroutine variable in my class, store the result of StartCoroutine, and StopCoroutine if it s being interrupted as appropriate.

You might also find that, if these are using unity's animation system, that animation events might tie in better, rather than having a separate coroutine to try and tie things together - these allow you to call monobehavior methods with an animation. It's kind of hard to get a full handle on what exactly the system you have here is doing, but I'm sure it should be possible to accomplish it.

Luigi Thirty
Apr 30, 2006

Emergency confection port.

Jewel posted:

You can probably also run this on your own powerful computer and save the heuristics in some kind of map that the game just indexes into. Kind of like old games storing trig tables.

Precalculating on my big-rear end PC is cheating! :colbert:

It needs to fit in 1MB of RAM and a 720K floppy for maximum period-accuracy anyway.

Jewel
May 2, 2009

Luigi Thirty posted:

Precalculating on my big-rear end PC is cheating! :colbert:

It needs to fit in 1MB of RAM and a 720K floppy for maximum period-accuracy anyway.

That doesn't sound like cheating at all! It's the equivalent of the devs of a c64 chess game leaving their computers on for weeks to precalculate a table to put in their game. And yeah, that means you just have to precalculate it in a minimal way!

Chernabog
Apr 16, 2007



Mastigophoran posted:

Hi, sorry for not seeing this and responding sooner, I think the solution to your problem is probably pretty simple.

You're probably better off, for this purpose, not using an animation tree like this, with animator triggers etc; you might be better served by using eg anim.Play("cannonShoot", -1, 0f); - this would have the animator jump to the correct animation when you want it to, and then just have that animation fall through states with an exit time into your idle state. One of your problems is (probably) that triggers are 'sticky', and will stay on triggered on until that trigger is read (or reset) for some reason, and you don't prevent the trigger from being reactivated if you push the A key again while it is cooling down, but you do prevent the coroutine from restarting if it as active, which is likely why your animation states are getting jiggered. I'd probably declare a Coroutine variable in my class, store the result of StartCoroutine, and StopCoroutine if it s being interrupted as appropriate.

You might also find that, if these are using unity's animation system, that animation events might tie in better, rather than having a separate coroutine to try and tie things together - these allow you to call monobehavior methods with an animation. It's kind of hard to get a full handle on what exactly the system you have here is doing, but I'm sure it should be possible to accomplish it.

Thanks, that's very helpful. I'll look into it in the future and report back.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
Is it considered bad practice to have mutators and accessors as member functions on components in ECS? I need to know for every frame whether or not the transformation, alpha or animation frame for a given renderable object has changed so I can update the uniform buffer if it has, and not make changes if it hasn't. For this I need a flag that tells the render system whether or not the data has changed, which would be done best by calling a mutator that automatically sets the flag. I could set the flag manually in the movement/physics system without needing any member functions, but then I'll have to remember to do that every time I change the members, which is just begging for hard-to-track bugs.

Is there a good solution to this that I've just overlooked?

evilentity
Jun 25, 2010

Joda posted:

I'm playing around a bit with Box2D and am wondering why I'm getting pixel-wide gaps between everything? It looks like this:

For performance reasons there is an accuracy limit. This also would probably not be visible if your bodies ware of a reasonable size. Within order of magnitude of 1x1 is reasonable as far as its concerned.

Adbot
ADBOT LOVES YOU

Polio Vax Scene
Apr 5, 2009



I fuzzily remember back when I was trying out Box2D a couple years ago I ended up making everything 10x scale due to a similar issue. So a 16x16 pixel box would be 160x160 'units' big.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply