0
\$\begingroup\$

I've been developing a 2D shooting platform videogame for the Sony PSP console using only the ONELua interpreter for the Lua programing language (since there is not any game engine for it). Despite its many useful modules, it doesn't come with tools to create platformers, because ONELua is not a game engine itself.

So I need to figure out how to implement my camera, maps and some other stuff myself. Since Lua is a scripting language, I've been applying best practices and an OOP approach in order to make it scalable and maintainable.

Despite researching a lot, all I'm finding is about Unity, GameMaker, Godot or any other already invented wheel:

  1. How would you make a 2D platformer map so that it interacts with environment (other objects, enemies, etc.)?

  2. Is the map represented by a matrix (kind of RPG map)?

  3. The objects should be hardcoded, I mean, do they have a fixed position?

    This last question is because I've read the code form another very similar project but the code has been hardcoded so I consider it as not very maintainable and scalable (since it has more than 1k lines of code in just one script), however at the end it could be hardcoded using some creational map tools, couldn't it? If so, I guess all above questions would be answered.

Based on the code that I've read, I surmise that I would put every object at a fixed position using a level editing tool, applying physics to move those physical objects and so on. Then, if the player "moves" (it would stay in the center of the screen simulating moving, just with a walking animation) then move the whole world (objects and environment) would approach the player, but I think it wouldn't be the best approach for performance.

\$\endgroup\$
2
  • \$\begingroup\$ Looks like you have a starting point, you should go ahead and try this! \$\endgroup\$
    – Vaillancourt
    Apr 24 at 3:13
  • 1
    \$\begingroup\$ It looks like you have multiple questions here: 1) How to author your map data, 2) How to instantiate objects according to that map definition, 3) How to implement a scrolling camera view, 4) How to implement various other object behaviours. The answer to any one of these questions will not answer the others, so you should focus on just the first step first. Ask a separate question if you want help implementing a moving camera, or other steps after that. \$\endgroup\$
    – DMGregory
    Apr 24 at 12:34
0
\$\begingroup\$

I have no idea about developing for Sony PSP. This answer presumes limited target hardware, and the goal of a simple 2D engine.


Budgets

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:

  1. 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.
  2. 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.
  3. 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.

\$\endgroup\$
3
  • \$\begingroup\$ thanks a lot for your answer. Now I have got almost everything clear. I'm thinking to implement a combination of both (Tile and entity), I mean, since I'm doing a 2D fan-videogame which is based on a 3D videogame that has large maps, and so, it has big areas to show, then my idea is having a matrix of areas which every index has its own entities so that they can replace the entities to the current handling systems and finally compute those entities. \$\endgroup\$
    – E. P.
    May 3 at 20:04
  • \$\begingroup\$ The only think I'm struggling is how to implement an efficient algorithm for rendering entities inside the camera's viewport. I've read that quadtrees are good for that task but not sure at all. My idea is load the whole "world" (matrix which in each index it has entities), put such entities into the systems (render, physics, etc.), and using the camera, just print those that are visible and finally calculate world, screen and camera coordinates. What do you think about? \$\endgroup\$
    – E. P.
    May 3 at 20:04
  • \$\begingroup\$ @E.P. If I understand correctly you will have an array of areas, where each area has entities. You must be able to take a position and compute the position on the array of areas for that position. Doing that, you must be able to get the area where the camera is. And render only the entities there. You may need to render also adjacent areas (for example, if the camera is near the edge, of the areas are too small for the visible area). If areas are too big for the visible area, then you can imagine diving areas into sub-areas, in a tree-like structure… A quadtree if you always divide in four. \$\endgroup\$
    – Theraot
    May 3 at 20:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.