Since Oblige 3 has NO kek'n documentation whatsoever because the Earth is indeed flat and NOT round (God Damnit J.K.Rowling), I'm going to show you how to make a module myself. We'll start with the basics.
THE MODULE INDEX
We'll assume you made an empty file for this, because there is no better way to do it than to do it yourself. The first thing that's going to be required is the actual module's summary index. We'll toss it at the end of the file, like so:
Code: Select all
OB_MODULES["squishy_two_monsters"] =
{
label = "Squishy Monster Cake 2",
for_games = { doom2 = 1 },
for_engines = { zdoom=1, gzdoom=1, skulltag=1 },
}
The Label field is the name of your module. Make it short but descriptive, it is usually the name of your mod. This is what people will see when they load up your script into Oblige. If you cuss here, other people will see it and know who to blame.
The for_games field is 100% self-explanatory. It names the games that your mod supports, in this case Doom II. The for_engines field is also self-explanatory, in this case which ports the mod runs with. In this case, ZDoom, GZDoom, and Skulltag.
MONSTERS
Now let's do the most basic of basics, and tell Oblige about our cool new monsters, otherwise they won't show up in maps and it'll be normal! There must be so many new monsters that I cannot see the regular monsters anymore! First we need to make a MONSTERS table, and put at least one monster in it. Let's take the, hmm, Dimensional Master first.
Code: Select all
SQUISHY_MONSTERS =
{
dimensional_master = -- Monster's identifier. This must be unique per monster, obviously, just like in Decorate.
{
-- Chance of appearing per room. 20 makes them fairly rare.
prob = 20,
-- Total health of our new monster, in HP. This sucker has so much HP it makes the Cyberdemon blush.
health = 12000,
-- Damage our monster does. Note that this is *per second*, so it can be higher than the basic attack's damage if it attacks more than once per second (eg. Chaingunners). He'll kill you just by looking at you.
damage = 700,
-- The type of attack our monster uses. Choices are "missile", "hitscan", or "melee". We only tell Oblige about the most likely attack it is to use. Never use melee unless there are really no ranged attacks at all. Missiles are easier to dodge, and thus less damage is done overall.
attack = "missile",
-- The amount of monsters that may appear in any given room. 1.0 spawns about 4 or 5 in every room, 0.1 makes them appear only once every 4 or 5 rooms. We want this sucker to be very alone, because he is very powerful.
density = 0.1,
-- A special field for annoying and powerful monsters. This is the chance out of 256 that they will just *not* appear at all in a level. We don't want to see dimensional masters very often, especially NOT every level because he is just that bad, so we make the skip chance rather high.
skip_prob = 150,
-- This is also special, this prevents the monster from being used more than any other monster in the level, a special case oblige tends to make on one monster for each level. We don't want to be taking on more than one dimensional master per room if it DOES appear, so let's be forgiving.
never_promote = true,
-- Tells Oblige that this monster gives ammo when you kill it. Ammo is the name and count is the amount of that ammo it gives. Note that it is also an array, so if a monster drops multiple ammo types, oblige will know and adjust accordingly.
give =
{
{ ammo = "dimensional_ammo", count = 1 },
{ ammo = "ethereal_ammo", count = 1 },
{ ammo = "light_ammo", count = 1 },
{ ammo = "dark_ammo", count = 1 },
},
},
}
Code: Select all
SQUISHY_THINGS =
{
dimensional_master = -- This MUST be the same as the monster's identifier in the MONSTERS table.
{
-- ID is the DoomEdNum of the creature, after its' class name in the Decorate.
id = 9397,
-- The type of object. This is a monster.
kind = "monster",
-- The size of the monster, in (R)adius and vertical (H)eight.
r = 20, h = 56
},
}
Code: Select all
OB_MODULES["squishy_two_monsters"] =
{
label = "Squishy Monster Cake 2",
for_games = { doom2 = 1 },
for_engines = { zdoom=1, gzdoom=1, skulltag=1 },
tables =
{
"monsters", SQUISHY_MONSTERS,
"things", SQUISHY_THINGS,
},
}
What's a mod without new weapons? I've heard at least ten people complain on this forum alone that they hate the original weapons by now, so let's mess with them for kek'n science!
The first vital thing is to know how to remove weapons. Since we want to nuke ALL of the weapons from the regular maps, let's just name all of the doom weapons:
Code: Select all
SQUISHY_WEAPONS =
{
berserk = REMOVE_ME,
saw = REMOVE_ME,
shotty = REMOVE_ME,
super = REMOVE_ME,
chain = REMOVE_ME,
launch = REMOVE_ME,
plasma = REMOVE_ME,
bfg = REMOVE_ME,
pistol = REMOVE_ME,
}
Now, let's add some new weapons. Below the slew of remove-me's is where the new weapons go. Now let's look at a definition:
Code: Select all
ultraslow_plasma =
{
-- Weapon preference. This is how much we prefer to give ammo for this weapon over other weapons.
pref=85,
-- Probability of adding. The higher this is, the earlier and more likely the weapon is to appear in the middle of the level. If we omit this, we will not consider putting it down in the middle of a level.
add_prob=20,
-- Same thing as above, but this is how likely the weapon is to show up in the start room with you. If we leave this out, Oblige will refuse to put this weapon in the start room.
start_prob=10,
-- Rate and Damage are linked. Rate is how many shots you can take in a second, and damage is how much damage each shot does directly to one monster. The total damage you can do with this weapon is basically (rate * damage), assuming perfect accuracy. Oblige knows better though.
rate=1,
damage=70,
-- This is a special sort of field. If the gun has the ability to inflict damage upon more than one monster at once, this tells Oblige about it.
splash={60,45,30,30,20,10},
-- The kind of attack. Choices are "missile", "hitscan", or "melee". It's the same field as in monster definitions above. Again, we only take the most powerful offensive attack into account, and ignore the alt-fire if there is one.
attack="missile",
-- The ammo that this weapon uses. This will be discussed a bit later.
ammo="cell",
-- How much ammo each shot of this gun uses. For example, one shot of the BFG uses 40 cells.
per=10,
-- Rarity is a special field. It is similar to skip_prob for monsters, in that it makes a weapon not appear in a level. This is a divisor though, so a weapon with rarity 5 will only have a 1 in 5 chance of appearing in any given level.
rarity=2,
-- How much initial ammo the weapon's pickup gives. Feel free to omit this if you start with the weapon.
give={ {ammo="cell",count=20} },
},
Now let's tell Oblige that we have a new starting weapon as we removed the pistol:
Code: Select all
SQUISHY_PLAYER_MODEL =
{
doomguy =
{
stats = { health=0, bullet=0, shell=0, rocket=0, cell=0 },
weapons = { fist=1, ultraslow_plasma=1 },
}
}
We add the new tables to the module index with the following lines:
Code: Select all
tables =
{
"monsters", SQUISHY_MONSTERS,
"things", SQUISHY_THINGS,
"weapons", SQUISHY_WEAPONS,
"player_model", SQUISHY_PLAYER_MODEL,
},
But wait! We told Oblige earlier that there are new ammo types! We'll need to alert the generator about what these ammo types or it'll be all confused and weird-like! Let's make an AMMOS table for immediate rectification of this emergency.
Code: Select all
SQUISHY_AMMOS =
{
dimensional_ammo = { start_bonus = 5 },
ethereal_ammo = { start_bonus = 5 },
light_ammo = { start_bonus = 20 },
dark_ammo = { start_bonus = 10 },
}
And since we changed the ammo that the player can has, we tell the game about it by changing the stats accordingly.
Code: Select all
SQUISHY_PLAYER_MODEL =
{
doomguy =
{
stats = { health=0, cell=0, dimensional_ammo=0, ethereal_ammo=0, light_ammo=0, dark_ammo=0 },
weapons = { fist=1, ultraslow_plasma=1 },
}
}
Now we'll need to do some maintenence to tell Oblige more about these ammo types, particularly how we acquire more ammo from the map. We update the THINGS table to add their physical devices. Let's assume there are two dimensional ammo pickups, big and small, which give 5 and 1 respectively, their doomednums being 9021 and 9022.
Let's also make a new powerup and call it the LOLSphere. It has doomednum 31337.
Code: Select all
dimensional_ammo_big =
{
id = 9021, kind = "pickup", r = 20, h = 24
}
dimensional_ammo_small =
{
id = 9022, kind = "pickup", r = 16, h = 16
}
lolsphere =
{
id = 31337, kind = "pickup", r = 20, h = 56
}
And now, powerups! This is a truly gross hook--err hack. Since Oblige doesn't properly support placing down powerups as secondary search items, we will tell Oblige that they're worth health! I know, it's a very ugly method of doing things, but it works! Because typically those powerups are gonna save us health anyway by allowing us to kill enemies or evade their attacks better, so it's true.
NOW we will make a new table called PICKUPS to handle stuff we can grab off of the floor, how disgusting. Let's tell Oblige about all three of our super duper pickups.
Code: Select all
SQUISHY_PICKUPS =
{
dimensional_ammo_big =
{
-- The probability that this pickup will be used over other pickups that give the same ammunition.
prob = 10,
-- The main statement. This is what the pickup is expected to give you. Possible choices are ammo and health. Both are self-explanatory.
give = { { ammo = "dimensional_ammo", count = 5 } },
}
dimensional_ammo_small =
{
prob = 40, -- Prefer small pickups over large ones
-- This makes oblige prefer to put down this many pickups in a row, rather than just spreading them all over the room willy-nilly. the syntax is { min, max }, which makes oblige only put down between min and max items per spot.
cluster = { 1, 4 },
give = { { ammo = "dimensional_ammo", count = 1 } },
}
lolsphere =
{
prob = 2 -- Powerups should always be RARE.
-- If this is true, then the item will be treated like a powerup and placed in the center of the room if possible instead of being thrown to the side like ammo where it's harder to pick up.
big_item = true,
-- If this item gives health, then we need to know if it can save us if we have *no* health. If armor is true, then we will prefer to not use this item when the player is guaranteed to have low health. Generally you want this to be true for powerups unless it can actually save you from imminent death, like Invulnerability.
armor = false,
-- Let's pretend this item gives you 120% extra HP. Note that this will make health NOT appear normally otherwise, so be sparing with it. Higher values will make the item more rare along with prob, so it will take tweaking to make a good powerup.
give = { { health = 120 } },
}
}
Code: Select all
tables =
{
"monsters", SQUISHY_MONSTERS,
"things", SQUISHY_THINGS,
"weapons", SQUISHY_WEAPONS,
"player_model", SQUISHY_PLAYER_MODEL,
"ammos", SQUISHY_AMMOS,
"pickups", SQUISHY_PICKUPS,
},
If there are any comments and questions, feel free to post and I'll try to clarify anything that needs clarifying. This is only a basic gameplay modding tutorial and does not go over texture selection and what not, but if it is requested enough, I'll write one for that as well.