I used to deal only with "ice cream" (illegal weapons) trading, buying in one city and selling them on another, to quickly earn lots of money, and then buying commercial spots but never opening them (too much hassle, having to micro-manage shops).
But after having bought about 200 or so, the game would inevitably crash a few weeks after my save file, so in the end I stopped playing it. I never got the exact details about the bug, but I hope this remake won't have it!
Besides that, the most fun thing was trying weird pizza recipes and seeing that the taste algorithm was a bit weird. I could put lots of chicken, or pineapple, and mix a few ingredients, and have some age groups rate them very highly.
But sabotaging the competition was still funnier than handling a normal business.
anyways i've been looking for offline, open source games so thanks for sharing.
Then you could take advantage of the deep simulation capability, not worring about traffic and things like that - for your Bookstore Tycoon or Donut Tycoon franchise.
The English version had some bizarre translation quirks, but those just add to the retro charm.
One time I found a bug where the game would crash if you followed a courier into an enemy HQ building while they had guards inside (I guess they kill the courier, which then leads to a null reference or something?). When the game crashed I was so scared that I had broke my grandpa's computer. Good times.
The only thing it was missing was multiplayer. I hope that somebody creates a full OpenRCT2 style remake of it someday; it has so much potential for online multiplayer and wacky mods.
There's always a simple explanation for anything that looks too complicated for an old game to do.
is that much of anything for a 25MHz CPU? We're talking about something cycling 25 million times per second, surely that's not such a big deal for a 386?
Eg storing the delta between items rather than tracking position directly, because the distance between cars is static for the length of the road, except during compression, insertion or removal of a car
At each choice cell, you just weigh the turn lower than going straight when randomly deciding. And if you don't want U-turns, you set a rule like it describes, or any sort of "cooldown" on turning.
Same principle applies to on-chain computation: gas costs force you to find closed-form solutions. For example, computing φⁿ (golden ratio to the power n) naively requires n multiplications. Using the matrix identity [[1,1],[1,0]]^n via repeated squaring gives you O(log n) — and the Fibonacci numbers fall out for free. The old game devs would have appreciated EVM constraints.
edit: actually if it hits an end of a road, it spawns to a lane next to it either goes opposite direction or turns (referencing first gif)
Wonder if they could have considered ensuring no cars stack on top of each other
There were many games growing up that gave me such a warped view of what was to be expected from the hardware. Battletoads, Crash Bandicoot, Marathon Trilogy (Macintosh), Age of Empires (Multiplayer), Roller Coaster Tycoon (of course).
that pizza will set you back 0 USD because rounding error, the dough is free (if I remember well) and a bit of minced tomato is less than a rounding error, so effectively zero
then you sell the pizza for the lowest price
customers will hate it, but the price is so good
you don’t even need ice cream anymore
Being able to do millions of things each second should enable all sorts of behaviors, especially for a game of the era when you asked the OS to kindly step aside while you run your program.
8bit like Nes (Nesjam late may/june), Gameboy(GBJam was last year, bi-annual), Atari,etc, but also for MSDOS, Amiga and more "mid-school" platforms together with semimodern like PS1.
Now, even with modern tools it's plenty of work to get impressive things working on older platforms (I had a Gameboy techdemo last time there was a compo that's due to grow ridiculously much).
https://www.youtube.com/watch?v=pGCoLh3NL7g
It's all about the lanes and the flow.
Pizza Tycoon was one of those games we got years later for £5 in some repackaged "Classic Games" collection but it came without a booklet or anything.
Supposedly the booklet was the key to getting the pizzas right as it had all the instructions on which elements were needed & where. (I heard someone say they used this as an antipiracy thing as without the booklet, it'd be playable but impossible, not sure if that's true lol)
We used to just cargo cult our way to good pizzas.
Pizza Tycoon was the US market name, internationally it was released as Pizza Connection
Reminds me of this. I found their video that had a breakdown of some of what they needed to do to make a game fit on NES really fascinating!
... but they'll be just as entertaining?
https://en.wikipedia.org/wiki/Frontier:_Elite_II
You could do the slingshot effect in it.
For older games, I would say the original Prince of Persia. I played it on an 8088 machine, and it was pretty impressive how he made the animations sophisticated and smooth.
As to why I did this; when I had some time between university and starting a job many years ago I was looking for a hobby coding project and was inspired by TTDPatch and OpenTTD so I figured I'd do the same but for Pizza Tycoon. No specific reason other than that I played the game a lot as a teenager and there were some small things that I found annoying, so I saw some room for quality of life improvements. Fully aware that not many people care about this game (also didn't really expect to really get very far tbh), but still I had (and have) a lot of fun and learned a lot in the process of writing a modern engine for this.
Maybe an issue would be people not all having the same type of hardware though? Maybe you target an emulator. (Some Fantasy Consoles sort of count here?)
I haven't looked expensively but some of the retro themed jams were missing the "spirit" I was expecting.
I did a Nokia jam a while back — monochrome, beeps — and I remember being kind of annoyed that the rules technically allowed 3D Unity games as long as they followed resolution and color palette.
(A 3D cube spinning on a TI calculator is a different matter ;)
The thing is a belt is modeled in terms of deltas rather than positions--there is no need to move each object each cycle. An object has a distance from the object in front. When the belt moves forward this relationship does not change--no need to update every pointer (and there can be a *lot* of belts in the game!) If the head of a belt can't move you only need to update one delta--the gap between the first free item and the stuck item in front of it and that value can already be known, no need to search. If you move the free item up against the stuck item you walk down the belt to find the new first free item.
You only need to modify the belt model if something is either added or removed from the belt. Objects get removed only by inserters, inserters examine only one cell of the belt, grabbing anything in that cell that matches what they are willing to grab (if they are feeding a machine they will only grab what the machine wants, otherwise they'll respect the filter list assigned to them.) When something gets added to a belt you add it to the list and update the delta of the object behind. No general update of the belt is needed in any situation, any more than you need to do anything to the items in a queue as you add and remove items.
Factorio is a game about optimization and the developers did a very good job of applying that idea to the game math. That is, until the masses of asteroids in the Space Age DLC.
The main difference from factorio belts I think is actually in the insertion — if there’s no room in the belt, insertion is blocked; whereas I’d expect a car to “slip in”.
But I think you can still say that maintains the property that a compressed belt will always be compressed, excepting insert/removal; and insertion/removal just requires updating a static number of deltas (2, in the middle of the line, 1 at the end of it)
Good luck! It's not always about the destination :P
They definitely do. I recommend GP check out PICO-8 which has some VERY real games on it like the original Celeste (by its original creators), Cattle Crisis, POOM, Combo Pool, Into Ruins, Dank Tomb, UFO Swamp Odyssey, Porklike, and much more. Most of which you can play on Itch.io for free in your browser.
I’ve been having a blast making a “real” and very full-featured PICO-8 game to serve as a “market fit” prototype — if a PICO-8 game on Itch gets meaningful attention, I’ve “found the fun” and therefore I should make “the full version” (non-PICO-8) for Steam, etc.
The way it worked was you had to offer at least a few pizzas that were reasonably close to recipes from the booklet in order to get any customers. Once you had that, you could get creative with custom recipes but if you only did custom recipes, you were bound to fail.
Speaking of your last comment: while very impressive, I feel a bit disappointed when someone's done something amazing with a Game Boy or SNES or whatnot, but the solution involves shoving an entire computer in the cartridge. This is still very cool but your console just becomes a head unit for your GTX 4080 or whatnot.
I've been working on Pizza Legacy, an open-source reimplementation of the 1994 DOS game Pizza Tycoon. The game has a close-zoom street view of the cities, and when you scroll around it you can see a steady stream of cars driving through the streets. Maybe 20 or 30 tiny sprites at a time, but they navigate the road network, queue behind each other at intersections, and generally look like a living city. Yes, it was a bit buggy because sometimes they would drive through each other, but it was good enough to just give some sense of life to the map. All that on a 25 MHz 386 CPU.
The first thing I implemented in 2010 when I started this project was that close zoom level, but it took 14 years before I finally had the cars driving around on it, in a way that I was happy about; I had multiple attempts over the years but every time I ran into problems I got stuck building an overly complicated system that was hard to reason about and no fun to work on.
One attempt in 2017 involved each tile keeping track of which positions were occupied, and every car had to ask the grid for permission before moving, reserving and freeing slots as it went. It basically turned into a shared locking system just to move a few pixels, with cars and tiles constantly trying to stay in sync.
All the while I had this nagging thought in the back of my mind: the original Pizza Tycoon ran this on a 25 MHz CPU, so why were my versions always so complicated?
Finally I went to the assembly (which I had spent many years slowly understanding better and documenting) to figure out what the original was doing, with the help of LLMs which were (a couple of years ago) this new and exciting technology that could better understand assembly than I could.
Now that I finally have it working I can see where I went wrong: I went into it with a brain full of modern concepts: scene graphs, path finding, collision detection, and of course plenty of CPU to run it all!
First, let's look at what a city actually looks like:

As you can see there are two-lane roads, T-junctions, intersections, and corners. In Pizza Tycoon maps are made up out of a grid of 160 by 120 tiles, where each tile is one of the tiles from landsym.vga:

The original landsym.vga file with added borders between tiles and text to indicate the row and column offset. Byte 0x54 means column 5, row 4 (roof tile of a depot).
Back to the traffic; the key insight that makes it possible to run this system on such a slow CPU: cars don't need to know where they're going. Each road tile type carries its own direction. Road tile 0x16 is the bottom part of a horizontal road, meaning that cars can only drive from left to right on these roads. Similarly road tile 0x06 is just for right to left traffic, then 0x26 and 0x36 are the same but for vertical traffic.
This means the city is basically just a bunch of one-way roads, once a car knows which tile it sits on, it can keep going.
Corners work the same way, 0x56 (CORNER_SW in my enum) is the corner that allows the car to either keep going west, or turn south. When a car hits a corner it flips a coin, 50% chance of going straight on, 50% chance of taking the turn. The maps have been designed in such a way that the roads always make sense, which means that next to the CORNER_SW there is another tile that is either a south to north traffic (so we have to go south) or it's another edge tile that allows either a turn or straight on.
There is one extra rule to keep traffic looking natural, if you just took a left turn the next corner forces you straight-on; no two consecutive left turns.

Valid directions per tile type indicated with arrows.
Cars move one pixel per frame. Each tick the main loop checks if a car is blocked, and if not, increments or decrements its screen coordinate by one depending on direction. East adds 1 to X. North subtracts 1 from Y.
There's a second progress counter, counting down from 16 to 1. When it hits zero it resets to 16 and the game runs the tile-boundary logic: look up the next tile, decide the new direction, update the sprite frame (to visually turn the car in the new direction). Since each tile is 16 pixels wide and tall, this runs exactly once per tile crossed. The per-pixel move happens every tick; the heavier tile logic runs only 1/16th as often.
When a car first spawns, progress is set to a random value between 1 and 16. That staggers all the cars so their tile-boundary checks don't all land on the same frame, spreading the work out evenly.
Unlike my various attempts at fancy collision detection, the original uses a straightforward pairwise check: for each car, walk the whole car list and ask "would these two overlap next tick?" If yes, set a wait counter of 10 ticks on the blocked car and move on to the next car.
But the collision detection code is written to bail out as fast as possible. The very first thing it does is extract the other car's direction; because roads are one-way, east and west never share a road, so an east car and a west car can never collide. That pair returns immediately, no coordinate reads at all. Same for east and south, west and north, and so on.
With say 25 cars in a typical city view there are 625 pairwise calls per frame. About half of those return in just a few CPU instructions on the direction check alone. Most of the rest fail the lane check (same-direction cars have to be on the same road, which is one equality comparison). The pairs that actually reach any coordinate arithmetic are usually single digits.
When a car does get blocked, the 10-tick wait creates natural traffic jams: cars bunch up, the front one eventually finds the way clear, the queue drains. There are some bugs in the system (especially when you let it run for a while and there are lot of intersections) but given that the point of this is not to run an accurate driving simulation but just show some movement on the screen, it works perfectly well and very efficiently. The collision detection system has some quirks; some combinations are never checked (e.g. eastbound car never intersects with a southbound car) that might be the reason behind some buginess.
When you enter the close-zoom view, the game scans all 132 tiles in the viewport (12 columns by 11 rows), and for each road tile it rolls against the district's traffic density to decide whether to spawn a car there, so higher-traffic districts are busier. Corner tiles are excluded from spawn points, so cars only appear on straight road tiles.
Cars that drive off the edge of the screen are respawned as a new (random) color car facing the other direction, on the tile going the other direction. This means that the game doesn't have to worry about respawning cars other than just every time one car drives of going east it spawns a new car below going west, etc.
Pay attention to the cars driving off the map at the edges, notice they are replaced by cars driving the opposite direction.
When you scroll, the newly exposed strip of tiles gets the same treatment of having a chance of having cars spawned on them.
Looking back at my failed attempts, I was designing for problems that the original just didn't consider. Cars don't need pathfinding because the map tells them where they can go. Collision detection was cheap because the early-exit logic makes most pairs basically free. There's no velocity or physics because 1 pixel per tick is enough to look convincing. When you're about to hit something just pause for 10 ticks, and when you have to make a turn you just travel half the width of the tile and then make your turn, works on every tile in any direction.
I reimplemented it following the assembly pretty closely, so just a couple of switch statements with different routing options per tile type, you can see the decide_desired_direction method in Car.cpp.