It’s FMV, so it’s no surprise they didn’t animate it. There’s basically no way of making it look good.
But if your graphics are all computer-generated then there’s nothing stopping you.
Forget the abstract concept of “nodes”. You’re using tiles, so just think of them like that.
You need a set of “open tiles” and “closed tiles”, and both kinds hold the position of said tile, the position of its parent tile, and the cost of getting to that tile.
When the algorithm starts, your open tile set contains the starting point. After that the algorithm will naturally expand outwards by querying neighboring tiles, which are very easy to find on a tilemap.
struct PathPoint {
// Node position
int16_t x, z, y;
// Parent node position
int16_t pX, pZ, pY;
}
static int cmpeq(struct PathPoint a, struct PathPoint b) {
return a.x == b.x && a.z == b.z && a.y == b.y;
}
// This function checks if the node is free (1 = free)
static int walk(struct PathPoint p, int dx, int dy, struct PathPoint *ret) {
p.pX = p.x, p.pZ = p.z, p.pY = p.y;
p.x += dx, p.y += dy;
p.cost++;
*ret = p;
// Clearly it must be in-bounds
if(p.x >= 0 && p.x < game_W && p.y >= 0 && p.y < game_H) {
// Game-specific logic here to determine which tiles can be walked on
return 1;
} else return 0;
// My game was 3D so this made entities fall downwards
size_t ind = GAME_POINTTOINDEX(p.x, p.z, p.y);
while(!game_Map[ind] && ret->z > 0) {
ind -= game_H;
ret->z--;
}
if(game_Map[ind]) ret->z++;
return 1;
}
// Returns index if exists, else -1
static int in_list(struct PathPoint p, struct PathPoint *list, size_t listLength) {
for(size_t i = 0; i < listLength; i++) {
if(cmpeq(list[i], p)) return i;
}
return -1;
}
// My heuristic function (chess distance)
static uint32_t chessdist(struct PathPoint a, struct PathPoint b) {
return max32(max32(abs32(a.x - b.x), abs32(a.y - b.y)), abs32(a.z - b.z));
}
size_t pathfind(struct PathPoint start, struct PathPoint end, struct PathPoint **result) {
// List of open nodes, in order from least to most costly
size_t openCount = 1;
struct PathPoint *open = malloc(sizeof(*open));
*open = start;
size_t closedCount = 0;
struct PathPoint *closed = NULL;
while(openCount) {
// Get first (least costly) node from open set
struct PathPoint p = open[0];
memmove(open, open + 1, sizeof(*open) * --openCount);
closed = realloc(closed, sizeof(*closed) * ++closedCount);
closed[closedCount - 1] = p;
if(cmpeq(p, end)) { // If p == end (we've found a path, now return it)
size_t padhCount = 1;
struct PathPoint *padh = malloc(sizeof(*padh) * padhCount);
padh[0] = p; // Starting with p (not end cause p has proper parent information)
// Go back through all the parent information to reconstruct the path
do {
int idx = in_list((struct PathPoint) {.x = padh->pX, .y = padh->pY, .z = padh->pZ}, closed, closedCount);
padh = realloc(padh, sizeof(*padh) * (padhCount + 1));
memmove(padh + 1, padh, sizeof(*padh) * padhCount++);
*padh = closed[idx];
} while(!cmpeq(*padh, start));
free(open);
free(closed);
*result = padh;
return padhCount;
}
// Try all eight neighbours
struct PathPoint candidate;
for(int dx = -1; dx <= 1; dx++) {
for(int dy = -1; dy <= 1; dy++) {
if(walk(p, dx, dy, &candidate) && in_list(candidate, closed, closedCount) == -1) {
// We can walk here!
candidate.cost += chessdist(candidate, end); // Apply heuristic
// No point in adding to the open list if it is already there
int openListID = in_list(candidate, open, openCount);
if(openListID == -1) {
// Add to the open list
// Find the correct index to keep it sorted
int i;
for(i = 0; i < openCount; i++) {
if(open[i].cost > candidate.cost) {
break;
}
}
open = realloc(open, sizeof(*open) * ++openCount);
memmove(&open[i + 1], &open[i], sizeof(*open) * (openCount - i - 1));
open[i] = candidate;
} else {
// Update parent information if we've found a shorter path to this node
if(candidate.cost < open[openListID].cost) {
open[openListID].cost = candidate.cost;
open[openListID].pX = p.x;
open[openListID].pZ = p.z;
open[openListID].pY = p.y;
}
}
}
}
}
}
failed:
free(open);
free(closed);
*result = NULL;
return 1;
}
I’ve added comments, but if I’m honest this isn’t much different to the pseudocode in Wikipedia.
From a C perspective there’s plenty of room for optimization, but it works. In C# there’s almost certainly an automatic sorted list/set or priority queue class in the standard library.
The way I handled this was to only create nodes as the algorithm went. The tilemap was your usual multi-dimensional array (as I assume yours is), and only when added to the open set was a tile turned into a graph vertex. This way, the graph is always as small as it needs to be for the algorithm to work.
With a tilemap you have no need to store an entire graph data structure, because the tilemap has a clear pattern. For instance, the for each neighbor of current
part of Wikipedia’s pseudocode is as simple as indexing to the neighboring tiles of the tilemap ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1), etc.)
The heuristic function can just be the straight-line distance to the target tile.
I have example code, but it is in C, is 3D, and it’s my C code, which makes it naturally a mess. Not sure if you’d like to see it.
This partly goes back to the part where the logical framerate feels too low. Falling feels instantaneous and you have very little time to react (and I don’t think it’s my reaction time either, though it was late yesterday).
My suggestion is to add the option of lowering gravitational force, especially if you won’t be increasing the logical framerate.
Not sure if this is intended, but I found myself spamming up and down to keep my level steady. I wouldn’t get rid of this though; it felt pretty rewarding when I discovered this trick.
I made it to the first checkpoint and then some. Being a few minutes before I considered quitting, I think it was placed rather well.
However, I would suggest a mode where the acceleration is a slightly lower. In addition, what is the logical framerate of the game? It’s a bit jarring for such a tight, fast-paced platformer to have its character move by like 10 pixels when you tap left or right once.
All in all, I liked it. May even consider playing some more later. I already spent more time than I’m willing to admit.
Ah, yes. Looks like that one has custom CSS enabled. You must contact support to get that. However, there’s a reason why it isn’t allowed by default. It is possible to make very good pages without, and CSS can be abused.
I don’t know what your jam looks like, but I have a feeling it’s more to do with that than any lack of CSS.
Technology being neutral doesn’t make it harmless. I don’t hate technology. I even said in my last post when technology should be used. But if it is used solely as a convenience, its users will inevitably devolve.
if there’s a new technology that prevents accident a lot more than driving your own truck and it’s way more friendly to the environment, then it’s undoubtedly better than professionally hiring a truck driver,
Disagreed, other than the environment part, which has nothing to do with this.
Of course I meant professionally. That’s what we’re talking about in the first place. Skill and labor should be rewarded, not stripped away. If a producer minimizes all labor and his own effort, that just shows me how little he cares about his product.
A driving accident means a skill deficit, which is solved by improving, not the reverse.
Type of jobs die and new are borns, the same professional can upgrade his skills to keep up with the changes, the problem here is people losing their means of income due to how fast these changes happen and the main point of it all: profit driven society.
Those same professionals shouldn’t have to upgrade their skills to support the degeneracy of humankind. If millions of people wish to drive trucks, they have that right. Likewise with art.
Wait, “upgrade”? Lol.
Do you use a car? or the internet? supermarkets? Online shopping? Aren’t these leading to better quality of life?
Yes, and people have never felt like they had an emptier life. Only in a very naive, short-term view are these technologies improving quality of life. All technologies attempt to isolate us from eachother, the real world, and dumben us to the point we cannot live without them. That is nothing to glorify, and especially nothing to enforce upon all of us.
And for the record, all of your examples I in fact strive to use minimally. Furthermore, I haven’t used a smartphone since 2017.
It’s the typical technophile rhetoric to suggest that if technology A was replaced by technology B, then it justifies technology C in doing the same, without any regard for all intricacies involved. This fundamental assumption is ridiculous, and has no basis.
Technology is great when it lets us stay sharp and grow sharper, not revert into fetuses. As that technology grows more advanced, the less does that apply.
I think I do understand your point, but if you had the convenience of making GTA V effortlessly, then you will have replaced hundreds of people’s jobs, and yourself put in 0 effort (by definition) in return for some gain. Hence that convenience would give you profit.
Somebody profits pretty much anywhere when convenience is involved, irregardless of the kind of society. This is why I equate the two – they’re identical in meaning but are applied in different areas of life. Any time you make use of a convenience, somebody suffers. Could be you, or somebody else. The question isn’t that, but whether that suffering worth it.
I think it’s useful to look deeper into the meaning of convenience. If you don’t then we’ll have to agree to disagree.
Those are some huge steps. Doing the same as we’ve done in the past makes no rational sense on its own. Secondly, even if AI is one or two steps higher, you still have to explain why that is a good thing. If you ask me, that most developers don’t know Assembly is a bad thing.
I wouldn’t compare GPT to RenPy at all. The latter is still programming, whereas the former is banging your head against a wall. I don’t want people to be dumbfucks. At some point, a line must be drawn.
Convenience can be defined as putting in less for equal or more gain. That differs little to none from the definition of profit.
Furthermore I have seen little to no evidence that more automation generally leads to higher life satisfaction. If a machine does more, then your own actions are less consequential, hence you are lesser as a person.
Giving an aircraft listener as a single example doesn’t prove the general case. There, the person does basically the same overall work with the radar as they did before, so its less of an issue. This is the same reason why digital art isn’t as controversial as AI art.
So no, I don’t agree that it would be great if you could make a GTA V game effortlessly. If that were the case, then you’d be doing almost zero work, hence the game isn’t made by you. And even if it were, nobody would care because they can make their own GTA V game. In your scenario, every person would be a profit-driven entrepreneur.
Not sure if you’re looking for arguments or something of the sort. Either way, I’m strongly against the automation of any good job, and devaluing of skill.
I’ve had some cases to which I’m sympathetic. One developer here uses AI as a last resort and wishes to switch to humane art once they are able to afford it. That, of course, brings its own problems. A lot of things suddenly become “too expensive” once people have the opportunity to avoid it.
My values heavily influence what I look for in products as a consumer. If I see AI, 99% chance I’m going to avoid it. It’s like Chinese products.
It’s not wrong if you use the word developer to mean someone who gets something “developed”, and that etymology goes way further back than computers. The people who write code are then both programmers and developers.
According to etymonline.com, “the modern uses are figurative and emerged in English 18c. and after: Transitive meaning “unfold more fully, bring out the potential in” is by 1750;”
Characters in my head don’t really have any set appearance, as my thoughts and imagination are too fluid to make any decision until I’ve actually drawn them on paper. I’m sure almost everyone is like this. I draw characters and other things multiple times until I get something I like, and with practice I should be able to do it quicker in time.
You can also consider hiring a concept artist, who’d enjoy the opportunity.
I don’t have anything empirical, but I’ve come to the conclusion that this mostly depends on the replay value of said game.
YouTubers might hinder story-based games, should they do full playthroughs and so spoil their audience. I’ve seen some publishers explicitly request them to not finish any let’s play, or they set a hard line. Something like this was done by the devs of At Dead of Night.
EDIT: I don’t mean to imply story-based games have zero replayability. One could have branching paths, alternate dialogue, easter eggs, yada-yada.
I did not say nor imply that it’s impossible.
Either way, your “technically yes” answer means just as much as my no – it’s useless to someone with his knowledge. The amount you put out would overwhelm him to the point of simply giving up.
I too could’ve made an essay on how to setup a VPS and (insert 50 obscure programming terms), “technically”, but I found it would’ve made me the ass instead.