jam
- 26 Devlogs
- 74 Total hours
A 2D puzzle game based off of solving traffic jams, written in C++ with SFML (no game engine).
A 2D puzzle game based off of solving traffic jams, written in C++ with SFML (no game engine).
Cars now fade out when they despawn and when they reach a destination! So when I sent this to a friend they got confused why cars kept disappearing, so I added this.
When a car reaches the destination, the car will fade out green, but if the car despawns because it has no route it will fade out red. This was actually harder than it seems because my code was just basically freeing the car class as soon as the car reached the destination, but I changed the code so it would decrement a counter before deleting itself and use the counter to change the color of the car.
So basically since the beginning of this project, I’ve been just putting ARIAL.TTF in the assets folder. It turns out that thats actually illigal and copyright infringement (oops), so I’ve switched to a different open-source font (and I included the license/attribution). I’ve also cleaned the repository history to remove any lingering font files so I’m not violating copyright or anything.
Besides that, I’ve created the first release, v0.1.5 (the 4 before were all broken/tests/copyright font issues). I used AI to help me write the github actions workflow (because like literally NO ONE knows how to do that) and got builds for Linux, MacOS, and Windows. I’ve only tested it on windows so far, but I’ll try and test linux on a VM later.
Anyway, I’ll be continuing to work on the game and make some UI/UX improvements.
So I tried putting SimCity style buildings and it didn’t really go very well. I think its mainly because
Other than that, I also updated the stats screen to make it look better and more easily show the requirements.
I got some more friends to try my game and got lots of feedback. Here’s what I added:
I’ll keep working on more UI/UX upgrades. The game is looking a lot nicer now too!
So I showed this to some of my friends and got some very helpful feedback especially on UX.
Feature improvements:
Bugfixes:
Overall, I don’t plan to make many more changes and will probably just add another 3-5 levels, work on the title screen, and get the game ready for shipping.
There were two major bugs that I fixed today:
I also updated the buttons and added a 4th level where cars are going both directions. It’s actually pretty hard to reach the target.
I also changed the pathfinding to take into account the speed limit of the road and put penalties for going through routes with more intersections.
I’ve added a background, two different car assets, and 3 different levels! I also upgraded the buttons (but I forgot to apply them to the simulation window, so you’ll see them in the next devlog). Additionally, I added dragging in the simulation window, which was in the Editor but not the Simulation for some reason.
There were also two major bugs that I fixed today:
Well, all 4 road types are now added so I can safely say that I am done with ALL the major parts of the game!
I also added anti-aliasing so the roads don’t look so jagged anymore. One lane roads were surprisingly easy (only like 2 easy bugs in the code) because most of the work I already did was generic enough to accept a road with 0 lanes on the left side. The rest of the time will be spent polishing everything up! Here’s my idea list so far:
Roads can no longer be placed overlapping other roads! Implementing this feature might seem really easy, but actually it was really, really annoying. One main problem was that SFML doesn’t have a native way to check if two sprites/rectangleShapes are intersecting so I had too implment the Separating Axis Theorem to check if two arbitray rectangles are intersecting. I also had some issues with rotating (wrong origin), but thankfully I fixed that pretty quick.
Anyway, I think the only thing left is to add all the road types (I’m planning on 1-lane one way, 2-lane one way, 2 lane road, 4 lane road, and maybe 6 lane road) and polish everything up!
I spend the last 4 hours working on the UI! So now when you start the game, you will see a simple title screen where you can start a new game from one of the levels (not shown in video) or load a saved game. Then you can go into the core gameplay loop: edit -> simulate -> stats screen (now shows pass/fail based on level conditions!).
It was mostly tedious to write every single ui class, but at least I finished most of the UI. The remaining things that I need to do is add more road placement constraints (no overlapping), add more types of roads, and POLISH! I’ll be working on those for the next two weeks until the end of Stardance I guess.
Pretty self explanatory I guess? The UI is still pretty horrible, so I’m still going to have to work on that. I couldn’t figure out how to get choose a folder, so I’m just using the portable-file-dialogs library. The file saving is pretty straightforward, you just choose a folder and it saves there.
The file format is pretty simple because it only saves the layout you made. Later, I’ll probably polish up the save dialogue and implement loading from the file. I might also work on the level selector screen or the stats screen to show how well you did!
Roads can now be demolished! Also, if you are in demolish mode and you hover over a road, it will highlight the road red. Some roads cannot be demolished, only roads that you placed can be demolished.
This feature seems really simple but it was a huge pain to implement, mostly because of the crazy amount of pointers to other objects everywhere. Also, remember how I said I shouldn’t be using size_t for both physical and internal IDs, well that came back to bite me. I spent like an hour debugging that, but at least that’s fixed now!
As you can see in the video, intersections now are filled grey and it actually looks okay. The main issue currently is that if an intersection only has two roads or if the roads are really close together, it causes the polygon to look quite skewed. I’ll probally be working on that next.
This was an absolute nightmare to do. Mostly because my previous code was not designed at all to do this. I had to hack together a solution where below a certain threshold the car is in the intersection. This has some side effects of sometimes the car goes slow in the intersection and sometimes fast, but I think its reasonable (tighter curve = slower?).
The biggest issue is that my code was designed assuming the two roads on the intersection were symmetrical (idk why i did that) so I had to basically re write the whole intersection code.
IDK why but earlier when I first made the BFS I was lazy and just used number of roads. Well, now it uses real road length to calculate distance. I had some problems involving queues and stuff, but it was pretty straightforward to get Dijkstra’s working.
The video just shows a case where the old algorithm would choose the super long route because it had less roads, but now it correctly chooses the shorter route.
As you can see in the video, the biggest improvements are the road preview and clicking [ESC] cancels building the road. The road preview also shows whether the road is valid. I had a ton of issues with the coordinate systems (there are like 3 different ones! pixels, global, view), but I was able to figure it out.
There wasn’t anything very complicated, but next time I’ll add some kind of visuals at intersections and probally work on fixing BFS.
The video also demonstrates additional features. The UI is still a bit simple, but that isn’t really the number one priority.
To do this, I reworked the game loop to use a new state variable to control if the screen would show the editor, simulator, or stats window (notice how it no longer opens a new window). I came across some bugs involving cars going the wrong way on roads and the app crashing if I added a new intersection (that was because I mixed up internal and external IDs).
Next, I think I will add a scoring system or a save load system. If you have any ideas on features that you think would make this better (besides the obvious), let me know!
As you can see in the recording, without drawing the roads, the cars just stop at the intersection because they cannot find any routes (gaps between roads are intersections, I’ll fix that later). By drawing a road, the cars can drive to their destination in the simulation.
The biggest issue I had while coding this was mixing up physical IDs and internal IDs, which are not interchangable (I should have probally used a class or struct to represent IDs instead of a raw size_t).
Next, I’ll work on making the intersections look better and maybe get some statistics on how well the cars preformed at the end of the simulation!
I spent almost 6 hours to refactor my code to use a much cleaner ownership system that should completely prevent memory leaks and have much better separation of the static parts of simulation vs. parts that area ctually getting simulated.
In a nutshell, what I did was make two classes, Layout and Simulation. Layout always exists and is the thing that is drawn on screen. Layout doesn’t have any cars or moving stuff and you can edit layout. When you start a simulation a NEW simulation object is created with all the cars which can simulated it. The clean split makes it a lot easier to know everything and edit/save stuff which might be usefull later.
I had to do a lot of changing and if you look at the git commit basically every file was modified, but now the architecture is much cleaner.
Next, I’ll work on adding the Simulate button and making a new window show up with the cars to simulate it.
So now I know why smart pointers are discouraged! So my ownership model was really screwed up and super confusing and I had some crazy memory problems and segmentation faults so I reverted back to yesterdays commit and am going to refactor the code to use SMART POINTERS (wow) and have a better ownership model.
I feel pretty sad that I basically made no progress with 3 hours of work but I guess I learned something?
SO the new plan is that Layout class will handle all things that are static in simulation and are just there (roads and intersections, both physical/logical) and Simulation will only handle all the cars and driving around. The EditorWindow class will have a pointer to (but now own) Layout so it can modify Layout but not Simulation. The SimulationWindow class will have a smart pointer to (and own) a simulation (fresh) and PhysicalCar s. This should help clarify ownership and prevent memory management issues.
I had to refactor a bunch of my code to use stuff allocated on the heap because I, stupidly, decided to initialize a bunch of my objects on the stack in a loop, causing a lot of the pointers to become hanging. Oh well, now I just have to make sure to remember to delete the allocated objects.
Some plain and dirty presets can be loaded and the textures look pretty bad, but it will look a lot better pretty soon. I’m going to work on adding the first player interaction: allowing the player to add a road by clicking twice. I expect this might be a bit hard and school’s starting so it will probably be a while before I post another devlog (depending on how hard it is for me to add it)
I also might try to get the road offsets and intersections better so it is more playable.
It’s a bit messy but if you look closely you can see the car follow the road (that road is supposed to be a 4 lane road but I didn’t draw it), switch onto a lane on the side, and keep accelerating. The framework has been built to easily expand to different types of roads like one way, 2 lane, 4 lane, etc.
Next I’ll start working on getting the car to transition at intersections and finish the simulation portion. Then I can get started on working on the player interaction part!
The traffic lights now enforce lane rules (cars must be on a certain lane when light is green to go to the next lane). The traffic lights are also auto generated in a bit of a “dumb” way. The traffic light just gives turns to each incoming road to go wherever they want and all other roads cannot go. Later, I might allow valid right turns, but that’s a problem for later.
Although I haven’t implemented the BFS search for the cars, given a route cars will now look ahead to the next intersection and randomly auto merge onto the lane (the cars are more likely to merge when they are closer to the intersection). This is to make sure that cars won’t all merge at the same time, which would be weird.
JAM is a puzzle video game about solving traffic jams! I don’t have much experience writing video games so this will be a first for me (although I have plenty of regular c++ experience). So far I’ve just written the very very basic car driving logic and have it printed out to the debug console (I plan to add actual graphics once core logic is done).
Currently I’ve got simple one-lane roads working and some really stupid intersections, but I’m working on multi-lane roads, merging, traffic light schedules, and cars actually waiting at intersections!