I have no idea about developing for Sony PSP. This answer presumes limited target hardware, and the goal of a simple 2D engine.
No, not money.
Your game will have a time budget and a memory bugdet.
The memory budget is how much it can have loaded at the same time. If you load a large tilemap, that consumes your memory budget. Similarly, if you load entities, that consumes your memory budget too. Thus, smaller tilemaps leave budget for more entities, and viceversa.
The time budget is how much time you can expend updating things between frames. If the code takes too much time, then your frame rate drops. If you are applying a "the world move, the player is stationary" strategy, that takes some of your time budget. And if you update too many entities, that also takes of your time budget.
Limited hardware means small budgets. Every feature will have some cost in these budgets. Implement within what you they can afford.
Tiles vs Entities
These are guidelines to keep in mind when consider which to use.
Giving that tiles exist in tilemaps, moving tiles is very limited (it is constrained to the grid of the tilemap). Thus, if something move, prefer using an entity. If it doesn't prefer a tile. Assuming that tiles don't move is OK.
Having multiple similar tiles is cheap. However, multiple entities are expensive. Thus, if something appears a lot, prefer using tiles. If it appears sparsely, you might use entities.
Having custom logic in entities is cheap. You might be able to attach logic to tiles, however they would always be loaded being expensive in memory (or if you decide to load and unload them on demand, it becomes expensive in time). This implies that having a lot of disparate logic attached to tiles is a bad idea. Thus, prefer using entities for custom logic. Even if they don't need to move. Only attach logic to tiles if it is very, very, common logic. Assuming that tiles don't have logic is OK.
Tiles and The World
Because of the limited hardware, we want to only be concerned to what is present on screen, which is what we need to render. To do that we create the world with tilemaps. The simplest implementation of the tilemap is an array of tiles (this is not great for large tilemaps, but I'm assuming that the memory budget is low for large tilemaps anyway).
It is also important to know how much the player can see in tiles. Bigger tiles, means less tiles on screen. Which is cheaper.
These are some options that would work on low hardware:
- We can keep a tilemap of what is on screen. The camera is stationary. And when the player reaches the edge of the screen we load and transition to a different tilemap.
- We can keep a tilemap of what is on screen. The camera can move. When it does, we update the tilemap, moving the tiles, and loading newly revealed parts of the map from storage.
- The tilemap does not have to be exactly what is on screen. We can have areas which are larger than what fits on screen, and only render the parts visible according to the position of the camera. When the player moves to another area, we load it as a whole.
Yes, they all work. However, they expend your budgets in different ways. For example, the first option will use less of both budgets if you need them for other things. However, if you don't, you might be able to afford something else.
What goes in a tile? An index. It goes to a table that has what to render (probably an offset in a texture atlas, perhaps even some means of animation), if it is passable (for physics, or a physics layer if you can afford that feature), and perhaps other things too. In particular, if it is the start position of an entity, so when they enter view you add their entities.
If you want to purchase the feature of logic attached to entities, you have an entry in that table for the custom logic, you can have triggers to run it when they enter view or when an entity collides. Example: a tile that causes damage on contact.
Special offer: You can have multiple tilemap render layers. You could also use them for parallax. Purchase now and receive completely free picture render layers for background and foreground.
I do not even know if there is a file system, nor if it is performant. If there isn't a performant file system, then hard-coding it is an option. It makes little difference if you design the map on a map editor or on paper. You need to encode it, either in a format that you code can parse, or as code directly. Just think as code as another file format.
However, you need to consider how you will query it. Will you be loading areas? It would make sense to split the world accordingly. Also, the code would have to either give you tilemps or individual tiles.
Entities and Physics
Then the game can iterate over the alive entities, to perform their physics and whatever logic is necessary.
I have some special offer feature for you, purchase now:
Keep track of which entities you updated last frame, and don't update those this frame. Or you can keep track of how far along the list of entities you managed to update, and start from there next frame. You may even assign entities to a "List A" or "List B" on creation, and update them on alternating frames. Costs memory, saves time.
Do not update entities that are not outside of view. When an entities is out of view, remove it. Costs time, saves memory.
Implement an Object Pool. keep a list of allocated-but-not-alive objects to be recycled. Costs memory, saves time.
Limit the total maximum of alive entities. If there are already too many, you don't add more. Costs time, saves memory.
What goes in an entity? A position, a sprite (you probably want to be able to animate it, and you may want to have either multiple sprite or sprites of different sizes), an update function, and a collision function. These functions should be able to call engine methods (e.g. play a sound).
Since we are going for simple engine, you would use invisible entities (i.e. entities without sprite) to perform any additional game logic. This was a staple of early game engines.
You will also need z-ordering/y-ordering. You could either keep a sorted list of the entities by their vertical position. Other clients that saw this product also saw: give them a z position and sort by that. But wait, there is more: you could assign them render layer, you render the layers in order, and each layer keeps a sorted list.
The simplest to implement is discrete physics, with euler integration, and for response simply aligns the entity to the gird of the tilemap.
We don't need to think about tile-tile collisions here (any code moving tiles should handle that). We only need to worry about entity-tile and entity-entity. Simplest collision for entity-tile is to get the range of tiles that the entity touches, and query if they are passable or not. For entity-entity AABB-AABB collision would work. Assuming that we only keep alive entities that are on screen, we don't have to worry about spase partitioning.
If an entity collides, you call its collision function (assuming it has). When an tile collides, you may trigger some logic attached to the tile, if you took that feature.
Offer for connoisseurs: You could have the concept of physics layers and mask. Not passable tiles could be on a layer reserved for them, or could specify a layer on the tiles. For each entity you specify on what layer it is, and with which layers it can collide. Should render layers also be physics layers? That makes the engine simpler, but also constraints what you can do. Since we are going for simple engine, yeah, sure. Although any layers could be considered a luxury item.
However, you may want more complex physics in some cases. Depending on what you want on the game. For example: Do you want slopes? Do you want bouncing? Do you want moving platforms? And so on.
Make sure to leave budget for the features the game needs. And if you have extra budget, you can afford some fancy features.