Author Topic: Generating special and boss levels  (Read 156 times)

Simon-v

  • Posts: 2
    • Personal website
Generating special and boss levels
« on: June 23, 2017, 12:56:35 AM »
Good day to all¸

I tend to find the boss levels included in Oblige repetitive. More variation would be welcome, but it's a lot of work to be done, for too little gain. Instead, i envisioned abandoning pre-built boss levels altogether, and having special, secret and boss levels generated by a normal, but slightly modified set of rules.

Example 1: Map 30

Use the normal generation algorithm. Use the "crazy" monster toughness setting. Assign higher weights to outdoor areas. Optionally, add a monster spawner somewhere on the level and monster teleport spots all over the place. Have the level end by a crusher switch. Result: Map 30 is fun to play, and is quite obviously the end-game.

Example 2: Secret maps 31/32

Use the normal generation algorithm. Use a higher monster count setting than normal (optionally, lock it to "nuts"). Use a higher monster strength setting than normal. Spawn a BFG9000 right in the starting room. Result: Maps that play very close to Plutonia's.

Example 3: Map 07

Use the normal generation algorithm. Force map size to "small". Use mancubi exclusively in the first half of the map. Use arachnotrons exclusively in the second half of the map. Result: Basically, a dead simple Dead Simple.


My question, therefore, is as follows:

I haven't had the opportunity to study Oblige's scripts yet. What changes need to be introduced to them to have the described effect? Where do i need to look? In other words, where would the "if map_number == 30 then ..." go?

andrewj

  • Developer
  • *****
  • Posts: 1419
Re: Generating special and boss levels
« Reply #1 on: June 24, 2017, 04:26:00 AM »
Your ideas for those special levels are quite good (perhaps not to my personal taste though).

They won't be trivial to implement though, but I can give some advice on what code to look at.

Firstly, special levels can be marked in the file games/doom/levels.lua in the DOOM.get_levels() function.  That is were prebuilt maps are handled (well partly).

The secret maps are already marked using "is_secret" field by that code.  I suggest starting with these for your experiments.

So to force monster amount to high in secrets, look in file scripts/monster.lua there is a function called calc_quantity().  What you can do is add a line right at the start which checks for a secret level and returns a high number.  For example:

Code: [Select]
local function calc_quantity()
    --
    -- result is a percentage (how many spots to use)
    --
    if LEVEL.is_secret then return 100 end

Forcing a BFG9000 in the start room is harder.  Hmmm.... you could do it by editing the visit_start_rooms() function in scripts/quest.lua and adding a line at the start:

Code: [Select]
local function visit_start_rooms()
  if LEVEL.is_secret then table.insert(LEVEL.start_room.weapons, "bfg") end

Play with that and see how you go.

Simon-v

  • Posts: 2
    • Personal website
Re: Generating special and boss levels
« Reply #2 on: July 07, 2017, 11:33:47 PM »
Thank you for the hints.

Seeking proper encapsulation, i was able to figure out the basics of module-making. Among other things, i found it possible to modify the VM state via hooks, one of which i immediately put to use, disabling the prebuilt map 30, to allow Oblige to generate it normally.

As i discovered, Oblige's default generation algorithms are quite good, and only ever need slight nudging. Here, i need clarifications.

I collected a list of hooks referenced in other modules. Are there any others available, but unused? When do they trigger? What data is available to them? In fact, i have to admit that, at present, the VM state at any given point is mostly a black box to me. I would, for example, like to:

1. Nudge the amount of monsters slightly up for a specific level. I trust the existing engine to handle the strength for me;

2.1. Increase the number of boss encounters for a specific level AND increase their variety; OR

2.2. Manually specify a set of boss encounters for a level and make sure all of them are placed.

A command line flag that would cause Oblige to generate only the desired levels would also be helpful: waiting for the full 32-level wad to finish generating is rather tiresome.

andrewj

  • Developer
  • *****
  • Posts: 1419
Re: Generating special and boss levels
« Reply #3 on: July 08, 2017, 06:58:19 PM »
The hooks are quite limited in what they can do.  Three main ones are:

(1) the "setup" hook which is called very early on (and once only).
(2) the "get_levels" hook, called later on (but once only)
(3) the "begin_level" hook is called before building each map

The hooks will modify global state, e.g. begin_level hooks often change things in the "LEVEL" table (information about the current level being generated).  Another example, the setup hooks in the Monster Control modules will modify the GAME.MONSTERS information (which is safe to modify since it is a copy of the original tables).

The hook system is too limited to do what you asked.  Some of the existing hook functions only work because the main scripts have code which checks for the changes they make.

If you want to change what boss monsters are used on a level, you need to look at code in scripts/levels.lua, especially the decide_boss_fights() function, e.g. add code which creates a FIGHT table explicitly for a specific monster.

Lastly, you can build only a single map by adding this on the command line:
Code: [Select]
only=MAP30